vm: reorder arithmetic opcodes

This commit is contained in:
Evgenii Stratonikov 2020-04-28 16:05:11 +03:00
parent fda943b5cf
commit a64a0f2681
6 changed files with 150 additions and 150 deletions

View file

@ -47,18 +47,18 @@ type rpcTestCase struct {
check func(t *testing.T, e *executor, result interface{}) check func(t *testing.T, e *executor, result interface{})
} }
const testContractHash = "7858559a8405f4e4e1834fcff274ddf4f1b8f407" const testContractHash = "642e2f47cc6883f0c196cf0dd3dcbb2333300173"
var rpcTestCases = map[string][]rpcTestCase{ var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": { "getapplicationlog": {
{ {
name: "positive", name: "positive",
params: `["fe1a3678b16eca35209acf85397708eb0f1668e4045ad4cd5d2453d3bc0a0a6d"]`, params: `["953b6e5ba85dd068c2eba5afd2ffdf8ff832b3a791976e2fd896baf5737b2616"]`,
result: func(e *executor) interface{} { return &result.ApplicationLog{} }, result: func(e *executor) interface{} { return &result.ApplicationLog{} },
check: func(t *testing.T, e *executor, acc interface{}) { check: func(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.ApplicationLog) res, ok := acc.(*result.ApplicationLog)
require.True(t, ok) require.True(t, ok)
expectedTxHash, err := util.Uint256DecodeStringLE("fe1a3678b16eca35209acf85397708eb0f1668e4045ad4cd5d2453d3bc0a0a6d") expectedTxHash, err := util.Uint256DecodeStringLE("953b6e5ba85dd068c2eba5afd2ffdf8ff832b3a791976e2fd896baf5737b2616")
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, expectedTxHash, res.TxHash) assert.Equal(t, expectedTxHash, res.TxHash)
assert.Equal(t, 1, len(res.Executions)) assert.Equal(t, 1, len(res.Executions))

Binary file not shown.

Binary file not shown.

View file

@ -98,38 +98,38 @@ const (
RIGHT Opcode = 0x81 RIGHT Opcode = 0x81
// Bitwise logic // Bitwise logic
INVERT Opcode = 0x83 INVERT Opcode = 0x90
AND Opcode = 0x84 AND Opcode = 0x91
OR Opcode = 0x85 OR Opcode = 0x92
XOR Opcode = 0x86 XOR Opcode = 0x93
EQUAL Opcode = 0x87 EQUAL Opcode = 0x97
// Arithmetic // Arithmetic
INC Opcode = 0x8B SIGN Opcode = 0x99
DEC Opcode = 0x8C ABS Opcode = 0x9A
SIGN Opcode = 0x8D NEGATE Opcode = 0x9B
NEGATE Opcode = 0x8F INC Opcode = 0x9C
ABS Opcode = 0x90 DEC Opcode = 0x9D
NOT Opcode = 0x91 ADD Opcode = 0x9E
NZ Opcode = 0x92 SUB Opcode = 0x9F
ADD Opcode = 0x93 MUL Opcode = 0xA0
SUB Opcode = 0x94 DIV Opcode = 0xA1
MUL Opcode = 0x95 MOD Opcode = 0xA2
DIV Opcode = 0x96 SHL Opcode = 0xA8
MOD Opcode = 0x97 SHR Opcode = 0xA9
SHL Opcode = 0x98 NOT Opcode = 0xAA
SHR Opcode = 0x99 BOOLAND Opcode = 0xAB
BOOLAND Opcode = 0x9A BOOLOR Opcode = 0xAC
BOOLOR Opcode = 0x9B NZ Opcode = 0xB1
NUMEQUAL Opcode = 0x9C NUMEQUAL Opcode = 0xB3
NUMNOTEQUAL Opcode = 0x9E NUMNOTEQUAL Opcode = 0xB4
LT Opcode = 0x9F LT Opcode = 0xB5
GT Opcode = 0xA0 LTE Opcode = 0xB6
LTE Opcode = 0xA1 GT Opcode = 0xB7
GTE Opcode = 0xA2 GTE Opcode = 0xB8
MIN Opcode = 0xA3 MIN Opcode = 0xB9
MAX Opcode = 0xA4 MAX Opcode = 0xBA
WITHIN Opcode = 0xA5 WITHIN Opcode = 0xBB
// Advanced data structures (arrays, structures, maps) // Advanced data structures (arrays, structures, maps)
PACK Opcode = 0xC0 PACK Opcode = 0xC0

View file

@ -84,36 +84,36 @@ func _() {
_ = x[SUBSTR-127] _ = x[SUBSTR-127]
_ = x[LEFT-128] _ = x[LEFT-128]
_ = x[RIGHT-129] _ = x[RIGHT-129]
_ = x[INVERT-131] _ = x[INVERT-144]
_ = x[AND-132] _ = x[AND-145]
_ = x[OR-133] _ = x[OR-146]
_ = x[XOR-134] _ = x[XOR-147]
_ = x[EQUAL-135] _ = x[EQUAL-151]
_ = x[INC-139] _ = x[SIGN-153]
_ = x[DEC-140] _ = x[ABS-154]
_ = x[SIGN-141] _ = x[NEGATE-155]
_ = x[NEGATE-143] _ = x[INC-156]
_ = x[ABS-144] _ = x[DEC-157]
_ = x[NOT-145] _ = x[ADD-158]
_ = x[NZ-146] _ = x[SUB-159]
_ = x[ADD-147] _ = x[MUL-160]
_ = x[SUB-148] _ = x[DIV-161]
_ = x[MUL-149] _ = x[MOD-162]
_ = x[DIV-150] _ = x[SHL-168]
_ = x[MOD-151] _ = x[SHR-169]
_ = x[SHL-152] _ = x[NOT-170]
_ = x[SHR-153] _ = x[BOOLAND-171]
_ = x[BOOLAND-154] _ = x[BOOLOR-172]
_ = x[BOOLOR-155] _ = x[NZ-177]
_ = x[NUMEQUAL-156] _ = x[NUMEQUAL-179]
_ = x[NUMNOTEQUAL-158] _ = x[NUMNOTEQUAL-180]
_ = x[LT-159] _ = x[LT-181]
_ = x[GT-160] _ = x[LTE-182]
_ = x[LTE-161] _ = x[GT-183]
_ = x[GTE-162] _ = x[GTE-184]
_ = x[MIN-163] _ = x[MIN-185]
_ = x[MAX-164] _ = x[MAX-186]
_ = x[WITHIN-165] _ = x[WITHIN-187]
_ = x[PACK-192] _ = x[PACK-192]
_ = x[UNPACK-193] _ = x[UNPACK-193]
_ = x[NEWARRAY0-194] _ = x[NEWARRAY0-194]
@ -139,7 +139,7 @@ func _() {
_ = x[THROWIFNOT-241] _ = x[THROWIFNOT-241]
} }
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPLJMPIFJMPIFLJMPIFNOTJMPIFNOTLJMPEQJMPEQLJMPNEJMPNELJMPGTJMPGTLJMPGEJMPGELJMPLTJMPLTLJMPLEJMPLELCALLCALLLOLDPUSH1RETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINPACKUNPACKNEWARRAY0NEWARRAYNEWARRAYTNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSISNULLISTYPECONVERTTHROWTHROWIFNOT" const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPLJMPIFJMPIFLJMPIFNOTJMPIFNOTLJMPEQJMPEQLJMPNEJMPNELJMPGTJMPGTLJMPGEJMPGELJMPLTJMPLTLJMPLEJMPLELCALLCALLLOLDPUSH1RETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLTEGTGTEMINMAXWITHINPACKUNPACKNEWARRAY0NEWARRAYNEWARRAYTNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSISNULLISTYPECONVERTTHROWTHROWIFNOT"
var _Opcode_map = map[Opcode]string{ var _Opcode_map = map[Opcode]string{
0: _Opcode_name[0:8], 0: _Opcode_name[0:8],
@ -216,36 +216,36 @@ var _Opcode_map = map[Opcode]string{
127: _Opcode_name[427:433], 127: _Opcode_name[427:433],
128: _Opcode_name[433:437], 128: _Opcode_name[433:437],
129: _Opcode_name[437:442], 129: _Opcode_name[437:442],
131: _Opcode_name[442:448], 144: _Opcode_name[442:448],
132: _Opcode_name[448:451], 145: _Opcode_name[448:451],
133: _Opcode_name[451:453], 146: _Opcode_name[451:453],
134: _Opcode_name[453:456], 147: _Opcode_name[453:456],
135: _Opcode_name[456:461], 151: _Opcode_name[456:461],
139: _Opcode_name[461:464], 153: _Opcode_name[461:465],
140: _Opcode_name[464:467], 154: _Opcode_name[465:468],
141: _Opcode_name[467:471], 155: _Opcode_name[468:474],
143: _Opcode_name[471:477], 156: _Opcode_name[474:477],
144: _Opcode_name[477:480], 157: _Opcode_name[477:480],
145: _Opcode_name[480:483], 158: _Opcode_name[480:483],
146: _Opcode_name[483:485], 159: _Opcode_name[483:486],
147: _Opcode_name[485:488], 160: _Opcode_name[486:489],
148: _Opcode_name[488:491], 161: _Opcode_name[489:492],
149: _Opcode_name[491:494], 162: _Opcode_name[492:495],
150: _Opcode_name[494:497], 168: _Opcode_name[495:498],
151: _Opcode_name[497:500], 169: _Opcode_name[498:501],
152: _Opcode_name[500:503], 170: _Opcode_name[501:504],
153: _Opcode_name[503:506], 171: _Opcode_name[504:511],
154: _Opcode_name[506:513], 172: _Opcode_name[511:517],
155: _Opcode_name[513:519], 177: _Opcode_name[517:519],
156: _Opcode_name[519:527], 179: _Opcode_name[519:527],
158: _Opcode_name[527:538], 180: _Opcode_name[527:538],
159: _Opcode_name[538:540], 181: _Opcode_name[538:540],
160: _Opcode_name[540:542], 182: _Opcode_name[540:543],
161: _Opcode_name[542:545], 183: _Opcode_name[543:545],
162: _Opcode_name[545:548], 184: _Opcode_name[545:548],
163: _Opcode_name[548:551], 185: _Opcode_name[548:551],
164: _Opcode_name[551:554], 186: _Opcode_name[551:554],
165: _Opcode_name[554:560], 187: _Opcode_name[554:560],
192: _Opcode_name[560:564], 192: _Opcode_name[560:564],
193: _Opcode_name[564:570], 193: _Opcode_name[564:570],
194: _Opcode_name[570:579], 194: _Opcode_name[570:579],

View file

@ -726,17 +726,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
} }
v.estack.Pop() v.estack.Pop()
case opcode.EQUAL:
b := v.estack.Pop()
if b == nil {
panic("no top-level element found")
}
a := v.estack.Pop()
if a == nil {
panic("no second-to-the-top element found")
}
v.estack.PushVal(a.value.Equals(b.value))
// Bit operations. // Bit operations.
case opcode.INVERT: case opcode.INVERT:
// inplace // inplace
@ -759,7 +748,42 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
a := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt()
v.estack.PushVal(new(big.Int).Xor(b, a)) v.estack.PushVal(new(big.Int).Xor(b, a))
case opcode.EQUAL:
b := v.estack.Pop()
if b == nil {
panic("no top-level element found")
}
a := v.estack.Pop()
if a == nil {
panic("no second-to-the-top element found")
}
v.estack.PushVal(a.value.Equals(b.value))
// Numeric operations. // Numeric operations.
case opcode.SIGN:
x := v.estack.Pop().BigInt()
v.estack.PushVal(x.Sign())
case opcode.ABS:
x := v.estack.Pop().BigInt()
v.estack.PushVal(x.Abs(x))
case opcode.NEGATE:
x := v.estack.Pop().BigInt()
v.estack.PushVal(x.Neg(x))
case opcode.INC:
x := v.estack.Pop().BigInt()
a := new(big.Int).Add(x, big.NewInt(1))
v.checkBigIntSize(a)
v.estack.PushVal(a)
case opcode.DEC:
x := v.estack.Pop().BigInt()
a := new(big.Int).Sub(x, big.NewInt(1))
v.checkBigIntSize(a)
v.estack.PushVal(a)
case opcode.ADD: case opcode.ADD:
a := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt()
v.checkBigIntSize(a) v.checkBigIntSize(a)
@ -780,14 +804,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
v.checkBigIntSize(c) v.checkBigIntSize(c)
v.estack.PushVal(c) v.estack.PushVal(c)
case opcode.DIV:
b := v.estack.Pop().BigInt()
v.checkBigIntSize(b)
a := v.estack.Pop().BigInt()
v.checkBigIntSize(a)
v.estack.PushVal(new(big.Int).Quo(a, b))
case opcode.MUL: case opcode.MUL:
a := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt()
v.checkBigIntSize(a) v.checkBigIntSize(a)
@ -798,6 +814,14 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
v.checkBigIntSize(c) v.checkBigIntSize(c)
v.estack.PushVal(c) v.estack.PushVal(c)
case opcode.DIV:
b := v.estack.Pop().BigInt()
v.checkBigIntSize(b)
a := v.estack.Pop().BigInt()
v.checkBigIntSize(a)
v.estack.PushVal(new(big.Int).Quo(a, b))
case opcode.MOD: case opcode.MOD:
b := v.estack.Pop().BigInt() b := v.estack.Pop().BigInt()
v.checkBigIntSize(b) v.checkBigIntSize(b)
@ -826,6 +850,10 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
v.checkBigIntSize(&item) v.checkBigIntSize(&item)
v.estack.PushVal(&item) v.estack.PushVal(&item)
case opcode.NOT:
x := v.estack.Pop().Bool()
v.estack.PushVal(!x)
case opcode.BOOLAND: case opcode.BOOLAND:
b := v.estack.Pop().Bool() b := v.estack.Pop().Bool()
a := v.estack.Pop().Bool() a := v.estack.Pop().Bool()
@ -836,6 +864,10 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
a := v.estack.Pop().Bool() a := v.estack.Pop().Bool()
v.estack.PushVal(a || b) v.estack.PushVal(a || b)
case opcode.NZ:
x := v.estack.Pop().BigInt()
v.estack.PushVal(x.Sign() != 0)
case opcode.NUMEQUAL: case opcode.NUMEQUAL:
b := v.estack.Pop().BigInt() b := v.estack.Pop().BigInt()
a := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt()
@ -851,16 +883,16 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
a := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt()
v.estack.PushVal(a.Cmp(b) == -1) v.estack.PushVal(a.Cmp(b) == -1)
case opcode.GT:
b := v.estack.Pop().BigInt()
a := v.estack.Pop().BigInt()
v.estack.PushVal(a.Cmp(b) == 1)
case opcode.LTE: case opcode.LTE:
b := v.estack.Pop().BigInt() b := v.estack.Pop().BigInt()
a := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt()
v.estack.PushVal(a.Cmp(b) <= 0) v.estack.PushVal(a.Cmp(b) <= 0)
case opcode.GT:
b := v.estack.Pop().BigInt()
a := v.estack.Pop().BigInt()
v.estack.PushVal(a.Cmp(b) == 1)
case opcode.GTE: case opcode.GTE:
b := v.estack.Pop().BigInt() b := v.estack.Pop().BigInt()
a := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt()
@ -890,38 +922,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
x := v.estack.Pop().BigInt() x := v.estack.Pop().BigInt()
v.estack.PushVal(a.Cmp(x) <= 0 && x.Cmp(b) == -1) v.estack.PushVal(a.Cmp(x) <= 0 && x.Cmp(b) == -1)
case opcode.INC:
x := v.estack.Pop().BigInt()
a := new(big.Int).Add(x, big.NewInt(1))
v.checkBigIntSize(a)
v.estack.PushVal(a)
case opcode.DEC:
x := v.estack.Pop().BigInt()
a := new(big.Int).Sub(x, big.NewInt(1))
v.checkBigIntSize(a)
v.estack.PushVal(a)
case opcode.SIGN:
x := v.estack.Pop().BigInt()
v.estack.PushVal(x.Sign())
case opcode.NEGATE:
x := v.estack.Pop().BigInt()
v.estack.PushVal(x.Neg(x))
case opcode.ABS:
x := v.estack.Pop().BigInt()
v.estack.PushVal(x.Abs(x))
case opcode.NOT:
x := v.estack.Pop().Bool()
v.estack.PushVal(!x)
case opcode.NZ:
x := v.estack.Pop().BigInt()
v.estack.PushVal(x.Cmp(big.NewInt(0)) != 0)
// Object operations // Object operations
case opcode.NEWARRAY0: case opcode.NEWARRAY0:
v.estack.PushVal(&ArrayItem{[]StackItem{}}) v.estack.PushVal(&ArrayItem{[]StackItem{}})