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