From 902a81528b9d2edcf93226a2ca13da6fcc1839e5 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 23 Dec 2019 08:57:48 +0100 Subject: wip: function pointers and other stuff --- src/bytecode/bytecode.c | 50 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) (limited to 'src/bytecode') diff --git a/src/bytecode/bytecode.c b/src/bytecode/bytecode.c index af9251b..add351f 100644 --- a/src/bytecode/bytecode.c +++ b/src/bytecode/bytecode.c @@ -177,15 +177,15 @@ static void add_functions(BytecodeCompilerContext *self) { |Function[]|Functions |Multiple non-extern functions, where the number of functions is defined by @num_funcs.| # Function - |Type|Field |Description | - |----|-------------------------|------------------------------------------------------------------------------------------------------------------------| - |u32 |func_offset |The offset in the program code (machine code) where the function starts. Is always 0 until the program has been started.| - |u8 |num_params |The number of parameters. | - |u32 |params_num_pointers |The number of pointers in the parameters. | - |u32 |params_fixed_size |The size of all non-pointer type parameters, in bytes. | - |u8 |num_return_types |The number of return values. | - |u32 |return_types_num_pointers|The number of pointers in the return types. | - |u32 |return_types_fixed_size |The size of all non-pointer type return types, in bytes. | + |Type|Field |Description | + |----|-------------------------|-------------------------------------------------------------------------------------------------------------------------| + |u32 |func_offset |The offset in the program code (machine code) where the function starts. Is always ~0 until the program has been started.| + |u8 |num_params |The number of parameters. | + |u32 |params_num_pointers |The number of pointers in the parameters. | + |u32 |params_fixed_size |The size of all non-pointer type parameters, in bytes. | + |u8 |num_return_types |The number of return values. | + |u32 |return_types_num_pointers|The number of pointers in the return types. | + |u32 |return_types_fixed_size |The size of all non-pointer type return types, in bytes. | */ Ir *ir = self->parser->ir; @@ -204,7 +204,7 @@ static void add_functions(BytecodeCompilerContext *self) { TypeSize params_total_size = function_signature_get_params_size(func->func_sig); TypeSize return_types_total_size = function_signature_get_return_types_size(func->func_sig); - header_func.func_offset = 0; + header_func.func_offset = ~(u32)0UL; header_func.num_params = buffer_get_size(&func->func_sig->parameters, FunctionParameter); header_func.params_num_pointers = params_total_size.num_pointers; @@ -301,12 +301,12 @@ static void add_export_functions(BytecodeCompilerContext *self) { |Exported function[]|Exported functions|Multiple exported functions, where the number of functions is defined by @num_export_func| # Exported function - |Type|Field |Description | - |----|------------------|--------------------------------------------------------------------------------------------------------------------------| - |u32 |instruction_offset|The offset in the instruction data where the exported function is defined. Is always 0 until the program has been started.| - |u8 |num_args |The number of arguments the functions has. | - |u8 |name_len |The length of the exported function name, in bytes. Excluding the null-terminate character. | - |u8[]|name |The name of the exported function, where the size is defined by @name_len. Names are null-terminated. | + |Type|Field |Description | + |----|------------------|---------------------------------------------------------------------------------------------------------------------------| + |u32 |instruction_offset|The offset in the instruction data where the exported function is defined. Is always ~0 until the program has been started.| + |u8 |num_args |The number of arguments the functions has. | + |u8 |name_len |The length of the exported function name, in bytes. Excluding the null-terminate character. | + |u8[]|name |The name of the exported function, where the size is defined by @name_len. Names are null-terminated. | */ Ir *ir = self->parser->ir; Buffer *instructions = &self->bytecode->data; @@ -324,7 +324,7 @@ static void add_export_functions(BytecodeCompilerContext *self) { throw_if_error(buffer_append(instructions, &export_funcs_size, sizeof(u32))); for(; export_func != export_func_end; ++export_func) { const char null_s = '\0'; - const u32 instruction_offset = 0; + const u32 instruction_offset = ~(u32)0UL; u8 num_args = buffer_get_size(&export_func->func_sig->parameters, FunctionParameter); throw_if_error(buffer_append(instructions, &instruction_offset, sizeof(instruction_offset))); throw_if_error(buffer_append(instructions, &num_args, sizeof(num_args))); @@ -472,6 +472,11 @@ static void add_instructions(BytecodeCompilerContext *self) { u32 num_instructions_index = self->bytecode->data.size; throw_if_error(buffer_append_empty(&self->bytecode->data, sizeof(num_instructions_index))); + /* + TODO: Limit registers from u16 to u7. Right now they are downcasted and will cause bugs + if there are too many registers used in the program. + */ + while(instruction != instructions_end) { IrInstruction ins = (IrInstruction)*instruction++; switch(ins) { @@ -490,6 +495,11 @@ static void add_instructions(BytecodeCompilerContext *self) { add_ins3(self, AMAL_OP_MOV, ir_ins_form1.lhs, ir_ins_form1.rhs, "mov r%d, r%d"); break; } + case IR_ASSIGN_FUNC: { + instruction += ir_extract_data(instruction, &ir_ins_form1, sizeof(ir_ins_form1)); + add_ins6(self, AMAL_OP_LOADF, ir_ins_form1.lhs, ir_ins_form1.rhs, "loadf r%d, f%d"); + break; + } case IR_ADD: { instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2)); add_ins5(self, AMAL_OP_ADD, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "add r%d, r%d, r%d"); @@ -614,6 +624,12 @@ static void add_instructions(BytecodeCompilerContext *self) { add_ins6(self, AMAL_OP_CALLE, ir_ins_func_call_extern.import_index, ir_ins_func_call_extern.func_decl_lhs->extern_index, "calle ef(%d,%d)"); break; } + case IR_CALLR: { + IrRegister reg; + instruction += ir_extract_data(instruction, ®, sizeof(reg)); + add_ins2(self, AMAL_OP_CALLR, reg, "callr r%d"); + break; + } case IR_JUMP_ZERO: { instruction += ir_extract_data(instruction, &ir_ins_jump_zero, sizeof(ir_ins_jump_zero)); add_ins6(self, AMAL_OP_JZ, ir_ins_jump_zero.condition_reg, ir_ins_jump_zero.target_label, "jz r%d, l%d"); -- cgit v1.2.3