mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-01-08 15:45:15 +00:00
vm: fix incorrect refcounting in POPITEM
We're popping an item (array) off the stack, OK, it triggers refs.Remove() for
it. Then we're pushing an inner item to the stack, OK, it triggers refs.Add()
for this element. Why are we removing it afterwards? Looks like something went
wrong in 324107b31e
(and https://github.com/nspcc-dev/neo-go/pull/1670)
since a simple test shows zero counter after POPITEM and -1 after popping the
only item left on the stack.
Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
parent
4a96bd1dc1
commit
270f0d2d7a
2 changed files with 14 additions and 1 deletions
|
@ -3,6 +3,7 @@ package vm
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -46,6 +47,19 @@ func TestRefCounter_Add(t *testing.T) {
|
|||
require.Equal(t, 2, int(*r))
|
||||
}
|
||||
|
||||
func TestRefCounterPopItem(t *testing.T) {
|
||||
prog := makeProgram(opcode.POPITEM)
|
||||
v := load(prog)
|
||||
v.estack.PushVal(stackitem.NewArray([]stackitem.Item{stackitem.Make(42)}))
|
||||
require.Equal(t, 2, int(v.refs))
|
||||
runVM(t, v)
|
||||
require.Equal(t, 1, v.estack.Len())
|
||||
require.Equal(t, 1, int(v.refs))
|
||||
_ = v.estack.Pop()
|
||||
require.Equal(t, 0, v.estack.Len())
|
||||
require.Equal(t, 0, int(v.refs))
|
||||
}
|
||||
|
||||
func BenchmarkRefCounter_Add(b *testing.B) {
|
||||
a := stackitem.NewArray(nil)
|
||||
rc := newRefCounter()
|
||||
|
|
|
@ -1459,7 +1459,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
case *stackitem.Struct:
|
||||
item.Remove(index)
|
||||
}
|
||||
v.refs.Remove(elem)
|
||||
|
||||
case opcode.SIZE:
|
||||
elem := v.estack.Pop()
|
||||
|
|
Loading…
Reference in a new issue