Consider both "argument scope" and lambda as return jump target#6351
Merged
headius merged 3 commits intojruby:masterfrom Aug 12, 2020
Merged
Consider both "argument scope" and lambda as return jump target#6351headius merged 3 commits intojruby:masterfrom
headius merged 3 commits intojruby:masterfrom
Conversation
In the logic to look for a valid return target, we find a lambda, via `IRRuntimeHelpers.initiateNonLocalReturn` calling `getContainingLambda`. However when we later try to detect if the return jump should propagate as a LocalJumpError (because its target scope is no longer active) we do not do this same search for a lambda (see `IRRuntimeHelpers.checkForLJE`). This inconsistency causes the errors from jruby#6350, because we incorrectly detect the target as the lambda, but do the detection against its parent scope and raise an IRReturnJump with an improper target scope. This jump then bubbles all the way off the stack and never becomes a LocalJumpError. In CRuby, when the lambda becomes inactive, the returnn target moves to the containing return target scope. This means a given return can potentially have two different targets, depending on whether its containing lambda is still on the stack or not. I believe the appropriate behavior in both cases from jruby#6350 is to raise LocalJumpError immediately. In each case, the return target for the proc should be the lambda, but the lambda is no longer active. The return target should not change to the containing scope, because that's not the proper return target. The change here adds the lambda logic to the LJE check, so that it sees the lambda return target is no longer active and eagerly raises the LJE. We will need to reconcile this difference with CRuby, but since this is such an obscure case I doubt it will affect real-world code.
56cd387 to
f2e41bd
Compare
Previous changes marked lambdas as return target when looking for a target scope, but did not consider it a target for searching the stack of active scopes. This should fix the resulting regression. Note that the logic for determining if a DynamicScope is a return target has now been moved into DynamicScope, and the double-check in checkForLJE which caused the regression has been removed. That method calls getContainingReturnToScope which already guarantees the resulting scope is a valid return target.
d1ecc3a to
45b973e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In the logic to look for a valid return target, we find a lambda, via
IRRuntimeHelpers.initiateNonLocalReturncallinggetContainingLambda. However when we later try to detect if the return jump should propagate as a LocalJumpError (because its target scope is no longer active) we do not do this same search for a lambda (seeIRRuntimeHelpers.checkForLJE). This inconsistency causes the errors from #6350, because we incorrectly detect the target as the lambda, but do the detection against its parent scope and raise an IRReturnJump with an improper target scope. This jump then bubbles all the way off the stack and never becomes a LocalJumpError.In CRuby, when the lambda becomes inactive, the return target moves to the containing return target scope. This means a given return can potentially have two different targets, depending on whether its containing lambda is still on the stack or not.
I believe the appropriate behavior in both cases from #6350 is to raise LocalJumpError immediately. In each case, the return target for the proc should be the lambda, but the lambda is no longer active. The return target should not change to the containing scope, because that's not the proper return target.
The change here adds the lambda logic to the LJE check, so that it sees the lambda return target is no longer active and eagerly raises the LJE.
We will need to reconcile this difference with CRuby, but since this is such an obscure case I doubt it will affect real-world code.
Fixes #6350.