mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-26 19:42:23 +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) {
|
if k < 0 || k >= len(a) {
|
||||||
panic("REMOVE: invalid index")
|
panic("REMOVE: invalid index")
|
||||||
}
|
}
|
||||||
v.refs.Remove(a[k])
|
toRemove := a[k]
|
||||||
t.Remove(k)
|
t.Remove(k)
|
||||||
|
v.refs.Remove(toRemove)
|
||||||
case *stackitem.Struct:
|
case *stackitem.Struct:
|
||||||
a := t.Value().([]stackitem.Item)
|
a := t.Value().([]stackitem.Item)
|
||||||
k := toInt(key.BigInt())
|
k := toInt(key.BigInt())
|
||||||
if k < 0 || k >= len(a) {
|
if k < 0 || k >= len(a) {
|
||||||
panic("REMOVE: invalid index")
|
panic("REMOVE: invalid index")
|
||||||
}
|
}
|
||||||
v.refs.Remove(a[k])
|
toRemove := a[k]
|
||||||
t.Remove(k)
|
t.Remove(k)
|
||||||
|
v.refs.Remove(toRemove)
|
||||||
case *stackitem.Map:
|
case *stackitem.Map:
|
||||||
index := t.Index(key.Item())
|
index := t.Index(key.Item())
|
||||||
// NEO 2.0 doesn't error on missing key.
|
// NEO 2.0 doesn't error on missing key.
|
||||||
if index >= 0 {
|
if index >= 0 {
|
||||||
elems := t.Value().([]stackitem.MapElement)
|
elems := t.Value().([]stackitem.MapElement)
|
||||||
v.refs.Remove(elems[index].Key)
|
key := elems[index].Key
|
||||||
v.refs.Remove(elems[index].Value)
|
val := elems[index].Value
|
||||||
t.Drop(index)
|
t.Drop(index)
|
||||||
|
v.refs.Remove(key)
|
||||||
|
v.refs.Remove(val)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
panic("REMOVE: invalid type")
|
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)
|
elems := arr.Value().([]stackitem.Item)
|
||||||
index := len(elems) - 1
|
index := len(elems) - 1
|
||||||
elem := elems[index]
|
elem := elems[index]
|
||||||
|
v.estack.PushItem(elem) // push item on stack firstly, to match the reference behaviour.
|
||||||
switch item := arr.(type) {
|
switch item := arr.(type) {
|
||||||
case *stackitem.Array:
|
case *stackitem.Array:
|
||||||
item.Remove(index)
|
item.Remove(index)
|
||||||
|
@ -1360,7 +1365,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
item.Remove(index)
|
item.Remove(index)
|
||||||
}
|
}
|
||||||
v.refs.Remove(elem)
|
v.refs.Remove(elem)
|
||||||
v.estack.PushItem(elem)
|
|
||||||
|
|
||||||
case opcode.SIZE:
|
case opcode.SIZE:
|
||||||
elem := v.estack.Pop()
|
elem := v.estack.Pop()
|
||||||
|
|
Loading…
Reference in a new issue