fix jumps to be less weird
This commit is contained in:
parent
49f7189470
commit
19a69d3be5
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
26
src/test.c
26
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;
|
||||
}
|
||||
|
||||
|
|
29
src/vm.c
29
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, +);
|
||||
|
|
10
test/add.asm
10
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
|
||||
|
|
Loading…
Reference in New Issue