Skip to content

Commit cfbd161

Browse files
committed
Added execution frames to the VM
1 parent a15a07b commit cfbd161

File tree

2 files changed

+98
-56
lines changed

2 files changed

+98
-56
lines changed

PhantasmaChain/VM/ExecutionFrame.cs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
3+
namespace Phantasma.VM
4+
{
5+
public class ExecutionFrame
6+
{
7+
public VMObject[] registers { get; private set; }
8+
9+
public ExecutionFrame()
10+
{
11+
registers = new VMObject[VirtualMachine.MaxRegisterCount];
12+
13+
for (int i = 0; i < VirtualMachine.MaxRegisterCount; i++)
14+
{
15+
registers[i] = new VMObject();
16+
}
17+
}
18+
19+
public VMObject GetRegister(int index)
20+
{
21+
if (index < 0 || index >= VirtualMachine.MaxRegisterCount)
22+
{
23+
throw new ArgumentException("Invalid index");
24+
}
25+
26+
return registers[index];
27+
}
28+
}
29+
}

PhantasmaChain/VM/VirtualMachine.cs

+69-56
Original file line numberDiff line numberDiff line change
@@ -20,41 +20,46 @@ public abstract class VirtualMachine
2020
public uint InstructionPointer { get; private set; }
2121
public ExecutionState State { get; private set; }
2222

23-
private VMObject[] registers = new VMObject[MaxRegisterCount];
24-
2523
private byte[] script;
2624

2725
public readonly Stack<VMObject> valueStack = new Stack<VMObject>();
2826
public readonly Stack<uint> callStack = new Stack<uint>();
2927

28+
private Stack<ExecutionFrame> frames = new Stack<ExecutionFrame>();
29+
public ExecutionFrame currentFrame { get; private set; }
30+
3031
public BigInteger gas { get; private set; }
3132

3233
public VirtualMachine(byte[] script)
3334
{
3435
InstructionPointer = 0;
3536
State = ExecutionState.Running;
3637

37-
for (int i=0; i<MaxRegisterCount; i++)
38-
{
39-
registers[i] = new VMObject();
40-
}
4138

4239
this.gas = 0;
4340
this.script = script;
4441
}
4542

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+
}
4749

48-
public VMObject GetRegister(int index)
50+
private void PopFrame()
4951
{
50-
if (index<0 || index >= MaxRegisterCount)
52+
if (frames.Count < 2)
5153
{
52-
throw new ArgumentException("Invalid index");
54+
throw new Exception("Not enough frames available");
5355
}
5456

55-
return registers[index];
57+
frames.Pop();
58+
this.currentFrame = frames.Peek();
5659
}
5760

61+
public abstract bool ExecuteInterop(string method);
62+
5863
public void Execute()
5964
{
6065
while (State == ExecutionState.Running)
@@ -177,7 +182,7 @@ public void Step()
177182
Expect(src < MaxRegisterCount);
178183
Expect(dst < MaxRegisterCount);
179184

180-
registers[dst] = registers[src];
185+
currentFrame.registers[dst] = currentFrame.registers[src];
181186
break;
182187
}
183188

@@ -189,7 +194,7 @@ public void Step()
189194
Expect(src < MaxRegisterCount);
190195
Expect(dst < MaxRegisterCount);
191196

192-
registers[dst].Copy(registers[src]);
197+
currentFrame.registers[dst].Copy(currentFrame.registers[src]);
193198
break;
194199
}
195200

@@ -202,7 +207,7 @@ public void Step()
202207
Expect(dst < MaxRegisterCount);
203208

204209
var bytes = ReadBytes(len);
205-
registers[dst].SetValue(bytes, type);
210+
currentFrame.registers[dst].SetValue(bytes, type);
206211

207212
break;
208213
}
@@ -212,7 +217,7 @@ public void Step()
212217
var src = Read8();
213218
Expect(src < MaxRegisterCount);
214219

