diff --git a/examples/gno.land/r/demo/bugs/mis_ownership/gno.mod b/examples/gno.land/r/demo/bugs/mis_ownership/gno.mod new file mode 100644 index 00000000000..5e8da42caa9 --- /dev/null +++ b/examples/gno.land/r/demo/bugs/mis_ownership/gno.mod @@ -0,0 +1,5 @@ +module "gno.land/r/demo/bugs/mis_ownership" + +require ( + "gno.land/r/demo/bugs/steal_ownership" v0.0.0-latest +) diff --git a/examples/gno.land/r/demo/bugs/mis_ownership/mis_ownership.gno b/examples/gno.land/r/demo/bugs/mis_ownership/mis_ownership.gno new file mode 100644 index 00000000000..def1b41685a --- /dev/null +++ b/examples/gno.land/r/demo/bugs/mis_ownership/mis_ownership.gno @@ -0,0 +1,16 @@ +package mis_ownership + +import "gno.land/r/demo/bugs/steal_ownership" + +var ( + x = uint32(42) + ptr = &x +) + +func init() { + steal_ownership.Steal(ptr) +} + +func Mutate() { + *ptr = 21 +} diff --git a/examples/gno.land/r/demo/bugs/steal_ownership/gno.mod b/examples/gno.land/r/demo/bugs/steal_ownership/gno.mod new file mode 100644 index 00000000000..459566d1807 --- /dev/null +++ b/examples/gno.land/r/demo/bugs/steal_ownership/gno.mod @@ -0,0 +1 @@ +module "gno.land/r/demo/bugs/steal_ownership" \ No newline at end of file diff --git a/examples/gno.land/r/demo/bugs/steal_ownership/steal_ownership.gno b/examples/gno.land/r/demo/bugs/steal_ownership/steal_ownership.gno new file mode 100644 index 00000000000..9aeaf4ff1dc --- /dev/null +++ b/examples/gno.land/r/demo/bugs/steal_ownership/steal_ownership.gno @@ -0,0 +1,7 @@ +package steal_ownership + +var ptr *uint32 + +func Steal(xptr *uint32) { + ptr = xptr +} diff --git a/gnovm/pkg/gnolang/realm.go b/gnovm/pkg/gnolang/realm.go index 40f770c7720..9807c3dae74 100644 --- a/gnovm/pkg/gnolang/realm.go +++ b/gnovm/pkg/gnolang/realm.go @@ -69,8 +69,16 @@ func (pid PkgID) Bytes() []byte { return pid.Hashlet[:] } +var pathsFromIds = make(map[string]string) + func PkgIDFromPkgPath(path string) PkgID { - return PkgID{HashBytes([]byte(path))} + id := PkgID{HashBytes([]byte(path))} + pathsFromIds[id.String()] = path + return id +} + +func PkgPathFromPkgID(id PkgID) string { + return pathsFromIds[id.String()] } func ObjectIDFromPkgPath(path string) ObjectID { @@ -145,7 +153,12 @@ func (rlm *Realm) DidUpdate(po, xo, co Object) { return // do nothing. } if po.GetObjectID().PkgID != rlm.ID { - panic("cannot modify external-realm or non-realm object") + opid := po.GetObjectID().PkgID + prettyName := PkgPathFromPkgID(opid) + if prettyName == "" { + prettyName = opid.String() + } + panic(fmt.Sprintf("cannot modify external-realm or non-realm object: object pkg path: %s, realm: %s", prettyName, rlm.Path)) } // From here on, po is real (not new-real). // Updates to .newCreated/.newEscaped /.newDeleted made here. (first gen)