-
-
Notifications
You must be signed in to change notification settings - Fork 925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Super does not mark literal blocks as escaped #4695
Comments
@headius Could you write a spec with this code? |
The case as written is not syntactically correct. It should look like this:
This does raise a LocalJumpError on CRuby, which is expected. The block has escaped its original activation.
In JRuby, it eventually turns into a LocalJumpError, but not before passing through all the other stack frames and bubbling out of the root of the script:
More clearly, what's happening is that we do not detect that the block has escaped its original activation because the super call is not wrapped in logic to mark it as such. In other call paths, such as via CachingCallSite, this is done with a try/finally that marks the block as escaped after the call has completed. I have a Ruby spec for this, and for the similar non-escaping case which does not raise an error on CRuby or JRuby. I will commit that after fixing the issue. |
The indy logic here is duplicating a fair amount of code, but indy super still needs to be reworked for caching and that will distill these duplications out. This at least provides a direct path for each form. Fixes jruby#4695
For #4686 and #4577 I did #4694 to start setting all literal blocks as "escaped" once the method they are passed to has returned. This allows us to properly raise LocalJumpError when a block with a break escapes its original context.
However I did not fix super, because there's longer and more complicated logic paths through which we'd need to push the literal closure information, and there's no one location where we can do the try/finally to set the block escaped.
This bug is for that work to be done.
Example case:
This should raise a rescuable LocalJumpError at the break, but instead it unrolls most of the stack.
The text was updated successfully, but these errors were encountered: