1 #include "vm_internal.h"
3 #include <string.h> // memcpy
4 #include <stdio.h> // printf, fixme, remove
5 #include <math.h> // fmodf, fixme, remove
8 //// SVMVMConfiguration configuration;
11 #define SVMVMMaxStack 128
12 #define SVMVMMaxPCStack 32
14 struct SVMModuleInstance
{
16 SVMFunctionLookupCallback lookupCallback
;
21 SVMInstruction
*instructions
;
23 uint32_t currentStackIdx
;
24 SVMOperand stack
[SVMVMMaxStack
];
26 uint32_t currentPCStackIdx
;
27 SVMPointer pcStack
[SVMVMMaxPCStack
];
30 //SVMVM *svmCreateVM(const SVMVMConfiguration *configuration) {
31 // SVMVM *vm = configuration->malloc(sizeof(SVMVM));
32 // memcpy(&vm->configuration, configuration, sizeof(SVMVMConfiguration));
37 //SVMModuleInstance *svmCreateModuleInstance(SVMVM *vm, SVMModule *module, void *userParam) {
38 // SVMModuleInstance *instance = vm->configuration.malloc(sizeof(SVMModuleInstance));
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;
51 size_t svmGetModuleInstanceSize(SVMModule
*module
) {
52 return sizeof(SVMModuleInstance
);
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;
68 void *svmGetModuleInstanceUserParameter(SVMModuleInstance
*instance
) {
69 return instance
->userParam
;
72 SVMRunOutcome
svmRunModuleInstance(SVMModuleInstance
*instance
) {
73 #define resolveStack(v) ((v) >= 0 ? (instance->currentStackIdx + (v)) : (SVMVMMaxStack + (v)))
76 if(instance
->currentPCStackIdx
< 0 || instance
->currentPCStackIdx
>= SVMVMMaxPCStack
) {
77 printf("EXCEEDED PCSTACK\n");
78 return SVMRunOutcomeError
;
81 SVMPointer
*instructionIdxP
= &instance
->pcStack
[instance
->currentPCStackIdx
];
82 SVMPointer instructionIdx
= *instructionIdxP
;
84 if (instructionIdx
>= instance
->module
->numInstructions
) return SVMRunOutcomeFinished
;
87 SVMInstruction instruction
= instance
->instructions
[instructionIdx
];
89 switch (instruction
.opcode
) {
90 case SVMOpcodeInvalid
:
92 printf("ERROR, FOUND BAD OPCODE: %u %u\n", instruction
.opcode
, instructionIdx
);
93 __builtin_unreachable();
95 return SVMRunOutcomeError
;
98 int32_t raw
= instance
->stack
[resolveStack(instruction
.p1
.stackOffset
)].__raw
;
99 instance
->stack
[resolveStack(instruction
.dst
.stackOffset
)].__raw
= raw
;
100 *instructionIdxP
= *instructionIdxP
+ 1;
105 instance
->stack
[resolveStack(instruction
.dst
.stackOffset
)].__raw
= instruction
.p1
.__raw
;
106 *instructionIdxP
= *instructionIdxP
+ 1;
110 // FIXME: Use of float
112 SVMFloat raw
= instance
->stack
[resolveStack(instruction
.p1
.stackOffset
)].floatLiteral
;
113 instance
->stack
[resolveStack(instruction
.dst
.stackOffset
)].floatLiteral
= fixedNegate(raw
);
114 *instructionIdxP
= *instructionIdxP
+ 1;
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;
126 int32_t raw
= instance
->stack
[resolveStack(instruction
.p1
.stackOffset
)].__raw
;
127 instance
->stack
[resolveStack(instruction
.dst
.stackOffset
)].__raw
= !(raw
);
128 *instructionIdxP
= *instructionIdxP
+ 1;
132 // FIXME: Use of float
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;
141 // FIXME: Use of float
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;
150 // FIXME: Use of float
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;
159 // FIXME: Use of float
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;
168 // FIXME: Use of float
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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
;
273 *instructionIdxP
= *instructionIdxP
+ 1;
277 case SVMOpcodeSLEEP
: {
278 *instructionIdxP
= *instructionIdxP
+ 1;
279 return SVMRunOutcomeSuspended
;
282 case SVMOpcodePOPJUMP
: {
283 instance
->currentPCStackIdx
--;
288 case SVMOpcodeJUMP
: {
289 *instructionIdxP
= instruction
.dst
.pointerLiteral
;
293 case SVMOpcodePUSHJUMP
: {
294 *instructionIdxP
= *instructionIdxP
+ 1;
295 instance
->currentPCStackIdx
++;
296 instance
->pcStack
[instance
->currentPCStackIdx
] = instruction
.dst
.pointerLiteral
;
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
307 *instructionIdxP
= *instructionIdxP
+ 1;
312 int32_t value
= instance
->stack
[resolveStack(instruction
.dst
.stackOffset
)].__raw
;
314 *instructionIdxP
= instruction
.p1
.pointerLiteral
;
316 *instructionIdxP
= *instructionIdxP
+ 1;
325 const char *svmGetString(SVMModuleInstance
*instance
, int32_t ptr
) {
326 return &instance
->strings
[ptr
];
329 SVMPublic
*svmGetPublicReference(SVMModule
*instance
, const char *nameFmt
, ...) {
333 SVMOperand
svmGetPublicValue(SVMModuleInstance
*instance
, int32_t ptr
) {