aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-26 13:59:51 +0200
committerBad Diode <bd@badd10de.dev>2021-10-26 13:59:51 +0200
commitb33b00390c605c74426b8376b4a71e17af4754fc (patch)
tree3038a72b0078cbecd5ab91da64bb7e8b8e5d86ec
parent583e0b431a6581206368968d56287a858d53b10a (diff)
downloadbdl-b33b00390c605c74426b8376b4a71e17af4754fc.tar.gz
bdl-b33b00390c605c74426b8376b4a71e17af4754fc.zip
Add initial tail-call optimization
-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: {