vm: implement NEWARRAY0 and NEWSTRUCT0 opcodes

This commit is contained in:
Evgenii Stratonikov 2020-04-24 12:31:59 +03:00
parent 03761421f8
commit 9fd04aefa5
4 changed files with 131 additions and 105 deletions

View file

@ -143,12 +143,12 @@ const (
CHECKMULTISIG Opcode = 0xAE CHECKMULTISIG Opcode = 0xAE
// Advanced data structures (arrays, structures, maps) // Advanced data structures (arrays, structures, maps)
PACK Opcode = 0xC0 PACK Opcode = 0xC0
UNPACK Opcode = 0xC1 UNPACK Opcode = 0xC1
// NEWARRAY0 Opcode = 0xC2 NEWARRAY0 Opcode = 0xC2
NEWARRAY Opcode = 0xC3 NEWARRAY Opcode = 0xC3
// NEWARRAYT Opcode = 0xC4 // NEWARRAYT Opcode = 0xC4
// NEWSTRUCT0 Opcode = 0xC5 NEWSTRUCT0 Opcode = 0xC5
NEWSTRUCT Opcode = 0xC6 NEWSTRUCT Opcode = 0xC6
NEWMAP Opcode = 0xC8 NEWMAP Opcode = 0xC8
SIZE Opcode = 0xCA SIZE Opcode = 0xCA

View file

@ -124,7 +124,9 @@ func _() {
_ = x[CHECKMULTISIG-174] _ = x[CHECKMULTISIG-174]
_ = x[PACK-192] _ = x[PACK-192]
_ = x[UNPACK-193] _ = x[UNPACK-193]
_ = x[NEWARRAY0-194]
_ = x[NEWARRAY-195] _ = x[NEWARRAY-195]
_ = x[NEWSTRUCT0-197]
_ = x[NEWSTRUCT-198] _ = x[NEWSTRUCT-198]
_ = x[NEWMAP-200] _ = x[NEWMAP-200]
_ = x[SIZE-202] _ = x[SIZE-202]
@ -140,7 +142,7 @@ func _() {
_ = x[THROWIFNOT-241] _ = x[THROWIFNOT-241]
} }
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LOLDPUSH1RETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPISNULLXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINSHA1SHA256HASH160HASH256CHECKSIGVERIFYCHECKMULTISIGPACKUNPACKNEWARRAYNEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVETHROWTHROWIFNOT" const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPLJMPIFJMPIFLJMPIFNOTJMPIFNOTLJMPEQJMPEQLJMPNEJMPNELJMPGTJMPGTLJMPGEJMPGELJMPLTJMPLTLJMPLEJMPLELCALLCALLLOLDPUSH1RETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPISNULLXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINSHA1SHA256HASH160HASH256CHECKSIGVERIFYCHECKMULTISIGPACKUNPACKNEWARRAY0NEWARRAYNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVETHROWTHROWIFNOT"
var _Opcode_map = map[Opcode]string{ var _Opcode_map = map[Opcode]string{
0: _Opcode_name[0:8], 0: _Opcode_name[0:8],
@ -173,104 +175,106 @@ var _Opcode_map = map[Opcode]string{
32: _Opcode_name[182:188], 32: _Opcode_name[182:188],
33: _Opcode_name[188:191], 33: _Opcode_name[188:191],
34: _Opcode_name[191:194], 34: _Opcode_name[191:194],
35: _Opcode_name[194:199], 35: _Opcode_name[194:198],
36: _Opcode_name[199:204], 36: _Opcode_name[198:203],
37: _Opcode_name[204:211], 37: _Opcode_name[203:209],
38: _Opcode_name[211:219], 38: _Opcode_name[209:217],
39: _Opcode_name[219:229], 39: _Opcode_name[217:226],
40: _Opcode_name[229:234], 40: _Opcode_name[226:231],
41: _Opcode_name[234:241], 41: _Opcode_name[231:237],
42: _Opcode_name[241:246], 42: _Opcode_name[237:242],
43: _Opcode_name[246:253], 43: _Opcode_name[242:248],
44: _Opcode_name[253:258], 44: _Opcode_name[248:253],
45: _Opcode_name[258:265], 45: _Opcode_name[253:259],
46: _Opcode_name[265:270], 46: _Opcode_name[259:264],
47: _Opcode_name[270:277], 47: _Opcode_name[264:270],
48: _Opcode_name[277:282], 48: _Opcode_name[270:275],
49: _Opcode_name[282:289], 49: _Opcode_name[275:281],
50: _Opcode_name[289:294], 50: _Opcode_name[281:286],
51: _Opcode_name[294:301], 51: _Opcode_name[286:292],
52: _Opcode_name[301:305], 52: _Opcode_name[292:296],
53: _Opcode_name[305:311], 53: _Opcode_name[296:301],
81: _Opcode_name[311:319], 81: _Opcode_name[301:309],
102: _Opcode_name[319:322], 102: _Opcode_name[309:312],
103: _Opcode_name[322:329], 103: _Opcode_name[312:319],
104: _Opcode_name[329:336], 104: _Opcode_name[319:326],
105: _Opcode_name[336:344], 105: _Opcode_name[326:334],
106: _Opcode_name[344:359], 106: _Opcode_name[334:349],
107: _Opcode_name[359:369], 107: _Opcode_name[349:359],
108: _Opcode_name[369:381], 108: _Opcode_name[359:371],
109: _Opcode_name[381:386], 109: _Opcode_name[371:376],
112: _Opcode_name[386:392], 112: _Opcode_name[376:382],
114: _Opcode_name[392:397], 114: _Opcode_name[382:387],
115: _Opcode_name[397:402], 115: _Opcode_name[387:392],
116: _Opcode_name[402:407], 116: _Opcode_name[392:397],
117: _Opcode_name[407:411], 117: _Opcode_name[397:401],
118: _Opcode_name[411:414], 118: _Opcode_name[401:404],
119: _Opcode_name[414:417], 119: _Opcode_name[404:407],
120: _Opcode_name[417:421], 120: _Opcode_name[407:411],
121: _Opcode_name[421:425], 121: _Opcode_name[411:415],
122: _Opcode_name[425:429], 122: _Opcode_name[415:419],
123: _Opcode_name[429:432], 123: _Opcode_name[419:422],
124: _Opcode_name[432:436], 124: _Opcode_name[422:426],
125: _Opcode_name[436:440], 125: _Opcode_name[426:430],
126: _Opcode_name[440:443], 126: _Opcode_name[430:433],
127: _Opcode_name[443:449], 127: _Opcode_name[433:439],
128: _Opcode_name[449:453], 128: _Opcode_name[439:443],
129: _Opcode_name[453:458], 129: _Opcode_name[443:448],
131: _Opcode_name[458:464], 131: _Opcode_name[448:454],
132: _Opcode_name[464:467], 132: _Opcode_name[454:457],
133: _Opcode_name[467:469], 133: _Opcode_name[457:459],
134: _Opcode_name[469:472], 134: _Opcode_name[459:462],
135: _Opcode_name[472:477], 135: _Opcode_name[462:467],
139: _Opcode_name[477:480], 139: _Opcode_name[467:470],
140: _Opcode_name[480:483], 140: _Opcode_name[470:473],
141: _Opcode_name[483:487], 141: _Opcode_name[473:477],
143: _Opcode_name[487:493], 143: _Opcode_name[477:483],
144: _Opcode_name[493:496], 144: _Opcode_name[483:486],
145: _Opcode_name[496:499], 145: _Opcode_name[486:489],
146: _Opcode_name[499:501], 146: _Opcode_name[489:491],
147: _Opcode_name[501:504], 147: _Opcode_name[491:494],
148: _Opcode_name[504:507], 148: _Opcode_name[494:497],
149: _Opcode_name[507:510], 149: _Opcode_name[497:500],
150: _Opcode_name[510:513], 150: _Opcode_name[500:503],
151: _Opcode_name[513:516], 151: _Opcode_name[503:506],
152: _Opcode_name[516:519], 152: _Opcode_name[506:509],
153: _Opcode_name[519:522], 153: _Opcode_name[509:512],
154: _Opcode_name[522:529], 154: _Opcode_name[512:519],
155: _Opcode_name[529:535], 155: _Opcode_name[519:525],
156: _Opcode_name[535:543], 156: _Opcode_name[525:533],
158: _Opcode_name[543:554], 158: _Opcode_name[533:544],
159: _Opcode_name[554:556], 159: _Opcode_name[544:546],
160: _Opcode_name[556:558], 160: _Opcode_name[546:548],
161: _Opcode_name[558:561], 161: _Opcode_name[548:551],
162: _Opcode_name[561:564], 162: _Opcode_name[551:554],
163: _Opcode_name[564:567], 163: _Opcode_name[554:557],
164: _Opcode_name[567:570], 164: _Opcode_name[557:560],
165: _Opcode_name[570:576], 165: _Opcode_name[560:566],
167: _Opcode_name[576:580], 167: _Opcode_name[566:570],
168: _Opcode_name[580:586], 168: _Opcode_name[570:576],
169: _Opcode_name[586:593], 169: _Opcode_name[576:583],
170: _Opcode_name[593:600], 170: _Opcode_name[583:590],
172: _Opcode_name[600:608], 172: _Opcode_name[590:598],
173: _Opcode_name[608:614], 173: _Opcode_name[598:604],
174: _Opcode_name[614:627], 174: _Opcode_name[604:617],
192: _Opcode_name[627:631], 192: _Opcode_name[617:621],
193: _Opcode_name[631:637], 193: _Opcode_name[621:627],
195: _Opcode_name[637:645], 194: _Opcode_name[627:636],
198: _Opcode_name[645:654], 195: _Opcode_name[636:644],
200: _Opcode_name[654:660], 197: _Opcode_name[644:654],
202: _Opcode_name[660:664], 198: _Opcode_name[654:663],
203: _Opcode_name[664:670], 200: _Opcode_name[663:669],
204: _Opcode_name[670:674], 202: _Opcode_name[669:673],
205: _Opcode_name[674:680], 203: _Opcode_name[673:679],
206: _Opcode_name[680:688], 204: _Opcode_name[679:683],
207: _Opcode_name[688:694], 205: _Opcode_name[683:689],
208: _Opcode_name[694:701], 206: _Opcode_name[689:697],
209: _Opcode_name[701:713], 207: _Opcode_name[697:703],
210: _Opcode_name[713:719], 208: _Opcode_name[703:710],
240: _Opcode_name[719:724], 209: _Opcode_name[710:722],
241: _Opcode_name[724:734], 210: _Opcode_name[722:728],
240: _Opcode_name[728:733],
241: _Opcode_name[733:743],
} }
func (i Opcode) String() string { func (i Opcode) String() string {

View file

@ -911,7 +911,10 @@ 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(x.Cmp(big.NewInt(0)) != 0) v.estack.PushVal(x.Cmp(big.NewInt(0)) != 0)
// Object operations. // Object operations
case opcode.NEWARRAY0:
v.estack.PushVal(&ArrayItem{[]StackItem{}})
case opcode.NEWARRAY: case opcode.NEWARRAY:
item := v.estack.Pop() item := v.estack.Pop()
switch t := item.value.(type) { switch t := item.value.(type) {
@ -930,6 +933,9 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
v.estack.PushVal(&ArrayItem{items}) v.estack.PushVal(&ArrayItem{items})
} }
case opcode.NEWSTRUCT0:
v.estack.PushVal(&StructItem{[]StackItem{}})
case opcode.NEWSTRUCT: case opcode.NEWSTRUCT:
item := v.estack.Pop() item := v.estack.Pop()
switch t := item.value.(type) { switch t := item.value.(type) {

View file

@ -1252,6 +1252,22 @@ func TestDECBigResult(t *testing.T) {
checkVMFailed(t, vm) checkVMFailed(t, vm)
} }
func TestNEWARRAY0(t *testing.T) {
prog := makeProgram(opcode.NEWARRAY0)
v := load(prog)
runVM(t, v)
require.Equal(t, 1, v.estack.Len())
require.Equal(t, &ArrayItem{[]StackItem{}}, v.estack.Pop().value)
}
func TestNEWSTRUCT0(t *testing.T) {
prog := makeProgram(opcode.NEWSTRUCT0)
v := load(prog)
runVM(t, v)
require.Equal(t, 1, v.estack.Len())
require.Equal(t, &StructItem{[]StackItem{}}, v.estack.Pop().value)
}
func TestNEWARRAYInteger(t *testing.T) { func TestNEWARRAYInteger(t *testing.T) {
prog := makeProgram(opcode.NEWARRAY) prog := makeProgram(opcode.NEWARRAY)
vm := load(prog) vm := load(prog)