Skip to content

Commit

Permalink
change realm to receiver's
Browse files Browse the repository at this point in the history
  • Loading branch information
jaekwon committed Jul 7, 2024
1 parent 60b99cc commit a91c84a
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 67 deletions.
2 changes: 2 additions & 0 deletions examples/gno.land/r/demo/tests/tests.gno
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ type TestRealmObject struct {
Field string
}

var TestRealmObjectValue TestRealmObject

func ModifyTestRealmObject(t *TestRealmObject) {
t.Field += "_modified"
}
Expand Down
54 changes: 35 additions & 19 deletions gnovm/pkg/gnolang/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ func (e Exception) Sprint(m *Machine) string {

type Machine struct {
// State
Ops []Op // main operations
NumOps int
Ops []Op // operations stack
NumOps int // number of operations
Values []TypedValue // buffer of values to be operated on
NumValues int // number of values
Exprs []Expr // pending expressions
Expand All @@ -47,9 +47,9 @@ type Machine struct {
Package *PackageValue // active package
Realm *Realm // active realm
Alloc *Allocator // memory allocations
Exceptions []Exception
NumResults int // number of results returned
Cycles int64 // number of "cpu" cycles
Exceptions []Exception // exceptions stack
NumResults int // number of results returned
Cycles int64 // number of "cpu" cycles performed

Debugger Debugger

Expand Down Expand Up @@ -199,6 +199,7 @@ func (m *Machine) Release() {
machinePool.Put(m)
}

// Convenience for initial setup of the machine.
func (m *Machine) SetActivePackage(pv *PackageValue) {
if err := m.CheckEmpty(); err != nil {
panic(errors.Wrap(err, "set package when machine not empty"))
Expand All @@ -210,6 +211,14 @@ func (m *Machine) SetActivePackage(pv *PackageValue) {
}
}

func (m *Machine) setCurrentPackage(pv *PackageValue) {
m.Package = pv
rlm := pv.GetRealm()
if rlm != nil {
m.Realm = rlm

Check warning on line 218 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L218

Added line #L218 was not covered by tests
}
}

//----------------------------------------
// top level Run* methods.

Expand Down Expand Up @@ -1797,29 +1806,36 @@ func (m *Machine) PushFrameCall(cx *CallExpr, fv *FuncValue, recv TypedValue) {
m.Printf("+F %#v\n", fr)
}
m.Frames = append(m.Frames, fr)
pv := fv.GetPackage(m.Store)
if pv == nil {
panic(fmt.Sprintf("package value missing in store: %s", fv.PkgPath))
}
rlm := pv.GetRealm()
if rlm == nil && recv.IsDefined() {
if recv.IsDefined() {
// If the receiver is defined, we enter the receiver's realm.
obj := recv.GetFirstObject(m.Store)
if obj == nil {
// could be a nil receiver.
// just ignore.
// set package and realm of function.
pv := fv.GetPackage(m.Store)
if pv == nil {
panic(fmt.Sprintf("package value missing in store: %s", fv.PkgPath))

Check warning on line 1817 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L1817

Added line #L1817 was not covered by tests
}
m.setCurrentPackage(pv) // maybe new realm
} else {
recvOID := obj.GetObjectInfo().ID
if !recvOID.IsZero() {
if recvOID.IsZero() {
// receiver isn't owned yet.
// just continue with current package and realm.
// XXX is this reasonable?
} else {
// override the pv and rlm with receiver's.
recvPkgOID := ObjectIDFromPkgID(recvOID.PkgID)
pv = m.Store.GetObject(recvPkgOID).(*PackageValue)
rlm = pv.GetRealm() // done
pv := m.Store.GetObject(recvPkgOID).(*PackageValue)
m.setCurrentPackage(pv) // maybe new realm
}
}
}
m.Package = pv
if rlm != nil && m.Realm != rlm {
m.Realm = rlm // enter new realm
} else {
pv := fv.GetPackage(m.Store)
if pv == nil {
panic(fmt.Sprintf("package value missing in store: %s", fv.PkgPath))

Check warning on line 1836 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L1836

Added line #L1836 was not covered by tests
}
m.setCurrentPackage(pv) // maybe new realm
}
}

Expand Down
3 changes: 1 addition & 2 deletions gnovm/tests/files/zrealm_crossrealm16.gno
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ func main() {
// }
// ]
// }
// switchrealm["gno.land/r/demo/tests/crossrealm"]
// switchrealm["gno.land/r/crossrealm_test"]
// u[f5a516808f8976c33939133293d598ce3bca4e8d:2]={
// "Blank": {},
Expand Down Expand Up @@ -593,5 +594,3 @@ func main() {
// }
// ]
// }
// switchrealm["gno.land/r/demo/tests/crossrealm"]
// switchrealm["gno.land/r/crossrealm_test"]
3 changes: 1 addition & 2 deletions gnovm/tests/files/zrealm_crossrealm17.gno
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ func main() {
// }
// ]
// }
// switchrealm["gno.land/r/demo/tests/crossrealm"]
// switchrealm["gno.land/r/crossrealm_test"]
// u[f5a516808f8976c33939133293d598ce3bca4e8d:2]={
// "Blank": {},
Expand Down Expand Up @@ -676,5 +677,3 @@ func main() {
// }
// ]
// }
// switchrealm["gno.land/r/demo/tests/crossrealm"]
// switchrealm["gno.land/r/crossrealm_test"]
37 changes: 37 additions & 0 deletions gnovm/tests/files/zrealm_crossrealm19_stdlibs.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// PKGPATH: gno.land/r/crossrealm_test
package crossrealm_test

import (
"std"

crossrealm "gno.land/r/demo/tests/crossrealm"
)

type fooer struct {
s string
}

func (f *fooer) Foo() {
f.s = "B"
println("hello " + f.s + " " + std.CurrentRealm().PkgPath())
}

var f *fooer

func init() {
f = &fooer{s: "A"}
crossrealm.SetFooer(f)
crossrealm.CallFoo()
}

func main() {
print(".")
}

// Output:
// hello B gno.land/r/demo/tests/crossrealm
// .

// Error:

// Realm:
11 changes: 8 additions & 3 deletions gnovm/tests/files/zrealm_crossrealm3_stdlibs.gno
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ func init() {
}

func main() {
// NOTE: but it is invalid to modify it using an external realm function.
// NOTE: it is valid to modify it using an external realm function,
// because the receiver makes the function run under this realm.
somevalue.Modify()
println(somevalue)
// we can even modify it directly.
somevalue.Field = "test_modified_directly"
println(somevalue)
}

// Error:
// cannot modify external-realm or non-realm object
// Output:
// (struct{("test_modified" string)} gno.land/r/demo/tests.TestRealmObject)
// (struct{("test_modified_directly" string)} gno.land/r/demo/tests.TestRealmObject)
12 changes: 6 additions & 6 deletions gnovm/tests/files/zrealm_crossrealm4_stdlibs.gno
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ import (
"gno.land/r/demo/tests"
)

// NOTE: it is valid to persist external realm types.
var somevalue tests.TestRealmObject
// NOTE: it is valid to persist a pointer to an external object
var somevalue *tests.TestRealmObject

func init() {
somevalue.Field = "test"
somevalue = &tests.TestRealmObjectValue
}

func main() {
// NOTE: but it is invalid to modify it using an external realm function.
// NOTE: it is valid to modify it using the external realm function.
somevalue.Modify()
println(somevalue)
}

// Error:
// cannot modify external-realm or non-realm object
// Output:
// &(struct{("_modified" string)} gno.land/r/demo/tests.TestRealmObject)
8 changes: 4 additions & 4 deletions gnovm/tests/files/zrealm_crossrealm5_stdlibs.gno
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import (
)

// NOTE: it is valid to persist external realm types.
var somevalue tests.TestRealmObject
var somevalue *tests.TestRealmObject

func init() {
somevalue.Field = "test"
somevalue = &tests.TestRealmObjectValue
}

func main() {
// NOTE: but it is invalid to modify it using an external realm function.
somevalue.Modify()
// NOTE: but it is invalid to modify it directly.
somevalue.Field = "test"
println(somevalue)
}

Expand Down
Loading

0 comments on commit a91c84a

Please sign in to comment.