diff --git a/gnovm/pkg/gnolang/machine.go b/gnovm/pkg/gnolang/machine.go index 94232e014d2..95f1a90fa2a 100644 --- a/gnovm/pkg/gnolang/machine.go +++ b/gnovm/pkg/gnolang/machine.go @@ -1629,6 +1629,30 @@ func (m *Machine) PushFrameCall(cx *CallExpr, fv *FuncValue, recv TypedValue) { rlm := pv.GetRealm() if rlm != nil && m.Realm != rlm { m.Realm = rlm // enter new realm + } else if rlm == nil && recv.V != nil { // XXX maybe improve this part. + // maybe this is a bound method of a recv of a realm. + // in that case, inherit the realm of the receiver. + recvv := recv.V + // deref if pointer. + // XXX I guess we want to deref as much as possible. + for { + if pv, ok := recvv.(PointerValue); ok { + recvv = pv.Deref().V + } else { + break + } + } + // Now check if it is an object. + obj, ok := recvv.(Object) + if ok { + recvOID := obj.GetObjectInfo().ID + if !recvOID.IsZero() { + recvPVOID := ObjectIDFromPkgID(recvOID.PkgID) + pv := m.Store.GetObject(recvPVOID).(*PackageValue) + rlm := pv.GetRealm() + m.Realm = rlm + } + } } } diff --git a/gnovm/pkg/gnolang/realm.go b/gnovm/pkg/gnolang/realm.go index 567aea58284..1a442e8d3e5 100644 --- a/gnovm/pkg/gnolang/realm.go +++ b/gnovm/pkg/gnolang/realm.go @@ -73,9 +73,23 @@ func PkgIDFromPkgPath(path string) PkgID { return PkgID{HashBytes([]byte(path))} } +// func ObjectIDFromPkgPath(path string) ObjectID { +// return ObjectID{ +// PkgID: PkgIDFromPkgPath(path), +// NewTime: 1, // by realm logic. +// } +// } + +// 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. } }