diff --git a/src/opcodes.h b/src/opcodes.h index d1b1acf..1d72e4b 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -4,55 +4,61 @@ #include "common.h" typedef enum { - OP_HALT, /* halt : terminate execution */ - OP_JMP, /* jump : jump to address dest unconditionally */ - OP_CALL, /* call : creates a new frame */ - OP_RETURN, /* retn : returns from a frame to the parent frame */ - OP_LOAD, /* load : dest = &[next memory location] */ - OP_LOAD_IMM, /* load : dest = &[next memory location] */ - OP_STORE, /* stor : next memory location = src1 as float */ - OP_PUSH, /* push : push str ref from register onto the stack and copy str */ - OP_POP, /* pop : pop int from stack onto the register */ - OP_REG_MOV, /* rmov : dest = src1 */ - OP_SYSCALL, /* sysc : */ - OP_ADD_INT, /* addi : dest = src1 + src2 */ - OP_SUB_INT, /* subi : dest = src1 - src2 */ - OP_MUL_INT, /* muli : dest = src1 * src2 */ - OP_DIV_INT, /* divi : dest = src1 / src2 */ - OP_ADD_UINT, /* addu : dest = src1 + src2 */ - OP_SUB_UINT, /* subu : dest = src1 - src2 */ - OP_MUL_UINT, /* mulu : dest = src1 * src2 */ - OP_DIV_UINT, /* divu : dest = src1 / src2 */ - OP_ADD_REAL, /* addr : dest = src1 + src2 */ - OP_SUB_REAL, /* subr : dest = src1 - src2 */ - OP_MUL_REAL, /* mulr : dest = src1 * src2 */ - OP_DIV_REAL, /* divr : dest = src1 / src2 */ - OP_INT_TO_REAL, /* itor : dest = src1 as real */ - OP_UINT_TO_REAL, /* utor : dest = src1 as real */ - OP_REAL_TO_INT, /* rtoi : dest = src1 as int */ - OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */ - OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */ - OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/ - OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */ - OP_JLE_INT, /* jlei : jump to address dest if src1 as int <= src2 as int */ - OP_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/ - OP_JEQ_UINT, /* jequ : jump to address dest if src1 as int == src2 as uint */ - OP_JGT_UINT, /* jgtu : jump to address dest if src1 as int > src2 as uint*/ - OP_JLT_UINT, /* jltu : jump to address dest if src1 as int < src2 as uint */ - OP_JLE_UINT, /* jleu : jump to address dest if src1 as int <= src2 as uint */ - OP_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/ - OP_JEQ_REAL, /* jeqr : jump to address dest if src1 as real == src2 as real */ - OP_JGE_REAL, /* jgtr : jump to address dest if src1 as real >= src2 as real */ - OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */ - OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */ - OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */ - OP_STRLEN, /* strl : dest = length of str at src1 ptr */ + OP_HALT, /* halt : terminate execution */ + OP_JMP, /* jump : jump to address dest unconditionally */ + OP_JMPF, /* jmpf : jump to address dest if flag is ne 0 */ + OP_CALL, /* call : creates a new frame */ + OP_RETURN, /* retn : returns from a frame to the parent frame */ + OP_LOAD, /* load : dest = &[next memory location] */ + OP_LOAD_IMM, /* load : dest = &[next memory location] */ + OP_STORE, /* stor : next memory location = src1 as float */ + OP_PUSH, /* push : push str ref from register onto the stack and copy str */ + OP_POP, /* pop : pop int from stack onto the register */ + OP_REG_MOV, /* rmov : dest = src1 */ + OP_SYSCALL, /* sysc : */ + OP_ADD_INT, /* addi : dest = src1 + src2 */ + OP_SUB_INT, /* subi : dest = src1 - src2 */ + OP_MUL_INT, /* muli : dest = src1 * src2 */ + OP_DIV_INT, /* divi : dest = src1 / src2 */ + OP_ADD_UINT, /* addu : dest = src1 + src2 */ + OP_SUB_UINT, /* subu : dest = src1 - src2 */ + OP_MUL_UINT, /* mulu : dest = src1 * src2 */ + OP_DIV_UINT, /* divu : dest = src1 / src2 */ + OP_ADD_REAL, /* addr : dest = src1 + src2 */ + OP_SUB_REAL, /* subr : dest = src1 - src2 */ + OP_MUL_REAL, /* mulr : dest = src1 * src2 */ + OP_DIV_REAL, /* divr : dest = src1 / src2 */ + OP_INT_TO_REAL, /* itor : dest = src1 as real */ + OP_UINT_TO_REAL, /* utor : dest = src1 as real */ + OP_REAL_TO_INT, /* rtoi : dest = src1 as int */ + OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */ + OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */ + OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/ + OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */ + OP_JLE_INT, /* jlei : jump to address dest if src1 as int <= src2 as int */ + OP_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/ + OP_JEQ_UINT, /* jequ : jump to address dest if src1 as int == src2 as uint */ + OP_JGT_UINT, /* jgtu : jump to address dest if src1 as int > src2 as uint*/ + OP_JLT_UINT, /* jltu : jump to address dest if src1 as int < src2 as uint */ + OP_JLE_UINT, /* jleu : jump to address dest if src1 as int <= src2 as uint */ + OP_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/ + OP_JEQ_REAL, /* jeqr : jump to address dest if src1 as real == src2 as real */ + OP_JGE_REAL, /* jgtr : jump to address dest if src1 as real >= src2 as real */ + OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */ + OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */ + OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */ + OP_STRLEN, /* strl : dest = length of str at src1 ptr */ + OP_STREQ, /* steq : dest = src1 ptr string == src2 ptr string */ + OP_STRCAT, /* scat : dest = ptr of src1 ptr string + src2 ptr string */ + OP_STR_GET_CHAR, /* sgch : dest = ptr of src1 ptr string, src2 index of string */ + OP_STR_FIND_CHAR, /* sfch : dest = ptr of src1 ptr string, src2 uint8 char */ + OP_STR_SLICE, /* ssli : dest = ptr of src1 ptr string, src2 start index, src3 end index */ OP_INT_TO_STRING, /* itos : dest = src1 as str */ OP_UINT_TO_STRING, /* utos : dest = src1 as str */ OP_REAL_TO_STRING, /* rtos : dest = src1 as str */ OP_STRING_TO_INT, /* stoi : dest = src1 as int */ OP_STRING_TO_UINT, /* stou : dest = src1 as uint */ - OP_STRING_TO_REAL /* stor : dest = src1 as real */ + OP_STRING_TO_REAL /* stor : dest = src1 as real */ } Opcode; #define MAX_REGS 32 @@ -98,13 +104,13 @@ typedef struct device_s { #define STACK_SIZE 256 #define DEVICES_SIZE 8 typedef struct vm_s { - u32 pc; /* program counter */ - u32 cp; /* code pointer (last allocated opcode) */ - u32 fp; /* frame pointer (current frame) */ - u32 sp; /* stack pointer (top of stack) */ - u32 rp; /* return stack pointer (top of stack) */ - u32 mp; /* memory pointer (last allocated value) */ - u32 dc; /* device count */ + u32 pc; /* program counter */ + u32 cp; /* code pointer (last allocated opcode) */ + u32 fp; /* frame pointer (current frame) */ + u32 sp; /* stack pointer (top of stack) */ + u32 rp; /* return stack pointer (top of stack) */ + u32 mp; /* memory pointer (last allocated value) */ + u32 dc; /* device count */ u32 flag; /* flag (temporary results like SYSCALL status) */ Frame frames[FRAMES_SIZE]; /* function call frames */ u32 stack[STACK_SIZE]; /* main stack */ diff --git a/src/test.c b/src/test.c index f82f503..101169d 100644 --- a/src/test.c +++ b/src/test.c @@ -48,16 +48,21 @@ bool compile_internal_test(const char *filename, VM *vm) { bool test_simple_compile(VM *vm) { u32 ptr; - u32 terminal_path_addr = str_alloc(vm, "/dev/term/0", 12); + u32 newline_addr = + str_alloc(vm, &vm->frames[vm->fp], "\n", 2); + u32 terminal_path_addr = + str_alloc(vm, &vm->frames[vm->fp], "/dev/term/0", 12); vm->code[vm->cp++] = OP_LOAD; vm->code[vm->cp++] = 0; ptr = real_alloc(vm, 1.0f); - write_u32(vm, code, vm->cp, ptr); vm->cp+=4; + write_u32(vm, code, vm->cp, ptr); + vm->cp += 4; vm->code[vm->cp++] = OP_LOAD; vm->code[vm->cp++] = 1; ptr = real_alloc(vm, 2.0f); - write_u32(vm, code, vm->cp, ptr); vm->cp+=4; + write_u32(vm, code, vm->cp, ptr); + vm->cp += 4; vm->code[vm->cp++] = OP_ADD_REAL; vm->code[vm->cp++] = 2; @@ -68,16 +73,22 @@ bool test_simple_compile(VM *vm) { vm->code[vm->cp++] = 3; vm->code[vm->cp++] = 2; + vm->code[vm->cp++] = OP_REAL_TO_STRING; + vm->code[vm->cp++] = 3; + vm->code[vm->cp++] = 2; + vm->code[vm->cp++] = OP_LOAD_IMM; vm->code[vm->cp++] = 2; - write_u32(vm, code, vm->cp, terminal_path_addr); vm->cp+=4; + write_u32(vm, code, vm->cp, terminal_path_addr); + vm->cp += 4; vm->code[vm->cp++] = OP_STRLEN; vm->code[vm->cp++] = 4; vm->code[vm->cp++] = 3; vm->code[vm->cp++] = OP_SYSCALL; - write_u32(vm, code, vm->cp, AS_UINT(SYSCALL_DEVICE_WRITE)); vm->cp+=4; + write_u32(vm, code, vm->cp, AS_UINT(SYSCALL_DEVICE_WRITE)); + vm->cp += 4; vm->code[vm->cp++] = 3; /* arg_count */ vm->code[vm->cp++] = 2; /* first_reg */ /* syscall_id=WRITE, arg_count=2, start_reg=3 ; print(sum.toS()); */ @@ -86,7 +97,9 @@ bool test_simple_compile(VM *vm) { } bool test_window_click_compile(VM *vm) { - u32 test_pixel_addr, loop_start, screen_path_addr = str_alloc(vm, "/dev/screen/0", 14); + u32 test_pixel_addr, loop_start, + screen_path_addr = + str_alloc(vm, &vm->frames[vm->fp], "/dev/screen/0", 14); vm->code[vm->cp++] = OP_LOAD; /* R0 = screen path */ vm->code[vm->cp++] = 0; diff --git a/src/vm.c b/src/vm.c index 5efb9bc..7a892e6 100644 --- a/src/vm.c +++ b/src/vm.c @@ -3,19 +3,25 @@ #include "opcodes.h" #include "str.h" -/* no inline fn in ANSI C :( */ #define COMPARE_AND_JUMP(type, op) \ do { \ - type value, value2; \ + i32 cond; \ + u32 mask, target; \ + u8 dest, src1, src2; \ + type value; \ + type value2; \ dest = read_u8(vm, code, vm->pc); \ vm->pc++; \ src1 = read_u8(vm, code, vm->pc); \ vm->pc++; \ src2 = read_u8(vm, code, vm->pc); \ vm->pc++; \ - value = vm->frames[vm->fp].registers[src1]; \ - value2 = vm->frames[vm->fp].registers[src2]; \ - vm->pc = (value op value2) ? vm->frames[vm->fp].registers[dest] : vm->pc; \ + value = frame.registers[src1]; \ + value2 = frame.registers[src2]; \ + cond = !!(value op value2); \ + mask = -(u32)cond; \ + target = frame.registers[dest]; \ + vm->pc = (target & mask) | (vm->pc & ~mask); \ return true; \ } while (0) @@ -27,14 +33,12 @@ vm->pc++; \ src2 = read_u8(vm, code, vm->pc); \ vm->pc++; \ - vm->frames[vm->fp].registers[dest] = (type)vm->frames[vm->fp] \ - .registers[src1] op(type) \ - vm->frames[vm->fp] \ - .registers[src2]; \ + frame.registers[dest] = \ + (type)frame.registers[src1] op(type) frame.registers[src2]; \ return true; \ } while (0) -u32 str_alloc(VM *vm, const char *str, u32 length) { +u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length) { u32 str_addr = vm->mp; u32 i = 0; vm->mp += 4; @@ -44,7 +48,7 @@ u32 str_alloc(VM *vm, const char *str, u32 length) { vm->memory[vm->mp++] = '\0'; write_u32(vm, memory, str_addr, length); - vm->frames[vm->fp].end = vm->mp; + frame->end = vm->mp; return str_addr; } @@ -55,9 +59,11 @@ bool step_vm(VM *vm) { u8 opcode, dest, src1, src2; u32 v, ptr; i32 value; + Frame frame; /* Get current instruction & Advance to next instruction */ opcode = vm->code[vm->pc++]; + frame = vm->frames[vm->fp]; switch (opcode) { case OP_HALT: { @@ -73,7 +79,7 @@ bool step_vm(VM *vm) { return true; } case OP_RETURN: { - vm->frames[vm->fp].rp = 0; /* reset register ptr */ + frame.rp = 0; /* reset register ptr */ vm->pc = vm->return_stack[--vm->rp]; /* set pc to return address */ vm->mp = vm->frames[vm->fp--].start; /* reset memory pointer to start @@ -85,7 +91,7 @@ bool step_vm(VM *vm) { vm->pc++; v = read_u32(vm, code, vm->pc); vm->pc += 4; - vm->frames[vm->fp].registers[dest] = v; + frame.registers[dest] = v; return true; } case OP_LOAD: { @@ -94,7 +100,7 @@ bool step_vm(VM *vm) { ptr = read_u32(vm, code, vm->pc); vm->pc += 4; v = read_u32(vm, memory, ptr); - vm->frames[vm->fp].registers[dest] = v; + frame.registers[dest] = v; return true; } case OP_STORE: { @@ -102,20 +108,20 @@ bool step_vm(VM *vm) { vm->pc++; ptr = read_u32(vm, code, vm->pc); vm->pc += 4; - v = vm->frames[vm->fp].registers[src1]; + v = frame.registers[src1]; write_u32(vm, memory, ptr, v); return true; } case OP_PUSH: { dest = read_u8(vm, code, vm->pc); vm->pc++; - vm->stack[++vm->sp] = vm->frames[vm->fp].registers[dest]; + vm->stack[++vm->sp] = frame.registers[dest]; return true; } case OP_POP: { dest = read_u8(vm, code, vm->pc); vm->pc++; - vm->frames[vm->fp].registers[dest] = vm->stack[vm->sp--]; + frame.registers[dest] = vm->stack[vm->sp--]; return true; } case OP_REG_MOV: { @@ -123,13 +129,21 @@ bool step_vm(VM *vm) { vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - vm->frames[vm->fp].registers[dest] = vm->frames[vm->fp].registers[src1]; + frame.registers[dest] = frame.registers[src1]; return true; } case OP_JMP: { dest = read_u8(vm, code, vm->pc); vm->pc++; - vm->pc = vm->frames[vm->fp].registers[dest]; /* Jump to address */ + vm->pc = frame.registers[dest]; /* Jump to address */ + return true; + } + case OP_JMPF: { /* error handling for syscall, jump if flag == 0 */ + u32 mask; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + mask = -(u32)(vm->flag == 0); + vm->pc = (dest & mask) | (vm->pc & ~mask); return true; } case OP_SYSCALL: { @@ -148,9 +162,8 @@ bool step_vm(VM *vm) { if (arg_count >= 2) { Device *dev; u32 path_ptr, mode; - path_ptr = - vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ - mode = vm->frames[vm->fp].registers[first_reg + 1]; /* R1: mode */ + path_ptr = frame.registers[first_reg]; /* R0: path pointer */ + mode = frame.registers[first_reg + 1]; /* R1: mode */ dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); if (dev) { @@ -173,11 +186,9 @@ bool step_vm(VM *vm) { Device *dev; u32 path_ptr, buffer_ptr, size; - path_ptr = - vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ - buffer_ptr = vm->frames[vm->fp] - .registers[first_reg + 1]; /* R1: buffer pointer */ - size = vm->frames[vm->fp].registers[first_reg + 2]; /* R2: size */ + path_ptr = frame.registers[first_reg]; /* R0: path pointer */ + buffer_ptr = frame.registers[first_reg + 1]; /* R1: buffer pointer */ + size = frame.registers[first_reg + 2]; /* R2: size */ dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); if (dev && dev->ops->read) { @@ -193,19 +204,17 @@ bool step_vm(VM *vm) { } case SYSCALL_DEVICE_WRITE: { - if (arg_count >= 2) { + if (arg_count >= 3) { Device *dev; u32 path_ptr, buffer_ptr, size; - path_ptr = - vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ - buffer_ptr = vm->frames[vm->fp] - .registers[first_reg + 1]; /* R1: buffer pointer */ - size = vm->frames[vm->fp].registers[first_reg + 2]; /* R2: size */ + path_ptr = frame.registers[first_reg]; /* R0: path pointer */ + buffer_ptr = frame.registers[first_reg + 1]; /* R1: buffer pointer */ + size = frame.registers[first_reg + 2]; /* R2: size */ dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); if (dev && dev->ops->write) { - vm->flag = dev->ops->write(dev->data, (const u8 *)&vm->memory[buffer_ptr + 4], - size); + vm->flag = dev->ops->write( + dev->data, (const u8 *)&vm->memory[buffer_ptr + 4], size); } else { vm->flag = 0; } @@ -219,8 +228,7 @@ bool step_vm(VM *vm) { if (arg_count >= 1) { Device *dev; u32 path_ptr; - path_ptr = - vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ + path_ptr = frame.registers[first_reg]; /* R0: path pointer */ dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); @@ -240,12 +248,9 @@ bool step_vm(VM *vm) { if (arg_count >= 3) { Device *dev; u32 path_ptr, args_ptr, cmd; - path_ptr = - vm->frames[vm->fp].registers[first_reg]; /* R0: device path */ - cmd = - vm->frames[vm->fp].registers[first_reg + 1]; /* R1: ioctl command */ - args_ptr = - vm->frames[vm->fp].registers[first_reg + 2]; /* R2: args pointer */ + path_ptr = frame.registers[first_reg]; /* R0: device path */ + cmd = frame.registers[first_reg + 1]; /* R1: ioctl command */ + args_ptr = frame.registers[first_reg + 2]; /* R2: args pointer */ dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); @@ -295,9 +300,8 @@ bool step_vm(VM *vm) { vm->pc++; src2 = read_u8(vm, code, vm->pc); vm->pc++; - vm->frames[vm->fp].registers[dest] = (vm->frames[vm->fp].registers[src1] * - vm->frames[vm->fp].registers[src2]) >> - 16; + frame.registers[dest] = + (frame.registers[src1] * frame.registers[src2]) >> 16; return true; } @@ -308,9 +312,8 @@ bool step_vm(VM *vm) { vm->pc++; src2 = read_u8(vm, code, vm->pc); vm->pc++; - vm->frames[vm->fp].registers[dest] = - (vm->frames[vm->fp].registers[src1] << 16) / - vm->frames[vm->fp].registers[src2]; + frame.registers[dest] = + (frame.registers[src1] << 16) / frame.registers[src2]; return true; } @@ -321,8 +324,7 @@ bool step_vm(VM *vm) { vm->pc++; src2 = read_u8(vm, code, vm->pc); vm->pc++; - vm->frames[vm->fp].registers[dest] = - vm->frames[vm->fp].registers[src1] + vm->frames[vm->fp].registers[src2]; + frame.registers[dest] = frame.registers[src1] + frame.registers[src2]; return true; } @@ -333,8 +335,7 @@ bool step_vm(VM *vm) { vm->pc++; src2 = read_u8(vm, code, vm->pc); vm->pc++; - vm->frames[vm->fp].registers[dest] = - vm->frames[vm->fp].registers[src1] - vm->frames[vm->fp].registers[src2]; + frame.registers[dest] = frame.registers[src1] - frame.registers[src2]; return true; } case OP_REAL_TO_INT: { @@ -342,12 +343,12 @@ bool step_vm(VM *vm) { vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - value = vm->frames[vm->fp].registers[src1]; + value = frame.registers[src1]; if (value >= 0) { - vm->frames[vm->fp].registers[dest] = value >> 16; + frame.registers[dest] = value >> 16; } else { - vm->frames[vm->fp].registers[dest] = -((-value) >> 16); + frame.registers[dest] = -((-value) >> 16); } return true; @@ -357,8 +358,7 @@ bool step_vm(VM *vm) { vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - vm->frames[vm->fp].registers[dest] = - (vm->frames[vm->fp].registers[src1] << 16); + frame.registers[dest] = (frame.registers[src1] << 16); return true; } case OP_REAL_TO_UINT: { @@ -366,11 +366,11 @@ bool step_vm(VM *vm) { vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - value = vm->frames[vm->fp].registers[src1]; + value = frame.registers[src1]; if (value < 0) { - vm->frames[vm->fp].registers[dest] = 0; + frame.registers[dest] = 0; } else { - vm->frames[vm->fp].registers[dest] = AS_UINT(value >> 16); + frame.registers[dest] = AS_UINT(value >> 16); } return true; } @@ -379,8 +379,7 @@ bool step_vm(VM *vm) { vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - vm->frames[vm->fp].registers[dest] = - AS_INT(vm->frames[vm->fp].registers[src1] << 16); + frame.registers[dest] = AS_INT(frame.registers[src1] << 16); return true; } case OP_JEQ_UINT: { @@ -434,9 +433,9 @@ bool step_vm(VM *vm) { vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - int_to_string(AS_INT(vm->frames[vm->fp].registers[src1]), buffer); - ptr = str_alloc(vm, buffer, strlen(buffer)); - vm->frames[vm->fp].registers[dest] = ptr; + int_to_string(AS_INT(frame.registers[src1]), buffer); + ptr = str_alloc(vm, &frame, buffer, strlen(buffer)); + frame.registers[dest] = ptr; return true; } case OP_UINT_TO_STRING: { @@ -445,9 +444,9 @@ bool step_vm(VM *vm) { vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - uint_to_string(vm->frames[vm->fp].registers[src1], buffer); - ptr = str_alloc(vm, buffer, strlen(buffer)); - vm->frames[vm->fp].registers[dest] = ptr; + uint_to_string(frame.registers[src1], buffer); + ptr = str_alloc(vm, &frame, buffer, strlen(buffer)); + frame.registers[dest] = ptr; return true; } case OP_REAL_TO_STRING: { @@ -456,9 +455,10 @@ bool step_vm(VM *vm) { vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - fixed_to_string(AS_INT(vm->frames[vm->fp].registers[src1]), buffer); - ptr = str_alloc(vm, buffer, strlen(buffer)); /* copy buffer to dest */ - vm->frames[vm->fp].registers[dest] = ptr; + fixed_to_string(AS_INT(frame.registers[src1]), buffer); + ptr = + str_alloc(vm, &frame, buffer, strlen(buffer)); /* copy buffer to dest */ + frame.registers[dest] = ptr; return true; } case OP_STRLEN: { @@ -468,9 +468,9 @@ bool step_vm(VM *vm) { src1 = read_u8(vm, code, vm->pc); vm->pc++; - ptr = vm->frames[vm->fp].registers[src1]; + ptr = frame.registers[src1]; length = read_u32(vm, memory, ptr); - vm->frames[vm->fp].registers[dest] = length; + frame.registers[dest] = length; return true; } case OP_STRING_TO_INT: { diff --git a/src/vm.h b/src/vm.h index 0e3dade..45462f1 100644 --- a/src/vm.h +++ b/src/vm.h @@ -4,7 +4,7 @@ #include "opcodes.h" bool step_vm(VM *vm); -u32 str_alloc(VM *vm, const char *str, u32 length); +u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length); void fixed_to_string(i32 value, char *buffer); void int_to_string(i32 value, char *buffer); void uint_to_string(u32 value, char *buffer);