0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
1 /*
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
2 * VirtualMachine.cpp
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
3 */
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
4
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
5 #include "VirtualMachine.h"
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
6
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
7 /*
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
8 * VirtualMachine
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
9 */
|
54
|
10 VirtualMachine::VirtualMachine() : nInstructionPointer(0), pFrame(NULL)
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
11 {
|
54
|
12 Clear();
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
13 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
14
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
15 /*
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
16 * Step
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
17 */
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
18 uint32 VirtualMachine::Step()
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
19 {
|
54
|
20 const uint8 nInstruction = Advance();
|
|
21 TRACE("Read instruction %d at address %d\n", nInstruction, nInstructionPointer - 1);
|
|
22
|
|
23 if(nInstruction == Instruction_Action)
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
24 {
|
54
|
25 const uint8 nParameter = Advance();
|
|
26 TRACE(" -- Action Decoded: %d\n", nParameter);
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
27
|
54
|
28 return nParameter;
|
|
29 }
|
|
30 else
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
31
|
54
|
32 if(nInstruction == Instruction_Call)
|
|
33 {
|
|
34 const uint8 nParameter = Advance();
|
|
35 TRACE(" -- Call Decoded: %d\n", nParameter);
|
|
36
|
|
37 const uint32 nFunction = nParameter;
|
|
38 const uint32 nContinuation = nInstructionPointer;
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
39
|
54
|
40 PushFrame(nFunction, nContinuation);
|
|
41 }
|
|
42 else
|
|
43
|
|
44 if(nInstruction == Instruction_Return)
|
|
45 {
|
|
46 if(pFrame)
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
47 {
|
54
|
48 PopFrame();
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
49 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
50 else
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
51 {
|
54
|
52 // no frame to pop, we are done
|
|
53 return Action_Complete;
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
54 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
55 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
56
|
54
|
57 return Action_None;
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
58 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
59
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
60 /*
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
61 * Reset
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
62 */
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
63 void VirtualMachine::Reset()
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
64 {
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
65 nInstructionPointer = 0;
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
66 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
67
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
68 /*
|
54
|
69 * Clear
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
70 */
|
54
|
71 void VirtualMachine::Clear()
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
72 {
|
54
|
73 for(uint32 i = 0; i < Capacity; ++i)
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
74 {
|
54
|
75 nMemory[i] = 0;
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
76 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
77 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
78
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
79 /*
|
54
|
80 * GetMemorySize
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
81 */
|
54
|
82 uint32 VirtualMachine::GetMemorySize() const
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
83 {
|
54
|
84 return Capacity;
|
|
85 }
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
86
|
54
|
87 /*
|
|
88 * GetMemoryPointer
|
|
89 */
|
|
90 uint8* VirtualMachine::GetMemoryPointer()
|
|
91 {
|
|
92 return &nMemory[0];
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
93 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
94
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
95 /*
|
54
|
96 * PushFrame
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
97 */
|
54
|
98 void VirtualMachine::PushFrame(uint32 nFunctionAddress, uint32 nContinuationAddress)
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
99 {
|
54
|
100 Frame* pInstance = pFrame;
|
|
101
|
|
102 while(pInstance)
|
|
103 {
|
|
104 if(pInstance->nAddress == nFunctionAddress && pInstance->nContinuation == nContinuationAddress)
|
|
105 {
|
|
106 break;
|
|
107 }
|
|
108
|
|
109 pInstance = pInstance->pLast;
|
|
110 }
|
|
111
|
|
112 if(pInstance)
|
|
113 {
|
|
114 while(pFrame && pFrame != pInstance)
|
|
115 {
|
|
116 Frame* pValue = pFrame;
|
|
117 pFrame = pValue->pLast;
|
|
118
|
|
119 kFrameAllocator.Free(pValue);
|
|
120 }
|
|
121
|
|
122 //ASSERT(pFrame != NULL);
|
|
123 }
|
|
124 else
|
|
125 {
|
|
126 pInstance = kFrameAllocator.Allocate();
|
|
127 pInstance->nAddress = nFunctionAddress;
|
|
128 pInstance->nContinuation = nContinuationAddress;
|
|
129 pInstance->pLast = pFrame;
|
|
130
|
|
131 pFrame = pInstance;
|
|
132 }
|
|
133
|
|
134 nInstructionPointer = nFunctionAddress;
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
135 }
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
136
|
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
137 /*
|
54
|
138 * PopFrame
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
139 */
|
54
|
140 void VirtualMachine::PopFrame()
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
141 {
|
54
|
142 if(pFrame)
|
|
143 {
|
|
144 nInstructionPointer = pFrame->nContinuation;
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
145
|
54
|
146 Frame* pInstance = pFrame;
|
|
147 pFrame = pInstance->pLast;
|
|
148
|
|
149 kFrameAllocator.Free(pInstance);
|
|
150 }
|
|
151 else
|
|
152 {
|
|
153 }
|
0
koryspansel <koryspansel@bendbroadband.com>
parents:
diff
changeset
|
154 }
|