This is less important than compiling exception handlers #966 (because just handling throw, which would return to the interpreter anyway, doesn't lead to compiling more code), but leaving an issue as a reminder and a place to discuss that.
TODO
- We could start from calling
rb_vm_throw and propagating ec->tag->state (after JIT-to-JIT calls) to the interpreter, like YJIT does.
- It's more complicated to propagate
ec->tag->state with ZJIT than with YJIT though. ZJIT uses multiple native frames for multiple ISEQ CFPs unlike YJIT, and rb_vm_throw needs to return a non-Qundef value, so the regular side-exit propagation doesn't work. It would need to check ec->tag->state besides Qundef.
- Instead, we might want to consider unwinding multiple frames at once. It could be more efficient than propagating
Qundef or ec->tag->state after JIT-to-JIT calls.
- We could also optimize
Insn::Throw into a jump at the HIR level when the inliner sees both throw and its catch.
This is less important than compiling exception handlers #966 (because just handling
throw, which would return to the interpreter anyway, doesn't lead to compiling more code), but leaving an issue as a reminder and a place to discuss that.TODO
rb_vm_throwand propagatingec->tag->state(after JIT-to-JIT calls) to the interpreter, like YJIT does.ec->tag->statewith ZJIT than with YJIT though. ZJIT uses multiple native frames for multiple ISEQ CFPs unlike YJIT, andrb_vm_throwneeds to return a non-Qundefvalue, so the regular side-exit propagation doesn't work. It would need to checkec->tag->statebesidesQundef.Qundeforec->tag->stateafter JIT-to-JIT calls.Insn::Throwinto a jump at the HIR level when the inliner sees both throw and its catch.