-
Notifications
You must be signed in to change notification settings - Fork 379
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(gnovm): use OpCall to run deferred statements #2597
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅ 📢 Thoughts on this report? Let us know! |
Btw this is against the current direction of #2596, as it heavily relies on the "frame as a pointer" system. Maybe there's a way to do this without Frame being a pointer. |
Looks like there's some CI trouble, back to draft for now. |
…p-call-for-defers
This PR is stale because it has been open 3 months with no activity. Remove stale label or comment or this will be closed in 3 months. |
I'm a bot that assists the Gno Core team in maintaining this repository. My role is to ensure that contributors understand and follow our guidelines, helping to streamline the development process. The following requirements must be fulfilled before a pull request can be merged. These requirements are defined in this configuration file. Automated Checks🔴 Maintainers must be able to edit this pull request Manual ChecksNo manual checks match this pull request. Debug
|
This is an itch that started when noticing something reviewing #2145, and then continued when breaking down #1672, and here we are.
Essentially, currently on
master
usingdefer
will not create a new*Frame
. This results, in #2145, in the deferred function not showing up in the stacktrace.doOpReturnCallDefers
(the function in charge of executing deferred functions) actually has its own copied implementation of OpCall.I haven't been able to fully track down the implications of not creating a new frame (zrealm_std7_stdlibs.gno is an attempt at doing so, but is actually correct on master, so 🤷). But what I do know is that having two copied implementations leads to bug being fixed in one case, and not in another one: to prove this, see
defer10.gno
.defer10's case is fixed on OpCall, as a previous commit moved it from using
copy(b.Values, dfr.Args)
to usingb.Values[i] = pv.Copy(m.Alloc)
over all the values instead. (ie. copying values by reference when calling a function).So, by always using OpCall to do everything, we create the frame correctly, and use a unique implementation to actually call functions.
I also modified the logic to determine whether a
recover()
can correctly recover a panic or not. (cc @deelawn). Instead of keeping a Scope counter in the Machine, theException
now contains a slice of the frame pointers at the time of creation of the exception. The frame will be considered as being run during a panicking sequence only if it is in this array. We use this both for recover(), and for doOpReturnCallDefers, too.@deelawn I tried using your system, but I couldn't get it working on a case like
recover12b
, with the new frame added. And I'm still not 100% sure how the system you had worked. Do you think this is ok?