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: handle assignments to dereferenced pointer values #1398

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2c023cf
recurse on DidUpdate for all ArrayValue elements
deelawn Oct 26, 2023
c4ed7e4
undid incorrect simplification
deelawn Oct 26, 2023
09df263
reworked solution
deelawn Oct 27, 2023
cec8f0d
Added txtar test
deelawn Oct 27, 2023
7ecb905
Merge branch 'master' into bug/slice-append
deelawn Oct 27, 2023
91b4586
alternate approach to saving nested reference values
deelawn Oct 31, 2023
b2e153a
scoped back which types of values can be saved dynamically
deelawn Oct 31, 2023
4b4b25c
Revert "alternate approach to saving nested reference values"
deelawn Nov 1, 2023
7df8c80
handle nested slices when appending to slices under capacity
deelawn Nov 2, 2023
77f79a8
Merge branch 'master' into bug/slice-append
deelawn Nov 7, 2023
6821083
wrap new sanity check in debug
deelawn Nov 7, 2023
811b5f6
Merge branch 'master' into bug/slice-append
deelawn Nov 8, 2023
b4279e9
fixed up txtar test
deelawn Nov 8, 2023
daa6914
added XX annotation
deelawn Nov 8, 2023
750ec38
reworked solution to avoid looping in DidUpdate
deelawn Nov 14, 2023
7392890
txtar test for 1167 test case
deelawn Nov 14, 2023
9c0c35a
improved append test and added more append deep copies
deelawn Nov 15, 2023
de2a233
handle additional append cases
deelawn Nov 15, 2023
1d7497c
first stab at a solution that fixes the issue
deelawn Nov 29, 2023
9133293
added realm qualifier
deelawn Nov 29, 2023
ed2ad73
use object accessor method
deelawn Nov 29, 2023
e7589fe
add txtar; fix pkg path in other
deelawn Dec 7, 2023
bb9fb88
Merge branch 'master' into bug/ptr-deref-assgn
deelawn Jan 8, 2024
d03eec7
restore object info copy functionality
deelawn Jan 8, 2024
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
129 changes: 129 additions & 0 deletions gno.land/cmd/gnoland/testdata/append.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# start a new node
gnoland start

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

# Call Append 1
gnokey maketx call -pkgpath gno.land/r/append -func Append -gas-fee 1000000ugnot -gas-wanted 2000000 -args '1' -broadcast -chainid=tendermint_test test1
stdout OK!

gnokey maketx call -pkgpath gno.land/r/append -func AppendNil -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

# Call Append 2
gnokey maketx call -pkgpath gno.land/r/append -func Append -gas-fee 1000000ugnot -gas-wanted 2000000 -args '2' -broadcast -chainid=tendermint_test test1
stdout OK!

# Call Append 3
gnokey maketx call -pkgpath gno.land/r/append -func Append -gas-fee 1000000ugnot -gas-wanted 2000000 -args '3' -broadcast -chainid=tendermint_test test1
stdout OK!

# Call render
gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout '("1-2-3-" string)'
stdout OK!

# Call Pop
gnokey maketx call -pkgpath gno.land/r/append -func Pop -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

# Call render
gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout '("2-3-" string)'
stdout OK!

# Call Append 42
gnokey maketx call -pkgpath gno.land/r/append -func Append -gas-fee 1000000ugnot -gas-wanted 2000000 -args '42' -broadcast -chainid=tendermint_test test1
stdout OK!

# Call render
gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout '("2-3-42-" string)'
stdout OK!

gnokey maketx call -pkgpath gno.land/r/append -func CopyAppend -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

gnokey maketx call -pkgpath gno.land/r/append -func PopB -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

# Call render
gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout '("2-3-42-" string)'
stdout OK!

gnokey maketx call -pkgpath gno.land/r/append -func AppendMoreAndC -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

gnokey maketx call -pkgpath gno.land/r/append -func ReassignC -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout '("2-3-42-70-100-" string)'
stdout OK!

gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args 'd' -broadcast -chainid=tendermint_test test1
stdout '("1-" string)'
stdout OK!

-- append.gno --
package append

import (
"gno.land/p/demo/ufmt"
)

type T struct{ i int }

var a, b, d []T
var c = []T{{i: 100}}


func init() {
a = make([]T, 0, 1)
}

func Pop() {
a = append(a[:0], a[1:]...)
}

func Append(i int) {
a = append(a, T{i: i})
}

func CopyAppend() {
b = append(a, T{i: 50}, T{i: 60})
}

func PopB() {
b = append(b[:0], b[1:]...)
}

func AppendMoreAndC() {
// Fill to capacity
a = append(a, T{i: 70})
// Above capacity; make new array
a = append(a, c...)
}

