Skip to content

Commit

Permalink
save package mempackage after init
Browse files Browse the repository at this point in the history
  • Loading branch information
deelawn committed Mar 30, 2024
1 parent 50134dc commit 77032fc
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
16 changes: 14 additions & 2 deletions gnovm/pkg/gnolang/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,10 +596,10 @@ func (m *Machine) runFiles(memPkg *std.MemPackage, fns ...*FileNode) {
}
}

// Save the mempackage if provided. We do this here so that it occurs before
// Save the realm mempackage if provided. We do this here so that it occurs before
// the init functions are run. This avoids any realm object ownership issues that may arise
// when passing around unpersisted realm object pointers to other realms during initialization.
if memPkg != nil {
if memPkg != nil && IsRealmPath(memPkg.Path) {
// store package values and types
m.savePackageValuesAndTypes()
// store mempackage
Expand All @@ -625,6 +625,18 @@ func (m *Machine) runFiles(memPkg *std.MemPackage, fns ...*FileNode) {
}
}
}

// If this is a package, we can save it after the init function because init is the
// only way stateful realm variables can be dynamically set in a package. We don't need to
// worry about pointer ownership issues for packages because they (eventually) will only be
// able to import other packages and those packages won't be able to persist any pointers
// to their own state that they receive from other packages.
if memPkg != nil && IsPackagePath(memPkg.Path) {
// store package values and types
m.savePackageValuesAndTypes()
// store mempackage
m.Store.AddMemPackage(memPkg)
}
}

// Save the machine's package using realm finalization deep crawl.
Expand Down
9 changes: 8 additions & 1 deletion gnovm/pkg/gnolang/realm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1521,14 +1521,21 @@ func isUnsaved(oo Object) bool {

// realmPathPrefix is the prefix used to identify pkgpaths which are meant to
// be realms and as such to have their state persisted. This is used by [IsRealmPath].
const realmPathPrefix = "gno.land/r/"
const (
realmPathPrefix = "gno.land/r/"
packagePathPrefix = "gno.land/p"
)

// IsRealmPath determines whether the given pkgpath is for a realm, and as such
// should persist the global state.
func IsRealmPath(pkgPath string) bool {
return strings.HasPrefix(pkgPath, realmPathPrefix)
}

func IsPackagePath(pkgPath string) bool {
return strings.HasPrefix(pkgPath, packagePathPrefix)
}

func prettyJSON(jstr []byte) []byte {
var c interface{}
err := json.Unmarshal(jstr, &c)
Expand Down

0 comments on commit 77032fc

Please sign in to comment.