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
Closure tracking #2357
Closure tracking #2357
Conversation
340b6fa
to
5202526
Compare
7e1f158
to
fb6f33d
Compare
81ed9e8
to
aad6fdd
Compare
This now implements both |
The question here - I may have that patch finished until next week. Do we get this for 1.6, or do we postpone it to "1.7" whatever the next release may be. |
94f8327
to
7e82a66
Compare
This adds closure awareness to Opal. Previously, some control flow instructions were working based on the most common situation and in certain situations we got that wrong. The previous implementation also led to a lot of scattered around code and a lot of logic duplication. My view is that this patch improves maintainability of our codebase a lot and allows for further improvements based on the new mini-DSL. Unfortunately, one of the downsides of this code is that runtime performance is slightly decreased.
7e82a66
to
479bf7e
Compare
A problem found with Opal-RSpec working branch:
|
lib/opal/nodes/rescue.rb
Outdated
@@ -10,6 +10,9 @@ class EnsureNode < Base | |||
children :begn, :ensr | |||
|
|||
def compile | |||
# FIXME: We don't need this if there's no rescue else | |||
push_closure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
push_closure if has_rescue_else?
maybe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unfortunately no... has_rescue_else? can be called only after we have traversed thru all the child nodes. as a followup to this, I plan to mark the throwers using a rewriter, replacing the current measures and the BreakFinder rewriter
lib/opal/nodes/rescue.rb
Outdated
@@ -49,6 +52,8 @@ def compile | |||
|
|||
line '}' | |||
|
|||
pop_closure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pop_closure if has_rescue_else?
maybe?
cf64bef
to
73fdb43
Compare
73fdb43
to
eb68e72
Compare
BreakFinder used to be called on-demand, now ThrowerFinder is a regular rewriter, implementing an early pass of closure tracking. This should provide some small reduction of generated code.
Don't create an IIFE, if our catcher is a JS_FUNCTION, because it means, that immediately after compiling a catcher we will wrap things with some kind of a function, so semantics will remain.
This is similar to what it used to be called before and also we can spare a couple of bytes.
453e725
to
e23d2f6
Compare
ceb99e8
to
f02d63d
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As always great to see all those specs go away 🎉
The closures make everything harder for how Opal is right now.
Consider this theoretical code:
What does this proc return? 6. Why? Because a closure stands in a way and next is ONLY compiled to return. A lot more issues - albeit you really need to try to break it - but some existing code may show deficiencies, eg. when you get two returners entangled.
So I propose to track the closures and use this knowledge to correctly dispatch the breakers/nexters/returners/retriers. If we get a closure in the way - we need to use exceptions.
Commit description of the finalized patch:
Also, I have verified that all linked issues are fixed by this patch.