@@ -20,41 +20,46 @@ public abstract class VirtualMachine
20
20
public uint InstructionPointer { get ; private set ; }
21
21
public ExecutionState State { get ; private set ; }
22
22
23
- private VMObject [ ] registers = new VMObject [ MaxRegisterCount ] ;
24
-
25
23
private byte [ ] script ;
26
24
27
25
public readonly Stack < VMObject > valueStack = new Stack < VMObject > ( ) ;
28
26
public readonly Stack < uint > callStack = new Stack < uint > ( ) ;
29
27
28
+ private Stack < ExecutionFrame > frames = new Stack < ExecutionFrame > ( ) ;
29
+ public ExecutionFrame currentFrame { get ; private set ; }
30
+
30
31
public BigInteger gas { get ; private set ; }
31
32
32
33
public VirtualMachine ( byte [ ] script )
33
34
{
34
35
InstructionPointer = 0 ;
35
36
State = ExecutionState . Running ;
36
37
37
- for ( int i = 0 ; i < MaxRegisterCount ; i ++ )
38
- {
39
- registers [ i ] = new VMObject ( ) ;
40
- }
41
38
42
39
this . gas = 0 ;
43
40
this . script = script ;
44
41
}
45
42
46
- public abstract bool ExecuteInterop ( string method ) ;
43
+ private void PushFrame ( )
44
+ {
45
+ var frame = new ExecutionFrame ( ) ;
46
+ frames . Push ( frame ) ;
47
+ this . currentFrame = frame ;
48
+ }
47
49
48
- public VMObject GetRegister ( int index )
50
+ private void PopFrame ( )
49
51
{
50
- if ( index < 0 || index >= MaxRegisterCount )
52
+ if ( frames . Count < 2 )
51
53
{
52
- throw new ArgumentException ( "Invalid index ") ;
54
+ throw new Exception ( "Not enough frames available ") ;
53
55
}
54
56
55
- return registers [ index ] ;
57
+ frames . Pop ( ) ;
58
+ this . currentFrame = frames . Peek ( ) ;
56
59
}
57
60
61
+ public abstract bool ExecuteInterop ( string method ) ;
62
+
58
63
public void Execute ( )
59
64
{
60
65
while ( State == ExecutionState . Running )
@@ -177,7 +182,7 @@ public void Step()
177
182
Expect ( src < MaxRegisterCount ) ;
178
183
Expect ( dst < MaxRegisterCount ) ;
179
184
180
- registers [ dst ] = registers [ src ] ;
185
+ currentFrame . registers [ dst ] = currentFrame . registers [ src ] ;
181
186
break ;
182
187
}
183
188
@@ -189,7 +194,7 @@ public void Step()
189
194
Expect ( src < MaxRegisterCount ) ;
190
195
Expect ( dst < MaxRegisterCount ) ;
191
196
192
- registers [ dst ] . Copy ( registers [ src ] ) ;
197
+ currentFrame . registers [ dst ] . Copy ( currentFrame . registers [ src ] ) ;
193
198
break ;
194
199
}
195
200
@@ -202,7 +207,7 @@ public void Step()
202
207
Expect ( dst < MaxRegisterCount ) ;
203
208
204
209
var bytes = ReadBytes ( len ) ;
205
- registers [ dst ] . SetValue ( bytes , type ) ;
210
+ currentFrame . registers [ dst ] . SetValue ( bytes , type ) ;
206
211
207
212
break ;
208
213
}
@@ -212,7 +217,7 @@ public void Step()
212
217
var src = Read8 ( ) ;
213
218
Expect ( src < MaxRegisterCount ) ;
214
219
215
- valueStack . Push ( registers [ src ] ) ;
220
+ valueStack . Push ( currentFrame . registers [ src ] ) ;
216
221
break ;
217
222
}
218
223
@@ -223,7 +228,7 @@ public void Step()
223
228
Expect ( valueStack . Count > 0 ) ;
224
229
Expect ( dst < MaxRegisterCount ) ;
225
230
226
- registers [ dst ] = valueStack . Pop ( ) ;
231
+ currentFrame . registers [ dst ] = valueStack . Pop ( ) ;
227
232
break ;
228
233
}
229
234
@@ -235,9 +240,9 @@ public void Step()
235
240
Expect ( src < MaxRegisterCount ) ;
236
241
Expect ( dst < MaxRegisterCount ) ;
237
242
238
- var temp = registers [ src ] ;
239
- registers [ src ] = registers [ dst ] ;
240
- registers [ dst ] = temp ;
243
+ var temp = currentFrame . registers [ src ] ;
244
+ currentFrame . registers [ src ] = currentFrame . registers [ dst ] ;
245
+ currentFrame . registers [ dst ] = temp ;
241
246
242
247
break ;
243
248
}
@@ -247,6 +252,8 @@ public void Step()
247
252
var ofs = Read16 ( ) ;
248
253
Expect ( ofs < script . Length ) ;
249
254
255
+ PushFrame ( ) ;
256
+
250
257
callStack . Push ( InstructionPointer ) ;
251
258
InstructionPointer = ofs ;
252
259
break ;
@@ -282,7 +289,7 @@ public void Step()
282
289
var src = Read8 ( ) ;
283
290
Expect ( src < MaxRegisterCount ) ;
284
291
285
- var status = registers [ src ] . AsBool ( ) ;
292
+ var status = currentFrame . registers [ src ] . AsBool ( ) ;
286
293
287
294
if ( opcode == Opcode . JMPNOT )
288
295
{
@@ -308,6 +315,8 @@ public void Step()
308
315
Expect ( ofs < script . Length ) ;
309
316
310
317
InstructionPointer = ofs ;
318
+
319
+ PopFrame ( ) ;
311
320
}
312
321
else
313
322
{
@@ -324,14 +333,14 @@ public void Step()
324
333
Expect ( src < MaxRegisterCount ) ;
325
334
Expect ( dst < MaxRegisterCount ) ;
326
335
327
- var A = registers [ src ] ;
328
- var B = registers [ dst ] ;
336
+ var A = currentFrame . registers [ src ] ;
337
+ var B = currentFrame . registers [ dst ] ;
329
338
330
339
if ( ! A . IsEmpty )
331
340
{
332
341
if ( B . IsEmpty )
333
342
{
334
- registers [ dst ] = A ;
343
+ currentFrame . registers [ dst ] = A ;
335
344
}
336
345
else
337
346
{
@@ -355,12 +364,12 @@ public void Step()
355
364
var len = ( int ) ReadVar ( 0xFFFF ) ;
356
365
357
366
Expect ( src < MaxRegisterCount ) ;
358
- Expect ( len <= registers [ src ] . Length ) ;
367
+ Expect ( len <= currentFrame . registers [ src ] . Length ) ;
359
368
360
369
var result = new byte [ len ] ;
361
- Array . Copy ( registers [ src ] . Data , result , len ) ;
370
+ Array . Copy ( currentFrame . registers [ src ] . Data , result , len ) ;
362
371
363
- registers [ src ] . Data = result ;
372
+ currentFrame . registers [ src ] . Data = result ;
364
373
break ;
365
374
}
366
375
@@ -370,14 +379,14 @@ public void Step()
370
379
var len = ( int ) ReadVar ( 0xFFFF ) ;
371
380
372
381
Expect ( src < MaxRegisterCount ) ;
373
- Expect ( len <= registers [ src ] . Length ) ;
382
+ Expect ( len <= currentFrame . registers [ src ] . Length ) ;
374
383
375
- var ofs = registers [ src ] . Length - len ;
384
+ var ofs = currentFrame . registers [ src ] . Length - len ;
376
385
377
386
var result = new byte [ len ] ;
378
- Array . Copy ( registers [ src ] . Data , ofs , result , 0 , len ) ;
379
-
380
- registers [ src ] . Data = result ;
387
+ Array . Copy ( currentFrame . registers [ src ] . Data , ofs , result , 0 , len ) ;
388
+
389
+ currentFrame . registers [ src ] . Data = result ;
381
390
break ;
382
391
}
383
392
@@ -389,7 +398,7 @@ public void Step()
389
398
Expect ( src < MaxRegisterCount ) ;
390
399
Expect ( dst < MaxRegisterCount ) ;
391
400
392
- registers [ dst ] . SetValue ( registers [ src ] . Length ) ;
401
+ currentFrame . registers [ dst ] . SetValue ( currentFrame . registers [ src ] . Length ) ;
393
402
break ;
394
403
}
395
404
@@ -401,9 +410,9 @@ public void Step()
401
410
Expect ( src < MaxRegisterCount ) ;
402
411
Expect ( dst < MaxRegisterCount ) ;
403
412
404
- var val = registers [ src ] . AsBool ( ) ;
413
+ var val = currentFrame . registers [ src ] . AsBool ( ) ;
405
414
406
- registers [ dst ] . SetValue ( ! val ) ;
415
+ currentFrame . registers [ dst ] . SetValue ( ! val ) ;
407
416
break ;
408
417
}
409
418
@@ -419,8 +428,8 @@ public void Step()
419
428
Expect ( srcB < MaxRegisterCount ) ;
420
429
Expect ( dst < MaxRegisterCount ) ;
421
430
422
- var a = registers [ srcA ] . AsBool ( ) ;
423
- var b = registers [ srcA ] . AsBool ( ) ;
431
+ var a = currentFrame . registers [ srcA ] . AsBool ( ) ;
432
+ var b = currentFrame . registers [ srcA ] . AsBool ( ) ;
424
433
425
434
bool result ;
426
435
switch ( opcode )
@@ -435,7 +444,7 @@ public void Step()
435
444
}
436
445
}
437
446
438
- registers [ dst ] . SetValue ( result ) ;
447
+ currentFrame . registers [ dst ] . SetValue ( result ) ;
439
448
break ;
440
449
}
441
450
@@ -451,8 +460,8 @@ public void Step()
451
460
Expect ( srcB < MaxRegisterCount ) ;
452
461
Expect ( dst < MaxRegisterCount ) ;
453
462
454
- var a = registers [ srcA ] . AsNumber ( ) ;
455
- var b = registers [ srcA ] . AsNumber ( ) ;
463
+ var a = currentFrame . registers [ srcA ] . AsNumber ( ) ;
464
+ var b = currentFrame . registers [ srcA ] . AsNumber ( ) ;
456
465
457
466
bool result ;
458
467
switch ( opcode )
@@ -469,7 +478,7 @@ public void Step()
469
478
}
470
479
}
471
480
472
- registers [ dst ] . SetValue ( result ) ;
481
+ currentFrame . registers [ dst ] . SetValue ( result ) ;
473
482
break ;
474
483
}
475
484
@@ -478,8 +487,8 @@ public void Step()
478
487
var dst = Read8 ( ) ;
479
488
Expect ( dst < MaxRegisterCount ) ;
480
489
481
- var val = registers [ dst ] . AsNumber ( ) ;
482
- registers [ dst ] . SetValue ( val + 1 ) ;
490
+ var val = currentFrame . registers [ dst ] . AsNumber ( ) ;
491
+ currentFrame . registers [ dst ] . SetValue ( val + 1 ) ;
483
492
484
493
break ;
485
494
}
@@ -489,8 +498,8 @@ public void Step()
489
498
var dst = Read8 ( ) ;
490
499
Expect ( dst < MaxRegisterCount ) ;
491
500
492
- var val = registers [ dst ] . AsNumber ( ) ;
493
- registers [ dst ] . SetValue ( val - 1 ) ;
501
+ var val = currentFrame . registers [ dst ] . AsNumber ( ) ;
502
+ currentFrame . registers [ dst ] . SetValue ( val - 1 ) ;
494
503
495
504
break ;
496
505
}
@@ -503,38 +512,42 @@ public void Step()
503
512
Expect ( src < MaxRegisterCount ) ;
504
513
Expect ( dst < MaxRegisterCount ) ;
505
514
506
- var val = registers [ src ] . AsNumber ( ) ;
515
+ var val = currentFrame . registers [ src ] . AsNumber ( ) ;
507
516
508
517
if ( val == 0 )
509
518
{
510
- registers [ dst ] . SetValue ( 0 ) ;
519
+ currentFrame . registers [ dst ] . SetValue ( 0 ) ;
511
520
}
512
521
else
513
522
{
514
- registers [ dst ] . SetValue ( val < 0 ? - 1 : 1 ) ;
523
+ currentFrame . registers [ dst ] . SetValue ( val < 0 ? - 1 : 1 ) ;
515
524
}
516
525
517
526
break ;
518
527
}
519
528
520
529
case Opcode . NEGATE :
521
530
{
531
+ var src = Read8 ( ) ;
522
532
var dst = Read8 ( ) ;
533
+ Expect ( src < MaxRegisterCount ) ;
523
534
Expect ( dst < MaxRegisterCount ) ;
524
535
525
- var val = registers [ dst ] . AsNumber ( ) ;
526
- registers [ dst ] . SetValue ( - val ) ;
536
+ var val = currentFrame . registers [ src ] . AsNumber ( ) ;
537
+ currentFrame . registers [ dst ] . SetValue ( - val ) ;
527
538
528
539
break ;
529
540
}
530
541
531
542
case Opcode . ABS :
532
543
{
544
+ var src = Read8 ( ) ;
533
545
var dst = Read8 ( ) ;
546
+ Expect ( src < MaxRegisterCount ) ;
534
547
Expect ( dst < MaxRegisterCount ) ;
535
548
536
- var val = registers [ dst ] . AsNumber ( ) ;
537
- registers [ dst ] . SetValue ( val < 0 ? - val : val ) ;
549
+ var val = currentFrame . registers [ src ] . AsNumber ( ) ;
550
+ currentFrame . registers [ dst ] . SetValue ( val < 0 ? - val : val ) ;
538
551
539
552
break ;
540
553
}
@@ -557,8 +570,8 @@ public void Step()
557
570
Expect ( srcB < MaxRegisterCount ) ;
558
571
Expect ( dst < MaxRegisterCount ) ;
559
572
560
- var a = registers [ srcA ] . AsNumber ( ) ;
561
- var b = registers [ srcA ] . AsNumber ( ) ;
573
+ var a = currentFrame . registers [ srcA ] . AsNumber ( ) ;
574
+ var b = currentFrame . registers [ srcA ] . AsNumber ( ) ;
562
575
563
576
BigInteger result ;
564
577
@@ -580,7 +593,7 @@ public void Step()
580
593
}
581
594
}
582
595
583
- registers [ dst ] . SetValue ( result ) ;
596
+ currentFrame . registers [ dst ] . SetValue ( result ) ;
584
597
break ;
585
598
}
586
599
@@ -594,7 +607,7 @@ public void Step()
594
607
Expect ( dst < MaxRegisterCount ) ;
595
608
Expect ( key < MaxRegisterCount ) ;
596
609
597
- registers [ dst ] . SetKey ( registers [ key ] . AsString ( ) , registers [ src ] ) ;
610
+ currentFrame . registers [ dst ] . SetKey ( currentFrame . registers [ key ] . AsString ( ) , currentFrame . registers [ src ] ) ;
598
611
599
612
break ;
600
613
}
@@ -609,7 +622,7 @@ public void Step()
609
622
Expect ( dst < MaxRegisterCount ) ;
610
623
Expect ( key < MaxRegisterCount ) ;
611
624
612
- registers [ dst ] = registers [ src ] . GetKey ( registers [ key ] . AsString ( ) ) ;
625
+ currentFrame . registers [ dst ] = currentFrame . registers [ src ] . GetKey ( currentFrame . registers [ key ] . AsString ( ) ) ;
613
626
614
627
break ;
615
628
}
0 commit comments