aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/bytecode/vm.h22
1 files changed, 15 insertions, 7 deletions
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index 98c94fa..6c44fc6 100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -261,13 +261,21 @@ vm_interpret(VM *vm) {
261 } break; 261 } break;
262 case OP_CALL: { 262 case OP_CALL: {
263 Object proc = array_pop(vm->stack); 263 Object proc = array_pop(vm->stack);
264 CallFrame new_frame = (CallFrame){ 264
265 .chunk = proc.chunk, 265 // Tail-call optimization.
266 .rp = vm->pc, 266 if (proc.chunk != frame->chunk || *vm->pc != OP_RETURN) {
267 .stack_offset = array_size(vm->stack) - array_size(proc.chunk->params), 267 CallFrame new_frame = (CallFrame){
268 }; 268 .chunk = proc.chunk,
269 array_push(vm->frames, new_frame); 269 .rp = vm->pc,
270 frame = &vm->frames[array_size(vm->frames) - 1]; 270 .stack_offset = array_size(vm->stack) - array_size(proc.chunk->params),
271 };
272 array_push(vm->frames, new_frame);
273 frame = &vm->frames[array_size(vm->frames) - 1];
274 } else {
275 // TODO: restore all parameters.
276 Object a = array_pop(vm->stack);
277 vm->stack[frame->stack_offset] = a;
278 }
271 vm->pc = frame->chunk->code; 279 vm->pc = frame->chunk->code;
272 } break; 280 } break;
273 case OP_RETURN: { 281 case OP_RETURN: {