mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-26 09:42:22 +00:00
vm: adjust refcount operations order
Perform add/set/remove operations with VM type firstly, and with refcounter after that. It is needed to be able to extend add/set/remove operations with extra checks.
This commit is contained in:
parent
a79c80cb8d
commit
107f5e0793
1 changed files with 9 additions and 5 deletions
14
pkg/vm/vm.go
14
pkg/vm/vm.go
|
@ -1301,24 +1301,28 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
if k < 0 || k >= len(a) {
|
||||
panic("REMOVE: invalid index")
|
||||
}
|
||||
v.refs.Remove(a[k])
|
||||
toRemove := a[k]
|
||||
t.Remove(k)
|
||||
v.refs.Remove(toRemove)
|
||||
case *stackitem.Struct:
|
||||
a := t.Value().([]stackitem.Item)
|
||||
k := toInt(key.BigInt())
|
||||
if k < 0 || k >= len(a) {
|
||||
panic("REMOVE: invalid index")
|
||||
}
|
||||
v.refs.Remove(a[k])
|
||||
toRemove := a[k]
|
||||
t.Remove(k)
|
||||
v.refs.Remove(toRemove)
|
||||
case *stackitem.Map:
|
||||
index := t.Index(key.Item())
|
||||
// NEO 2.0 doesn't error on missing key.
|
||||
if index >= 0 {
|
||||
elems := t.Value().([]stackitem.MapElement)
|
||||
v.refs.Remove(elems[index].Key)
|
||||
v.refs.Remove(elems[index].Value)
|
||||
key := elems[index].Key
|
||||
val := elems[index].Value
|
||||
t.Drop(index)
|
||||
v.refs.Remove(key)
|
||||
v.refs.Remove(val)
|
||||
}
|
||||
default:
|
||||
panic("REMOVE: invalid type")
|
||||
|
@ -1353,6 +1357,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
elems := arr.Value().([]stackitem.Item)
|
||||
index := len(elems) - 1
|
||||
elem := elems[index]
|
||||
v.estack.PushItem(elem) // push item on stack firstly, to match the reference behaviour.
|
||||
switch item := arr.(type) {
|
||||
case *stackitem.Array:
|
||||
item.Remove(index)
|
||||
|
@ -1360,7 +1365,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
item.Remove(index)
|
||||
}
|
||||
v.refs.Remove(elem)
|
||||
v.estack.PushItem(elem)
|
||||
|
||||
case opcode.SIZE:
|
||||
elem := v.estack.Pop()
|
||||
|
|
Loading…
Reference in a new issue