Index: vm/jitrino/src/jet/cg_regs.cpp =================================================================== --- vm/jitrino/src/jet/cg_regs.cpp (revision 542415) +++ vm/jitrino/src/jet/cg_regs.cpp (working copy) @@ -625,25 +625,13 @@ targetIsMultiRef = targetIsMultiRef || (m_insts[targetPC].ref_count > 1); } } - - if (to_eh) { - // we're generating a 'goto/fall through/if_' to a basic block - // if the BB is also the catch handler, then it can't have a - // ref_count less than 2. - assert(m_insts[to].ref_count > 1); - // Must have only Exception on the top of stack - assert(m_jframe->size() == 1 && m_jframe->top(0) == jobj); - // if top of the stack is currently not on the gr_ret, then - // force it to be there - assert(m_jframe->dip(0).is_reg() && m_jframe->dip(0).reg() == gr_ret); - } - + if (!targetIsMultiRef && !to_eh) { // nothing to do anymore if (is_set(DBG_TRACE_CG)) { dbg(";;>~bb_leave\n"); } return; } - + for (unsigned i=0; !to_eh && isize(); i++) { Val& v = m_jframe->dip(i); // already in the memory - nothing to do @@ -699,6 +687,29 @@ v = Val(jt, m_base, vlocal_off(i)); rref(v); } + + if (to_eh) { + // we're generating a 'goto/fall through/if_' to a basic block + // if the BB is also the catch handler, then it can't have a + // ref_count less than 2. + assert(m_insts[to].ref_count > 1); + // Must have only Exception on the top of stack + assert(m_jframe->size() == 1 && m_jframe->top(0) == jobj); + // if top of the stack is currently not on the gr_ret, then + // force it to be there + Val& ev = m_jframe->dip(0); + if (!ev.is_reg() || ev.reg() != gr_ret) { + // locals were just spilled and no other stack items left + // therefore gr_ret must be unused, simply load the Exception + assert(rrefs(gr_ret) == 0); + Opnd reg(ev.jt(), gr_ret); + do_mov(reg, ev.as_opnd()); + rfree(ev); + ev.to_reg(gr_ret); + rref(ev); + } + } + if (is_set(DBG_TRACE_CG)) { dbg(";;>~bb_leave\n"); } } Index: vm/jitrino/src/jet/compiler.cpp =================================================================== --- vm/jitrino/src/jet/compiler.cpp (revision 543439) +++ vm/jitrino/src/jet/compiler.cpp (working copy) @@ -970,8 +970,9 @@ gen_dbg_check_bb_stack(); } - if (bbinfo.ehandler) { - // + if (bbinfo.ehandler && pc == parentPC) { + // This is a 'normal' handler, unreached via fall-through so far + // (otherwise parent bb must leave stack in consistent state). // Here, we invoke gen_save_ret() because this is how the idea of // exception handlers works in DRL VM: // Loosely speaking, calling 'throw_' is like a regular