Optimizations, have return ask if it is a heap value, move lexer up
This commit is contained in:
parent
fbff4dd188
commit
197b8ee0ef
|
|
@ -0,0 +1,2 @@
|
||||||
|
.ccls-cache/
|
||||||
|
build/
|
||||||
|
|
@ -108,3 +108,5 @@ build/
|
||||||
.gdb_history
|
.gdb_history
|
||||||
.vscode
|
.vscode
|
||||||
.clangd
|
.clangd
|
||||||
|
.directory
|
||||||
|
perf.*
|
||||||
12
Makefile
12
Makefile
|
|
@ -44,8 +44,8 @@ ifeq ($(BUILD_MODE), release)
|
||||||
LDFLAGS += -s
|
LDFLAGS += -s
|
||||||
TARGET_SUFFIX := -release
|
TARGET_SUFFIX := -release
|
||||||
else
|
else
|
||||||
CORE_CFLAGS += -g -DDEBUG
|
CORE_CFLAGS += -O0 -ggdb3 -fno-omit-frame-pointer -DDEBUG
|
||||||
PLATFORM_CFLAGS += -g -DDEBUG
|
PLATFORM_CFLAGS += -O0 -ggdb3 -fno-omit-frame-pointer -DDEBUG
|
||||||
TARGET_SUFFIX := -debug
|
TARGET_SUFFIX := -debug
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
@ -91,14 +91,14 @@ ifeq ($(BUILD_MODE), release)
|
||||||
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
||||||
$(ARCH_DIR)/devices.c\
|
$(ARCH_DIR)/devices.c\
|
||||||
$(SRC_DIR)/tools/lexer.c \
|
$(SRC_DIR)/tools/lexer.c \
|
||||||
$(SRC_DIR)/tools/assembler/assembler.c \
|
$(SRC_DIR)/tools/assembler/assembler.c
|
||||||
$(SRC_DIR)/tools/compiler/compiler.c
|
# $(SRC_DIR)/tools/compiler/compiler.c
|
||||||
else
|
else
|
||||||
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
||||||
$(ARCH_DIR)/devices.c \
|
$(ARCH_DIR)/devices.c \
|
||||||
$(SRC_DIR)/tools/lexer.c \
|
$(SRC_DIR)/tools/lexer.c \
|
||||||
$(SRC_DIR)/tools/assembler/assembler.c \
|
$(SRC_DIR)/tools/assembler/assembler.c
|
||||||
$(SRC_DIR)/tools/compiler/compiler.c
|
# $(SRC_DIR)/tools/compiler/compiler.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# --- OBJECT FILES ---
|
# --- OBJECT FILES ---
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include "../../tools/compiler/compiler.h"
|
//#include "../../tools/compiler/compiler.h"
|
||||||
#include "../../tools/assembler/assembler.h"
|
#include "../../tools/assembler/assembler.h"
|
||||||
#include "../../vm/vm.h"
|
#include "../../vm/vm.h"
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
|
|
@ -225,8 +225,8 @@ bool compileAndSave(const char *source_file, const char *output_file, VM *vm) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
ScopeTable table = {0};
|
ScopeTable table = {0};
|
||||||
symbol_table_init(&table);
|
/* symbol_table_init(&table); */
|
||||||
compile(vm, &table, source);
|
/* compile(vm, &table, source); */
|
||||||
#ifndef STATIC
|
#ifndef STATIC
|
||||||
free(table.scopes);
|
free(table.scopes);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -340,7 +340,9 @@ i32 main(i32 argc, char *argv[]) {
|
||||||
&console_device_ops, 4);
|
&console_device_ops, 4);
|
||||||
|
|
||||||
if (terminal_only_mode) {
|
if (terminal_only_mode) {
|
||||||
while (step_vm(&vm));
|
while (step_vm(&vm)) {
|
||||||
|
//printf("code[%d] = %s\n", vm.pc, opcode_to_string(vm.code[vm.pc]));
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ void asm_emit_u32(VM *vm, u32 value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol *asm_symbol_table_lookup(ScopeTable *table, const char *name, u32 length,
|
Symbol *asm_symbol_table_lookup(ScopeTable *table, const char *name, u32 length,
|
||||||
i32 scope_ref) {
|
i32 scope_ref) {
|
||||||
SymbolTable st = table->scopes[scope_ref];
|
SymbolTable st = table->scopes[scope_ref];
|
||||||
for (u32 i = 0; i < st.count; i++) {
|
for (u32 i = 0; i < st.count; i++) {
|
||||||
if (st.symbols[i].name_length == length) {
|
if (st.symbols[i].name_length == length) {
|
||||||
|
|
@ -214,7 +214,8 @@ u8 asm_symbol_table_add(ScopeTable *table, Symbol s) {
|
||||||
printf("code[%d] = %s\n", s.ref, s.name);
|
printf("code[%d] = %s\n", s.ref, s.name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
table->scopes[table->scope_ref].symbols[table->scopes[table->scope_ref].count] = s;
|
table->scopes[table->scope_ref]
|
||||||
|
.symbols[table->scopes[table->scope_ref].count] = s;
|
||||||
u8 index = table->scopes[table->scope_ref].count;
|
u8 index = table->scopes[table->scope_ref].count;
|
||||||
table->scopes[table->scope_ref].count++;
|
table->scopes[table->scope_ref].count++;
|
||||||
return index;
|
return index;
|
||||||
|
|
@ -602,11 +603,8 @@ void asm_define_branch(VM *vm, ScopeTable *st) {
|
||||||
|
|
||||||
int asm_get_instruction_byte_size(const char *opname) {
|
int asm_get_instruction_byte_size(const char *opname) {
|
||||||
|
|
||||||
if (strcmp(opname, "return") == 0) {
|
if (strcmp(opname, "return") == 0 ||
|
||||||
return 2;
|
strcmp(opname, "neg_int") == 0 || strcmp(opname, "abs_int") == 0 ||
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(opname, "neg_int") == 0 || strcmp(opname, "abs_int") == 0 ||
|
|
||||||
strcmp(opname, "neg_nat") == 0 || strcmp(opname, "abs_nat") == 0 ||
|
strcmp(opname, "neg_nat") == 0 || strcmp(opname, "abs_nat") == 0 ||
|
||||||
strcmp(opname, "neg_real") == 0 || strcmp(opname, "abs_real") == 0 ||
|
strcmp(opname, "neg_real") == 0 || strcmp(opname, "abs_real") == 0 ||
|
||||||
strcmp(opname, "int_to_string") == 0 ||
|
strcmp(opname, "int_to_string") == 0 ||
|
||||||
|
|
@ -699,9 +697,9 @@ int asm_get_instruction_byte_size(const char *opname) {
|
||||||
token = next_token(); \
|
token = next_token(); \
|
||||||
} \
|
} \
|
||||||
/*printf("code[%d]=%s\n %d + %d = %d\n", vm->cp, op, \
|
/*printf("code[%d]=%s\n %d + %d = %d\n", vm->cp, op, \
|
||||||
* asm_get_instruction_byte_size(op), vm->cp, vm->cp + \
|
* asm_get_instruction_byte_size(op), vm->cp, vm->cp + \
|
||||||
* asm_get_instruction_byte_size(op)); */ \
|
* asm_get_instruction_byte_size(op)); */ \
|
||||||
vm->cp += asm_get_instruction_byte_size(op); \
|
vm->cp += asm_get_instruction_byte_size(op); \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -729,7 +727,8 @@ void asm_build_symbol_table(VM *vm, char *source, ScopeTable *st) {
|
||||||
if (token.type == TOKEN_RBRACE) {
|
if (token.type == TOKEN_RBRACE) {
|
||||||
i32 current_scope = st->scope_ref;
|
i32 current_scope = st->scope_ref;
|
||||||
i32 parent = st->scopes[current_scope].parent;
|
i32 parent = st->scopes[current_scope].parent;
|
||||||
if (parent < 0) parent = 0;
|
if (parent < 0)
|
||||||
|
parent = 0;
|
||||||
st->scope_ref = parent;
|
st->scope_ref = parent;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -773,6 +772,15 @@ void asm_build_symbol_table(VM *vm, char *source, ScopeTable *st) {
|
||||||
|
|
||||||
asm_get_reg(next, st);
|
asm_get_reg(next, st);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
|
|
||||||
|
next = next_token();
|
||||||
|
if (next.type == TOKEN_SEMICOLON) {
|
||||||
|
/* assume it is not a heap value */
|
||||||
|
vm->cp++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
vm->cp++;
|
||||||
asm_next_token_is(TOKEN_SEMICOLON);
|
asm_next_token_is(TOKEN_SEMICOLON);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -959,7 +967,8 @@ void asm_emit_bytecode(VM *vm, char *source, ScopeTable *st) {
|
||||||
if (token.type == TOKEN_RBRACE) {
|
if (token.type == TOKEN_RBRACE) {
|
||||||
i32 current_scope = st->scope_ref;
|
i32 current_scope = st->scope_ref;
|
||||||
i32 parent = st->scopes[current_scope].parent;
|
i32 parent = st->scopes[current_scope].parent;
|
||||||
if (parent < 0) parent = 0;
|
if (parent < 0)
|
||||||
|
parent = 0;
|
||||||
st->scope_ref = parent;
|
st->scope_ref = parent;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1012,12 +1021,40 @@ void asm_emit_bytecode(VM *vm, char *source, ScopeTable *st) {
|
||||||
/* put 0xFF as return register */
|
/* put 0xFF as return register */
|
||||||
asm_emit_byte(vm, 0xFF);
|
asm_emit_byte(vm, 0xFF);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
|
|
||||||
|
/* if no return then also no heap */
|
||||||
|
asm_emit_byte(vm, false);
|
||||||
|
vm->cp++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 reg = asm_get_reg(next, st);
|
u32 reg = asm_get_reg(next, st);
|
||||||
asm_emit_byte(vm, reg);
|
asm_emit_byte(vm, reg);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
|
|
||||||
|
next = next_token();
|
||||||
|
if (next.type == TOKEN_SEMICOLON) {
|
||||||
|
/* assume it is not a heap value */
|
||||||
|
asm_emit_byte(vm, false);
|
||||||
|
vm->cp++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (next.type) {
|
||||||
|
case TOKEN_KEYWORD_TRUE: {
|
||||||
|
asm_emit_byte(vm, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TOKEN_KEYWORD_FALSE: {
|
||||||
|
asm_emit_byte(vm, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printf("Error: must be true or false for if it is a heap value");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
vm->cp++;
|
||||||
|
|
||||||
asm_next_token_is(TOKEN_SEMICOLON);
|
asm_next_token_is(TOKEN_SEMICOLON);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define UNDAR_CODEGEN_H
|
#define UNDAR_CODEGEN_H
|
||||||
|
|
||||||
#include "../vm/common.h"
|
#include "../vm/common.h"
|
||||||
|
#include "lexer.h"
|
||||||
|
|
||||||
typedef enum { GLOBAL, LOCAL, VAR } ScopeType;
|
typedef enum { GLOBAL, LOCAL, VAR } ScopeType;
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
@ -66,6 +67,7 @@ struct symbol_s {
|
||||||
char name[MAX_SYMBOL_NAME_LENGTH];
|
char name[MAX_SYMBOL_NAME_LENGTH];
|
||||||
u8 name_length;
|
u8 name_length;
|
||||||
SymbolType type;
|
SymbolType type;
|
||||||
|
TokenType return_type;
|
||||||
ScopeType scope;
|
ScopeType scope;
|
||||||
u32 ref; // vm->mp if global, vm->pc local, register if var
|
u32 ref; // vm->mp if global, vm->pc local, register if var
|
||||||
u32 size; // size of symbol
|
u32 size; // size of symbol
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ static char advance() {
|
||||||
return lexer.current[-1];
|
return lexer.current[-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static char peek() { return *lexer.current; }
|
char peek() { return *lexer.current; }
|
||||||
|
|
||||||
static char peek_next() {
|
static char peek_next() {
|
||||||
if (is_at_end())
|
if (is_at_end())
|
||||||
|
|
|
||||||
|
|
@ -86,5 +86,6 @@ typedef struct {
|
||||||
void init_lexer(const char *source);
|
void init_lexer(const char *source);
|
||||||
Token next_token();
|
Token next_token();
|
||||||
const char* token_type_to_string(TokenType type);
|
const char* token_type_to_string(TokenType type);
|
||||||
|
char peek();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,6 @@ typedef enum {
|
||||||
|
|
||||||
#define MAX_LOCALS 256
|
#define MAX_LOCALS 256
|
||||||
typedef struct frame_s {
|
typedef struct frame_s {
|
||||||
u32 heap_mask[8];
|
|
||||||
u32 locals[MAX_LOCALS]; /* $0-$255 */
|
u32 locals[MAX_LOCALS]; /* $0-$255 */
|
||||||
u32 start; /* start of memory block */
|
u32 start; /* start of memory block */
|
||||||
u32 end; /* end of memory block */
|
u32 end; /* end of memory block */
|
||||||
|
|
|
||||||
67
src/vm/vm.c
67
src/vm/vm.c
|
|
@ -16,7 +16,7 @@ const char radix_set[11] = "0123456789";
|
||||||
u8 src1, src2; \
|
u8 src1, src2; \
|
||||||
type value; \
|
type value; \
|
||||||
type value2; \
|
type value2; \
|
||||||
target = read_u32(vm, code, vm->pc); \
|
target = *code_u32; \
|
||||||
vm->pc += 4; \
|
vm->pc += 4; \
|
||||||
src1 = read_u8(vm, code, vm->pc); \
|
src1 = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
|
|
@ -58,23 +58,6 @@ const char radix_set[11] = "0123456789";
|
||||||
return true; \
|
return true; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Set heap status for a register in current frame */
|
|
||||||
void set_heap_status(VM *vm, u8 reg, bool is_heap) {
|
|
||||||
u32 index = reg / 32;
|
|
||||||
u32 mask = 1 << (reg % 32);
|
|
||||||
|
|
||||||
if (is_heap) {
|
|
||||||
vm->frames[vm->fp].heap_mask[index] |= mask;
|
|
||||||
} else {
|
|
||||||
vm->frames[vm->fp].heap_mask[index] &= ~mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if register contains heap pointer */
|
|
||||||
bool is_heap_value(VM *vm, u8 reg) {
|
|
||||||
u32 index = reg / 32;
|
|
||||||
return (vm->frames[vm->fp].heap_mask[index] >> (reg % 32)) & 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 str_alloc(VM *vm, Frame *frame, 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;
|
||||||
|
|
@ -95,20 +78,20 @@ u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length) {
|
||||||
*/
|
*/
|
||||||
bool step_vm(VM *vm) {
|
bool step_vm(VM *vm) {
|
||||||
/* Get current instruction & Advance to next instruction */
|
/* Get current instruction & Advance to next instruction */
|
||||||
u8 opcode = vm->code[vm->pc++];
|
|
||||||
Frame *frame = &vm->frames[vm->fp];
|
Frame *frame = &vm->frames[vm->fp];
|
||||||
|
u8 opcode = vm->code[vm->pc++];
|
||||||
|
u32 *code_u32 = (u32*)(&vm->code[vm->pc]);
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case OP_EXIT: {
|
case OP_EXIT: {
|
||||||
vm->flag = read_u32(vm, code, vm->pc);
|
vm->flag = *code_u32;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case OP_CALL: {
|
case OP_CALL: {
|
||||||
u8 N, return_reg, src_reg, args[MAX_LOCALS];
|
u8 N, return_reg, src_reg, args[MAX_LOCALS];
|
||||||
Frame *child;
|
Frame *child;
|
||||||
u32 jmp, mask, i;
|
u32 jmp, i;
|
||||||
|
jmp = *code_u32;
|
||||||
jmp = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
N = vm->code[vm->pc++];
|
N = vm->code[vm->pc++];
|
||||||
|
|
||||||
|
|
@ -135,16 +118,13 @@ bool step_vm(VM *vm) {
|
||||||
for (i = 0; i < N; i++) {
|
for (i = 0; i < N; i++) {
|
||||||
src_reg = args[i];
|
src_reg = args[i];
|
||||||
child->locals[i] = frame->locals[src_reg];
|
child->locals[i] = frame->locals[src_reg];
|
||||||
mask = 1 << (src_reg % 32);
|
|
||||||
if (frame->heap_mask[src_reg / 32] & mask) {
|
|
||||||
child->heap_mask[i / 32] |= 1 << (i % 32);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vm->pc = jmp;
|
vm->pc = jmp;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_RETURN: {
|
case OP_RETURN: {
|
||||||
|
bool is_heap_value;
|
||||||
u8 child_return_reg;
|
u8 child_return_reg;
|
||||||
u32 value;
|
u32 value;
|
||||||
u32 ptr;
|
u32 ptr;
|
||||||
|
|
@ -154,13 +134,14 @@ bool step_vm(VM *vm) {
|
||||||
Frame *parent;
|
Frame *parent;
|
||||||
|
|
||||||
child_return_reg = vm->code[vm->pc++];
|
child_return_reg = vm->code[vm->pc++];
|
||||||
|
is_heap_value = vm->code[vm->pc++];
|
||||||
child = frame;
|
child = frame;
|
||||||
parent = &vm->frames[vm->fp - 1];
|
parent = &vm->frames[vm->fp - 1];
|
||||||
|
|
||||||
if (child_return_reg != 0xFF && parent->return_reg != 0xFF) {
|
if (child_return_reg != 0xFF) {
|
||||||
value = child->locals[child_return_reg];
|
value = child->locals[child_return_reg];
|
||||||
|
|
||||||
if (is_heap_value(vm, child_return_reg)) {
|
if (is_heap_value) {
|
||||||
ptr = value;
|
ptr = value;
|
||||||
size = *(u32 *)(vm->memory + ptr - 4);
|
size = *(u32 *)(vm->memory + ptr - 4);
|
||||||
new_ptr = parent->end;
|
new_ptr = parent->end;
|
||||||
|
|
@ -171,11 +152,8 @@ bool step_vm(VM *vm) {
|
||||||
memcopy(vm->memory + new_ptr + 4, vm->memory + ptr + 4, size);
|
memcopy(vm->memory + new_ptr + 4, vm->memory + ptr + 4, size);
|
||||||
parent->end += size + 4;
|
parent->end += size + 4;
|
||||||
parent->locals[parent->return_reg] = new_ptr;
|
parent->locals[parent->return_reg] = new_ptr;
|
||||||
parent->heap_mask[parent->return_reg / 32] |= (1 << parent->return_reg);
|
|
||||||
} else {
|
} else {
|
||||||
parent->locals[parent->return_reg] = value;
|
parent->locals[parent->return_reg] = value;
|
||||||
parent->heap_mask[parent->return_reg / 32] &=
|
|
||||||
~(1 << parent->return_reg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,7 +165,7 @@ bool step_vm(VM *vm) {
|
||||||
case OP_LOAD_IMM: {
|
case OP_LOAD_IMM: {
|
||||||
u32 v;
|
u32 v;
|
||||||
u8 dest;
|
u8 dest;
|
||||||
v = read_u32(vm, code, vm->pc);
|
v = *code_u32;
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
dest = read_u8(vm, code, vm->pc);
|
dest = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
@ -205,13 +183,12 @@ bool step_vm(VM *vm) {
|
||||||
size = frame->locals[src1];
|
size = frame->locals[src1];
|
||||||
write_u32(vm, memory, vm->mp, size);
|
write_u32(vm, memory, vm->mp, size);
|
||||||
vm->mp += (size + 4);
|
vm->mp += (size + 4);
|
||||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_ABS_32: {
|
case OP_LOAD_ABS_32: {
|
||||||
u32 v, ptr;
|
u32 v, ptr;
|
||||||
u8 dest;
|
u8 dest;
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
ptr = *code_u32;
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = read_u32(vm, memory, ptr);
|
v = read_u32(vm, memory, ptr);
|
||||||
dest = read_u8(vm, code, vm->pc);
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
|
@ -222,7 +199,7 @@ bool step_vm(VM *vm) {
|
||||||
case OP_LOAD_ABS_16: {
|
case OP_LOAD_ABS_16: {
|
||||||
u32 v, ptr;
|
u32 v, ptr;
|
||||||
u8 dest;
|
u8 dest;
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
ptr = *code_u32;
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = read_u16(vm, memory, ptr);
|
v = read_u16(vm, memory, ptr);
|
||||||
dest = read_u8(vm, code, vm->pc);
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
|
@ -233,7 +210,7 @@ bool step_vm(VM *vm) {
|
||||||
case OP_LOAD_ABS_8: {
|
case OP_LOAD_ABS_8: {
|
||||||
u32 v, ptr;
|
u32 v, ptr;
|
||||||
u8 dest;
|
u8 dest;
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
ptr = *code_u32;
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = read_u8(vm, memory, ptr);
|
v = read_u8(vm, memory, ptr);
|
||||||
dest = read_u8(vm, code, vm->pc);
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
|
@ -544,23 +521,16 @@ bool step_vm(VM *vm) {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
dest = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame->locals[dest] = frame->locals[src1];
|
frame->locals[dest] = frame->locals[src1];
|
||||||
|
|
||||||
if (is_heap_value(vm, src1)) {
|
|
||||||
set_heap_status(vm, dest, true);
|
|
||||||
} else {
|
|
||||||
set_heap_status(vm, dest, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_JMP: {
|
case OP_JMP: {
|
||||||
u32 jmp = read_u32(vm, code, vm->pc);
|
u32 jmp = *code_u32;
|
||||||
vm->pc = jmp; /* Jump to address */
|
vm->pc = jmp; /* Jump to address */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_JMPF: { /* error handling for syscall, jump if flag == 0 */
|
case OP_JMPF: { /* error handling for syscall, jump if flag == 0 */
|
||||||
u32 mask;
|
u32 mask;
|
||||||
u32 jmp = read_u32(vm, code, vm->pc);
|
u32 jmp = *code_u32;
|
||||||
mask = -(u32)(vm->flag == 0);
|
mask = -(u32)(vm->flag == 0);
|
||||||
vm->pc = (jmp & mask) | (vm->pc & ~mask);
|
vm->pc = (jmp & mask) | (vm->pc & ~mask);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -568,7 +538,7 @@ bool step_vm(VM *vm) {
|
||||||
case OP_SYSCALL: {
|
case OP_SYSCALL: {
|
||||||
u32 syscall_id;
|
u32 syscall_id;
|
||||||
|
|
||||||
syscall_id = read_u32(vm, code, vm->pc);
|
syscall_id = *code_u32;
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
|
|
||||||
switch (syscall_id) {
|
switch (syscall_id) {
|
||||||
|
|
@ -966,7 +936,6 @@ bool step_vm(VM *vm) {
|
||||||
buffer[--i] = '0';
|
buffer[--i] = '0';
|
||||||
|
|
||||||
frame->locals[dest] = str_alloc(vm, frame, buffer + i, MAX_LEN_INT32 - i);
|
frame->locals[dest] = str_alloc(vm, frame, buffer + i, MAX_LEN_INT32 - i);
|
||||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_NAT_TO_STRING: {
|
case OP_NAT_TO_STRING: {
|
||||||
|
|
@ -991,7 +960,6 @@ bool step_vm(VM *vm) {
|
||||||
buffer[--i] = '0';
|
buffer[--i] = '0';
|
||||||
/* Copy from buffer[i] to buffer + MAX_LEN_INT32 */
|
/* Copy from buffer[i] to buffer + MAX_LEN_INT32 */
|
||||||
frame->locals[dest] = str_alloc(vm, frame, buffer + i, MAX_LEN_INT32 - i);
|
frame->locals[dest] = str_alloc(vm, frame, buffer + i, MAX_LEN_INT32 - i);
|
||||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_STRING: {
|
case OP_REAL_TO_STRING: {
|
||||||
|
|
@ -1036,7 +1004,6 @@ bool step_vm(VM *vm) {
|
||||||
buffer[--i] = '-';
|
buffer[--i] = '-';
|
||||||
|
|
||||||
frame->locals[dest] = str_alloc(vm, frame, buffer + i, MAX_LEN_REAL32 - i);
|
frame->locals[dest] = str_alloc(vm, frame, buffer + i, MAX_LEN_REAL32 - i);
|
||||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_STRLEN: {
|
case OP_STRLEN: {
|
||||||
|
|
|
||||||
BIN
test/add.rom
BIN
test/add.rom
Binary file not shown.
BIN
test/fib.rom
BIN
test/fib.rom
Binary file not shown.
BIN
test/hello.rom
BIN
test/hello.rom
Binary file not shown.
BIN
test/loop.rom
BIN
test/loop.rom
Binary file not shown.
BIN
test/malloc.rom
BIN
test/malloc.rom
Binary file not shown.
Binary file not shown.
BIN
test/paint.rom
BIN
test/paint.rom
Binary file not shown.
BIN
test/simple.rom
BIN
test/simple.rom
Binary file not shown.
BIN
test/window.rom
BIN
test/window.rom
Binary file not shown.
Loading…
Reference in New Issue