aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode/vm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytecode/vm.h')
-rwxr-xr-xsrc/bytecode/vm.h24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index 3f59aff..84d2432 100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -183,6 +183,11 @@ vm_interpret(VM *vm) {
183 Object obj = frame->chunk->constants[constant]; 183 Object obj = frame->chunk->constants[constant];
184 array_push(vm->stack, obj); 184 array_push(vm->stack, obj);
185 } break; 185 } break;
186 case OP_DEF_LOCAL: {
187 Object value = array_pop(vm->stack);
188 ssize_t idx = AS_FIXNUM(array_pop(vm->stack));
189 vm->stack[frame->stack_offset + idx] = value;
190 } break;
186 case OP_DEF: { 191 case OP_DEF: {
187 Object value = array_pop(vm->stack); 192 Object value = array_pop(vm->stack);
188 Object name = array_pop(vm->stack); 193 Object name = array_pop(vm->stack);
@@ -281,12 +286,15 @@ vm_interpret(VM *vm) {
281 } else if (n_args > n_params) { 286 } else if (n_args > n_params) {
282 RUNTIME_ERROR(ERR_TOO_MANY_ARGS); 287 RUNTIME_ERROR(ERR_TOO_MANY_ARGS);
283 } 288 }
289 ssize_t n_locals = array_size(proc.chunk->locals) - n_params;
284 290
285 // DEBUG:... 291#ifdef DEBUG
286 // disassemble_chunk(proc.chunk); 292 disassemble_chunk(proc.chunk);
293#endif
287 294
288 // Tail-call optimization. 295 // Tail-call optimization.
289 if (proc.chunk != frame->chunk || *vm->pc != OP_RETURN) { 296 if (proc.chunk != frame->chunk || *vm->pc != OP_RETURN) {
297 // Prepare new call frame.
290 CallFrame new_frame = (CallFrame){ 298 CallFrame new_frame = (CallFrame){
291 .chunk = proc.chunk, 299 .chunk = proc.chunk,
292 .rp = vm->pc, 300 .rp = vm->pc,
@@ -294,14 +302,20 @@ vm_interpret(VM *vm) {
294 }; 302 };
295 array_push(vm->frames, new_frame); 303 array_push(vm->frames, new_frame);
296 frame = &vm->frames[array_size(vm->frames) - 1]; 304 frame = &vm->frames[array_size(vm->frames) - 1];
305
306 // Prepare local slots.
307 for (ssize_t i = 0; i < n_locals; i++) {
308 array_push(vm->stack, NIL_VAL);
309 }
297 } else { 310 } else {
298 // Bind tail-call parameters. 311 // Bind tail-call parameters.
299 for (size_t i = 0; i < (size_t)n_params; i++) { 312 for (ssize_t i = 0; i < n_params; i++) {
300 Object obj = array_peek(vm->stack, n_params - 1 - i); 313 Object obj = array_peek(vm->stack, n_locals + n_params - 1 - i);
301 vm->stack[frame->stack_offset + i] = obj; 314 vm->stack[frame->stack_offset + i] = obj;
302 } 315 }
316
303 // Reset stack size. 317 // Reset stack size.
304 array_head(vm->stack)->size = frame->stack_offset + n_params; 318 array_head(vm->stack)->size = frame->stack_offset + n_params + n_locals;
305 } 319 }
306 vm->pc = frame->chunk->code; 320 vm->pc = frame->chunk->code;
307 } break; 321 } break;