It seems that OP_JMPUW does not call the ensure block when a is pointing to the beginning of the begin block.
For example:
for _ in [1] begin puts 1 redo ensure puts 2 break end end
Ruby 3.3 will print:
1
2
=> nil
mruby (master) is indefinitly printing 1.
This probably happens because OP_JMPUW is pointing to puts 1, so it interprets it as jumping before puts 1 and after the begin keyword. However, it should jump before puts 1 to outside of the begin block and call the ensure block.
If I understand correctly, the condition should be changed from:
a < mrb_irep_catch_handler_unpack(ch->begin)
to:
a <= mrb_irep_catch_handler_unpack(ch->begin)