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(gnovm): prevent cyclic references in type declarations #2081

Merged
merged 38 commits into from
Aug 16, 2024

Conversation

ltzmaxwell
Copy link
Contributor

@ltzmaxwell ltzmaxwell commented May 13, 2024

Address #2008.

In this pull request, we're implementing a special handling for type declarations to check cynic dependency. Due to their unique nature, we must meticulously search through their fields to identify potential cyclic reference.

Contributors' checklist...
  • [*] Added new tests, or not needed, or not feasible
  • Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory
  • Updated the official documentation or not needed
  • [*] No breaking changes were made, or a BREAKING CHANGE: xxx message was included in the description
  • Added references to related issues and PRs
  • Provided any useful hints for running manual tests
  • Added new benchmarks to generated graphs, if any. More info here.

@github-actions github-actions bot added 📦 🤖 gnovm Issues or PRs gnovm related 📦 ⛰️ gno.land Issues or PRs gno.land package related labels May 13, 2024
Copy link

codecov bot commented May 13, 2024

Codecov Report

Attention: Patch coverage is 97.05882% with 2 lines in your changes missing coverage. Please review.

Project coverage is 60.21%. Comparing base (1f58ee4) to head (284805f).
Report is 14 commits behind head on master.

Files Patch % Lines
gnovm/pkg/gnolang/preprocess.go 97.05% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2081      +/-   ##
==========================================
+ Coverage   60.11%   60.21%   +0.09%     
==========================================
  Files         560      561       +1     
  Lines       74911    75060     +149     
==========================================
+ Hits        45036    45198     +162     
+ Misses      26500    26485      -15     
- Partials     3375     3377       +2     
Flag Coverage Δ
contribs/gnodev 61.40% <ø> (ø)
contribs/gnofaucet 14.46% <ø> (ø)
gno.land 64.75% <ø> (+0.56%) ⬆️
gnovm 64.29% <97.05%> (+0.15%) ⬆️
misc/genstd 80.54% <ø> (ø)
misc/logos 19.88% <ø> (ø)
tm2 62.07% <ø> (+0.10%) ⬆️

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.

@ltzmaxwell ltzmaxwell marked this pull request as draft May 13, 2024 11:36
@zivkovicmilos zivkovicmilos linked an issue May 15, 2024 that may be closed by this pull request
@Kouteki Kouteki added this to the 🏗4️⃣ test4.gno.land milestone May 15, 2024
@petar-dambovaliev
Copy link
Contributor

petar-dambovaliev commented May 15, 2024

This might be solvable by adding some logic in transcribe, without a dependency graph.

This might be a better place than transcribe.

var runDeclarationFor func(fn *FileNode, decl Decl)

I don't know. Try it out and see what is the most appropriate place for this.

@ltzmaxwell ltzmaxwell changed the title WIP: fix(gnovm): Prevent cyclic references in struct declarations fix(gnovm): Prevent cyclic references in struct declarations May 15, 2024
@ltzmaxwell ltzmaxwell marked this pull request as ready for review May 15, 2024 16:25
@ltzmaxwell
Copy link
Contributor Author

This might be solvable by adding some logic in transcribe, without a dependency graph.

This might be a better place than transcribe.

var runDeclarationFor func(fn *FileNode, decl Decl)

I don't know. Try it out and see what is the most appropriate place for this.

This is great and proves to be the right way to go. It's already updated, please take a look @petar-dambovaliev .

@ltzmaxwell ltzmaxwell changed the title fix(gnovm): prevent cyclic references in struct declarations WIP: fix(gnovm): prevent cyclic references in struct declarations Jul 24, 2024
@ltzmaxwell ltzmaxwell changed the title WIP: fix(gnovm): prevent cyclic references in struct declarations WIP: fix(gnovm): prevent cyclic references in type declarations Jul 29, 2024
@ltzmaxwell ltzmaxwell removed the don't merge Please don't merge this functionality temporarily label Aug 5, 2024
@ltzmaxwell ltzmaxwell changed the title WIP: fix(gnovm): prevent cyclic references in type declarations fix(gnovm): prevent cyclic references in type declarations Aug 5, 2024
@ltzmaxwell
Copy link
Contributor Author

