vm: reorder Array/Map opcodes

Also SIZE can be used for both Arrays/Maps and ByteArrays.
This commit is contained in:
Evgenii Stratonikov 2020-04-24 12:24:08 +03:00
parent f940d6e5ad
commit 03761421f8
9 changed files with 119 additions and 129 deletions

View file

@ -398,7 +398,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
ast.Walk(c, n.High) ast.Walk(c, n.High)
} else { } else {
emit.Opcode(c.prog.BinWriter, opcode.OVER) emit.Opcode(c.prog.BinWriter, opcode.OVER)
emit.Opcode(c.prog.BinWriter, opcode.ARRAYSIZE) emit.Opcode(c.prog.BinWriter, opcode.SIZE)
} }
emit.Opcode(c.prog.BinWriter, opcode.OVER) emit.Opcode(c.prog.BinWriter, opcode.OVER)
@ -858,7 +858,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
ast.Walk(c, n.X) ast.Walk(c, n.X)
emit.Opcode(c.prog.BinWriter, opcode.ARRAYSIZE) emit.Opcode(c.prog.BinWriter, opcode.SIZE)
emit.Opcode(c.prog.BinWriter, opcode.PUSH0) emit.Opcode(c.prog.BinWriter, opcode.PUSH0)
c.pushStackLabel(label, 2) c.pushStackLabel(label, 2)
@ -1030,13 +1030,7 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
switch name { switch name {
case "len": case "len":
arg := expr.Args[0] emit.Opcode(c.prog.BinWriter, opcode.SIZE)
typ := c.typeInfo.Types[arg].Type
if isStringType(typ) {
emit.Opcode(c.prog.BinWriter, opcode.SIZE)
} else {
emit.Opcode(c.prog.BinWriter, opcode.ARRAYSIZE)
}
case "append": case "append":
arg := expr.Args[0] arg := expr.Args[0]
typ := c.typeInfo.Types[arg].Type typ := c.typeInfo.Types[arg].Type

View file

@ -28,34 +28,34 @@ func TestInvocationScriptCreationGood(t *testing.T) {
script: "0c023432676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "0c023432676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{}}},
script: "10c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "10c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ByteArrayType, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ByteArrayType, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}},
script: "0c1450befd26fdf6e4d957c11e078b24ebce6291456f11c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "0c1450befd26fdf6e4d957c11e078b24ebce6291456f11c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.SignatureType, Value: Param{Type: StringT, Value: "4edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f"}}}}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.SignatureType, Value: Param{Type: StringT, Value: "4edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f"}}}}}},
script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.StringType, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.StringType, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}},
script: "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash160Type, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash160Type, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}},
script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash256Type, Value: Param{Type: StringT, Value: "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"}}}}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash256Type, Value: Param{Type: StringT, Value: "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"}}}}}},
script: "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.PublicKeyType, Value: Param{Type: StringT, Value: "03c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c1"}}}}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.PublicKeyType, Value: Param{Type: StringT, Value: "03c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c1"}}}}}},
script: "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.IntegerType, Value: Param{Type: NumberT, Value: 42}}}}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.IntegerType, Value: Param{Type: NumberT, Value: 42}}}}}},
script: "002a11c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "002a11c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "true"}}}}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "true"}}}}}},
script: "1111c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "1111c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, { }, {
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "false"}}}}}}, ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "false"}}}}}},
script: "1011c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50", script: "1011c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}} }}
for _, ps := range paramScripts { for _, ps := range paramScripts {
script, err := CreateFunctionInvocationScript(contract, ps.ps) script, err := CreateFunctionInvocationScript(contract, ps.ps)

View file

@ -48,18 +48,18 @@ type rpcTestCase struct {
check func(t *testing.T, e *executor, result interface{}) check func(t *testing.T, e *executor, result interface{})
} }
const testContractHash = "6b9e88be61028590ebbb1296cbee09beed4ae75d" const testContractHash = "7858559a8405f4e4e1834fcff274ddf4f1b8f407"
var rpcTestCases = map[string][]rpcTestCase{ var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": { "getapplicationlog": {
{ {
name: "positive", name: "positive",
params: `["4459d8050e0abb0a42a9ec5a84dee1c5f8c449b11859265ef45a47c5ea369bc5"]`, params: `["4108062977676178e8453a8ef84a702e01bb35af8a65c7529d04704fcb5f1e0e"]`,
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("4459d8050e0abb0a42a9ec5a84dee1c5f8c449b11859265ef45a47c5ea369bc5") expectedTxHash, err := util.Uint256DecodeStringLE("4108062977676178e8453a8ef84a702e01bb35af8a65c7529d04704fcb5f1e0e")
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,7 +98,6 @@ const (
SUBSTR Opcode = 0x7F SUBSTR Opcode = 0x7F
LEFT Opcode = 0x80 LEFT Opcode = 0x80
RIGHT Opcode = 0x81 RIGHT Opcode = 0x81
SIZE Opcode = 0x82
// Bitwise logic // Bitwise logic
INVERT Opcode = 0x83 INVERT Opcode = 0x83
@ -144,20 +143,24 @@ const (
CHECKMULTISIG Opcode = 0xAE CHECKMULTISIG Opcode = 0xAE
// Advanced data structures (arrays, structures, maps) // Advanced data structures (arrays, structures, maps)
ARRAYSIZE Opcode = 0xC0 PACK Opcode = 0xC0
PACK Opcode = 0xC1 UNPACK Opcode = 0xC1
UNPACK Opcode = 0xC2 // NEWARRAY0 Opcode = 0xC2
PICKITEM Opcode = 0xC3 NEWARRAY Opcode = 0xC3
SETITEM Opcode = 0xC4 // NEWARRAYT Opcode = 0xC4
NEWARRAY Opcode = 0xC5 // NEWSTRUCT0 Opcode = 0xC5
NEWSTRUCT Opcode = 0xC6 NEWSTRUCT Opcode = 0xC6
NEWMAP Opcode = 0xC7 NEWMAP Opcode = 0xC8
APPEND Opcode = 0xC8 SIZE Opcode = 0xCA
REVERSE Opcode = 0xC9 HASKEY Opcode = 0xCB
REMOVE Opcode = 0xCA KEYS Opcode = 0xCC
HASKEY Opcode = 0xCB VALUES Opcode = 0xCD
KEYS Opcode = 0xCC PICKITEM Opcode = 0xCE
VALUES Opcode = 0xCD APPEND Opcode = 0xCF
SETITEM Opcode = 0xD0
REVERSEITEMS Opcode = 0xD1
REMOVE Opcode = 0xD2
// CLEARITEMS Opcode = 0xD3
// Exceptions // Exceptions
THROW Opcode = 0xF0 THROW Opcode = 0xF0

View file

@ -85,7 +85,6 @@ func _() {
_ = x[SUBSTR-127] _ = x[SUBSTR-127]
_ = x[LEFT-128] _ = x[LEFT-128]
_ = x[RIGHT-129] _ = x[RIGHT-129]
_ = x[SIZE-130]
_ = x[INVERT-131] _ = x[INVERT-131]
_ = x[AND-132] _ = x[AND-132]
_ = x[OR-133] _ = x[OR-133]
@ -123,25 +122,25 @@ func _() {
_ = x[CHECKSIG-172] _ = x[CHECKSIG-172]
_ = x[VERIFY-173] _ = x[VERIFY-173]
_ = x[CHECKMULTISIG-174] _ = x[CHECKMULTISIG-174]
_ = x[ARRAYSIZE-192] _ = x[PACK-192]
_ = x[PACK-193] _ = x[UNPACK-193]
_ = x[UNPACK-194] _ = x[NEWARRAY-195]
_ = x[PICKITEM-195]
_ = x[SETITEM-196]
_ = x[NEWARRAY-197]
_ = x[NEWSTRUCT-198] _ = x[NEWSTRUCT-198]
_ = x[NEWMAP-199] _ = x[NEWMAP-200]
_ = x[APPEND-200] _ = x[SIZE-202]
_ = x[REVERSE-201]
_ = x[REMOVE-202]
_ = x[HASKEY-203] _ = x[HASKEY-203]
_ = x[KEYS-204] _ = x[KEYS-204]
_ = x[VALUES-205] _ = x[VALUES-205]
_ = x[PICKITEM-206]
_ = x[APPEND-207]
_ = x[SETITEM-208]
_ = x[REVERSEITEMS-209]
_ = x[REMOVE-210]
_ = x[THROW-240] _ = x[THROW-240]
_ = x[THROWIFNOT-241] _ = x[THROWIFNOT-241]
} }
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LOLDPUSH1RETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPISNULLXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTSIZEINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINSHA1SHA256HASH160HASH256CHECKSIGVERIFYCHECKMULTISIGARRAYSIZEPACKUNPACKPICKITEMSETITEMNEWARRAYNEWSTRUCTNEWMAPAPPENDREVERSEREMOVEHASKEYKEYSVALUESTHROWTHROWIFNOT" const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LOLDPUSH1RETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPISNULLXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINSHA1SHA256HASH160HASH256CHECKSIGVERIFYCHECKMULTISIGPACKUNPACKNEWARRAYNEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVETHROWTHROWIFNOT"
var _Opcode_map = map[Opcode]string{ var _Opcode_map = map[Opcode]string{
0: _Opcode_name[0:8], 0: _Opcode_name[0:8],
@ -219,60 +218,59 @@ var _Opcode_map = map[Opcode]string{
127: _Opcode_name[443:449], 127: _Opcode_name[443:449],
128: _Opcode_name[449:453], 128: _Opcode_name[449:453],
129: _Opcode_name[453:458], 129: _Opcode_name[453:458],
130: _Opcode_name[458:462], 131: _Opcode_name[458:464],
131: _Opcode_name[462:468], 132: _Opcode_name[464:467],
132: _Opcode_name[468:471], 133: _Opcode_name[467:469],
133: _Opcode_name[471:473], 134: _Opcode_name[469:472],
134: _Opcode_name[473:476], 135: _Opcode_name[472:477],
135: _Opcode_name[476:481], 139: _Opcode_name[477:480],
139: _Opcode_name[481:484], 140: _Opcode_name[480:483],
140: _Opcode_name[484:487], 141: _Opcode_name[483:487],
141: _Opcode_name[487:491], 143: _Opcode_name[487:493],
143: _Opcode_name[491:497], 144: _Opcode_name[493:496],
144: _Opcode_name[497:500], 145: _Opcode_name[496:499],
145: _Opcode_name[500:503], 146: _Opcode_name[499:501],
146: _Opcode_name[503:505], 147: _Opcode_name[501:504],
147: _Opcode_name[505:508], 148: _Opcode_name[504:507],
148: _Opcode_name[508:511], 149: _Opcode_name[507:510],
149: _Opcode_name[511:514], 150: _Opcode_name[510:513],
150: _Opcode_name[514:517], 151: _Opcode_name[513:516],
151: _Opcode_name[517:520], 152: _Opcode_name[516:519],
152: _Opcode_name[520:523], 153: _Opcode_name[519:522],
153: _Opcode_name[523:526], 154: _Opcode_name[522:529],
154: _Opcode_name[526:533], 155: _Opcode_name[529:535],
155: _Opcode_name[533:539], 156: _Opcode_name[535:543],
156: _Opcode_name[539:547], 158: _Opcode_name[543:554],
158: _Opcode_name[547:558], 159: _Opcode_name[554:556],
159: _Opcode_name[558:560], 160: _Opcode_name[556:558],
160: _Opcode_name[560:562], 161: _Opcode_name[558:561],
161: _Opcode_name[562:565], 162: _Opcode_name[561:564],
162: _Opcode_name[565:568], 163: _Opcode_name[564:567],
163: _Opcode_name[568:571], 164: _Opcode_name[567:570],
164: _Opcode_name[571:574], 165: _Opcode_name[570:576],
165: _Opcode_name[574:580], 167: _Opcode_name[576:580],
167: _Opcode_name[580:584], 168: _Opcode_name[580:586],
168: _Opcode_name[584:590], 169: _Opcode_name[586:593],
169: _Opcode_name[590:597], 170: _Opcode_name[593:600],
170: _Opcode_name[597:604], 172: _Opcode_name[600:608],
172: _Opcode_name[604:612], 173: _Opcode_name[608:614],
173: _Opcode_name[612:618], 174: _Opcode_name[614:627],
174: _Opcode_name[618:631], 192: _Opcode_name[627:631],
192: _Opcode_name[631:640], 193: _Opcode_name[631:637],
193: _Opcode_name[640:644], 195: _Opcode_name[637:645],
194: _Opcode_name[644:650], 198: _Opcode_name[645:654],
195: _Opcode_name[650:658], 200: _Opcode_name[654:660],
196: _Opcode_name[658:665], 202: _Opcode_name[660:664],
197: _Opcode_name[665:673], 203: _Opcode_name[664:670],
198: _Opcode_name[673:682], 204: _Opcode_name[670:674],
199: _Opcode_name[682:688], 205: _Opcode_name[674:680],
200: _Opcode_name[688:694], 206: _Opcode_name[680:688],
201: _Opcode_name[694:701], 207: _Opcode_name[688:694],
202: _Opcode_name[701:707], 208: _Opcode_name[694:701],
203: _Opcode_name[707:713], 209: _Opcode_name[701:713],
204: _Opcode_name[713:717], 210: _Opcode_name[713:719],
205: _Opcode_name[717:723], 240: _Opcode_name[719:724],
240: _Opcode_name[723:728], 241: _Opcode_name[724:734],
241: _Opcode_name[728:738],
} }
func (i Opcode) String() string { func (i Opcode) String() string {

View file

@ -1058,7 +1058,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
panic(fmt.Sprintf("SETITEM: invalid item type %s", t)) panic(fmt.Sprintf("SETITEM: invalid item type %s", t))
} }
case opcode.REVERSE: case opcode.REVERSEITEMS:
a := v.estack.Pop().Array() a := v.estack.Pop().Array()
if len(a) > 1 { if len(a) > 1 {
for i, j := 0, len(a)-1; i <= j; i, j = i+1, j-1 { for i, j := 0, len(a)-1; i <= j; i, j = i+1, j-1 {
@ -1100,7 +1100,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
panic("REMOVE: invalid type") panic("REMOVE: invalid type")
} }
case opcode.ARRAYSIZE: case opcode.SIZE:
elem := v.estack.Pop() elem := v.estack.Pop()
// Cause there is no native (byte) item type here, hence we need to check // Cause there is no native (byte) item type here, hence we need to check
// the type of the item for array size operations. // the type of the item for array size operations.
@ -1113,11 +1113,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
v.estack.PushVal(len(elem.Bytes())) v.estack.PushVal(len(elem.Bytes()))
} }
case opcode.SIZE:
elem := v.estack.Pop()
arr := elem.Bytes()
v.estack.PushVal(len(arr))
case opcode.JMP, opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode.JMPIFNOTL, case opcode.JMP, opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode.JMPIFNOTL,
opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL,

View file

@ -1581,8 +1581,8 @@ func TestSIZEBool(t *testing.T) {
assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) assert.Equal(t, makeStackItem(1), vm.estack.Pop().value)
} }
func TestARRAYSIZEArray(t *testing.T) { func TestSIZEArray(t *testing.T) {
prog := makeProgram(opcode.ARRAYSIZE) prog := makeProgram(opcode.SIZE)
vm := load(prog) vm := load(prog)
vm.estack.PushVal([]StackItem{ vm.estack.PushVal([]StackItem{
makeStackItem(1), makeStackItem(1),
@ -1593,8 +1593,8 @@ func TestARRAYSIZEArray(t *testing.T) {
assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) assert.Equal(t, makeStackItem(2), vm.estack.Pop().value)
} }
func TestARRAYSIZEMap(t *testing.T) { func TestSIZEMap(t *testing.T) {
prog := makeProgram(opcode.ARRAYSIZE) prog := makeProgram(opcode.SIZE)
vm := load(prog) vm := load(prog)
m := NewMapItem() m := NewMapItem()
@ -2534,19 +2534,19 @@ func TestUNPACKGood(t *testing.T) {
assert.Equal(t, int64(1), vm.estack.Peek(len(elements)+1).BigInt().Int64()) assert.Equal(t, int64(1), vm.estack.Peek(len(elements)+1).BigInt().Int64())
} }
func TestREVERSEBadNotArray(t *testing.T) { func TestREVERSEITEMSBadNotArray(t *testing.T) {
prog := makeProgram(opcode.REVERSE) prog := makeProgram(opcode.REVERSEITEMS)
vm := load(prog) vm := load(prog)
vm.estack.PushVal(1) vm.estack.PushVal(1)
checkVMFailed(t, vm) checkVMFailed(t, vm)
} }
func testREVERSEIssue437(t *testing.T, i1, i2 opcode.Opcode, reversed bool) { func testREVERSEITEMSIssue437(t *testing.T, i1, i2 opcode.Opcode, reversed bool) {
prog := makeProgram( prog := makeProgram(
opcode.PUSH0, i1, opcode.PUSH0, i1,
opcode.DUP, opcode.PUSH1, opcode.APPEND, opcode.DUP, opcode.PUSH1, opcode.APPEND,
opcode.DUP, opcode.PUSH2, opcode.APPEND, opcode.DUP, opcode.PUSH2, opcode.APPEND,
opcode.DUP, i2, opcode.REVERSE) opcode.DUP, i2, opcode.REVERSEITEMS)
vm := load(prog) vm := load(prog)
vm.Run() vm.Run()
@ -2567,15 +2567,15 @@ func testREVERSEIssue437(t *testing.T, i1, i2 opcode.Opcode, reversed bool) {
} }
} }
func TestREVERSEIssue437(t *testing.T) { func TestREVERSEITEMSIssue437(t *testing.T) {
t.Run("Array+Array", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWARRAY, opcode.NEWARRAY, true) }) t.Run("Array+Array", func(t *testing.T) { testREVERSEITEMSIssue437(t, opcode.NEWARRAY, opcode.NEWARRAY, true) })
t.Run("Struct+Struct", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWSTRUCT, opcode.NEWSTRUCT, true) }) t.Run("Struct+Struct", func(t *testing.T) { testREVERSEITEMSIssue437(t, opcode.NEWSTRUCT, opcode.NEWSTRUCT, true) })
t.Run("Array+Struct", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWARRAY, opcode.NEWSTRUCT, false) }) t.Run("Array+Struct", func(t *testing.T) { testREVERSEITEMSIssue437(t, opcode.NEWARRAY, opcode.NEWSTRUCT, false) })
t.Run("Struct+Array", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWSTRUCT, opcode.NEWARRAY, false) }) t.Run("Struct+Array", func(t *testing.T) { testREVERSEITEMSIssue437(t, opcode.NEWSTRUCT, opcode.NEWARRAY, false) })
} }
func TestREVERSEGoodOneElem(t *testing.T) { func TestREVERSEITEMSGoodOneElem(t *testing.T) {
prog := makeProgram(opcode.DUP, opcode.REVERSE) prog := makeProgram(opcode.DUP, opcode.REVERSEITEMS)
elements := []int{22} elements := []int{22}
vm := load(prog) vm := load(prog)
vm.estack.PushVal(1) vm.estack.PushVal(1)
@ -2588,13 +2588,13 @@ func TestREVERSEGoodOneElem(t *testing.T) {
assert.Equal(t, int64(elements[0]), e.Int64()) assert.Equal(t, int64(elements[0]), e.Int64())
} }
func TestREVERSEGoodStruct(t *testing.T) { func TestREVERSEITEMSGoodStruct(t *testing.T) {
eodd := []int{22, 34, 42, 55, 81} eodd := []int{22, 34, 42, 55, 81}
even := []int{22, 34, 42, 55, 81, 99} even := []int{22, 34, 42, 55, 81, 99}
eall := [][]int{eodd, even} eall := [][]int{eodd, even}
for _, elements := range eall { for _, elements := range eall {
prog := makeProgram(opcode.DUP, opcode.REVERSE) prog := makeProgram(opcode.DUP, opcode.REVERSEITEMS)
vm := load(prog) vm := load(prog)
vm.estack.PushVal(1) vm.estack.PushVal(1)
@ -2616,13 +2616,13 @@ func TestREVERSEGoodStruct(t *testing.T) {
} }
} }
func TestREVERSEGood(t *testing.T) { func TestREVERSEITEMSGood(t *testing.T) {
eodd := []int{22, 34, 42, 55, 81} eodd := []int{22, 34, 42, 55, 81}
even := []int{22, 34, 42, 55, 81, 99} even := []int{22, 34, 42, 55, 81, 99}
eall := [][]int{eodd, even} eall := [][]int{eodd, even}
for _, elements := range eall { for _, elements := range eall {
prog := makeProgram(opcode.DUP, opcode.REVERSE) prog := makeProgram(opcode.DUP, opcode.REVERSEITEMS)
vm := load(prog) vm := load(prog)
vm.estack.PushVal(1) vm.estack.PushVal(1)
vm.estack.PushVal(elements) vm.estack.PushVal(elements)