215-
valueStack.Push(registers[src]);
220+
valueStack.Push(currentFrame.registers[src]);
216221
break;
217222
}
218223

@@ -223,7 +228,7 @@ public void Step()
223228
Expect(valueStack.Count > 0);
224229
Expect(dst < MaxRegisterCount);
225230

226-
registers[dst] = valueStack.Pop();
231+
currentFrame.registers[dst] = valueStack.Pop();
227232
break;
228233
}
229234

@@ -235,9 +240,9 @@ public void Step()
235240
Expect(src < MaxRegisterCount);
236241
Expect(dst < MaxRegisterCount);
237242

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;
241246

242247
break;
243248
}
@@ -247,6 +252,8 @@ public void Step()
247252
var ofs = Read16();
248253
Expect(ofs < script.Length);
249254

255+
PushFrame();
256+
250257
callStack.Push(InstructionPointer);
251258
InstructionPointer = ofs;
252259
break;
@@ -282,7 +289,7 @@ public void Step()
282289
var src = Read8();
283290
Expect(src < MaxRegisterCount);
284291

285-
var status = registers[src].AsBool();
292+
var status = currentFrame.registers[src].AsBool();
286293

287294
if (opcode == Opcode.JMPNOT)
288295
{
@@ -308,6 +315,8 @@ public void Step()
308315
Expect(ofs < script.Length);
309316

310317
InstructionPointer = ofs;
318+
319+
PopFrame();
311320
}
312321
else
313322
{
@@ -324,14 +333,14 @@ public void Step()
324333
Expect(src < MaxRegisterCount);
325334
Expect(dst < MaxRegisterCount);
326335

327-
var A = registers[src];
328-
var B = registers[dst];
336+
var A = currentFrame.registers[src];
337+
var B = currentFrame.registers[dst];
329338

330339
if (!A.IsEmpty)
331340
{
332341
if (B.IsEmpty)
333342
{
334-
registers[dst] = A;
343+
currentFrame.registers[dst] = A;
335344
}
336345
else
337346
{
@@ -355,12 +364,12 @@ public void Step()
355364
var len = (int)ReadVar(0xFFFF);
356365

357366
Expect(src < MaxRegisterCount);
358-
Expect(len <= registers[src].Length);
367+
Expect(len <= currentFrame.registers[src].Length);
359368

360369
var result = new byte[len];
361-
Array.Copy(registers[src].Data, result, len);
370+
Array.Copy(currentFrame.registers[src].Data, result, len);
362371

363-
registers[src].Data = result;
372+
currentFrame.registers[src].Data = result;
364373
break;
365374
}
366375

@@ -370,14 +379,14 @@ public void Step()
370379
var len = (int)ReadVar(0xFFFF);
371380

372381
Expect(src < MaxRegisterCount);
373-
Expect(len <= registers[src].Length);
382+
Expect(len <= currentFrame.registers[src].Length);
374383

375-
var ofs = registers[src].Length - len;
384+
var ofs = currentFrame.registers[src].Length - len;
376385

377386
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;
381390
break;
382391
}
383392

@@ -389,7 +398,7 @@ public void Step()
389398
Expect(src < MaxRegisterCount);
390399
Expect(dst < MaxRegisterCount);
391400

392-
registers[dst].SetValue(registers[src].Length);
401+
currentFrame.registers[dst].SetValue(currentFrame.registers[src].Length);
393402
break;
394403
}
395404

@@ -401,9 +410,9 @@ public void Step()
401410
Expect(src < MaxRegisterCount);
402411
Expect(dst < MaxRegisterCount);
403412

404-
var val = registers[src].AsBool();
413+
var val = currentFrame.registers[src].AsBool();
405414

406-
registers[dst].SetValue(!val);
415+
currentFrame.registers[dst].SetValue(!val);
407416
break;
408417
}
409418

