diff --git a/gnovm/pkg/gnolang/machine.go b/gnovm/pkg/gnolang/machine.go index 95f1a90fa2a..8665e049e9f 100644 --- a/gnovm/pkg/gnolang/machine.go +++ b/gnovm/pkg/gnolang/machine.go @@ -1627,33 +1627,25 @@ func (m *Machine) PushFrameCall(cx *CallExpr, fv *FuncValue, recv TypedValue) { } m.Package = pv 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 { + 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() { - recvPVOID := ObjectIDFromPkgID(recvOID.PkgID) - pv := m.Store.GetObject(recvPVOID).(*PackageValue) - rlm := pv.GetRealm() - m.Realm = rlm + recvPkgOID := ObjectIDFromPkgID(recvOID.PkgID) + pv := m.Store.GetObject(recvPkgOID).(*PackageValue) + rlm = pv.GetRealm() // done } } } + if rlm != nil && m.Realm != rlm { + // enter new realm + m.Realm = rlm + } } func (m *Machine) PushFrameGoNative(cx *CallExpr, fv *NativeValue) { diff --git a/gnovm/pkg/gnolang/ownership.go b/gnovm/pkg/gnolang/ownership.go index f2afc393d05..39f9af27ecb 100644 --- a/gnovm/pkg/gnolang/ownership.go +++ b/gnovm/pkg/gnolang/ownership.go @@ -332,6 +332,7 @@ func (tv *TypedValue) GetFirstObject(store Store) Object { // something in it; in that case, ignore the base. That will // likely require maybe a preparation step in persistence // ( or unlikely, a second type of ref-counting). + // XXX is there an issue with Base=nil pointers here cross realm? if cv.Base != nil { return cv.Base.(Object) } else { diff --git a/gnovm/pkg/gnolang/realm.go b/gnovm/pkg/gnolang/realm.go index 1a442e8d3e5..f4a4b17dcb5 100644 --- a/gnovm/pkg/gnolang/realm.go +++ b/gnovm/pkg/gnolang/realm.go @@ -70,16 +70,11 @@ 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))} } -// 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) @@ -159,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") } // From here on, po is real (not new-real).