ltzmaxwell commented Aug 5, 2024

this PR is updated:

  1. Conduct the check in the preprocessing stage, more specifically, when predefineNow2. The advantage of this approach is that it allows checks to be performed at the very beginning, avoiding the issue of fragmented checks throughout later stages;
  2. Compared to the previous implementation, it avoids introducing a new dependency graph to solve the problem, making the solution relatively streamlined.

@mvertes @petar-dambovaliev @thehowl @ajnavarro would you please conduct a second review, Thank you! 🙏

Copy link
Contributor

@deelawn deelawn 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. I tried to break it but wasn't able to 😄. Just a suggestion for changing the panic message.

gnovm/pkg/gnolang/preprocess.go Outdated Show resolved Hide resolved
Co-authored-by: deelawn <dboltz03@gmail.com>
Copy link
Contributor

@piux2 piux2 left a comment

Choose a reason for hiding this comment

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

@ltzmaxwell the code looks goods and testing cases are well defined.

Have we considered this cyclic dependency case? The Go compiler caught it.

package main

func main() {

}

var a = f1()
var b = f2()

func f1() int {
	return b + 1
}

func f2() int {
	return a + 1
}

// https://go.dev/play/p/FqTP7KNKQ0E?v=goprev

$ go tool compile cyclefunc.go
cyclefunc.go:7:5: initialization cycle for a
cyclefunc.go:7:5: a refers to
cyclefunc.go:10:6: f1 refers to
cyclefunc.go:8:5: b refers to
cyclefunc.go:14:6: f2 refers to
cyclefunc.go:7:5: a

@ltzmaxwell
Copy link
Contributor Author

@ltzmaxwell the code looks goods and testing cases are well defined.

Have we considered this cyclic dependency case? The Go compiler caught it.

package main

func main() {

}

var a = f1()
var b = f2()

func f1() int {
	return b + 1
}

func f2() int {
	return a + 1
}

// https://go.dev/play/p/FqTP7KNKQ0E?v=goprev

$ go tool compile cyclefunc.go cyclefunc.go:7:5: initialization cycle for a cyclefunc.go:7:5: a refers to cyclefunc.go:10:6: f1 refers to cyclefunc.go:8:5: b refers to cyclefunc.go:14:6: f2 refers to cyclefunc.go:7:5: a

@piux2 Thank you for your review! This particular case isn't included in the current PR, as it focuses on cycles in type declarations, whereas the issue above pertains to value declarations. Nonetheless, it's an excellent catch. I propose we track it with a separate issue and address it in a subsequent PR, what do you think?

@ltzmaxwell ltzmaxwell merged commit 1e0e52c into gnolang:master Aug 16, 2024
117 checks passed
MikaelVallenet pushed a commit to MikaelVallenet/gno that referenced this pull request Aug 17, 2024
)

Address gnolang#2008.


In this pull request, we're implementing a special handling for type
declarations to check cynic dependency. Due to their unique nature, we
must meticulously search through their fields to identify potential
cyclic reference.

<details><summary>Contributors' checklist...</summary>

- [*] Added new tests, or not needed, or not feasible
- [ ] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [ ] Updated the official documentation or not needed
- [*] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [ ] Added references to related issues and PRs
- [ ] Provided any useful hints for running manual tests
- [ ] Added new benchmarks to [generated
graphs](https://gnoland.github.io/benchmarks), if any. More info
[here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
</details>

---------

Co-authored-by: deelawn <dboltz03@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📦 ⛰️ gno.land Issues or PRs gno.land package related 📦 🤖 gnovm Issues or PRs gnovm related
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

bug: self-referential types crash the VM
9 participants