aboutsummaryrefslogtreecommitdiff
path: root/src/bytecode
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytecode')
-rw-r--r--src/bytecode/bytecode.c50
1 files changed, 33 insertions, 17 deletions
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, &reg, 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");