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

View file

@ -28,34 +28,34 @@ func TestInvocationScriptCreationGood(t *testing.T) {
script: "0c023432676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}, {
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"}}}}}},
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"}}}}}},
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"}}}}}},
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"}}}}}},
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"}}}}}},
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"}}}}}},
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}}}}}},
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"}}}}}},
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"}}}}}},
script: "1011c10c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
script: "1011c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
}}
for _, ps := range paramScripts {
script, err := CreateFunctionInvocationScript(contract, ps.ps)

View file

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

View file

@ -85,7 +85,6 @@ func _() {
_ = x[SUBSTR-127]
_ = x[LEFT-128]
_ = x[RIGHT-129]
_ = x[SIZE-130]
_ = x[INVERT-131]
_ = x[AND-132]
_ = x[OR-133]
@ -123,25 +122,25 @@ func _() {
_ = x[CHECKSIG-172]
_ = x[VERIFY-173]
_ = x[CHECKMULTISIG-174]
_ = x[ARRAYSIZE-192]
_ = x[PACK-193]
_ = x[UNPACK-194]
_ = x[PICKITEM-195]
_ = x[SETITEM-196]
_ = x[NEWARRAY-197]
_ = x[PACK-192]
_ = x[UNPACK-193]
_ = x[NEWARRAY-195]
_ = x[NEWSTRUCT-198]
_ = x[NEWMAP-199]
_ = x[APPEND-200]
_ = x[REVERSE-201]
_ = x[REMOVE-202]
_ = x[NEWMAP-200]
_ = x[SIZE-202]
_ = x[HASKEY-203]
_ = x[KEYS-204]
_ = x[VALUES-205]
_ = x[PICKITEM-206]
_ = x[APPEND-207]
_ = x[SETITEM-208]
_ = x[REVERSEITEMS-209]
_ = x[REMOVE-210]
_ = x[THROW-240]
_ = 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{
0: _Opcode_name[0:8],
@ -219,60 +218,59 @@ var _Opcode_map = map[Opcode]string{
127: _Opcode_name[443:449],
128: _Opcode_name[449:453],
129: _Opcode_name[453:458],
130: _Opcode_name[458:462],
131: _Opcode_name[462:468],
132: _Opcode_name[468:471],
133: _Opcode_name[471:473],
134: _Opcode_name[473:476],
135: _Opcode_name[476:481],
139: _Opcode_name[481:484],
140: _Opcode_name[484:487],
141: _Opcode_name[487:491],
143: _Opcode_name[491:497],
144: _Opcode_name[497:500],
145: _Opcode_name[500:503],
146: _Opcode_name[503:505],
147: _Opcode_name[505:508],
148: _Opcode_name[508:511],
149: _Opcode_name[511:514],
150: _Opcode_name[514:517],
151: _Opcode_name[517:520],
152: _Opcode_name[520:523],
153: _Opcode_name[523:526],
154: _Opcode_name[526:533],
155: _Opcode_name[533:539],
156: _Opcode_name[539:547],
158: _Opcode_name[547:558],
159: _Opcode_name[558:560],
160: _Opcode_name[560:562],
161: _Opcode_name[562:565],
162: _Opcode_name[565:568],
163: _Opcode_name[568:571],
164: _Opcode_name[571:574],
165: _Opcode_name[574:580],
167: _Opcode_name[580:584],
168: _Opcode_name[584:590],
169: _Opcode_name[590:597],
170: _Opcode_name[597:604],
172: _Opcode_name[604:612],
173: _Opcode_name[612:618],
174: _Opcode_name[618:631],
192: _Opcode_name[631:640],
193: _Opcode_name[640:644],
194: _Opcode_name[644:650],
195: _Opcode_name[650:658],
196: _Opcode_name[658:665],
197: _Opcode_name[665:673],
198: _Opcode_name[673:682],
199: _Opcode_name[682:688],
200: _Opcode_name[688:694],
201: _Opcode_name[694:701],
202: _Opcode_name[701:707],
203: _Opcode_name[707:713],
204: _Opcode_name[713:717],
205: _Opcode_name[717:723],
240: _Opcode_name[723:728],
241: _Opcode_name[728:738],
131: _Opcode_name[458:464],
132: _Opcode_name[464:467],
133: _Opcode_name[467:469],
134: _Opcode_name[469:472],
135: _Opcode_name[472:477],
139: _Opcode_name[477:480],
140: _Opcode_name[480:483],
141: _Opcode_name[483:487],
143: _Opcode_name[487:493],
144: _Opcode_name[493:496],
145: _Opcode_name[496:499],
146: _Opcode_name[499:501],
147: _Opcode_name[501:504],
148: _Opcode_name[504:507],
149: _Opcode_name[507:510],
150: _Opcode_name[510:513],
151: _Opcode_name[513:516],
152: _Opcode_name[516:519],
153: _Opcode_name[519:522],
154: _Opcode_name[522:529],
155: _Opcode_name[529:535],
156: _Opcode_name[535:543],
158: _Opcode_name[543:554],
159: _Opcode_name[554:556],
160: _Opcode_name[556:558],
161: _Opcode_name[558:561],
162: _Opcode_name[561:564],
163: _Opcode_name[564:567],
164: _Opcode_name[567:570],
165: _Opcode_name[570:576],
167: _Opcode_name[576:580],
168: _Opcode_name[580:586],
169: _Opcode_name[586:593],
170: _Opcode_name[593:600],
172: _Opcode_name[600:608],
173: _Opcode_name[608:614],
174: _Opcode_name[614:627],
192: _Opcode_name[627:631],
193: _Opcode_name[631:637],
195: _Opcode_name[637:645],
198: _Opcode_name[645:654],
200: _Opcode_name[654:660],
202: _Opcode_name[660:664],
203: _Opcode_name[664:670],
204: _Opcode_name[670:674],
205: _Opcode_name[674:680],
206: _Opcode_name[680:688],
207: _Opcode_name[688:694],
208: _Opcode_name[694:701],
209: _Opcode_name[701:713],
210: _Opcode_name[713:719],
240: _Opcode_name[719:724],
241: _Opcode_name[724:734],
}
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))
}
case opcode.REVERSE:
case opcode.REVERSEITEMS:
a := v.estack.Pop().Array()
if len(a) > 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")
}
case opcode.ARRAYSIZE:
case opcode.SIZE:
elem := v.estack.Pop()
// Cause there is no native (byte) item type here, hence we need to check
// 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()))
}
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,
opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
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)
}
func TestARRAYSIZEArray(t *testing.T) {
prog := makeProgram(opcode.ARRAYSIZE)
func TestSIZEArray(t *testing.T) {
prog := makeProgram(opcode.SIZE)
vm := load(prog)
vm.estack.PushVal([]StackItem{
makeStackItem(1),
@ -1593,8 +1593,8 @@ func TestARRAYSIZEArray(t *testing.T) {
assert.Equal(t, makeStackItem(2), vm.estack.Pop().value)
}
func TestARRAYSIZEMap(t *testing.T) {
prog := makeProgram(opcode.ARRAYSIZE)
func TestSIZEMap(t *testing.T) {
prog := makeProgram(opcode.SIZE)
vm := load(prog)
m := NewMapItem()
@ -2534,19 +2534,19 @@ func TestUNPACKGood(t *testing.T) {
assert.Equal(t, int64(1), vm.estack.Peek(len(elements)+1).BigInt().Int64())
}
func TestREVERSEBadNotArray(t *testing.T) {
prog := makeProgram(opcode.REVERSE)
func TestREVERSEITEMSBadNotArray(t *testing.T) {
prog := makeProgram(opcode.REVERSEITEMS)
vm := load(prog)
vm.estack.PushVal(1)
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(
opcode.PUSH0, i1,
opcode.DUP, opcode.PUSH1, opcode.APPEND,
opcode.DUP, opcode.PUSH2, opcode.APPEND,
opcode.DUP, i2, opcode.REVERSE)
opcode.DUP, i2, opcode.REVERSEITEMS)
vm := load(prog)
vm.Run()
@ -2567,15 +2567,15 @@ func testREVERSEIssue437(t *testing.T, i1, i2 opcode.Opcode, reversed bool) {
}
}
func TestREVERSEIssue437(t *testing.T) {
t.Run("Array+Array", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWARRAY, opcode.NEWARRAY, true) })
t.Run("Struct+Struct", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWSTRUCT, opcode.NEWSTRUCT, true) })
t.Run("Array+Struct", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWARRAY, opcode.NEWSTRUCT, false) })
t.Run("Struct+Array", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWSTRUCT, opcode.NEWARRAY, false) })
func TestREVERSEITEMSIssue437(t *testing.T) {
t.Run("Array+Array", func(t *testing.T) { testREVERSEITEMSIssue437(t, opcode.NEWARRAY, opcode.NEWARRAY, true) })
t.Run("Struct+Struct", func(t *testing.T) { testREVERSEITEMSIssue437(t, opcode.NEWSTRUCT, opcode.NEWSTRUCT, true) })
t.Run("Array+Struct", func(t *testing.T) { testREVERSEITEMSIssue437(t, opcode.NEWARRAY, opcode.NEWSTRUCT, false) })
t.Run("Struct+Array", func(t *testing.T) { testREVERSEITEMSIssue437(t, opcode.NEWSTRUCT, opcode.NEWARRAY, false) })
}
func TestREVERSEGoodOneElem(t *testing.T) {
prog := makeProgram(opcode.DUP, opcode.REVERSE)
func TestREVERSEITEMSGoodOneElem(t *testing.T) {
prog := makeProgram(opcode.DUP, opcode.REVERSEITEMS)
elements := []int{22}
vm := load(prog)
vm.estack.PushVal(1)
@ -2588,13 +2588,13 @@ func TestREVERSEGoodOneElem(t *testing.T) {
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}
even := []int{22, 34, 42, 55, 81, 99}
eall := [][]int{eodd, even}
for _, elements := range eall {
prog := makeProgram(opcode.DUP, opcode.REVERSE)
prog := makeProgram(opcode.DUP, opcode.REVERSEITEMS)
vm := load(prog)
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}
even := []int{22, 34, 42, 55, 81, 99}
eall := [][]int{eodd, even}
for _, elements := range eall {
prog := makeProgram(opcode.DUP, opcode.REVERSE)
prog := makeProgram(opcode.DUP, opcode.REVERSEITEMS)
vm := load(prog)
vm.estack.PushVal(1)
vm.estack.PushVal(elements)