typedef struct {
gcc_jit_block *gcc_bb;
+ /* When non zero indicates a stack pointer restart. */
+ gcc_jit_lvalue **top;
bool terminated;
} basic_block_t;
case Bgotoifnonnil:
case Bgotoifnilelsepop:
case Bgotoifnonnilelsepop:
+ case Bpushcatch:
+ case Bpushconditioncase:
op = FETCH2;
bb_start_pc[bb_n++] = op;
new_bb = true;
new_bb = true;
break;
/* Other ops changing bb */
- case Bpushcatch:
- case Bpushconditioncase:
case Bsub1:
case Badd1:
case Bnegate:
++i;
snprintf (block_name, sizeof (block_name), "bb_%d", i);
curr_bb.gcc_bb = gcc_jit_function_new_block (comp.func, block_name);
+ curr_bb.top = NULL;
curr_bb.terminated = false;
}
bb_map[pc] = curr_bb;
comp.bblock->terminated = true;
}
comp.bblock = &bb_map[pc];
+ if (bb_map[pc].top)
+ stack = bb_map[pc].top;
op = FETCH;
switch (op)
}
CASE (Bpushconditioncase) /* New in 24.4. */
- type = CATCHER;
+ type = CONDITION_CASE;
goto pushhandler;
CASE (Bpushcatch) /* New in 24.4. */
- type = CONDITION_CASE;;
+ type = CATCHER;
pushhandler:
{
/* struct handler *c = push_handler (POP, type); */
bb_map[pc].gcc_bb,
push_h_val_block);
+ gcc_jit_lvalue **stack_to_restore = stack;
+ /* This emit the handler part. */
+
basic_block_t bb_orig = *comp.bblock;
comp.bblock->gcc_bb = push_h_val_block;
/* current_thread->m_handlerlist = c->next; */
gcc_jit_rvalue_dereference_field (gcc_jit_lvalue_as_rvalue (c),
NULL,
comp.handler_val_field));
+ bb_map[handler_pc].top = stack;
*comp.bblock = bb_orig;
gcc_jit_block_end_with_jump (push_h_val_block, NULL,
bb_map[handler_pc].gcc_bb);
+
+ stack = stack_to_restore;
++pushhandler_n;
}
break;