]> git.bts.cx Git - sun.git/blob - runtime/src/sun/vm/vm.c
do not evaluate variables until they are used
[sun.git] / runtime / src / sun / vm / vm.c
1 #include "vm_internal.h"
2
3 #include <string.h> // memcpy
4 #include <stdio.h> // printf, fixme, remove
5 #include <math.h> // fmodf, fixme, remove
6
7 //struct SVMVM {
8 //// SVMVMConfiguration configuration;
9 //};
10
11 #define SVMVMMaxStack 128
12 #define SVMVMMaxPCStack 32
13
14 struct SVMModuleInstance {
15 //SVMVM *vm;
16 SVMFunctionLookupCallback lookupCallback;
17 SVMModule *module;
18 void *userParam;
19
20 char *strings;
21 SVMInstruction *instructions;
22
23 uint32_t currentStackIdx;
24 SVMOperand stack[SVMVMMaxStack];
25
26 uint32_t currentPCStackIdx;
27 SVMPointer pcStack[SVMVMMaxPCStack];
28 };
29
30 //SVMVM *svmCreateVM(const SVMVMConfiguration *configuration) {
31 // SVMVM *vm = configuration->malloc(sizeof(SVMVM));
32 // memcpy(&vm->configuration, configuration, sizeof(SVMVMConfiguration));
33 // return vm;
34 //}
35
36
37 //SVMModuleInstance *svmCreateModuleInstance(SVMVM *vm, SVMModule *module, void *userParam) {
38 // SVMModuleInstance *instance = vm->configuration.malloc(sizeof(SVMModuleInstance));
39 // instance->vm = vm;
40 // instance->module = module;
41 // instance->userParam = userParam;
42 // instance->strings = (char *)((void *)module + sizeof(SVMModule));
43 // instance->instructions = (SVMInstruction *)((void *)module + sizeof(SVMModule) + module->stringBlobLength);
44 // instance->currentStackIdx = 0;
45 // instance->currentPCStackIdx = 0;
46 // instance->pcStack[0] = 0;
47 // return instance;
48 //}
49
50
51 size_t svmGetModuleInstanceSize(SVMModule *module) {
52 return sizeof(SVMModuleInstance);
53 }
54
55 SVMModuleInstance *svnResetModuleInstanceMemory(SVMModule *module, void *memory, void *userParameter, SVMFunctionLookupCallback lookupCallback) {
56 SVMModuleInstance *instance = (SVMModuleInstance *)memory;
57 instance->lookupCallback = lookupCallback;
58 instance->module = module;
59 instance->userParam = userParameter;
60 instance->strings = (char *)((void *)module + sizeof(SVMModule));
61 instance->instructions = (SVMInstruction *)((void *)module + sizeof(SVMModule) + module->stringBlobLength);
62 instance->currentStackIdx = 0;
63 instance->currentPCStackIdx = 0;
64 instance->pcStack[0] = 0;
65 return instance;
66 }
67
68 void *svmGetModuleInstanceUserParameter(SVMModuleInstance *instance) {
69 return instance->userParam;
70 }
71
72 SVMRunOutcome svmRunModuleInstance(SVMModuleInstance *instance) {
73 #define resolveStack(v) ((v) >= 0 ? (instance->currentStackIdx + (v)) : (SVMVMMaxStack + (v)))
74
75 for (;;) {
76 if(instance->currentPCStackIdx < 0 || instance->currentPCStackIdx >= SVMVMMaxPCStack) {
77 printf("EXCEEDED PCSTACK\n");
78 return SVMRunOutcomeError;
79 }
80
81 SVMPointer *instructionIdxP = &instance->pcStack[instance->currentPCStackIdx];
82 SVMPointer instructionIdx = *instructionIdxP;
83
84 if (instructionIdx >= instance->module->numInstructions) return SVMRunOutcomeFinished;
85
86 // ...
87 SVMInstruction instruction = instance->instructions[instructionIdx];
88
89 switch (instruction.opcode) {
90 case SVMOpcodeInvalid:
91 default:
92 printf("ERROR, FOUND BAD OPCODE: %u %u\n", instruction.opcode, instructionIdx);
93 __builtin_unreachable();
94 //exit(1);
95 return SVMRunOutcomeError;
96
97 case SVMOpcodeMOV: {
98 int32_t raw = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
99 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = raw;
100 *instructionIdxP = *instructionIdxP + 1;
101 break;
102 }
103
104 case SVMOpcodeSET: {
105 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = instruction.p1.__raw;
106 *instructionIdxP = *instructionIdxP + 1;
107 break;
108 }
109
110 // FIXME: Use of float
111 case SVMOpcodeINV: {
112 SVMFloat raw = instance->stack[resolveStack(instruction.p1.stackOffset)].floatLiteral;
113 instance->stack[resolveStack(instruction.dst.stackOffset)].floatLiteral = fixedNegate(raw);
114 *instructionIdxP = *instructionIdxP + 1;
115 break;
116 }
117
118 case SVMOpcodeBNOT: {
119 int32_t raw = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
120 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = ~(raw);
121 *instructionIdxP = *instructionIdxP + 1;
122 break;
123 }
124
125 case SVMOpcodeNOT: {
126 int32_t raw = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
127 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = !(raw);
128 *instructionIdxP = *instructionIdxP + 1;
129 break;
130 }
131
132 // FIXME: Use of float
133 case SVMOpcodeADD: {
134 SVMFloat rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].floatLiteral;
135 SVMFloat rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].floatLiteral;
136 instance->stack[resolveStack(instruction.dst.stackOffset)].floatLiteral = fixedAdd(rawLHS, rawRHS);
137 *instructionIdxP = *instructionIdxP + 1;
138 break;
139 }
140
141 // FIXME: Use of float
142 case SVMOpcodeSUB: {
143 SVMFloat rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].floatLiteral;
144 SVMFloat rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].floatLiteral;
145 instance->stack[resolveStack(instruction.dst.stackOffset)].floatLiteral = fixedSubtract(rawLHS, rawRHS);
146 *instructionIdxP = *instructionIdxP + 1;
147 break;
148 }
149
150 // FIXME: Use of float
151 case SVMOpcodeMUL: {
152 SVMFloat rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].floatLiteral;
153 SVMFloat rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].floatLiteral;
154 instance->stack[resolveStack(instruction.dst.stackOffset)].floatLiteral = fixedMultiply(rawLHS, rawRHS);
155 *instructionIdxP = *instructionIdxP + 1;
156 break;
157 }
158
159 // FIXME: Use of float
160 case SVMOpcodeDIV: {
161 SVMFloat rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].floatLiteral;
162 SVMFloat rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].floatLiteral;
163 instance->stack[resolveStack(instruction.dst.stackOffset)].floatLiteral = fixedDivide(rawLHS, rawRHS);
164 *instructionIdxP = *instructionIdxP + 1;
165 break;
166 }
167
168 // FIXME: Use of float
169 case SVMOpcodeMOD: {
170 SVMFloat rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].floatLiteral;
171 SVMFloat rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].floatLiteral;
172 instance->stack[resolveStack(instruction.dst.stackOffset)].floatLiteral = fixedMod(rawLHS, rawRHS);
173 *instructionIdxP = *instructionIdxP + 1;
174 break;
175 }
176
177 case SVMOpcodeBAND: {
178 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
179 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
180 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS & rawRHS;
181 *instructionIdxP = *instructionIdxP + 1;
182 break;
183 }
184
185 case SVMOpcodeBOR: {
186 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
187 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
188 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS | rawRHS;
189 *instructionIdxP = *instructionIdxP + 1;
190 break;
191 }
192
193 case SVMOpcodeBXOR: {
194 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
195 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
196 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS ^ rawRHS;
197 *instructionIdxP = *instructionIdxP + 1;
198 break;
199 }
200
201 case SVMOpcodeAND: {
202 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
203 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
204 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS && rawRHS;
205 *instructionIdxP = *instructionIdxP + 1;
206 break;
207 }
208
209 case SVMOpcodeOR: {
210 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
211 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
212 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS || rawRHS;
213 *instructionIdxP = *instructionIdxP + 1;
214 break;
215 }
216
217 case SVMOpcodeEQ: {
218 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
219 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
220 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS == rawRHS;
221 *instructionIdxP = *instructionIdxP + 1;
222 break;
223 }
224
225 case SVMOpcodeNEQ: {
226 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
227 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
228 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS != rawRHS;
229 *instructionIdxP = *instructionIdxP + 1;
230 break;
231 }
232
233 case SVMOpcodeLT: {
234 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
235 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
236 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS < rawRHS;
237 *instructionIdxP = *instructionIdxP + 1;
238 break;
239 }
240
241 case SVMOpcodeLTEQ: {
242 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
243 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
244 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS <= rawRHS;
245 *instructionIdxP = *instructionIdxP + 1;
246 break;
247 }
248
249 case SVMOpcodeGT: {
250 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
251 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
252 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS > rawRHS;
253 *instructionIdxP = *instructionIdxP + 1;
254 break;
255 }
256
257 case SVMOpcodeGTEQ: {
258 int32_t rawLHS = instance->stack[resolveStack(instruction.p1.stackOffset)].__raw;
259 int32_t rawRHS = instance->stack[resolveStack(instruction.p2.stackOffset)].__raw;
260 instance->stack[resolveStack(instruction.dst.stackOffset)].__raw = rawLHS >= rawRHS;
261 *instructionIdxP = *instructionIdxP + 1;
262 break;
263 }
264
265 case SVMOpcodeSTK: {
266 SVMStackOffset offset = instruction.dst.stackOffset;
267 instance->currentStackIdx += offset;
268 if(instance->currentStackIdx < 0 || instance->currentStackIdx >= SVMVMMaxStack) {
269 printf("EXCEEDED STACK\n");
270 return SVMRunOutcomeError;
271 }
272 // assert >=0 ?
273 *instructionIdxP = *instructionIdxP + 1;
274 break;
275 }
276
277 case SVMOpcodeSLEEP: {
278 *instructionIdxP = *instructionIdxP + 1;
279 return SVMRunOutcomeSuspended;
280 }
281
282 case SVMOpcodePOPJUMP: {
283 instance->currentPCStackIdx--;
284 // assert >=0 ?
285 break;
286 }
287
288 case SVMOpcodeJUMP: {
289 *instructionIdxP = instruction.dst.pointerLiteral;
290 break;
291 }
292
293 case SVMOpcodePUSHJUMP: {
294 *instructionIdxP = *instructionIdxP + 1;
295 instance->currentPCStackIdx++;
296 instance->pcStack[instance->currentPCStackIdx] = instruction.dst.pointerLiteral;
297 break;
298 }
299
300 case SVMOpcodeCALL: {
301 // const char *name = svmGetString(instance, instruction.dst.pointerLiteral);
302 SVMFunctionCallback function = instance->lookupCallback(instruction.dst.pointerLiteral, instance->userParam);
303 if (function != NULL) {
304 int32_t parameterCount = (int32_t)instruction.p1.integerLiteral;
305 function(instance, parameterCount, &instance->stack[instance->currentStackIdx]); // FIXME
306 }
307 *instructionIdxP = *instructionIdxP + 1;
308 break;
309 }
310
311 case SVMOpcodeJT: {
312 int32_t value = instance->stack[resolveStack(instruction.dst.stackOffset)].__raw;
313 if (value) {
314 *instructionIdxP = instruction.p1.pointerLiteral;
315 } else {
316 *instructionIdxP = *instructionIdxP + 1;
317 }
318
319 break;
320 }
321 }
322 }
323 }
324
325 const char *svmGetString(SVMModuleInstance *instance, int32_t ptr) {
326 return &instance->strings[ptr];
327 }
328
329 SVMPublic *svmGetPublicReference(SVMModule *instance, const char *nameFmt, ...) {
330
331 }
332
333 SVMOperand svmGetPublicValue(SVMModuleInstance *instance, int32_t ptr) {
334
335 }