Skip to content
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

fix: re-create blocks on for loop iterations #1768

Closed
wants to merge 3 commits into from

Conversation

thehowl
Copy link
Member

@thehowl thehowl commented Mar 13, 2024

This is an attempt at an alternative to fix #1135. See a current solution at #1585.

The solution is simple: for all our for loops, whenever we reach the end of its body and are about to go back at the top, re-create their Blocks from scratch, copying over the bodyStmt. In the case of three-clause for loops, copy over any current values of the declared initialization variables. This is consistent with the behaviour as of Go 1.22.

This fix is "dumb", for now. I'm pretty sure re-creating a Block on each iteration is not the best thing for performance, and this may be a step that we can try to "optimize out" if the for loop doesn't generate a closure (as most for loops are). However, it is a very small patch, and I'd like to gauge whether we like this fix and should adopt some variation of it or not.

Credit to maxwell for the tests added. (Note: the goto tests still don't work; however, I think the fix for the goto tests involves correctly "understanding" the difference between assignment/defintiion within the GnoVM, and as such are out of scope here. Naturally, if there is an alternative fix that gets within the same patch to fix this issue and the goto issue, I'm all ears)

cc/ @jaekwon @deelawn @ltzmaxwell

@thehowl thehowl self-assigned this Mar 13, 2024
@thehowl thehowl requested review from piux2 and moul as code owners March 13, 2024 18:47
@github-actions github-actions bot added the 📦 🤖 gnovm Issues or PRs gnovm related label Mar 13, 2024
Copy link

codecov bot commented Mar 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 47.95%. Comparing base (55db42e) to head (a69768e).
Report is 285 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1768      +/-   ##
==========================================
+ Coverage   47.50%   47.95%   +0.44%     
==========================================
  Files         388      441      +53     
  Lines       61375    65211    +3836     
==========================================
+ Hits        29159    31273    +2114     
- Misses      29774    31333    +1559     
- Partials     2442     2605     +163     
Flag Coverage Δ
contribs/gnodev 23.81% <ø> (?)
contribs/gnofaucet 14.46% <ø> (?)
contribs/gnokeykc 0.00% <ø> (?)
contribs/gnomd 0.00% <ø> (?)
gno.land 62.54% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jaekwon
Copy link
Contributor

jaekwon commented Mar 14, 2024

The main issue I see with this is that it will affect performance for every for loop iteration.
By far most for loops don't suffer from this problem, so it makes sense to provide this type of solution for when for loops do have an escaping variable in a closure.
But I think this is more of a Go quirk (I'd say, even a misdesign), and we want the VM to work with many languages.
I will try to implement a preprocessor solution now, one that turns every closure into a double closure.
The closure injected by the preprocessor will be called immediately with the variables that are captured by the inner closure.
The performance won't be better than this solution (actually not sure), but it should be a simple solution that doesn't affect the underlying VM design, so will be better suited for other langauges too. We will see!

@thehowl
Copy link
Member Author

thehowl commented Mar 18, 2024

Closing for house-keeping and seeing as you made another PR

@thehowl thehowl closed this Mar 18, 2024
@jaekwon
Copy link
Contributor

jaekwon commented Mar 25, 2024

My PR isn't good, but found a better way which we talked about in the call.
Basically, ForStmt bodies should be wrapped with a BlockStmt and i := i if necessary,
and

GOTO:
{
   should
   look
   like
   this (until the next goto within the same block)
}
GOTO2:
{
   if
   implicit
   loop
}

@ltzmaxwell
Copy link
Contributor

loop var escape issues is being fixed in #2429 and #2440 , we can put a hold on reviewing this PR and decide our next steps based on the status of the #2429 and #2440 solution.

@thehowl
Copy link
Member Author

thehowl commented Jul 24, 2024

Closing in favour of other PRs.

@thehowl thehowl closed this Jul 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📦 🤖 gnovm Issues or PRs gnovm related
Projects
Status: Done
Archived in project
Development

Successfully merging this pull request may close these issues.

for loops maintain the same block on iteration, which is referenced in any closures generated within
4 participants