Make optimized execution preserve exceptional control flow and handler state rather than restricting deoptimization to empty-handler numeric regions.
Acceptance
- Model calls, throwing operations, exception edges, and handler stacks in optimizer frame states.
- Reconstruct accumulator, operand stack, locals, catch/finally records, completion values, and exact resume IP/steps.
- Preserve termination, watchdog, debugger, and host-trap behavior through optimized frames.
- Fail closed before observable work for unsupported call or handler shapes.
- Pass focused differential tests for caught/uncaught throws, nested catch/finally, return/throw through finally, and host exceptions.
Landed checkpoints
a8d094a: deoptimization metadata owns ordered catch/finally records; the VM validates and transactionally replaces locals, stack, accumulator, handlers, and IP, while malformed handler metadata leaves the activation untouched.321b159: optimizer block/edge frame states select owned handler slices; lowering carries them through program ownership into published deoptimization metadata with checked depths and ranges.1ee7e18: structured normal-flow handler dataflow reaches active-catch side exits end to end; mismatched merges, unbalanced pops, calls, and throwing instructions reject before publication.e95f7be: side-exit reconstruction reserves the optimized operand-stack storage before its transactional commit, fixing the shared CI compile failure without changing hot append behavior.0f8bc81: explicitthrowis an optimizer terminal effect with an exact pre-instruction frame state and mandatory native side exit; caught throws and propagation to a caller handler preserve value, handlers, IP, and step counts under normal and TSan tests.3c5f856: normally unreachable handler blocks stay bytecode-only after the mandatory throw exit, enabling nested throw-through-finally while reachable unsupported effects still reject.668bead:abrupt_returnpublishes the return completion and active finally stack before resuming canonical bytecode unwinding.96d74a1: directcallpublishes a pre-effect frame state; function-valued parameters and arguments survive without irrelevant Number guards, while normal results and caught call exceptions resume in bytecode.c3681fc:new_calluses the same pre-effect reconstruction contract for constructor-valued parameters and arguments.5fa8ade: the legacy empty-handler reconstruction fixture explicitly initializes the handler slice, and an unfiltered CI-equivalent unit shard passes 326/326.a95fa40: a conditional-loop OSR differential executes native work, reconstructs the exact header before the 1,024-step boundary, and proves bytecode consumes a pending shell-timeout host trap at precisely step 1,024.89fc073: fresh optimized-loop activations prove cooperative stop, expired-watchdog, and shell-timeout requests all resume bytecode and fire at exactly step 1,024; normal and TSan focused gates pass.ad0b211: optimizer, baseline, and direct native entry now fail closed whenever debugger, host, or profiler statement hooks are installed, even with an existing owner lease and artifact; refusal consumes no steps or native-attempt counters.
Current checkpoint
Complete through 1b812e2, e3cb3bb, and 0cb719d (documentation at c3833eb, bd94239, and 80281cc). Explicit throws own catch/finally SSA edges; deterministic nested catch and finally bodies execute natively; calls, constructors, properties, coercions, and every interpreter-owned effect own exact pre-effect recovery plus exceptional target/unwind metadata. Uncaught throws, caller propagation, nested finally, return and break through finally, caught JS/host call exceptions, property/coercion/environment/iterator exceptions, termination, watchdog, shell timeout, debugger fallback, invalidation, precise stack maps, and moving-GC recovery are covered.
The focused exceptional-target batch passes 4/4 and the combined optimizer TSan filter passes 87/87 with zero failures or leaks. Benchmark scores are unchanged because no published workload changed. Fully executable calls/effects and native dynamic completion dispatch are intentionally tracked as the next implementation layer in #439 rather than weakening this recovery issue acceptance.