From df640dc7f55fef962b598562e10d8dd4d60fedc0 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 21 Aug 2019 07:02:02 +0200 Subject: Code cleanup in ssa/bytecode. Remove ugly memcpy --- src/bytecode/bytecode.c | 237 +++++------------------------------------------- src/ssa/ssa.c | 117 ++++++++++++------------ src/std/buffer.c | 7 +- src/std/hash_map.c | 1 + 4 files changed, 86 insertions(+), 276 deletions(-) diff --git a/src/bytecode/bytecode.c b/src/bytecode/bytecode.c index 8daa4ce..80cc95b 100644 --- a/src/bytecode/bytecode.c +++ b/src/bytecode/bytecode.c @@ -23,49 +23,9 @@ int bytecode_init(Bytecode *self, ArenaAllocator *allocator) { return buffer_init(&self->data, allocator); } -static CHECK_RESULT usize ssa_extract_form1(u8 *instruction_data, SsaInsForm1 *result) { - am_memcpy(&result->lhs, instruction_data, sizeof(result->lhs)); - am_memcpy(&result->rhs, instruction_data + sizeof(result->lhs), sizeof(result->rhs)); - return sizeof(result->lhs) + sizeof(result->rhs); -} - -static CHECK_RESULT usize ssa_extract_form2(u8 *instruction_data, SsaInsForm2 *result) { - am_memcpy(&result->result, instruction_data, sizeof(result->result)); - am_memcpy(&result->lhs, instruction_data + sizeof(result->result), sizeof(result->lhs)); - am_memcpy(&result->rhs, instruction_data + sizeof(result->result) + sizeof(result->lhs), sizeof(result->rhs)); - return sizeof(result->result) + sizeof(result->lhs) + sizeof(result->rhs); -} - -static CHECK_RESULT usize ssa_extract_func_start(u8 *instruction_data, SsaInsFuncStart *result) { - am_memcpy(&result->func_index, instruction_data, sizeof(result->func_index)); - am_memcpy(&result->num_params_regs, instruction_data + sizeof(result->func_index), sizeof(result->num_params_regs)); - am_memcpy(&result->num_local_vars_regs, instruction_data + sizeof(result->func_index) + sizeof(result->num_params_regs), sizeof(result->num_local_vars_regs)); - return sizeof(result->func_index) + sizeof(result->num_params_regs) + sizeof(result->num_local_vars_regs); -} - -static CHECK_RESULT usize ssa_extract_func_call(u8 *instruction_data, SsaInsFuncCall *result) { - result->num_args = instruction_data[0]; - am_memcpy(&result->result, instruction_data + 1, sizeof(result->result)); - am_memcpy(&result->func_decl, instruction_data + 1 + sizeof(result->result), sizeof(result->func_decl)); - return sizeof(u8) + sizeof(result->result) + sizeof(result->func_decl); -} - -static CHECK_RESULT usize ssa_extract_func_call_extern(u8 *instruction_data, SsaInsFuncCallExtern *result) { - result->num_args = instruction_data[0]; - am_memcpy(&result->result, instruction_data + 1, sizeof(result->result)); - am_memcpy(&result->extern_func_index, instruction_data + 1 + sizeof(result->result), sizeof(result->extern_func_index)); - return sizeof(u8) + sizeof(result->result) + sizeof(result->extern_func_index); -} - -static CHECK_RESULT usize ssa_extract_jump_zero(u8 *instruction_data, SsaInsJumpZero *result) { - am_memcpy(&result->condition_reg, instruction_data, sizeof(result->condition_reg)); - am_memcpy(&result->jump_offset, instruction_data + sizeof(result->condition_reg), sizeof(result->jump_offset)); - return sizeof(result->condition_reg) + sizeof(result->jump_offset); -} - -static CHECK_RESULT usize ssa_extract_jump(u8 *instruction_data, SsaInsJump *result) { - am_memcpy(&result->jump_offset, instruction_data, sizeof(result->jump_offset)); - return sizeof(result->jump_offset); +static CHECK_RESULT usize ssa_extract_data(u8 *instruction_data, void *result, usize size) { + am_memcpy(result, instruction_data, size); + return size; } static void add_intermediates(BytecodeCompilerContext *self) { @@ -328,10 +288,6 @@ static void add_instructions(BytecodeCompilerContext *self) { |Instruction|Instructions data|The instructions data. Each instructions begins with an opcode, see #Opcode| */ - Ssa *ssa; - u8 *instruction; - u8 *instructions_end; - SsaInsForm1 ssa_ins_form1; SsaInsForm2 ssa_ins_form2; SsaInsFuncStart ssa_ins_func_start; @@ -340,210 +296,69 @@ static void add_instructions(BytecodeCompilerContext *self) { SsaInsJumpZero ssa_ins_jump_zero; SsaInsJump ssa_ins_jump; - FILE *file; - char *filename; + Ssa *ssa = self->parser->ssa; + u8 *instruction = buffer_begin(&ssa->instructions); + u8 *instructions_end = buffer_end(&ssa->instructions); - u32 num_instructions_index; - num_instructions_index = self->bytecode.data.size; + u32 num_instructions_index = self->bytecode.data.size; throw_if_error(buffer_append_empty(&self->bytecode.data, sizeof(num_instructions_index))); - #ifdef COMPILE_TO_C - LhsExpr *reg_types[NUM_MAX_REGS]; /* TODO: Remove this. Encode this data in the register itself */ - SsaRegister func_arg_stack[NUM_MAX_FUNC_ARGS]; /* TODO: Remove this? */ - int func_arg_index; - #endif - - ssa = self->parser->ssa; - instruction = buffer_begin(&ssa->instructions); - instructions_end = buffer_end(&ssa->instructions); - /*#warning "dont forget to remove this" */ - filename = malloc(self->parser->tokenizer.code_name.size + 3); - filename[0] = '\0'; - strcat(filename, self->parser->tokenizer.code_name.data); - strcat(filename, ".z"); - file = fopen(filename, "wb"); - free(filename); - #ifdef COMPILE_TO_C - #ifdef DEBUG - am_memset(reg_types, 0, sizeof(reg_types)); - #endif - func_arg_index = 0; - - fputs("typedef i64 signed long long;\n", file); - fputs("typedef f64 double;\n", file); - - #define ARITH_OP(op) do {\ - const char *rhs_type_name; \ - instruction += ssa_extract_form2(instruction, &ssa_ins_form2); \ - assert(ssa_ins_form2.result < NUM_MAX_REGS); \ - assert(ssa_ins_form2.lhs < NUM_MAX_REGS); \ - rhs_type_name = lhs_expr_get_c_name(self, reg_types[ssa_ins_form2.lhs]); \ - fprintf(file, "%s r%d = r%d %s r%d;\n", rhs_type_name, ssa_ins_form2.result, ssa_ins_form2.lhs, (op), ssa_ins_form2.rhs); \ - reg_types[ssa_ins_form2.result] = reg_types[ssa_ins_form2.lhs]; \ - } while(0) - - while(instruction != instructions_end) { - switch((SsaInstruction)*instruction++) { - case SSA_ASSIGN_INTER: { - SsaNumber number; - instruction += ssa_extract_form1(instruction, &ssa_ins_form1); - number = ssa_get_intermediate(ssa, ssa_ins_form1.rhs); - assert(ssa_ins_form1.lhs < NUM_MAX_REGS); - if(number.type == SSA_NUMBER_TYPE_INTEGER) { - fprintf(file, "i64 r%d = %zu;\n", ssa_ins_form1.lhs, number.value.integer); - reg_types[ssa_ins_form1.lhs] = self->parser->compiler->default_types.i64; - } else if(number.type == SSA_NUMBER_TYPE_FLOAT) { - fprintf(file, "f64 r%d = %f;\n", ssa_ins_form1.lhs, number.value.floating); - reg_types[ssa_ins_form1.lhs] = self->parser->compiler->default_types.f64; - } else { - assert(bool_false && "TODO: Implement"); - } - break; - } - case SSA_ASSIGN_STRING: { - BufferView str; - instruction += ssa_extract_form1(instruction, &ssa_ins_form1); - str = ssa_get_string(ssa, ssa_ins_form1.rhs); - fprintf(file, "const char* r%d = \"%.*s\";\n", ssa_ins_form1.lhs, (int)str.size, str.data); - assert(ssa_ins_form1.lhs < NUM_MAX_REGS); - reg_types[ssa_ins_form1.lhs] = self->parser->compiler->default_types.str; - break; - } - case SSA_ASSIGN_REG: { - const char *rhs_type_name; - instruction += ssa_extract_form1(instruction, &ssa_ins_form1); - assert(ssa_ins_form1.rhs < NUM_MAX_REGS); - rhs_type_name = lhs_expr_get_c_name(self, reg_types[ssa_ins_form1.rhs]); - fprintf(file, "%s r%d = r%d;\n", rhs_type_name, ssa_ins_form1.lhs, ssa_ins_form1.rhs); - reg_types[ssa_ins_form1.lhs] = reg_types[ssa_ins_form1.rhs]; - break; - } - case SSA_ADD: { - ARITH_OP("+"); - break; - } - case SSA_SUB: { - ARITH_OP("-"); - break; - } - case SSA_MUL: { - ARITH_OP("*"); - break; - } - case SSA_DIV: { - ARITH_OP("/"); - break; - } - case SSA_EQUALS: { - ARITH_OP("=="); - break; - } - case SSA_FUNC_START: { - int i; - instruction += ssa_extract_func_start(instruction, &ssa_ins_func_start); - fprintf(file, "void f%zu(", ssa_ins_func_start.func_index); - fputs(") {\n", file); - for(i = 0; i < ssa_ins_func_start.num_args; ++i) { - if(i > 0) - fputs(", ", file); - fprintf(file, "p%d", i); - } - break; - } - case SSA_FUNC_END: - fputs("}\n", file); - break; - case SSA_PUSH: { - SsaRegister reg; - am_memcpy(®, instruction, sizeof(SsaRegister)); - instruction += sizeof(SsaRegister); - assert(func_arg_index < NUM_MAX_FUNC_ARGS); - func_arg_stack[func_arg_index++] = reg; - break; - } - case SSA_CALL: { - int i; - instruction += ssa_extract_func_call(instruction, &ssa_ins_func_call); - fprintf(file, "r%d = f%p(", ssa_ins_func_call.result, ssa_ins_func_call.func_decl); - for(i = 0; i < func_arg_index; ++i) { - if(i > 0) - fputs(", ", file); - fprintf(file, "r%d", func_arg_stack[i]); - } - func_arg_index = 0; - fputs(");\n", file); - break; - } - case SSA_JUMP_ZERO: { - assert(bool_false && "Not implemented!"); - instruction += ssa_extract_jump_zero(instruction, &ssa_ins_jump_zero); - break; - } - case SSA_JUMP: { - assert(bool_false && "Not implemented!"); - instruction += ssa_extract_jump(instruction, &ssa_ins_jump); - break; - } - } - } - #else /* TODO: Keep all registers under 256 */ - while(instruction != instructions_end) { SsaInstruction ins = (SsaInstruction)*instruction++; switch(ins) { case SSA_ASSIGN_INTER: { - instruction += ssa_extract_form1(instruction, &ssa_ins_form1); + instruction += ssa_extract_data(instruction, &ssa_ins_form1, sizeof(ssa_ins_form1)); add_ins6(self, AMAL_OP_MOVI, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "movi r%d, i%d"); break; } case SSA_ASSIGN_STRING: { - instruction += ssa_extract_form1(instruction, &ssa_ins_form1); + instruction += ssa_extract_data(instruction, &ssa_ins_form1, sizeof(ssa_ins_form1)); add_ins6(self, AMAL_OP_MOVD, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "movd r%d, s%d"); break; } case SSA_ASSIGN_REG: { - instruction += ssa_extract_form1(instruction, &ssa_ins_form1); + instruction += ssa_extract_data(instruction, &ssa_ins_form1, sizeof(ssa_ins_form1)); add_ins3(self, AMAL_OP_MOV, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "mov r%d, r%d"); break; } case SSA_ADD: { - instruction += ssa_extract_form2(instruction, &ssa_ins_form2); + instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2)); add_ins5(self, AMAL_OP_ADD, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "add r%d, r%d, r%d"); break; } case SSA_SUB: { - instruction += ssa_extract_form2(instruction, &ssa_ins_form2); + instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2)); add_ins5(self, AMAL_OP_SUB, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "sub r%d, r%d, r%d"); break; } case SSA_IMUL: { - instruction += ssa_extract_form2(instruction, &ssa_ins_form2); + instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2)); add_ins5(self, AMAL_OP_IMUL, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "imul r%d, r%d, r%d"); break; } case SSA_MUL: { - instruction += ssa_extract_form2(instruction, &ssa_ins_form2); + instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2)); add_ins5(self, AMAL_OP_MUL, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "mul r%d, r%d, r%d"); break; } case SSA_IDIV: { - instruction += ssa_extract_form2(instruction, &ssa_ins_form2); + instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2)); add_ins5(self, AMAL_OP_IDIV, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "idiv r%d, r%d, r%d"); break; } case SSA_DIV: { - instruction += ssa_extract_form2(instruction, &ssa_ins_form2); + instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2)); add_ins5(self, AMAL_OP_DIV, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "div r%d, r%d, r%d"); break; } case SSA_EQUALS: { - instruction += ssa_extract_form2(instruction, &ssa_ins_form2); + instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2)); add_ins5(self, AMAL_OP_CMP, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "cmp r%d, r%d, r%d"); break; } case SSA_FUNC_START: { - instruction += ssa_extract_func_start(instruction, &ssa_ins_func_start); + instruction += ssa_extract_data(instruction, &ssa_ins_func_start, sizeof(ssa_ins_func_start)); add_ins6(self, AMAL_OP_FUNC_START, ssa_ins_func_start.num_params_regs, ssa_ins_func_start.num_local_vars_regs, "func_start %d, %u"); break; } @@ -567,22 +382,22 @@ static void add_instructions(BytecodeCompilerContext *self) { the function indices can be increased by their block index (ssa_func_index + block index), where block index is defined as the size of all previous files' number of functions. */ - instruction += ssa_extract_func_call(instruction, &ssa_ins_func_call); + instruction += ssa_extract_data(instruction, &ssa_ins_func_call, sizeof(ssa_ins_func_call)); add_ins7(self, AMAL_OP_CALL, ssa_ins_func_call.func_decl->ssa_func_index, ssa_ins_func_call.num_args, ssa_ins_func_call.result, "call f%d, %d, r%d"); break; } case SSA_CALL_EXTERN: { - instruction += ssa_extract_func_call_extern(instruction, &ssa_ins_func_call_extern); + instruction += ssa_extract_data(instruction, &ssa_ins_func_call_extern, sizeof(ssa_ins_func_call_extern)); add_ins7(self, AMAL_OP_CALLE, ssa_ins_func_call_extern.extern_func_index, ssa_ins_func_call_extern.num_args, ssa_ins_func_call_extern.result, "calle ef%d, %d, r%d"); break; } case SSA_JUMP_ZERO: { - instruction += ssa_extract_jump_zero(instruction, &ssa_ins_jump_zero); + instruction += ssa_extract_data(instruction, &ssa_ins_jump_zero, sizeof(ssa_ins_jump_zero)); add_ins6(self, AMAL_OP_JZ, ssa_ins_jump_zero.condition_reg, ssa_ins_jump_zero.jump_offset, "jz r%d, %d"); break; } case SSA_JUMP: { - instruction += ssa_extract_jump(instruction, &ssa_ins_jump); + instruction += ssa_extract_data(instruction, &ssa_ins_jump, sizeof(ssa_ins_jump)); add_ins4(self, AMAL_OP_JMP, ssa_ins_jump.jump_offset, "jmp %d"); break; } @@ -598,14 +413,10 @@ static void add_instructions(BytecodeCompilerContext *self) { /* Prepend instructions with its size */ { - u32 instructions_size; /* -sizeof to Remove the count itself from the size of the instructions size */ - instructions_size = self->bytecode.data.size - num_instructions_index - sizeof(instructions_size); - am_memcpy(&self->bytecode.data.data[num_instructions_index], &instructions_size, sizeof(instructions_size)); + const u32 instructions_size = self->bytecode.data.size - num_instructions_index - sizeof(instructions_size); + am_memcpy(self->bytecode.data.data + num_instructions_index, &instructions_size, sizeof(instructions_size)); } - - #endif /* COMPILE_TO_C */ - fclose(file); } void generate_bytecode_from_ssa(BytecodeCompilerContext *self) { diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c index 01c4f0f..39b5a80 100644 --- a/src/ssa/ssa.c +++ b/src/ssa/ssa.c @@ -193,12 +193,11 @@ static CHECK_RESULT int ssa_try_add_extern_func(Ssa *self, FunctionSignature *fu } static CHECK_RESULT int ssa_add_ins_form1(Ssa *self, SsaInstruction ins_type, SsaRegister lhs, u16 rhs) { - const usize index = self->instructions.size; - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister) + sizeof(u16))); - self->instructions.data[index + 0] = ins_type; - am_memcpy(self->instructions.data + index + 1, &lhs, sizeof(lhs)); - am_memcpy(self->instructions.data + index + 3, &rhs, sizeof(rhs)); - return 0; + SsaInsForm1 ins_form_1; + ins_form_1.lhs = lhs; + ins_form_1.rhs = rhs; + return_if_error(buffer_append(&self->instructions, &ins_type, 1)); + return buffer_append(&self->instructions, &ins_form_1, sizeof(ins_form_1)); } static const char* binop_type_to_string(SsaInstruction binop_type) { @@ -214,15 +213,14 @@ static const char* binop_type_to_string(SsaInstruction binop_type) { } static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstruction ins_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result) { - const usize index = self->instructions.size; + SsaInsForm2 ins_form_2; return_if_error(ssa_get_unique_reg(self, result)); - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister) + sizeof(SsaRegister) + sizeof(SsaRegister))); - self->instructions.data[index + 0] = ins_type; - am_memcpy(self->instructions.data + index + 1, result, sizeof(SsaRegister)); - am_memcpy(self->instructions.data + index + 3, &lhs, sizeof(lhs)); - am_memcpy(self->instructions.data + index + 5, &rhs, sizeof(rhs)); + ins_form_2.result = *result; + ins_form_2.lhs = lhs; + ins_form_2.rhs = rhs; amal_log_debug("r%d = r%d %s r%d", *result, lhs, binop_type_to_string(ins_type), rhs); - return 0; + return_if_error(buffer_append(&self->instructions, &ins_type, 1)); + return buffer_append(&self->instructions, &ins_form_2, sizeof(ins_form_2)); } static CHECK_RESULT int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number) { @@ -250,7 +248,8 @@ static CHECK_RESULT int ssa_ins_binop(Ssa *self, SsaInstruction binop_type, SsaR } static CHECK_RESULT int ssa_ins_func_start(Ssa *self, SsaRegister num_reg_params, SsaFuncIndex *result, usize *func_metadata_index) { - const usize index = self->instructions.size; + const u8 ins_type = SSA_FUNC_START; + SsaInsFuncStart ins_func_start; /* Overflow */ if(self->func_counter + 1 <= self->func_counter) { @@ -258,86 +257,82 @@ static CHECK_RESULT int ssa_ins_func_start(Ssa *self, SsaRegister num_reg_params return -1; } - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaFuncIndex) + sizeof(SsaRegister) + sizeof(u16))); *result = self->func_counter++; - self->instructions.data[index + 0] = SSA_FUNC_START; - am_memcpy(self->instructions.data + index + 1, result, sizeof(SsaFuncIndex)); - am_memcpy(self->instructions.data + index + 1 + sizeof(SsaFuncIndex), &num_reg_params, sizeof(SsaRegister)); - *func_metadata_index = index + 1 + sizeof(SsaFuncIndex) + sizeof(num_reg_params); - /* No need to add data to instructions.data here, it can contain undefined data until we set it (@ the caller) */ + ins_func_start.func_index = *result; + ins_func_start.num_params_regs = num_reg_params; + /* Dont set number of local registers yet. That will be set by @func_metadata_index later when it's known */ + /*ins_func_start.num_local_vars_regs = ---*/ + return_if_error(buffer_append(&self->instructions, &ins_type, 1)); + return_if_error(buffer_append(&self->instructions, &ins_func_start, sizeof(ins_func_start))); + *func_metadata_index = self->instructions.size - sizeof(ins_func_start.num_local_vars_regs); amal_log_debug("FUNC_START f%u, %d", *result, num_reg_params); return 0; } static CHECK_RESULT int ssa_ins_func_end(Ssa *self) { - const u8 ins = SSA_FUNC_END; + const u8 ins_type = SSA_FUNC_END; amal_log_debug("FUNC_END"); - return buffer_append(&self->instructions, &ins, 1); + return buffer_append(&self->instructions, &ins_type, 1); } static CHECK_RESULT int ssa_ins_push(Ssa *self, SsaRegister reg) { - const usize index = self->instructions.size; - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister))); - self->instructions.data[index + 0] = SSA_PUSH; - am_memcpy(self->instructions.data + index + 1, ®, sizeof(SsaRegister)); + const u8 ins_type = SSA_PUSH; amal_log_debug("PUSH r%d", reg); - return 0; + return_if_error(buffer_append(&self->instructions, &ins_type, 1)); + return buffer_append(&self->instructions, ®, sizeof(reg)); } static CHECK_RESULT int ssa_ins_call(Ssa *self, FunctionDecl *func_decl, u8 num_args, SsaRegister *result) { - const usize index = self->instructions.size; + const u8 ins_type = SSA_CALL; + SsaInsFuncCall ins_func_call; return_if_error(ssa_get_unique_reg(self, result)); - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(u8) + sizeof(SsaRegister) + sizeof(func_decl))); - self->instructions.data[index + 0] = SSA_CALL; - self->instructions.data[index + 1] = num_args; - am_memcpy(self->instructions.data + index + 2, result, sizeof(SsaRegister)); - am_memcpy(self->instructions.data + index + 2 + sizeof(SsaRegister), &func_decl, sizeof(func_decl)); + ins_func_call.num_args = num_args; + ins_func_call.result = *result; + ins_func_call.func_decl = func_decl; amal_log_debug("r%d = CALL %d, %p", *result, num_args, func_decl); - return 0; + return_if_error(buffer_append(&self->instructions, &ins_type, 1)); + return buffer_append(&self->instructions, &ins_func_call, sizeof(ins_func_call)); } static CHECK_RESULT int ssa_ins_call_extern(Ssa *self, SsaExternFuncIndex extern_func_index, u8 num_args, SsaRegister *result) { - const usize index = self->instructions.size; - assert(extern_func_index < self->extern_func_counter); + const u8 ins_type = SSA_CALL_EXTERN; + SsaInsFuncCallExtern ins_func_call_extern; return_if_error(ssa_get_unique_reg(self, result)); - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(u8) + sizeof(SsaRegister) + sizeof(extern_func_index))); - self->instructions.data[index + 0] = SSA_CALL_EXTERN; - self->instructions.data[index + 1] = num_args; - am_memcpy(self->instructions.data + index + 2, result, sizeof(SsaRegister)); - am_memcpy(self->instructions.data + index + 2 + sizeof(SsaRegister), &extern_func_index, sizeof(extern_func_index)); + assert(extern_func_index < self->extern_func_counter); + ins_func_call_extern.num_args = num_args; + ins_func_call_extern.result = *result; + ins_func_call_extern.extern_func_index = extern_func_index; amal_log_debug("r%d = CALL_EXTERN %d, %d", *result, num_args, extern_func_index); - return 0; + return_if_error(buffer_append(&self->instructions, &ins_type, 1)); + return buffer_append(&self->instructions, &ins_func_call_extern, sizeof(ins_func_call_extern)); } static CHECK_RESULT int ssa_ins_jumpzero(Ssa *self, SsaRegister condition_reg, JumpOffset jump_offset) { - const usize index = self->instructions.size; - - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister) + sizeof(JumpOffset))); - self->instructions.data[index + 0] = SSA_JUMP_ZERO; - am_memcpy(self->instructions.data + index + 1, &condition_reg, sizeof(SsaRegister)); - am_memcpy(self->instructions.data + index + 1 + sizeof(SsaRegister), &jump_offset, sizeof(JumpOffset)); + const u8 ins_type = SSA_JUMP_ZERO; + SsaInsJumpZero ins_jump_zero; + ins_jump_zero.condition_reg = condition_reg; + ins_jump_zero.jump_offset = jump_offset; if(jump_offset == 0) amal_log_debug("JUMP_ZERO r%d, DUMMY", condition_reg); else amal_log_debug("JUMP_ZERO r%d, %d", condition_reg, jump_offset); - return 0; + return_if_error(buffer_append(&self->instructions, &ins_type, 1)); + return buffer_append(&self->instructions, &ins_jump_zero, sizeof(ins_jump_zero)); } static CHECK_RESULT int ssa_ins_jump(Ssa *self, JumpOffset jump_offset) { - const usize index = self->instructions.size; - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(JumpOffset))); - self->instructions.data[index + 0] = SSA_JUMP; - am_memcpy(self->instructions.data + index + 1, &jump_offset, sizeof(JumpOffset)); + const u8 ins_type = SSA_JUMP; + SsaInsJump ins_jump; + ins_jump.jump_offset = jump_offset; amal_log_debug("JUMP %d", jump_offset); - return 0; + return_if_error(buffer_append(&self->instructions, &ins_type, 1)); + return buffer_append(&self->instructions, &ins_jump, sizeof(ins_jump)); } static CHECK_RESULT int ssa_ins_return(Ssa *self, SsaRegister reg) { - const usize index = self->instructions.size; - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister))); - self->instructions.data[index + 0] = SSA_RET; - am_memcpy(self->instructions.data + index + 1, ®, sizeof(SsaRegister)); - return 0; + const u8 ins_type = SSA_RET; + return_if_error(buffer_append(&self->instructions, &ins_type, 1)); + return buffer_append(&self->instructions, ®, sizeof(reg)); } static usize ssa_ins_get_index(Ssa *self) { @@ -352,9 +347,9 @@ static CHECK_RESULT int ssa_ins_jump_set_target(Ssa *self, usize jump_ins_index) /* TODO: Should something be done about this? */ if(jump_offset < -0x7FFF || jump_offset > 0x7FFF) { amal_log_error("Unexpected error. Jump offset has to be less than +-32767, was %d", jump_offset); - return 1; + return -1; } - am_memcpy(self->instructions.data + jump_ins_index + 1 + sizeof(SsaRegister), &jump_offset, sizeof(JumpOffset)); + am_memcpy(self->instructions.data + jump_ins_index + 1 + offsetof(SsaInsJumpZero, jump_offset), &jump_offset, sizeof(JumpOffset)); break; } default: diff --git a/src/std/buffer.c b/src/std/buffer.c index 93e8558..a482bb9 100644 --- a/src/std/buffer.c +++ b/src/std/buffer.c @@ -37,9 +37,12 @@ static CHECK_RESULT int buffer_ensure_capacity(Buffer *self, usize new_capacity) if(capacity == 0) { capacity = new_capacity; } else { - while(capacity < new_capacity) { - capacity *= 1.5; + double cap = capacity; + const double new_cap = new_capacity; + while(cap < new_cap) { + cap *= 1.5; } + capacity = cap; } alloc_result = am_realloc(self->data, capacity, &new_mem); diff --git a/src/std/hash_map.c b/src/std/hash_map.c index 48e9e38..98ebf40 100644 --- a/src/std/hash_map.c +++ b/src/std/hash_map.c @@ -85,6 +85,7 @@ int hash_map_init(HashMap *self, ArenaAllocator *allocator, usize value_type_siz return_if_error(buffer_init(&self->buckets, self->allocator)); assert(self->buckets.size == 0); return_if_error(buffer_append_empty(&self->buckets, sizeof(HashMapBucket) * HASH_MAP_INITIAL_SIZE)); + assert(HASH_MAP_INITIAL_SIZE != 0); am_memset(self->buckets.data, 0, self->buckets.size); return 0; } -- cgit v1.2.3