Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev/jae/boundmethodrealm' into d…
Browse files Browse the repository at this point in the history
…ev/moul/grc20reg
  • Loading branch information
moul committed Jul 5, 2024
2 parents e8668f0 + 75b1d10 commit e1a79fe
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 3 deletions.
24 changes: 24 additions & 0 deletions examples/gno.land/p/demo/tests/p_crossrealm/p_crossrealm.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package p_crossrealm

type Stringer interface {
String() string
}

type Container struct {
A int
B Stringer
}

func (c *Container) Touch() *Container {
c.A += 1
return c
}

func (c *Container) Print() {
println("A:", c.A)
if c.B == nil {
println("B: undefined")
} else {
println("B:", c.B.String())
}
}
29 changes: 29 additions & 0 deletions examples/gno.land/r/demo/tests/crossrealm/crossrealm.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package crossrealm

import (
"gno.land/p/demo/tests/p_crossrealm"
"gno.land/p/demo/ufmt"
)

type LocalStruct struct {
A int
}

func (ls *LocalStruct) String() string {
return ufmt.Sprintf("LocalStruct{%d}", ls.A)
}

// local is saved locally in this realm
var local *LocalStruct

func init() {
local = &LocalStruct{A: 123}
}

// Make1 returns a local object wrapped by a p struct
func Make1() *p_crossrealm.Container {
return &p_crossrealm.Container{
A: 1,
B: local,
}
}
24 changes: 22 additions & 2 deletions gnovm/pkg/gnolang/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,11 @@ func (m *Machine) runMemPackage(memPkg *std.MemPackage, save, overrides bool) (*
} else {
pn = NewPackageNode(Name(memPkg.Name), memPkg.Path, &FileSet{})
pv = pn.NewPackage()
m.Store.SetBlockNode(pn)
if true { // TODO finish SetBlockNode()
m.Store.SetBlockNode(pn)
} else {
// TODO m.Store.SetCacheBlockNode(pn)
}
m.Store.SetCachePackage(pv)
}
m.SetActivePackage(pv)
Expand Down Expand Up @@ -1740,8 +1744,24 @@ func (m *Machine) PushFrameCall(cx *CallExpr, fv *FuncValue, recv TypedValue) {
}
m.Package = pv
rlm := pv.GetRealm()
if rlm == nil && recv.IsDefined() {
// if bound method, get realm from receiver.
obj := recv.GetFirstObject(m.Store)
if obj == nil {
// panic("XXX not sure why this would be")
fmt.Println("XXX XXX", recv.String())
} else {
recvOID := obj.GetObjectInfo().ID
if !recvOID.IsZero() {
recvPkgOID := ObjectIDFromPkgID(recvOID.PkgID)
pv := m.Store.GetObject(recvPkgOID).(*PackageValue)
rlm = pv.GetRealm() // done
}
}
}
if rlm != nil && m.Realm != rlm {
m.Realm = rlm // enter new realm
// enter new realm
m.Realm = rlm
}
}

Expand Down
15 changes: 14 additions & 1 deletion gnovm/pkg/gnolang/realm.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,21 @@ func (pid PkgID) Bytes() []byte {
}

func PkgIDFromPkgPath(path string) PkgID {
// fmt.Printf("PkgPath %s -> PkgID %v", path,
// PkgID{HashBytes([]byte(path))})
return PkgID{HashBytes([]byte(path))}
}

// Returns the ObjectID of the PackageValue associated with path.
func ObjectIDFromPkgPath(path string) ObjectID {
pkgID := PkgIDFromPkgPath(path)
return ObjectIDFromPkgID(pkgID)
}

// Returns the ObjectID of the PackageValue associated with pkgID.
func ObjectIDFromPkgID(pkgID PkgID) ObjectID {
return ObjectID{
PkgID: PkgIDFromPkgPath(path),
PkgID: pkgID,
NewTime: 1, // by realm logic.
}
}
Expand Down Expand Up @@ -145,6 +154,10 @@ func (rlm *Realm) DidUpdate(po, xo, co Object) {
return // do nothing.
}
if po.GetObjectID().PkgID != rlm.ID {
// fmt.Println("PO", po.String())
// fmt.Println("PO.PKGID", po.GetObjectID().PkgID)
// fmt.Println("rlm", rlm)
// fmt.Println("rlm.ID", rlm.ID)
panic("cannot modify external-realm or non-realm object")
}

Expand Down
17 changes: 17 additions & 0 deletions gnovm/tests/files/zrealm_crossrealm13.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// PKGPATH: gno.land/r/crossrealm_test
package crossrealm_test

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

func main() {
// even though we are running within a realm,
// we aren't storing the result of crossrealm.Make1(),
// so this should print fine.
crossrealm.Make1().Touch().Print()
}

// Output:
// A: 2
// B: LocalStruct{123}

0 comments on commit e1a79fe

Please sign in to comment.