From d5fee839f729557278d2a26b0557766ccc381a04 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sun, 18 Mar 2018 03:42:15 -0400 Subject: [PATCH] Add in calling of external functions (malloc and free for now), move memory addresses to be real memeory addresses, add support for sizeof compiler intrinsic --- stdlib/bytecode_generator.krak | 96 +++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/stdlib/bytecode_generator.krak b/stdlib/bytecode_generator.krak index 9c60cd1..206b7da 100644 --- a/stdlib/bytecode_generator.krak +++ b/stdlib/bytecode_generator.krak @@ -73,6 +73,9 @@ fun offset_into_struct(struct_type: *type, ident: *ast_node): ulong { } var register_size = #sizeof<*void> +var malloc_addr = -1 +var free_addr = -2 + adt operand_size { b8, b16, @@ -345,14 +348,27 @@ obj bytecode_generator (Object) { }) }) fixup_function_addresses.for_each(fun(p: pair) { - instructions[p.first].imm.val = functions[node_function_idx[p.second]].instruction_start + if (p.second->function.is_extern) { + if (p.second->function.name == "malloc") + instructions[p.first].imm.val = malloc_addr + else if (p.second->function.name == "free") + instructions[p.first].imm.val = free_addr + else + error("bad extern function used: " + p.second->function.name) + } else { + instructions[p.first].imm.val = functions[node_function_idx[p.second]].instruction_start + } }) for (var i = 0; i < functions.size - 1; i++;) functions[i].instruction_end = functions[i+1].instruction_start functions.last().instruction_end = instructions.size /*return make_pair(functions, instructions)*/ } - fun generate_function_definition(node: *ast_node): int { + fun generate_function_definition(node: *ast_node) { + if (node->function.is_extern) { + println("Skipping extern function " + node->function.name) + return + } reset_reg() node_function_idx[node] = functions.size functions.add(bytecode_function(get_name(node), instructions.size)) @@ -381,7 +397,6 @@ obj bytecode_generator (Object) { instructions[push_frame_idx].addi.bi = -functions.last().frame_size - return -1 } fun generate_declaration_statement(node: *ast_node): int { var identifier = node->declaration_statement.identifier @@ -553,7 +568,7 @@ obj bytecode_generator (Object) { } fun generate_function_call(node: *ast_node, lvalue: bool): int { var func = node->function_call.func - if (is_function(func) && func->function.body_statement == null()) { + if (is_function(func) && !func->function.is_extern && func->function.body_statement == null()) { var name = func->function.name var parameter_nodes = node->function_call.parameters // generate with lvalue=true to make return a pointer @@ -732,8 +747,12 @@ obj bytecode_generator (Object) { } fun generate_compiler_intrinsic(node: *ast_node): int { - instructions.add(byte_inst::nop()) - return -1 + if (node->compiler_intrinsic.intrinsic == "sizeof") { + if (node->compiler_intrinsic.parameters.size || node->compiler_intrinsic.type_parameters.size != 1) + error("wrong parameters to sizeof compiler intrinsic") + return emit_imm(type_size(node->compiler_intrinsic.type_parameters[0])) + } + error("bad compiler intrinsic " + node->compiler_intrinsic.intrinsic) } fun generate(node: *ast_node): int return generate(node, false) @@ -977,12 +996,13 @@ obj bytecode_generator (Object) { var main_entry = functions.find_first_satisfying(fun(block: bytecode_function): bool return block.name == "main";) var registers.construct(reg_max): vector registers.size = reg_max - registers[0] = -register_size // with the stack being zeroed out, this makes it a return address of 0 registers[1] = 0xdeadbeefcafebabe var stack_size = 8 * 1024 * 1024 + var got_malloc = null() var stack = new(stack_size) + stack_size for (var i = 0; i < stack_size; i++;) stack[-i + -1] = 0 + registers[0] = (stack-register_size) cast long // with the stack being zeroed out, this makes it a return address of 0 for (var i = main_entry.instruction_start; i < instructions.size; i++;) { println(string("evaling: ") + i + ": " + to_string(instructions[i])) match(instructions[i]) { @@ -1006,41 +1026,56 @@ obj bytecode_generator (Object) { byte_inst::lz(a) registers[a.to_reg] = registers[a.a] < 0 byte_inst::ez(a) registers[a.to_reg] = registers[a.a] == 0 byte_inst::ldr(l) match (l.size) { - operand_size::b8() registers[l.reg] = *(stack + registers[l.base_reg] + l.offset) cast *char - operand_size::b16() registers[l.reg] = *(stack + registers[l.base_reg] + l.offset) cast *short - operand_size::b32() registers[l.reg] = *(stack + registers[l.base_reg] + l.offset) cast *int - operand_size::b64() registers[l.reg] = *(stack + registers[l.base_reg] + l.offset) cast *long + operand_size::b8() registers[l.reg] = *(registers[l.base_reg] + l.offset) cast *char + operand_size::b16() registers[l.reg] = *(registers[l.base_reg] + l.offset) cast *short + operand_size::b32() registers[l.reg] = *(registers[l.base_reg] + l.offset) cast *int + operand_size::b64() registers[l.reg] = *(registers[l.base_reg] + l.offset) cast *long } byte_inst::str(s) match (s.size) { - operand_size::b8() *(stack + registers[s.base_reg] + s.offset) cast *uchar = registers[s.reg] - operand_size::b16() *(stack + registers[s.base_reg] + s.offset) cast *ushort = registers[s.reg] - operand_size::b32() *(stack + registers[s.base_reg] + s.offset) cast *uint = registers[s.reg] - operand_size::b64() *(stack + registers[s.base_reg] + s.offset) cast *ulong = registers[s.reg] + operand_size::b8() *(registers[s.base_reg] + s.offset) cast *uchar = registers[s.reg] + operand_size::b16() *(registers[s.base_reg] + s.offset) cast *ushort = registers[s.reg] + operand_size::b32() *(registers[s.base_reg] + s.offset) cast *uint = registers[s.reg] + operand_size::b64() *(registers[s.base_reg] + s.offset) cast *ulong = registers[s.reg] } byte_inst::jmp(offset) i += offset - 1 // to counteract pc inc byte_inst::jz(j) if (registers[j.reg] == 0) i += j.offset - 1 // to counteract pc inc byte_inst::call(c) { - /*registers[0] -= register_size*/ - registers[0] = registers[0] - register_size - *(stack + registers[0]) cast *long = i + 1 - i = registers[c] - 1 - print("call!") - println("first part of memory is (after push)") - for (var i = 0; i < 8*8; i+=8;) { - print(string("-") + i + string(": ")) - for (var j = 0; j < 8; j++;) { - if (j == 4) + var func_start = registers[c] + // extern call + if (func_start < 0) { + if (func_start == malloc_addr) + /*registers[2] = (malloc(*(stack + registers[0]) cast *ulong)) cast long*/ + { + got_malloc = malloc(*(registers[0]) cast *ulong) + registers[2] = (got_malloc) cast long + } + else if (func_start == free_addr) + free(*(registers[0]) cast **void) + else + error(string("bad extern call number") + func_start) + } else { + /*registers[0] -= register_size*/ + registers[0] = registers[0] - register_size + *(registers[0]) cast *long = i + 1 + i = func_start - 1 + print("call!") + println("first part of memory is (after push)") + for (var i = 0; i < 8*8; i+=8;) { + print(string("-") + i + string(": ")) + for (var j = 0; j < 8; j++;) { + if (j == 4) + print(" ") + print(*(stack - (i+j)*#sizeof - 1) cast *uchar) print(" ") - print(*(stack - (i+j)*#sizeof - 1) cast *uchar) - print(" ") + } + println() } - println() + println("Done") } - println("Done") } byte_inst::ret() { - var pc = *(stack + registers[0]) cast *long + var pc = *(registers[0]) cast *long /*registers[0] += register_size*/ registers[0] = registers[0] + register_size print("returning! return value is\n\t") @@ -1059,6 +1094,7 @@ obj bytecode_generator (Object) { } println("Done") if (pc == 0) { + println(string("got malloc is ") + *(got_malloc) cast *int) return value } else { i = pc - 1