return 1;
}
+/*@
+ * @deftypefun int jit_insn_new_block (jit_function_t func)
+ * Start a new basic block, without giving it an explicit label.
+ * @end deftypefun
+@*/
+int jit_insn_new_block(jit_function_t func)
+{
+ jit_block_t block = _jit_block_create(func, 0);
+ if(!block)
+ {
+ return 0;
+ }
+ if(!(func->builder->current_block->ends_in_dead))
+ {
+ block->entered_via_top = 1;
+ }
+ func->builder->current_block = block;
+ return 1;
+}
+
int _jit_load_opcode(int base_opcode, jit_type_t type,
jit_value_t value, int no_temps)
{
int jit_insn_branch(jit_function_t func, jit_label_t *label)
{
jit_insn_t insn;
- jit_block_t block;
if(!label)
{
return 0;
insn->flags = JIT_INSN_DEST_IS_LABEL;
insn->dest = (jit_value_t)(*label);
func->builder->current_block->ends_in_dead = 1;
- block = _jit_block_create(func, 0);
- if(!block)
- {
- return 0;
- }
- func->builder->current_block = block;
- return 1;
+ return jit_insn_new_block(func);
}
/*@
add_block:
/* Add a new block for the fall-through case */
- block = _jit_block_create(func, 0);
- if(!block)
- {
- return 0;
- }
- block->entered_via_top = 1;
- func->builder->current_block = block;
- return 1;
+ return jit_insn_new_block(func);
}
/*@
add_block:
/* Add a new block for the fall-through case */
- block = _jit_block_create(func, 0);
- if(!block)
- {
- return 0;
- }
- block->entered_via_top = 1;
- func->builder->current_block = block;
- return 1;
+ return jit_insn_new_block(func);
}
/*@
jit_function_t temp_func;
jit_value_t *new_args;
jit_value_t return_value;
- jit_block_t block;
jit_insn_t insn;
/* Bail out if there is something wrong with the parameters */
func->builder->non_leaf = 1;
/* Start a new block and output the "call" instruction */
- block = _jit_block_create(func, 0);
- if(!block)
+ if(!jit_insn_new_block(func))
{
return 0;
}
- block->entered_via_top = 1;
- func->builder->current_block = block;
- insn = _jit_block_add_insn(block);
+ insn = _jit_block_add_insn(func->builder->current_block);
if(!insn)
{
return 0;
if((flags & JIT_CALL_NORETURN) != 0)
{
func->builder->current_block->ends_in_dead = 1;
- if(!jit_insn_label(func, 0))
+ if(!jit_insn_new_block(func))
{
return 0;
}
{
jit_value_t *new_args;
jit_value_t return_value;
- jit_block_t block;
jit_insn_t insn;
/* Bail out if there is something wrong with the parameters */
func->builder->non_leaf = 1;
/* Start a new block and output the "call_indirect" instruction */
- block = _jit_block_create(func, 0);
- if(!block)
+ if(!jit_insn_new_block(func))
{
return 0;
}
- block->entered_via_top = 1;
- func->builder->current_block = block;
- insn = _jit_block_add_insn(block);
+ insn = _jit_block_add_insn(func->builder->current_block);
if(!insn)
{
return 0;
if((flags & JIT_CALL_NORETURN) != 0)
{
func->builder->current_block->ends_in_dead = 1;
- if(!jit_insn_label(func, 0))
+ if(!jit_insn_new_block(func))
{
return 0;
}
{
jit_value_t *new_args;
jit_value_t return_value;
- jit_block_t block;
jit_insn_t insn;
/* Bail out if there is something wrong with the parameters */
func->builder->non_leaf = 1;
/* Start a new block and output the "call_vtable_ptr" instruction */
- block = _jit_block_create(func, 0);
- if(!block)
+ if(!jit_insn_new_block(func))
{
return 0;
}
- block->entered_via_top = 1;
- func->builder->current_block = block;
- insn = _jit_block_add_insn(block);
+ insn = _jit_block_add_insn(func->builder->current_block);
if(!insn)
{
return 0;
if((flags & JIT_CALL_NORETURN) != 0)
{
func->builder->current_block->ends_in_dead = 1;
- if(!jit_insn_label(func, 0))
+ if(!jit_insn_new_block(func))
{
return 0;
}
{
jit_value_t *new_args;
jit_value_t return_value;
- jit_block_t block;
jit_insn_t insn;
/* Bail out if there is something wrong with the parameters */
func->builder->non_leaf = 1;
/* Start a new block and output the "call_external" instruction */
- block = _jit_block_create(func, 0);
- if(!block)
+ if(!jit_insn_new_block(func))
{
return 0;
}
- block->entered_via_top = 1;
- func->builder->current_block = block;
- insn = _jit_block_add_insn(block);
+ insn = _jit_block_add_insn(func->builder->current_block);
if(!insn)
{
return 0;
if((flags & JIT_CALL_NORETURN) != 0)
{
func->builder->current_block->ends_in_dead = 1;
- if(!jit_insn_label(func, 0))
+ if(!jit_insn_new_block(func))
{
return 0;
}
func->builder->current_block->ends_in_dead = 1;
/* Start a new block just after the "return" instruction */
- if(!_jit_block_create(func, 0))
- {
- return 0;
- }
- return 1;
+ return jit_insn_new_block(func);
}
/*@
func->builder->current_block->ends_in_dead = 1;
/* Start a new block just after the "return" instruction */
- if(!_jit_block_create(func, 0))
- {
- return 0;
- }
- return 1;
+ return jit_insn_new_block(func);
}
/*@
int jit_insn_default_return(jit_function_t func)
{
jit_block_t current;
- jit_insn_t last;
/* Ensure that we have a builder for this function */
if(!_jit_function_ensure_builder(func))
/* If the last block ends in an unconditional branch, or is dead,
then we don't need to add a default return */
current = func->builder->current_block;
- if(current->ends_in_dead)
- {
- /* The block ends in dead */
- return 2;
- }
- last = _jit_block_get_last(current);
- if(last)
+ while(current != 0)
{
if(current->ends_in_dead)
{
- /* This block ends in an unconditional branch, return, etc */
return 2;
}
- }
- else if(!(current->entered_via_top) && !(current->entered_via_branch))
- {
- /* This block is never entered */
- return 2;
+ else if(!(current->entered_via_top) &&
+ !(current->entered_via_branch))
+ {
+ return 2;
+ }
+ else if(current->entered_via_branch)
+ {
+ break;
+ }
+ else if(current->first_insn <= current->last_insn)
+ {
+ break;
+ }
+ current = current->prev;
}
/* Add a simple "void" return to terminate the function */
@*/
int jit_insn_throw(jit_function_t func, jit_value_t value)
{
- jit_block_t block;
if(!_jit_function_ensure_builder(func))
{
return 0;
return 0;
}
func->builder->current_block->ends_in_dead = 1;
- block = _jit_block_create(func, 0);
- if(!block)
- {
- return 0;
- }
- func->builder->current_block = block;
- return 1;
+ return jit_insn_new_block(func);
}
/*@
@*/
int jit_insn_rethrow_unhandled(jit_function_t func)
{
- jit_block_t block;
jit_value_t value;
#if !defined(JIT_BACKEND_INTERP)
jit_type_t type;
/* The current block ends in dead and we need to start a new block */
func->builder->current_block->ends_in_dead = 1;
- block = _jit_block_create(func, 0);
- if(!block)
- {
- return 0;
- }
- func->builder->current_block = block;
- return 1;
+ return jit_insn_new_block(func);
}
/*@
@*/
int jit_insn_return_from_finally(jit_function_t func)
{
- jit_block_t block;
-
/* Mark the end of the "finally" clause */
if(!create_noarg_note(func, JIT_OP_LEAVE_FINALLY))
{
func->builder->current_block->ends_in_dead = 1;
/* Create a new block for the following code */
- block = _jit_block_create(func, 0);
- if(!block)
- {
- return 0;
- }
- return 1;
+ return jit_insn_new_block(func);
}
/*@
@*/
int jit_insn_return_from_filter(jit_function_t func, jit_value_t value)
{
- jit_block_t block;
-
/* Mark the end of the "filter" clause */
if(!create_unary_note(func, JIT_OP_LEAVE_FILTER, value))
{
func->builder->current_block->ends_in_dead = 1;
/* Create a new block for the following code */
- block = _jit_block_create(func, 0);
- if(!block)
- {
- return 0;
- }
- return 1;
+ return jit_insn_new_block(func);
}
/*@
(jit_function_t func, jit_label_t *label,
jit_value_t value, jit_type_t type)
{
- jit_block_t block;
jit_insn_t insn;
/* Ensure that we have a function builder */
insn->value1 = value;
/* Create a new block, and add the filter return logic to it */
- block = _jit_block_create(func, 0);
- if(!block)
+ if(!jit_insn_new_block(func))
{
return 0;
}
- block->entered_via_top = 1;
return create_dest_note(func, JIT_OP_CALL_FILTER_RETURN, type);
}
first_block->entered_via_top = 1;
/* Create a new block after the last one we moved, to start fresh */
- return jit_insn_label(func, 0);
+ return jit_insn_new_block(func);
}
/*@
if(move_current)
{
func->builder->current_block = func->builder->last_block;
- return jit_insn_label(func, 0);
+ return jit_insn_new_block(func);
}
/* Done */