Interpreter - bounds checking

This commit is contained in:
Ginger Bill
2016-10-31 00:10:31 +00:00
parent 5271adb82f
commit fa0eb88b7b
3 changed files with 72 additions and 14 deletions
+3 -1
View File
@@ -24,7 +24,9 @@ set compiler_warnings= ^
-wd4505 -wd4512 -wd4550 -wd4505 -wd4512 -wd4550
set compiler_includes= set compiler_includes=
set libs= kernel32.lib set libs= ^
kernel32.lib ^
"src\dyncall\lib\*.lib"
set linker_flags= -incremental:no -opt:ref -subsystem:console set linker_flags= -incremental:no -opt:ref -subsystem:console
+3 -5
View File
@@ -166,19 +166,17 @@ int main(int argc, char **argv) {
ssa_gen_tree(&ssa); ssa_gen_tree(&ssa);
#if 1
{ {
VirtualMachine vm = {}; VirtualMachine vm = {};
vm_init(&vm, &ssa.module); vm_init(&vm, &ssa.module);
defer (vm_destroy(&vm)); defer (vm_destroy(&vm));
String name = make_string("main"); ssaProcedure *start_proc = vm_lookup_procedure(&vm, make_string("main"));
ssaValue *main_proc_value = *map_get(&vm.module->members, hash_string(name));
GB_ASSERT(main_proc_value->kind == ssaValue_Proc);
ssaProcedure *start_proc = &main_proc_value->Proc;
Array<vmValue> args = {}; // Empty Array<vmValue> args = {}; // Empty
vm_call_procedure(&vm, start_proc, args); vm_call_procedure(&vm, start_proc, args);
} }
#endif
{ {
ssaFileBuffer buf = {}; ssaFileBuffer buf = {};
+66 -8
View File
@@ -566,6 +566,12 @@ vmValue vm_load(VirtualMachine *vm, void *ptr, Type *type) {
return result; return result;
} }
ssaProcedure *vm_lookup_procedure(VirtualMachine *vm, String name) {
ssaValue *v = ssa_lookup_member(vm->module, name);
GB_ASSERT(v->kind == ssaValue_Proc);
ssaProcedure *proc = &v->Proc;
return proc;
}
void vm_exec_instr(VirtualMachine *vm, ssaValue *value) { void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
GB_ASSERT(value->kind == ssaValue_Instr); GB_ASSERT(value->kind == ssaValue_Instr);
@@ -581,9 +587,7 @@ void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
switch (instr->kind) { switch (instr->kind) {
case ssaInstr_StartupRuntime: { case ssaInstr_StartupRuntime: {
#if 0 #if 0
ssaValue *v = ssa_lookup_member(vm->module, make_string(SSA_STARTUP_RUNTIME_PROC_NAME)); ssaProcedure *proc = vm_lookup_procedure(vm, make_string(SSA_STARTUP_RUNTIME_PROC_NAME));
GB_ASSERT(v->kind == ssaValue_Proc);
ssaProcedure *proc = &v->Proc;
Array<vmValue> args = {}; // Empty Array<vmValue> args = {}; // Empty
vm_call_procedure(vm, proc, args); // NOTE(bill): No return value vm_call_procedure(vm, proc, args); // NOTE(bill): No return value
#endif #endif
@@ -639,8 +643,8 @@ void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
i32 elem_index = instr->StructElementPtr.elem_index; i32 elem_index = instr->StructElementPtr.elem_index;
Type *t = ssa_type(instr->StructElementPtr.address); Type *t = ssa_type(instr->StructElementPtr.address);
i64 offset_in_bytes = vm_type_offset_of(vm, type_deref(t), elem_index); i64 offset = vm_type_offset_of(vm, type_deref(t), elem_index);
void *ptr = cast(u8 *)address.val_ptr + offset_in_bytes; void *ptr = cast(u8 *)address.val_ptr + offset;
vm_set_value(f, value, vm_make_value_ptr(ptr)); vm_set_value(f, value, vm_make_value_ptr(ptr));
} break; } break;
@@ -788,7 +792,16 @@ void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
} }
if (gb_is_between(bo->op, Token__ComparisonBegin+1, Token__ComparisonEnd-1)) { if (gb_is_between(bo->op, Token__ComparisonBegin+1, Token__ComparisonEnd-1)) {
GB_PANIC("TODO(bill): Comparison operations"); switch (bo->op) {
case Token_CmpEq: break;
case Token_NotEq: break;
case Token_Lt: break;
case Token_Gt: break;
case Token_LtEq: break;
case Token_GtEq: break;
}
gb_printf_err("TODO(bill): Comparison operations %.*s\n", LIT(token_strings[bo->op]));
vm_set_value(f, value, vm_make_value_int(1)); // HACK(bill): always true
} else { } else {
vmValue v = {}; vmValue v = {};
vmValue l = vm_operand_value(vm, bo->left); vmValue l = vm_operand_value(vm, bo->left);
@@ -808,12 +821,31 @@ void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
case Token_AndNot: v.val_int = l.val_int & (~r.val_int); break; case Token_AndNot: v.val_int = l.val_int & (~r.val_int); break;
// TODO(bill): Take into account size of integer and signedness
case Token_Quo: GB_PANIC("TODO(bill): BinaryOp Integer Token_Quo"); break; case Token_Quo: GB_PANIC("TODO(bill): BinaryOp Integer Token_Quo"); break;
case Token_Mod: GB_PANIC("TODO(bill): BinaryOp Integer Token_Mod"); break; case Token_Mod: GB_PANIC("TODO(bill): BinaryOp Integer Token_Mod"); break;
} }
} else if (is_type_float(t)) { } else if (is_type_float(t)) {
GB_PANIC("TODO(bill): Float BinaryOp"); if (t == t_f32) {
switch (bo->op) {
case Token_Add: v.val_f32 = l.val_f32 + r.val_f32; break;
case Token_Sub: v.val_f32 = l.val_f32 - r.val_f32; break;
case Token_Mul: v.val_f32 = l.val_f32 * r.val_f32; break;
case Token_Quo: v.val_f32 = l.val_f32 / r.val_f32; break;
case Token_Mod: GB_PANIC("TODO(bill): BinaryOp f32 Token_Mod"); break;
}
} else if (t == t_f64) {
switch (bo->op) {
case Token_Add: v.val_f64 = l.val_f64 + r.val_f64; break;
case Token_Sub: v.val_f64 = l.val_f64 - r.val_f64; break;
case Token_Mul: v.val_f64 = l.val_f64 * r.val_f64; break;
case Token_Quo: v.val_f64 = l.val_f64 / r.val_f64; break;
case Token_Mod: GB_PANIC("TODO(bill): BinaryOp f64 Token_Mod"); break;
}
}
} else { } else {
GB_PANIC("TODO(bill): Vector BinaryOp"); GB_PANIC("TODO(bill): Vector BinaryOp");
} }
@@ -863,14 +895,40 @@ void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
} break; } break;
case ssaInstr_BoundsCheck: { case ssaInstr_BoundsCheck: {
auto *bc = &instr->BoundsCheck;
Array<vmValue> args = {};
array_init(&args, vm->stack_allocator, 5);
array_add(&args, vm_exact_value(vm, NULL, make_exact_value_string(bc->pos.file), t_string));
array_add(&args, vm_exact_value(vm, NULL, make_exact_value_integer(bc->pos.line), t_int));
array_add(&args, vm_exact_value(vm, NULL, make_exact_value_integer(bc->pos.column), t_int));
array_add(&args, vm_operand_value(vm, bc->index));
array_add(&args, vm_operand_value(vm, bc->len));
ssaProcedure *proc = vm_lookup_procedure(vm, make_string("__bounds_check_error"));
vm_call_procedure(vm, proc, args);
} break; } break;
case ssaInstr_SliceBoundsCheck: { case ssaInstr_SliceBoundsCheck: {
auto *bc = &instr->SliceBoundsCheck;
Array<vmValue> args = {};
ssaProcedure *proc;
array_init(&args, vm->stack_allocator, 7);
array_add(&args, vm_exact_value(vm, NULL, make_exact_value_string(bc->pos.file), t_string));
array_add(&args, vm_exact_value(vm, NULL, make_exact_value_integer(bc->pos.line), t_int));
array_add(&args, vm_exact_value(vm, NULL, make_exact_value_integer(bc->pos.column), t_int));
array_add(&args, vm_operand_value(vm, bc->low));
array_add(&args, vm_operand_value(vm, bc->high));
if (!bc->is_substring) {
array_add(&args, vm_operand_value(vm, bc->max));
proc = vm_lookup_procedure(vm, make_string("__slice_expr_error"));
} else {
proc = vm_lookup_procedure(vm, make_string("__substring_expr_error"));
}
vm_call_procedure(vm, proc, args);
} break; } break;
default: { default: {
GB_PANIC("<unknown instr> %d\n", instr->kind); GB_PANIC("<unknown instr> %d\n", instr->kind);
} break; } break;