diff options
Diffstat (limited to 'src/bytecode/vm.h')
-rwxr-xr-x | src/bytecode/vm.h | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index 0ce6dec..98c94fa 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h | |||
@@ -19,6 +19,8 @@ typedef struct CallFrame { | |||
19 | // Object *locals; | 19 | // Object *locals; |
20 | // Return counter. | 20 | // Return counter. |
21 | u8 *rp; | 21 | u8 *rp; |
22 | // Starting point of the locals for this procedure. | ||
23 | size_t stack_offset; | ||
22 | } CallFrame; | 24 | } CallFrame; |
23 | 25 | ||
24 | typedef struct VM { | 26 | typedef struct VM { |
@@ -149,8 +151,7 @@ vm_interpret(VM *vm) { | |||
149 | return; | 151 | return; |
150 | } | 152 | } |
151 | 153 | ||
152 | u8 *last = frame->chunk->code + array_size(frame->chunk->code); | 154 | while (true) { |
153 | while (vm->pc < last) { | ||
154 | #ifdef DEBUG_TRACE_EXECUTION | 155 | #ifdef DEBUG_TRACE_EXECUTION |
155 | printf("stack: [ "); | 156 | printf("stack: [ "); |
156 | for (size_t i = 0; i < array_size(vm->stack); i++) { | 157 | for (size_t i = 0; i < array_size(vm->stack); i++) { |
@@ -164,6 +165,10 @@ vm_interpret(VM *vm) { | |||
164 | #endif | 165 | #endif |
165 | u8 instruction = *vm->pc++; | 166 | u8 instruction = *vm->pc++; |
166 | switch (instruction) { | 167 | switch (instruction) { |
168 | case OP_LOCAL: { | ||
169 | u8 local = *vm->pc++; | ||
170 | array_push(vm->stack, vm->stack[frame->stack_offset + local]); | ||
171 | } break; | ||
167 | case OP_CONSTANT: { | 172 | case OP_CONSTANT: { |
168 | u8 constant = *vm->pc++; | 173 | u8 constant = *vm->pc++; |
169 | Object obj = frame->chunk->constants[constant]; | 174 | Object obj = frame->chunk->constants[constant]; |
@@ -256,7 +261,11 @@ vm_interpret(VM *vm) { | |||
256 | } break; | 261 | } break; |
257 | case OP_CALL: { | 262 | case OP_CALL: { |
258 | Object proc = array_pop(vm->stack); | 263 | Object proc = array_pop(vm->stack); |
259 | CallFrame new_frame = (CallFrame){proc.chunk, vm->pc}; | 264 | CallFrame new_frame = (CallFrame){ |
265 | .chunk = proc.chunk, | ||
266 | .rp = vm->pc, | ||
267 | .stack_offset = array_size(vm->stack) - array_size(proc.chunk->params), | ||
268 | }; | ||
260 | array_push(vm->frames, new_frame); | 269 | array_push(vm->frames, new_frame); |
261 | frame = &vm->frames[array_size(vm->frames) - 1]; | 270 | frame = &vm->frames[array_size(vm->frames) - 1]; |
262 | vm->pc = frame->chunk->code; | 271 | vm->pc = frame->chunk->code; |
@@ -272,6 +281,9 @@ vm_interpret(VM *vm) { | |||
272 | } | 281 | } |
273 | vm->pc = frame->rp; | 282 | vm->pc = frame->rp; |
274 | array_head(vm->frames)->size--; | 283 | array_head(vm->frames)->size--; |
284 | Object ret = array_pop(vm->stack); | ||
285 | array_head(vm->stack)->size = frame->stack_offset; | ||
286 | array_push(vm->stack, ret); | ||
275 | frame = &vm->frames[array_size(vm->frames) - 1]; | 287 | frame = &vm->frames[array_size(vm->frames) - 1]; |
276 | } break; | 288 | } break; |
277 | case OP_DROP: { | 289 | case OP_DROP: { |