-
Notifications
You must be signed in to change notification settings - Fork 6
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
AST inlining breaks capture semantics #5
Comments
I commited a patch for TruffleSOM here. |
Could you describe what the patch is doing? (would be great if the commit message for a complicated problem could outline the solution) I think, there only needs to be a fix for inlined blocks that have embedded blocks (transitively). And probably only in loops. If I read the patch correctly, you added a node that instantiates a frame object. This is indeed fairly intricate. One other approach to the problem would be to see whether there is any code that is actually broken by that. I guess, by introducing the checks for the condition (nested block with access to outer scope variable that got inlined in a loop, and that escape themselves). The condition is likely rare enough. |
Following your paragraphs...
|
Hmm, the bug is also a problem for local variables: 1 to: 10 do: [ :i |
| local |
local isNil ifTrue: [ local := 0 ] ifFalse: [ local := local + 1 ].
local println ]. And that's an issue even without any blocks involved, because the previous value of the previous iteration should not be visible. The last bit I mentioned before was about checking whether the bug is triggered in the existing code. In the sense of adding assertions in the interpreter, that trigger when the bug would occur. |
There is another aspect that is broken here. The expression above evaluates incorrectly, because |
I see. Well in this case I would say that the solution proposed in my patch can be extended to include local vars also, but apparently, for complying with the proper semantics, the creation of a new frame is mandatory. An alternative (optimization) would be to only capture the variables really used inside the embedded blocks. I would have to check if nested blocks are accesible to check for that information. Then, All NonLocalVariableReads inside the methods of the embedded blocks must be replace to nodes similar to the one I proposed in the patch, that first checks for the variable in the new created frame, and if not there, continue with the standard binding. But, considering that the inlining is mainly for optimizing performance, and that probably one of the main factors of overhead is the frame creation, perhaps a plausible alternative is to find all the scenarios where the inlining fails and do not inline. However I guess that a precise selection of this scenarios is not easy either. |
A new frame might not be necessary. But, the slot needs to be reset to an uninitialized value before the next iteration. That's likely problematic for primitive slots. When we bite the bullet to create a frame, it likely simpler and potentially faster to not separate subsets of slots. At least in the interpreter, one would still need to go one more context level out to reach the slots that got inlined in the outer context. |
I might have a look at this end of next week. Until then, I won't be able to touch code related to this issue. |
It may not be mandatory in the second example you introduced, but in the original one where the embedded block escapes I think it is not enough to reset slots. |
Resetting of slots is only for local variables that are not captured. It is somewhat a separate issue. Resetting doesn't solve the issues when vars are captured. |
@eregon found a bug in the AST inlining in SOMns. The following test does not result in the correct output:
This issue is very likely to be a problem for TruffleSOM, too.
The text was updated successfully, but these errors were encountered: