Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gnovm): correct map key persistence #3127

Merged
merged 10 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions gno.land/pkg/integration/testdata/ptr_mapkey.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
gnoland start

# add contract
gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/demo/ptrmap -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

gnokey maketx call -pkgpath gno.land/r/demo/ptrmap -func AddToMap -args 5 -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

gnokey maketx call -pkgpath gno.land/r/demo/ptrmap -func GetFromMap -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout '(5 int)'
stdout OK!

-- gno.mod --
module gno.land/r/demo/ptrmap

-- realm.gno --
package ptrmap

var (
m = map[*int]int{}
i = new(int)
)

func AddToMap(value int) {
m[i] = value
}

func GetFromMap() int {
return m[i]
}
3 changes: 2 additions & 1 deletion gnovm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ run.bench.storage: build.bench.storage
########################################
# Test suite
.PHONY: test
test: _test.cmd _test.pkg _test.stdlibs
test: _test.filetest _test.cmd _test.pkg _test.stdlibs

.PHONY: _test.cmd
_test.cmd:
Expand Down Expand Up @@ -116,6 +116,7 @@ _test.pkg:
_test.stdlibs:
go run ./cmd/gno test -v ./stdlibs/...

.PHONY: _test.filetest
_test.filetest:;
go test pkg/gnolang/files_test.go -test.short -run 'TestFiles$$/' $(GOTEST_FLAGS)

Expand Down
1 change: 1 addition & 0 deletions gnovm/pkg/gnolang/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,7 @@ func (tv *TypedValue) ComputeMapKey(store Store, omitType bool) MapKey {
pbz := tv.PrimitiveBytes()
bz = append(bz, pbz...)
case *PointerType:
fillValueTV(store, tv)
ptr := uintptr(unsafe.Pointer(tv.V.(PointerValue).TV))
bz = append(bz, uintptrToBytes(&ptr)...)
case FieldType:
Expand Down
27 changes: 27 additions & 0 deletions gnovm/tests/files/ptrmap_1.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

var (
m = map[int]int{}
i = 0
)

func AddToMap(value int) {
m[i] = value
}

func GetFromMap() int {
return m[i]
}

func init() {
AddToMap(5)
}

func main() {
r := GetFromMap()
println(r == 5)
}

// Output:
// true
21 changes: 21 additions & 0 deletions gnovm/tests/files/ptrmap_10.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

var (
m = map[*int]string{}
a, b = 1, 2
arr = [2]*int{&a, &b}
)

func init() {
m[arr[0]] = "first key"
}

func main() {
println(m[arr[0]]) // Output: first key
println(m[arr[1]] == "")
}

// Output:
// first key
// true
22 changes: 22 additions & 0 deletions gnovm/tests/files/ptrmap_11.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

var (
m = map[*int]string{}
a, b = 1, 2
S = []*int{&a, &b} // slice
index = 0
)

func init() {
m[S[index]] = "first key"
}

func main() {
println(m[S[index]]) // Output: first key
println(m[S[1]] == "")
}

// Output:
// first key
// true
21 changes: 21 additions & 0 deletions gnovm/tests/files/ptrmap_12.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

var (
m = map[*int]string{}
a, b = 1, 2
S = []*int{&a, &b}
)

func init() {
m[S[0]] = "first key"
}

func main() {
println(m[S[0]]) // Output: first key
println(m[S[1]] == "")
}

// Output:
// first key
// true
22 changes: 22 additions & 0 deletions gnovm/tests/files/ptrmap_13.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

type MyStruct struct {
Index int
}

var m = make(map[*int]string)
var a, b = 1, 2
var s = []*int{&a, &b}
var myStruct = MyStruct{Index: 0}

func init() {
m[s[myStruct.Index]] = "a"
}

func main() {
println(m[s[myStruct.Index]])
}

// Output:
// a
20 changes: 20 additions & 0 deletions gnovm/tests/files/ptrmap_14.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

var (
m = map[*int]string{}
a = 0
ptr *int = &a // A pointer to an int
i1 **int = &ptr
)

func init() {
m[*i1] = "first key"
}

func main() {
println(m[*i1]) // Output: first key
}

// Output:
// first key
23 changes: 23 additions & 0 deletions gnovm/tests/files/ptrmap_15.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

type MyStruct struct {
Key *int
}

var (
m = map[*int]string{}
i1 = MyStruct{Key: new(int)}
)

func init() {
*i1.Key = 1 // Set the value of the pointer
m[i1.Key] = "first key"
}

func main() {
println(m[i1.Key]) // Output: first key
}

// Output:
// first key
24 changes: 24 additions & 0 deletions gnovm/tests/files/ptrmap_16.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

type Foo struct {
name string
}

var (
arr = [3]Foo{Foo{"a"}, Foo{"b"}, Foo{"c"}}
m = map[*Foo]string{}
)

func init() {
m[&arr[0]] = "first key"
}

func main() {
println(m[&arr[0]])
println(m[&arr[1]] == "")
}

// Output:
// first key
// true
23 changes: 23 additions & 0 deletions gnovm/tests/files/ptrmap_17.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

type Foo struct {
name string
}

var (
arr = [3]Foo{Foo{"a"}, Foo{"b"}, Foo{"c"}}
m = map[*Foo]string{}
index = 0
)

func init() {
m[&arr[index]] = "first key"
}

func main() {
println(m[&arr[index]])
}

// Output:
// first key
33 changes: 33 additions & 0 deletions gnovm/tests/files/ptrmap_18.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

var (
m = map[*int]int{}
i = 0
)

func AddToMap(value int) {
m[&i] = value
}

func GetFromMap() int {
return m[&i]
}

func init() {
i = 1
AddToMap(5)
}

func main() {
r := GetFromMap()
println(r == 5)

i = 2
r = GetFromMap()
println(r == 5)
}

// Output:
// true
// true
37 changes: 37 additions & 0 deletions gnovm/tests/files/ptrmap_19.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

var (
m = map[*int]int{}
i = 0
)

func AddToMap(value int) {
m[&i] = value
}

func GetFromMap() int {
i := 0
{
{
return m[&i]
}
}
}

func init() {
AddToMap(5)
}

func main() {
r := GetFromMap()
println(r == 5)

i = 2
r = GetFromMap()
println(r == 5)
}

// Output:
// false
// false
35 changes: 35 additions & 0 deletions gnovm/tests/files/ptrmap_2.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// PKGPATH: gno.land/r/ptr_map
package ptr_map

var (
m = map[*int]int{}
i = new(int)
)

func AddToMap(value int) {
m[i] = value
}

func GetFromMap() int {
return m[i]
}

func init() {
*i = 1
AddToMap(5)
}

// ----above is initialized and persisted before main is executed.

func main() {
r := GetFromMap()
println(r == 5)

*i = 2 // this changes TV, also Base of a pointer value
r = GetFromMap()
println(r == 5)
}

// Output:
// true
// true
Loading
Loading