From ad8c598e84bd1e5469e2487cc3e4d0ea784d0ff3 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Mon, 25 Oct 2021 14:32:18 +0200 Subject: Add callframe support for the VM --- src/bytecode/vm.h | 70 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 29 deletions(-) (limited to 'src/bytecode/vm.h') diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index b6f9848..23c3d89 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h @@ -8,13 +8,20 @@ #include "debug.h" #include "hashtable.h" +#define VM_FRAMES_CAP 64 #define VM_STACK_CAP 1024 -typedef struct VM { - // Program code. - Chunk *chunk; - // Program counter. +typedef struct CallFrame { + // Current code being run. + Object procedure; + // Current program counter for this call. u8 *pc; + // Ref to stack. Is this really needed? + // Object *stack; +} CallFrame; + +typedef struct VM { + CallFrame *frames; // Stack. Object *stack; // Global variables. @@ -24,17 +31,22 @@ typedef struct VM { void vm_init(VM *vm); void vm_free(VM *vm); void vm_reset(VM *vm); -void vm_interpret(VM *vm, Chunk *chunk); +void vm_interpret(VM *vm); void vm_init(VM *vm) { *vm = (VM){0}; + array_init(vm->frames, VM_FRAMES_CAP); + for (size_t i = 0; i < array_cap(vm->frames); i++) { + vm->frames[i] = (CallFrame){0}; + } array_init(vm->stack, VM_STACK_CAP); vm->globals = ht_init(); } void vm_free(VM *vm) { + array_free(vm->frames); array_free(vm->stack); ht_free(vm->globals); } @@ -50,16 +62,16 @@ vm_reset(VM *vm) { error_push((Error){ \ .type = ERR_TYPE_RUNTIME, \ .value = ERR_WRONG_ARG_TYPE, \ - .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, \ - .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, \ + .line = chunk->lines[frame->pc - chunk->code - 1].line, \ + .col = chunk->lines[frame->pc - chunk->code - 1].col, \ }) #define SYMBOL_NOT_FOUND_ERR() \ error_push((Error){ \ .type = ERR_TYPE_RUNTIME, \ .value = ERR_SYMBOL_NOT_FOUND, \ - .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, \ - .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, \ + .line = chunk->lines[frame->pc - chunk->code - 1].line, \ + .col = chunk->lines[frame->pc - chunk->code - 1].col, \ }) #define FIXNUM_ARITHMETIC_OP(OP) \ @@ -123,11 +135,11 @@ vm_reset(VM *vm) { } while (false) void -vm_interpret(VM *vm, Chunk *chunk) { - vm->chunk = chunk; - vm->pc = vm->chunk->code; +vm_interpret(VM *vm) { + CallFrame *frame = &vm->frames[array_size(vm->frames) - 1]; + Chunk *chunk = frame->procedure.chunk; - if (vm->chunk->code == NULL || array_size(vm->chunk->code) == 0) { + if (chunk->code == NULL || array_size(chunk->code) == 0) { error_push((Error){ .type = ERR_TYPE_RUNTIME, .value = ERR_EMPTY_CHUNK, @@ -135,8 +147,8 @@ vm_interpret(VM *vm, Chunk *chunk) { return; } - u8 *last = vm->chunk->code + array_size(vm->chunk->code); - while (vm->pc < last) { + u8 *last = chunk->code + array_size(chunk->code); + while (frame->pc < last) { #ifdef DEBUG_TRACE_EXECUTION printf("stack: [ "); for (size_t i = 0; i < array_size(vm->stack); i++) { @@ -146,13 +158,13 @@ vm_interpret(VM *vm, Chunk *chunk) { } } printf(" ]\nop: "); - disassemble_instruction(vm->chunk, (vm->pc - vm->chunk->code)); + disassemble_instruction(chunk, (frame->pc - chunk->code)); #endif - u8 instruction = *vm->pc++; + u8 instruction = *frame->pc++; switch (instruction) { case OP_CONSTANT: { - u8 constant = *vm->pc++; - Object obj = vm->chunk->constants[constant]; + u8 constant = *frame->pc++; + Object obj = chunk->constants[constant]; array_push(vm->stack, obj); } break; case OP_DEF: { @@ -197,17 +209,17 @@ vm_interpret(VM *vm, Chunk *chunk) { case OP_LESS_EQUAL: { FIXNUM_COMPARE_OP(<=); } break; case OP_GREATER_EQUAL: { FIXNUM_COMPARE_OP(>=); } break; case OP_JUMP: { - u16 a = *vm->pc++; - u16 b = *vm->pc++; + u16 a = *frame->pc++; + u16 b = *frame->pc++; s16 offset = (a << 8) | b; - vm->pc += offset; + frame->pc += offset; } break; case OP_JUMP_IF_FALSE: { - u16 a = *vm->pc++; - u16 b = *vm->pc++; + u16 a = *frame->pc++; + u16 b = *frame->pc++; s16 offset = (a << 8) | b; if (IS_FALSE(array_pop(vm->stack))) { - vm->pc += offset; + frame->pc += offset; } } break; case OP_DISPLAY: { @@ -248,8 +260,8 @@ vm_interpret(VM *vm, Chunk *chunk) { error_push((Error){ .type = ERR_TYPE_RUNTIME, .value = ERR_NOT_IMPLEMENTED, - .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, - .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, + .line = chunk->lines[frame->pc - chunk->code - 1].line, + .col = chunk->lines[frame->pc - chunk->code - 1].col, }); return; } break; @@ -259,8 +271,8 @@ vm_interpret(VM *vm, Chunk *chunk) { error_push((Error){ .type = ERR_TYPE_RUNTIME, .value = ERR_PC_OOB, - .line = vm->chunk->lines[0].line, - .col = vm->chunk->lines[0].col, + .line = chunk->lines[0].line, + .col = chunk->lines[0].col, }); } -- cgit v1.2.1