func ReassignC() {
c[0] = T{i: 200}
}

func AppendNil() {
d = append(d, a...)
}

func Render(path string) string {
source := a
if path == "d" {
source = d
}

var s string
for i:=0;i<len(source);i++{
s+=ufmt.Sprintf("%d-", source[i].i)
}
return s
}
107 changes: 107 additions & 0 deletions gno.land/cmd/gnoland/testdata/issue-1167.txtar
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate a second on these changes?

Were they not reproducing 1167 correctly?

Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Reproducible Test for https://github.com/gnolang/gno/issues/1167

gnoland start

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

# execute New
gnokey maketx call -pkgpath gno.land/r/xx -func New -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

# execute Delta for the first time
gnokey maketx call -pkgpath gno.land/r/xx -func Delta -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout '"1,1,1;" string'

# execute Delta for the second time
gnokey maketx call -pkgpath gno.land/r/xx -func Delta -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout '1,1,1;2,2,2;" string'

# execute Delta for the third time
gnokey maketx call -pkgpath gno.land/r/xx -func Delta -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout '1,1,1;2,2,2;3,3,3;" string'

# execute Render
gnokey maketx call -pkgpath gno.land/r/xx -func Render -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout '1,1,1;2,2,2;3,3,3;" string'

-- realm.gno --
package xx

import (
"strconv"

"gno.land/p/demo/avl"
)

type Move struct {
N1, N2, N3 byte
}

type Position struct {
Moves []Move
}

func (p Position) clone() Position {
mv := p.Moves
return Position{Moves: mv}
}

func (oldp Position) update() Position {
p := oldp.clone()

counter++
// This is a workaround for the wrong behaviour (ie. uncomment this line):
// p.Moves = append([]Move{}, p.Moves...)
p.Moves = append(p.Moves, Move{counter, counter, counter})
return p
}

type Game struct {
Position Position
}

var games avl.Tree // id -> *Game

var counter byte

func New(s string) string {
// Bug shows if Moves has a cap > 0 when initialised.
el := &Game{Position: Position{Moves: make([]Move, 0, 2)}}
games.Set(s, el)
return values(el.Position)
}

func Delta(s string) string {
v, _ := games.Get(s)
g, ok := v.(*Game)
if !ok {
panic("invalid game")
}
n := g.Position.update()
g.Position = n
ret := values(n)
return ret
}

func Render(s string) string {
v, _ := games.Get(s)
g, ok := v.(*Game)
if !ok {
panic("invalid game")
}
return values(g.Position)
}

func values(x Position) string {
s := ""
for _, val := range x.Moves {
s += strconv.Itoa(int(val.N1)) + "," + strconv.Itoa(int(val.N2)) + "," + strconv.Itoa(int(val.N3)) + ";"
}
return s
}
67 changes: 67 additions & 0 deletions gno.land/cmd/gnoland/testdata/issue-1326.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Reproducible Test for https://github.com/gnolang/gno/issues/1167

gnoland start

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

# execute New
gnokey maketx call -pkgpath gno.land/r/xx -func New -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

# execute Delta for the first time
gnokey maketx call -pkgpath gno.land/r/xx -func Delta -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!

-- realm.gno --
package xx

import (
"strconv"

"gno.land/p/demo/avl"
)

type Move struct {
N1, N2, N3 byte
}

type S struct {
Moves []Move
}

func (s S) clone() S {
mv := s.Moves
return S{Moves: mv}
}

func (olds S) change() S {
s := olds.clone()

counter++
s.Moves = append([]Move{}, s.Moves...)
s.Moves = append(s.Moves, Move{counter, counter, counter})
return s
}

var el *S
var counter byte

func New() {
el = &S{}
}

func Delta() string {
n := el.change()
*el = n
return Values()
}

func Values() string {
s := ""
for _, val := range el.Moves {
s += strconv.Itoa(int(val.N1)) + "," + strconv.Itoa(int(val.N2)) + "," + strconv.Itoa(int(val.N3)) + ";"
}
return s
}
2 changes: 2 additions & 0 deletions gnovm/pkg/gnolang/realm.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ func (rlm *Realm) DidUpdate(po, xo, co Object) {
// Updates to .newCreated/.newEscaped /.newDeleted made here. (first gen)
// More appends happen during FinalizeRealmTransactions(). (second+ gen)
rlm.MarkDirty(po)

if co != nil {
co.IncRefCount()
if co.GetRefCount() > 1 {
Expand All @@ -166,6 +167,7 @@ func (rlm *Realm) DidUpdate(po, xo, co Object) {
rlm.MarkNewReal(co)
}
}

if xo != nil {
xo.DecRefCount()
if xo.GetRefCount() == 0 {
Expand Down
Loading
Loading