Skip to content

fix(gnovm): use OpCall to run deferred statements #2597

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

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

thehowl
Copy link
Member

@thehowl thehowl commented Jul 17, 2024

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 using defer 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 using b.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, the Exception 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?

@thehowl thehowl self-assigned this Jul 17, 2024
@thehowl thehowl requested review from jaekwon, moul, piux2, deelawn, mvertes and a team as code owners July 17, 2024 01:04
@github-actions github-actions bot added 🧾 package/realm Tag used for new Realms or Packages. 📦 🤖 gnovm Issues or PRs gnovm related labels Jul 17, 2024
Copy link

codecov bot commented Jul 17, 2024

Codecov Report

Attention: Patch coverage is 98.59155% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
gnovm/pkg/gnolang/op_call.go 98.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@thehowl
Copy link
Member Author

thehowl commented Jul 17, 2024

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.

@thehowl thehowl marked this pull request as draft July 17, 2024 01:37
@thehowl
Copy link
Member Author

thehowl commented Jul 17, 2024

Looks like there's some CI trouble, back to draft for now.

Copy link

github-actions bot commented Dec 3, 2024

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.

@github-actions github-actions bot added the Stale label Dec 3, 2024
@Gno2D2
Copy link
Collaborator

Gno2D2 commented Dec 3, 2024

🛠 PR Checks Summary

🔴 Must not contain the "don't merge" label

Manual Checks (for Reviewers):
  • IGNORE the bot requirements for this PR (force green CI check)
Read More

🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers.

✅ Automated Checks (for Contributors):

🔴 Must not contain the "don't merge" label

☑️ Contributor Actions:
  1. Fix any issues flagged by automated checks.
  2. Follow the Contributor Checklist to ensure your PR is ready for review.
    • Add new tests, or document why they are unnecessary.
    • Provide clear examples/screenshots, if necessary.
    • Update documentation, if required.
    • Ensure no breaking changes, or include BREAKING CHANGE notes.
    • Link related issues/PRs, where applicable.
☑️ Reviewer Actions:
  1. Complete manual checks for the PR, including the guidelines and additional checks if applicable.
📚 Resources:
Debug
Automated Checks
Must not contain the "don't merge" label

If

🟢 Condition met
└── 🟢 A label matches this pattern: don't merge (label: don't merge)

Then

🔴 Requirement not satisfied
└── 🔴 On no pull request

Manual Checks
**IGNORE** the bot requirements for this PR (force green CI check)

If

🟢 Condition met
└── 🟢 On every pull request

Can be checked by

  • Any user with comment edit permission

@jefft0 jefft0 mentioned this pull request Dec 3, 2024
@github-actions github-actions bot removed the Stale label Dec 4, 2024
@thehowl thehowl added this to the 🚀 Mainnet beta launch milestone Feb 18, 2025
@Kouteki Kouteki removed request for a team and deelawn February 24, 2025 13:01
@Kouteki Kouteki moved this from Triage to Todo in 🧙‍♂️gno.land core team Mar 18, 2025
@Kouteki Kouteki moved this from Todo to In Progress in 🧙‍♂️gno.land core team Mar 18, 2025
@github-actions github-actions bot added the 📦 ⛰️ gno.land Issues or PRs gno.land package related label Apr 3, 2025
@ltzmaxwell ltzmaxwell removed request for moul and piux2 April 3, 2025 04:37
@ltzmaxwell ltzmaxwell marked this pull request as ready for review April 3, 2025 07:59
@Kouteki Kouteki moved this from In Progress to In Review in 🧙‍♂️gno.land core team Apr 3, 2025
Copy link
Contributor

@petar-dambovaliev petar-dambovaliev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a couple of small improvements.

// and wait for return.
if m.hasNoUnrecovered() {
return
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you take out this stuff and omit the else? Less scopes, easier to read.

} else {
// Keep panicking
last := m.PopUntilLastCallFrame()
if last == nil {
// Build exception string just as go, separated by \n\t.
exs := make([]string, len(m.Exceptions))
var bld strings.Builder
Copy link
Contributor

@petar-dambovaliev petar-dambovaliev Apr 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you preallocate some good amount to avoid multiple reallocations?
Maybe bld.Grow(len(m.Exceptions) * number_of_chars_in_an_iteration)

@ltzmaxwell ltzmaxwell added the don't merge Please don't merge this functionality temporarily label Apr 5, 2025
@ltzmaxwell
Copy link
Contributor

don't merge. be better after #4060 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
don't merge Please don't merge this functionality temporarily 📦 ⛰️ gno.land Issues or PRs gno.land package related 📦 🤖 gnovm Issues or PRs gnovm related 🧾 package/realm Tag used for new Realms or Packages.
Projects
Status: In Progress
Status: In Review
Development

Successfully merging this pull request may close these issues.

4 participants