@@ -419,8 +428,8 @@ public void Step()
419428
Expect(srcB < MaxRegisterCount);
420429
Expect(dst < MaxRegisterCount);
421430

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();
424433

425434
bool result;
426435
switch (opcode)
@@ -435,7 +444,7 @@ public void Step()
435444
}
436445
}
437446

438-
registers[dst].SetValue(result);
447+
currentFrame.registers[dst].SetValue(result);
439448
break;
440449
}
441450

@@ -451,8 +460,8 @@ public void Step()
451460
Expect(srcB < MaxRegisterCount);
452461
Expect(dst < MaxRegisterCount);
453462

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();
456465

457466
bool result;
458467
switch (opcode)
@@ -469,7 +478,7 @@ public void Step()
469478
}
470479
}
471480

472-
registers[dst].SetValue(result);
481+
currentFrame.registers[dst].SetValue(result);
473482
break;
474483
}
475484

@@ -478,8 +487,8 @@ public void Step()
478487
var dst = Read8();
479488
Expect(dst < MaxRegisterCount);
480489

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);
483492

484493
break;
485494
}
@@ -489,8 +498,8 @@ public void Step()
489498
var dst = Read8();
490499
Expect(dst < MaxRegisterCount);
491500

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);
494503

495504
break;
496505
}
@@ -503,38 +512,42 @@ public void Step()
503512
Expect(src < MaxRegisterCount);
504513
Expect(dst < MaxRegisterCount);
505514

506-
var val = registers[src].AsNumber();
515+
var val = currentFrame.registers[src].AsNumber();
507516

508517
if (val == 0)
509518
{
510-
registers[dst].SetValue(0);
519+
currentFrame.registers[dst].SetValue(0);
511520
}
512521
else
513522
{
514-
registers[dst].SetValue(val < 0 ? -1 : 1);
523+
currentFrame.registers[dst].SetValue(val < 0 ? -1 : 1);
515524
}
516525

517526
break;
518527
}
519528

520529
case Opcode.NEGATE:
521530
{
531+
var src = Read8();
522532
var dst = Read8();
533+
Expect(src < MaxRegisterCount);
523534
Expect(dst < MaxRegisterCount);
524535

525-
var val = registers[dst].AsNumber();
526-
registers[dst].SetValue(-val);
536+
var val = currentFrame.registers[src].AsNumber();
537+
currentFrame.registers[dst].SetValue(-val);
527538

528539
break;
529540
}
530541

531542
case Opcode.ABS:
532543
{
544+
var src = Read8();
533545
var dst = Read8();
546+
Expect(src < MaxRegisterCount);
534547
Expect(dst < MaxRegisterCount);
535548

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);
538551

539552
break;
540553
}
@@ -557,8 +570,8 @@ public void Step()
557570
Expect(srcB < MaxRegisterCount);
558571
Expect(dst < MaxRegisterCount);
559572

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();
562575

563576
BigInteger result;
564577

@@ -580,7 +593,7 @@ public void Step()
580593
}
581594
}
582595

583-
registers[dst].SetValue(result);
596+
currentFrame.registers[dst].SetValue(result);
584597
break;
585598
}
586599

@@ -594,7 +607,7 @@ public void Step()
594607
Expect(dst < MaxRegisterCount);
595608
Expect(key < MaxRegisterCount);
596609

597-
registers[dst].SetKey(registers[key].AsString(), registers[src]);
610+
currentFrame.registers[dst].SetKey(currentFrame.registers[key].AsString(), currentFrame.registers[src]);
598611

599612
break;
600613
}
@@ -609,7 +622,7 @@ public void Step()
609622
Expect(dst < MaxRegisterCount);
610623
Expect(key < MaxRegisterCount);
611624

612-
registers[dst] = registers[src].GetKey(registers[key].AsString());
625+
currentFrame.registers[dst] = currentFrame.registers[src].GetKey(currentFrame.registers[key].AsString());
613626

614627
break;
615628
}

0 commit comments

Comments
 (0)