add branchless jmps

This commit is contained in:
zongor 2025-09-20 10:05:52 -07:00
parent cf0318e96f
commit 2d72240652
4 changed files with 151 additions and 132 deletions

View File

@ -6,6 +6,7 @@
typedef enum { typedef enum {
OP_HALT, /* halt : terminate execution */ OP_HALT, /* halt : terminate execution */
OP_JMP, /* jump : jump to address dest unconditionally */ 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_CALL, /* call : creates a new frame */
OP_RETURN, /* retn : returns from a frame to the parent frame */ OP_RETURN, /* retn : returns from a frame to the parent frame */
OP_LOAD, /* load : dest = &[next memory location] */ OP_LOAD, /* load : dest = &[next memory location] */
@ -47,6 +48,11 @@ typedef enum {
OP_JLT_REAL, /* jler : 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_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_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_INT_TO_STRING, /* itos : dest = src1 as str */
OP_UINT_TO_STRING, /* utos : dest = src1 as str */ OP_UINT_TO_STRING, /* utos : dest = src1 as str */
OP_REAL_TO_STRING, /* rtos : dest = src1 as str */ OP_REAL_TO_STRING, /* rtos : dest = src1 as str */

View File

@ -48,16 +48,21 @@ bool compile_internal_test(const char *filename, VM *vm) {
bool test_simple_compile(VM *vm) { bool test_simple_compile(VM *vm) {
u32 ptr; 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++] = OP_LOAD;
vm->code[vm->cp++] = 0; vm->code[vm->cp++] = 0;
ptr = real_alloc(vm, 1.0f); 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++] = OP_LOAD;
vm->code[vm->cp++] = 1; vm->code[vm->cp++] = 1;
ptr = real_alloc(vm, 2.0f); 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++] = OP_ADD_REAL;
vm->code[vm->cp++] = 2; vm->code[vm->cp++] = 2;
@ -68,16 +73,22 @@ bool test_simple_compile(VM *vm) {
vm->code[vm->cp++] = 3; vm->code[vm->cp++] = 3;
vm->code[vm->cp++] = 2; 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++] = OP_LOAD_IMM;
vm->code[vm->cp++] = 2; 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++] = OP_STRLEN;
vm->code[vm->cp++] = 4; vm->code[vm->cp++] = 4;
vm->code[vm->cp++] = 3; vm->code[vm->cp++] = 3;
vm->code[vm->cp++] = OP_SYSCALL; 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++] = 3; /* arg_count */
vm->code[vm->cp++] = 2; /* first_reg */ vm->code[vm->cp++] = 2; /* first_reg */
/* syscall_id=WRITE, arg_count=2, start_reg=3 ; print(sum.toS()); */ /* 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) { 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++] = OP_LOAD; /* R0 = screen path */
vm->code[vm->cp++] = 0; vm->code[vm->cp++] = 0;

148
src/vm.c
View File

@ -3,19 +3,25 @@
#include "opcodes.h" #include "opcodes.h"
#include "str.h" #include "str.h"
/* no inline fn in ANSI C :( */
#define COMPARE_AND_JUMP(type, op) \ #define COMPARE_AND_JUMP(type, op) \
do { \ do { \
type value, value2; \ i32 cond; \
u32 mask, target; \
u8 dest, src1, src2; \
type value; \
type value2; \
dest = read_u8(vm, code, vm->pc); \ dest = read_u8(vm, code, vm->pc); \
vm->pc++; \ vm->pc++; \
src1 = read_u8(vm, code, vm->pc); \ src1 = read_u8(vm, code, vm->pc); \
vm->pc++; \ vm->pc++; \
src2 = read_u8(vm, code, vm->pc); \ src2 = read_u8(vm, code, vm->pc); \
vm->pc++; \ vm->pc++; \
value = vm->frames[vm->fp].registers[src1]; \ value = frame.registers[src1]; \
value2 = vm->frames[vm->fp].registers[src2]; \ value2 = frame.registers[src2]; \
vm->pc = (value op value2) ? vm->frames[vm->fp].registers[dest] : vm->pc; \ cond = !!(value op value2); \
mask = -(u32)cond; \
target = frame.registers[dest]; \
vm->pc = (target & mask) | (vm->pc & ~mask); \
return true; \ return true; \
} while (0) } while (0)
@ -27,14 +33,12 @@
vm->pc++; \ vm->pc++; \
src2 = read_u8(vm, code, vm->pc); \ src2 = read_u8(vm, code, vm->pc); \
vm->pc++; \ vm->pc++; \
vm->frames[vm->fp].registers[dest] = (type)vm->frames[vm->fp] \ frame.registers[dest] = \
.registers[src1] op(type) \ (type)frame.registers[src1] op(type) frame.registers[src2]; \
vm->frames[vm->fp] \
.registers[src2]; \
return true; \ return true; \
} while (0) } 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 str_addr = vm->mp;
u32 i = 0; u32 i = 0;
vm->mp += 4; vm->mp += 4;
@ -44,7 +48,7 @@ u32 str_alloc(VM *vm, const char *str, u32 length) {
vm->memory[vm->mp++] = '\0'; vm->memory[vm->mp++] = '\0';
write_u32(vm, memory, str_addr, length); write_u32(vm, memory, str_addr, length);
vm->frames[vm->fp].end = vm->mp; frame->end = vm->mp;
return str_addr; return str_addr;
} }
@ -55,9 +59,11 @@ bool step_vm(VM *vm) {
u8 opcode, dest, src1, src2; u8 opcode, dest, src1, src2;
u32 v, ptr; u32 v, ptr;
i32 value; i32 value;
Frame frame;
/* Get current instruction & Advance to next instruction */ /* Get current instruction & Advance to next instruction */
opcode = vm->code[vm->pc++]; opcode = vm->code[vm->pc++];
frame = vm->frames[vm->fp];
switch (opcode) { switch (opcode) {
case OP_HALT: { case OP_HALT: {
@ -73,7 +79,7 @@ bool step_vm(VM *vm) {
return true; return true;
} }
case OP_RETURN: { 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->pc = vm->return_stack[--vm->rp]; /* set pc to return address */
vm->mp = vm->mp =
vm->frames[vm->fp--].start; /* reset memory pointer to start vm->frames[vm->fp--].start; /* reset memory pointer to start
@ -85,7 +91,7 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
v = read_u32(vm, code, vm->pc); v = read_u32(vm, code, vm->pc);
vm->pc += 4; vm->pc += 4;
vm->frames[vm->fp].registers[dest] = v; frame.registers[dest] = v;
return true; return true;
} }
case OP_LOAD: { case OP_LOAD: {
@ -94,7 +100,7 @@ bool step_vm(VM *vm) {
ptr = read_u32(vm, code, vm->pc); ptr = read_u32(vm, code, vm->pc);
vm->pc += 4; vm->pc += 4;
v = read_u32(vm, memory, ptr); v = read_u32(vm, memory, ptr);
vm->frames[vm->fp].registers[dest] = v; frame.registers[dest] = v;
return true; return true;
} }
case OP_STORE: { case OP_STORE: {
@ -102,20 +108,20 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
ptr = read_u32(vm, code, vm->pc); ptr = read_u32(vm, code, vm->pc);
vm->pc += 4; vm->pc += 4;
v = vm->frames[vm->fp].registers[src1]; v = frame.registers[src1];
write_u32(vm, memory, ptr, v); write_u32(vm, memory, ptr, v);
return true; return true;
} }
case OP_PUSH: { case OP_PUSH: {
dest = read_u8(vm, code, vm->pc); dest = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
vm->stack[++vm->sp] = vm->frames[vm->fp].registers[dest]; vm->stack[++vm->sp] = frame.registers[dest];
return true; return true;
} }
case OP_POP: { case OP_POP: {
dest = read_u8(vm, code, vm->pc); dest = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
vm->frames[vm->fp].registers[dest] = vm->stack[vm->sp--]; frame.registers[dest] = vm->stack[vm->sp--];
return true; return true;
} }
case OP_REG_MOV: { case OP_REG_MOV: {
@ -123,13 +129,21 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src1 = read_u8(vm, code, vm->pc); src1 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
vm->frames[vm->fp].registers[dest] = vm->frames[vm->fp].registers[src1]; frame.registers[dest] = frame.registers[src1];
return true; return true;
} }
case OP_JMP: { case OP_JMP: {
dest = read_u8(vm, code, vm->pc); dest = read_u8(vm, code, vm->pc);
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; return true;
} }
case OP_SYSCALL: { case OP_SYSCALL: {
@ -148,9 +162,8 @@ bool step_vm(VM *vm) {
if (arg_count >= 2) { if (arg_count >= 2) {
Device *dev; Device *dev;
u32 path_ptr, mode; u32 path_ptr, mode;
path_ptr = path_ptr = frame.registers[first_reg]; /* R0: path pointer */
vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ mode = frame.registers[first_reg + 1]; /* R1: mode */
mode = vm->frames[vm->fp].registers[first_reg + 1]; /* R1: mode */
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
if (dev) { if (dev) {
@ -173,11 +186,9 @@ bool step_vm(VM *vm) {
Device *dev; Device *dev;
u32 path_ptr, buffer_ptr, size; u32 path_ptr, buffer_ptr, size;
path_ptr = path_ptr = frame.registers[first_reg]; /* R0: path pointer */
vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ buffer_ptr = frame.registers[first_reg + 1]; /* R1: buffer pointer */
buffer_ptr = vm->frames[vm->fp] size = frame.registers[first_reg + 2]; /* R2: size */
.registers[first_reg + 1]; /* R1: buffer pointer */
size = vm->frames[vm->fp].registers[first_reg + 2]; /* R2: size */
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
if (dev && dev->ops->read) { if (dev && dev->ops->read) {
@ -193,19 +204,17 @@ bool step_vm(VM *vm) {
} }
case SYSCALL_DEVICE_WRITE: { case SYSCALL_DEVICE_WRITE: {
if (arg_count >= 2) { if (arg_count >= 3) {
Device *dev; Device *dev;
u32 path_ptr, buffer_ptr, size; u32 path_ptr, buffer_ptr, size;
path_ptr = path_ptr = frame.registers[first_reg]; /* R0: path pointer */
vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ buffer_ptr = frame.registers[first_reg + 1]; /* R1: buffer pointer */
buffer_ptr = vm->frames[vm->fp] size = frame.registers[first_reg + 2]; /* R2: size */
.registers[first_reg + 1]; /* R1: buffer pointer */
size = vm->frames[vm->fp].registers[first_reg + 2]; /* R2: size */
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
if (dev && dev->ops->write) { if (dev && dev->ops->write) {
vm->flag = dev->ops->write(dev->data, (const u8 *)&vm->memory[buffer_ptr + 4], vm->flag = dev->ops->write(
size); dev->data, (const u8 *)&vm->memory[buffer_ptr + 4], size);
} else { } else {
vm->flag = 0; vm->flag = 0;
} }
@ -219,8 +228,7 @@ bool step_vm(VM *vm) {
if (arg_count >= 1) { if (arg_count >= 1) {
Device *dev; Device *dev;
u32 path_ptr; u32 path_ptr;
path_ptr = path_ptr = frame.registers[first_reg]; /* R0: path pointer */
vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); 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) { if (arg_count >= 3) {
Device *dev; Device *dev;
u32 path_ptr, args_ptr, cmd; u32 path_ptr, args_ptr, cmd;
path_ptr = path_ptr = frame.registers[first_reg]; /* R0: device path */
vm->frames[vm->fp].registers[first_reg]; /* R0: device path */ cmd = frame.registers[first_reg + 1]; /* R1: ioctl command */
cmd = args_ptr = frame.registers[first_reg + 2]; /* R2: args pointer */
vm->frames[vm->fp].registers[first_reg + 1]; /* R1: ioctl command */
args_ptr =
vm->frames[vm->fp].registers[first_reg + 2]; /* R2: args pointer */
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
@ -295,9 +300,8 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src2 = read_u8(vm, code, vm->pc); src2 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
vm->frames[vm->fp].registers[dest] = (vm->frames[vm->fp].registers[src1] * frame.registers[dest] =
vm->frames[vm->fp].registers[src2]) >> (frame.registers[src1] * frame.registers[src2]) >> 16;
16;
return true; return true;
} }
@ -308,9 +312,8 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src2 = read_u8(vm, code, vm->pc); src2 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
vm->frames[vm->fp].registers[dest] = frame.registers[dest] =
(vm->frames[vm->fp].registers[src1] << 16) / (frame.registers[src1] << 16) / frame.registers[src2];
vm->frames[vm->fp].registers[src2];
return true; return true;
} }
@ -321,8 +324,7 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src2 = read_u8(vm, code, vm->pc); src2 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
vm->frames[vm->fp].registers[dest] = frame.registers[dest] = frame.registers[src1] + frame.registers[src2];
vm->frames[vm->fp].registers[src1] + vm->frames[vm->fp].registers[src2];
return true; return true;
} }
@ -333,8 +335,7 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src2 = read_u8(vm, code, vm->pc); src2 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
vm->frames[vm->fp].registers[dest] = frame.registers[dest] = frame.registers[src1] - frame.registers[src2];
vm->frames[vm->fp].registers[src1] - vm->frames[vm->fp].registers[src2];
return true; return true;
} }
case OP_REAL_TO_INT: { case OP_REAL_TO_INT: {
@ -342,12 +343,12 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src1 = read_u8(vm, code, vm->pc); src1 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
value = vm->frames[vm->fp].registers[src1]; value = frame.registers[src1];
if (value >= 0) { if (value >= 0) {
vm->frames[vm->fp].registers[dest] = value >> 16; frame.registers[dest] = value >> 16;
} else { } else {
vm->frames[vm->fp].registers[dest] = -((-value) >> 16); frame.registers[dest] = -((-value) >> 16);
} }
return true; return true;
@ -357,8 +358,7 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src1 = read_u8(vm, code, vm->pc); src1 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
vm->frames[vm->fp].registers[dest] = frame.registers[dest] = (frame.registers[src1] << 16);
(vm->frames[vm->fp].registers[src1] << 16);
return true; return true;
} }
case OP_REAL_TO_UINT: { case OP_REAL_TO_UINT: {
@ -366,11 +366,11 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src1 = read_u8(vm, code, vm->pc); src1 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
value = vm->frames[vm->fp].registers[src1]; value = frame.registers[src1];
if (value < 0) { if (value < 0) {
vm->frames[vm->fp].registers[dest] = 0; frame.registers[dest] = 0;
} else { } else {
vm->frames[vm->fp].registers[dest] = AS_UINT(value >> 16); frame.registers[dest] = AS_UINT(value >> 16);
} }
return true; return true;
} }
@ -379,8 +379,7 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src1 = read_u8(vm, code, vm->pc); src1 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
vm->frames[vm->fp].registers[dest] = frame.registers[dest] = AS_INT(frame.registers[src1] << 16);
AS_INT(vm->frames[vm->fp].registers[src1] << 16);
return true; return true;
} }
case OP_JEQ_UINT: { case OP_JEQ_UINT: {
@ -434,9 +433,9 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src1 = read_u8(vm, code, vm->pc); src1 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
int_to_string(AS_INT(vm->frames[vm->fp].registers[src1]), buffer); int_to_string(AS_INT(frame.registers[src1]), buffer);
ptr = str_alloc(vm, buffer, strlen(buffer)); ptr = str_alloc(vm, &frame, buffer, strlen(buffer));
vm->frames[vm->fp].registers[dest] = ptr; frame.registers[dest] = ptr;
return true; return true;
} }
case OP_UINT_TO_STRING: { case OP_UINT_TO_STRING: {
@ -445,9 +444,9 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src1 = read_u8(vm, code, vm->pc); src1 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
uint_to_string(vm->frames[vm->fp].registers[src1], buffer); uint_to_string(frame.registers[src1], buffer);
ptr = str_alloc(vm, buffer, strlen(buffer)); ptr = str_alloc(vm, &frame, buffer, strlen(buffer));
vm->frames[vm->fp].registers[dest] = ptr; frame.registers[dest] = ptr;
return true; return true;
} }
case OP_REAL_TO_STRING: { case OP_REAL_TO_STRING: {
@ -456,9 +455,10 @@ bool step_vm(VM *vm) {
vm->pc++; vm->pc++;
src1 = read_u8(vm, code, vm->pc); src1 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
fixed_to_string(AS_INT(vm->frames[vm->fp].registers[src1]), buffer); fixed_to_string(AS_INT(frame.registers[src1]), buffer);
ptr = str_alloc(vm, buffer, strlen(buffer)); /* copy buffer to dest */ ptr =
vm->frames[vm->fp].registers[dest] = ptr; str_alloc(vm, &frame, buffer, strlen(buffer)); /* copy buffer to dest */
frame.registers[dest] = ptr;
return true; return true;
} }
case OP_STRLEN: { case OP_STRLEN: {
@ -468,9 +468,9 @@ bool step_vm(VM *vm) {
src1 = read_u8(vm, code, vm->pc); src1 = read_u8(vm, code, vm->pc);
vm->pc++; vm->pc++;
ptr = vm->frames[vm->fp].registers[src1]; ptr = frame.registers[src1];
length = read_u32(vm, memory, ptr); length = read_u32(vm, memory, ptr);
vm->frames[vm->fp].registers[dest] = length; frame.registers[dest] = length;
return true; return true;
} }
case OP_STRING_TO_INT: { case OP_STRING_TO_INT: {

View File

@ -4,7 +4,7 @@
#include "opcodes.h" #include "opcodes.h"
bool step_vm(VM *vm); 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 fixed_to_string(i32 value, char *buffer);
void int_to_string(i32 value, char *buffer); void int_to_string(i32 value, char *buffer);
void uint_to_string(u32 value, char *buffer); void uint_to_string(u32 value, char *buffer);