fix jumps to be less weird

This commit is contained in:
zongor 2025-07-10 21:46:29 -04:00
parent 49f7189470
commit 19a69d3be5
5 changed files with 33 additions and 42 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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, +);

View File

@ -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