diff --git a/src/main.c b/src/main.c index 47eb362..e63a6f7 100644 --- a/src/main.c +++ b/src/main.c @@ -27,9 +27,10 @@ void mainloop() { int main(int argc, char **argv) { vm.frames_size = FRAMES_SIZE; + vm.return_stack_size = STACK_SIZE; vm.stack_size = STACK_SIZE; vm.memory_size = MEMORY_SIZE; - vm.frames[vm.fp].allocated.end = test_add_function_compile(vm.memory); + test_add_function_compile(vm.memory); #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(mainloop, 0, 1); diff --git a/src/opcodes.h b/src/opcodes.h index ecb9bb2..a0b878d 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -27,13 +27,16 @@ typedef struct { #define STACK_SIZE 256 typedef struct { uint32_t pc; /* Program counter */ - uint32_t fp; /* Frame pointer (last allocated value) */ - uint32_t rp; /* Return stack pointer (top of stack) */ + uint32_t fp; /* Frame pointer plast allocated value) */ + uint32_t sp; /* stack pointer (top of stack) */ + uint32_t rp; /* return stack pointer (top of stack) */ uint32_t mp; /* Memory pointer (last allocated value) */ uint32_t frames_size; Frame frames[FRAMES_SIZE]; /* function call frames */ uint32_t stack_size; Value stack[STACK_SIZE]; /* main stack */ + uint32_t return_stack_size; + Value return_stack[STACK_SIZE]; /* return stack (for recursion) */ uint32_t memory_size; Value memory[MEMORY_SIZE]; /* memory array */ } VM; diff --git a/src/test.c b/src/test.c index a8f1c60..78e70f4 100644 --- a/src/test.c +++ b/src/test.c @@ -43,34 +43,26 @@ uint32_t test_loop_compile(Value *memory) { } uint32_t test_add_function_compile(Value *memory) { - uint32_t i = 3; - memory[i++].u = OP(OP_POPU, 0, 0, 0); /* return ptr */ - memory[i++].u = OP(OP_POPI, 1, 0, 0); /* a int */ - memory[i++].u = OP(OP_POPI, 2, 0, 0); /* b int */ - memory[i++].u = OP(OP_ADD_INT, 3, 2, 1); /* a + b */ - memory[i++].u = OP(OP_PUSHI, 3, 0, 0); /* return */ - memory[i++].u = OP(OP_RETURN, 0, 0, 0); - uint32_t main = i; - memory[0].u = OP(OP_LOADF, 0, 0, 0); - memory[1].u = main; - memory[2].u = OP(OP_JMP, 0, 0, 0); /* jump to 'main' */ + uint32_t i = 0; + /* fn main() */ memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */ memory[i++].i = 1; memory[i++].u = OP(OP_PUSHI, 0, 0, 0); memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */ memory[i++].i = 1; memory[i++].u = OP(OP_PUSHI, 0, 0, 0); - uint32_t add_fn_return = i + 6; /* after the call */ - memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* return */ - memory[i++].u = add_fn_return; - memory[i++].u = OP(OP_PUSHU, 0, 0, 0); - memory[i++].u = OP(OP_LOADU, 0, 0, 0); /* add fn ptr */ - memory[i++].u = 3; memory[i++].u = OP(OP_CALL, 0, 0, 0); /* ); */ + memory[i++].u = 12; memory[i++].u = OP(OP_POPI, 0, 0, 0); /* get return value */ memory[i++].u = OP(OP_INT_TO_STRING, 1, 0, 0); memory[i++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print(sum.toS()); */ memory[i++].u = OP(OP_HALT, 0, 0, 0); + /* fn add() */ + memory[i++].u = OP(OP_POPI, 0, 0, 0); /* a int */ + memory[i++].u = OP(OP_POPI, 1, 0, 0); /* b int */ + memory[i++].u = OP(OP_ADD_INT, 2, 1, 0); /* a + b */ + memory[i++].u = OP(OP_PUSHI, 2, 0, 0); /* push on stack */ + memory[i++].u = OP(OP_RETURN, 0, 0, 0); return i; } diff --git a/src/vm.c b/src/vm.c index 2fa7d11..bdfe93f 100644 --- a/src/vm.c +++ b/src/vm.c @@ -54,23 +54,20 @@ bool step_vm(VM *vm) { switch (opcode) { case OP_HALT: return false; - case OP_CALL: - vm->pc = vm->frames[vm->fp] - .registers[dest] - .u; /* set pc to location of function in memory */ - vm->fp++; /* increment to the next free frame */ + case OP_CALL:; + uint32_t jmp = + vm->memory[vm->pc++].u; /* set pc to location of function in memory */ + vm->return_stack[vm->rp++].u = vm->pc; /* set return address */ + vm->fp++; /* increment to the next free frame */ vm->frames[vm->fp].allocated.start = vm->mp; /* set start of new memory block */ + vm->pc = jmp; return true; case OP_RETURN: - vm->pc = vm->stack[vm->rp].u; /* set pc to return address */ + vm->pc = vm->return_stack[--vm->rp].u; /* set pc to return address */ Slice s = vm->frames[vm->fp].allocated; /* get allocated slice */ memset(&vm->memory[s.start], 0, s.end - s.start); /* deallocate memory from slice */ - uint32_t parent_rp = vm->frames[vm->fp - 1].rp; /* get parents rp */ - vm->frames[vm->fp - 1].registers[parent_rp++] = - vm->frames[vm->fp].registers[src1]; /* set the return value to the last - register in the parent frame */ memset(&vm->frames[vm->fp], 0, sizeof(Frame)); /* reset the frame */ vm->fp--; /* pop the frame */ vm->mp = s.start; /* reset memory pointer to start of old slice */ @@ -94,22 +91,22 @@ bool step_vm(VM *vm) { vm->memory[vm->pc++].f = vm->frames[vm->fp].registers[dest].f; return true; case OP_PUSHI: - vm->stack[++vm->rp].i = vm->frames[vm->fp].registers[dest].i; + vm->stack[++vm->sp].i = vm->frames[vm->fp].registers[dest].i; return true; case OP_PUSHU: - vm->stack[++vm->rp].u = vm->frames[vm->fp].registers[dest].u; + vm->stack[++vm->sp].u = vm->frames[vm->fp].registers[dest].u; return true; case OP_PUSHF: - vm->stack[++vm->rp].f = vm->frames[vm->fp].registers[dest].f; + vm->stack[++vm->sp].f = vm->frames[vm->fp].registers[dest].f; return true; case OP_POPI: - vm->frames[vm->fp].registers[dest].i = vm->stack[vm->rp--].i; + vm->frames[vm->fp].registers[dest].i = vm->stack[vm->sp--].i; return true; case OP_POPU: - vm->frames[vm->fp].registers[dest].u = vm->stack[vm->rp--].u; + vm->frames[vm->fp].registers[dest].u = vm->stack[vm->sp--].u; return true; case OP_POPF: - vm->frames[vm->fp].registers[dest].f = vm->stack[vm->rp--].f; + vm->frames[vm->fp].registers[dest].f = vm->stack[vm->sp--].f; return true; case OP_ADD_INT: MATH_OP(i, +); diff --git a/test/add.asm b/test/add.asm index 93da211..1ff3b38 100644 --- a/test/add.asm +++ b/test/add.asm @@ -10,9 +10,7 @@ main: halt add: - popu $0 ; pop unsigned int - popi $1 ; int a - popi $2 ; int b - addi $3 $2 $1 ; a + b - pushi $3 ; push a + b onto stack for return - return $0 ; actually do the return + popi $0 ; int a + popi $1 ; int b + addi $2 $1 $0 ; a + b + return $2 ; actually do the return