* The startup interpreter used to pop rescue pc entries only when an exception was rescued OR when the exception-end-region marker instruction was executed. However, in the no-exception case, after the ensure code is run, there is a jump that exits the entire rescue region. In this scenario, the exception-end-region marker instruction is completely skipped. This can be seen with this snippet below. When control reaches the final print, there is still a rescue PC on the stack. In most cases, this doesn't matter, but this is still a bug which is waiting to trip us up in more complex rescue-ensure nesting scenarios as in the bug report. ------------------------------ class Foo < Exception; end def foo p 0 begin p 1 raise "whatever" rescue Foo p 2 rescue p 3 ensure p 4 end p 'boo!' end foo ------------------------------ * In this commit, I added a boolean flag to jumps that exit the exception region. In the startup interpreter, this flag is inspected to pop a rescue pc entry. * With this fix, I also undid my change in dbffda3 since this boolean flag also handles that scenario -- I should have caught this issue back then. * This issue doesn't manifest outside the startup interpreter because CFG construction handles everything properly and sets up the right rescue PCs in all scenarios. * I also noticed an unrelated issue -- a duplicate label was being emitted in ensure bodies -- I didn't investigate how/why this didn't cause problems during CFG construction, but evidently it did't.
* Since the additional cost of (implicitly) converting to long is low compared to the convert to double and floating-point operation.
… blocks. If the block references the local var assigned in the argument list before the argument list is processed, it'll end up implicitly declaring a detached local variable with a default value. When the argument list is processed, the local assign will be at a higher level and declare a local variable with the same name, but it'll be shadowed in the block since the block's local variable will be nearer in scope. Fixes #2999: Argument values assigned to local variables not available in block.
Fixes #3001: Incorrect frame used for block variable access.