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:
Anna Shaleva 2022-05-31 08:02:13 +03:00
parent a79c80cb8d
commit 107f5e0793

View file

@ -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()