From d684985f9d146c4b6495508adef57a1ea60ba13a Mon Sep 17 00:00:00 2001 From: Thomas Bruyelle Date: Tue, 27 Jun 2023 12:20:39 +0200 Subject: [PATCH] fix(gnovm): load map from state (#932) --- gnovm/docs/go-gno-compatibility.md | 4 ++-- gnovm/pkg/gnolang/realm.go | 2 +- gnovm/pkg/gnolang/values.go | 5 ++++- gnovm/tests/challenges/persist_map.gno | 18 ------------------ gnovm/tests/files/persist_map.gno | 22 ++++++++++++++++++++++ 5 files changed, 29 insertions(+), 22 deletions(-) delete mode 100644 gnovm/tests/challenges/persist_map.gno create mode 100644 gnovm/tests/files/persist_map.gno diff --git a/gnovm/docs/go-gno-compatibility.md b/gnovm/docs/go-gno-compatibility.md index 890186edebf..1162c7285aa 100644 --- a/gnovm/docs/go-gno-compatibility.md +++ b/gnovm/docs/go-gno-compatibility.md @@ -45,12 +45,12 @@ Legend: full, partial, missing, TBD. | `rune` | full | full | | `interface{}` | full | full | | `[]T` (slices) | full | full* | -| `map[T1]T2` | full | missing (in progress, will be for launch) | +| `map[T1]T2` | full | full* | | `func (T1...) T2...` | full | full (needs more tests) | | `*T` (pointers) | full | full* | | `chan T` (channels) | missing (after launch) | missing (after launch) | -**\*:** depends on `T` +**\*:** depends on `T`/`T1`/`T2` Additional native types: diff --git a/gnovm/pkg/gnolang/realm.go b/gnovm/pkg/gnolang/realm.go index 6e1301c023f..40f770c7720 100644 --- a/gnovm/pkg/gnolang/realm.go +++ b/gnovm/pkg/gnolang/realm.go @@ -1341,7 +1341,7 @@ func fillTypesOfValue(store Store, val Value) Value { fillTypesTV(store, &cv.Receiver) return cv case *MapValue: - cv.MakeMap(cv.List.Size) // TODO move out. + cv.vmap = make(map[MapKey]*MapListItem, cv.List.Size) for cur := cv.List.Head; cur != nil; cur = cur.Next { fillTypesTV(store, &cur.Key) fillTypesTV(store, &cur.Value) diff --git a/gnovm/pkg/gnolang/values.go b/gnovm/pkg/gnolang/values.go index 495fcf74cb7..3de74ac0130 100644 --- a/gnovm/pkg/gnolang/values.go +++ b/gnovm/pkg/gnolang/values.go @@ -11,6 +11,7 @@ import ( "unsafe" "github.com/cockroachdb/apd" + "github.com/gnolang/gno/tm2/pkg/crypto" ) @@ -661,7 +662,9 @@ func (ml *MapList) UnmarshalAmino(mlimg MapListImage) error { ml.Head = item } item.Prev = ml.Tail - ml.Tail.Next = item + if ml.Tail != nil { + ml.Tail.Next = item + } ml.Tail = item ml.Size++ } diff --git a/gnovm/tests/challenges/persist_map.gno b/gnovm/tests/challenges/persist_map.gno deleted file mode 100644 index 886e306f52d..00000000000 --- a/gnovm/tests/challenges/persist_map.gno +++ /dev/null @@ -1,18 +0,0 @@ -// PKGPATH: gno.land/r/demo/tests_test -package tests_test - -var amap map[string]string = map[string]string{"a": "1"} - -func init() { - println("preinit", amap) - amap["b"] = "2" - println("postinit", amap) -} - -func main() { - println("premain", amap) - amap["b"] = "2" - println("postmain", amap) -} - -// Current behavior: panics diff --git a/gnovm/tests/files/persist_map.gno b/gnovm/tests/files/persist_map.gno new file mode 100644 index 00000000000..53a1ad80f77 --- /dev/null +++ b/gnovm/tests/files/persist_map.gno @@ -0,0 +1,22 @@ +// PKGPATH: gno.land/r/demo/tests_test +package tests_test + +var amap map[string]string = map[string]string{"a": "1"} + +func init() { + println("preinit", amap) + amap["b"] = "2" + println("postinit", amap) +} + +func main() { + println("premain", amap) + amap["c"] = "3" + println("postmain", amap) +} + +// Output: +// preinit map{("a" string):("1" string)} +// postinit map{("a" string):("1" string),("b" string):("2" string)} +// premain map{("a" string):("1" string),("b" string):("2" string)} +// postmain map{("a" string):("1" string),("b" string):("2" string),("c" string):("3" string)}