diff options
Diffstat (limited to 'src/bytecode')
-rw-r--r-- | src/bytecode/bytecode.c | 51 |
1 files changed, 18 insertions, 33 deletions
diff --git a/src/bytecode/bytecode.c b/src/bytecode/bytecode.c index 7c4fe08..9bf5f24 100644 --- a/src/bytecode/bytecode.c +++ b/src/bytecode/bytecode.c @@ -58,47 +58,24 @@ static CHECK_RESULT usize ssa_extract_jump(u8 *instruction_data, SsaInsJump *res return sizeof(result->jump_offset); } -static void add_header(BytecodeCompilerContext *self) { - /*doc(Bytecode header) - # Header layout - |Size|Name |Description | - |----|-------------|----------------------------------------------------------------------------| - |4 |Magic number |The magic number used to identify an amalgam bytecode file. | - |1 |Major version|The major version of the bytecode. Updates in this is a breaking change. | - |1 |Minor version|The minor version of the bytecode. Updates in this are backwards compatible.| - |1 |Patch version|The patch version of the bytecode. Updates in this are only minor bug fixes.| - The versions in the header only changes for every release, not every change. - */ - - const u32 magic_number = 0xdec05eba; - const u8 major_version = 1; - const u8 minor_version = 0; - const u8 patch_version = 0; - - Buffer *instructions; - instructions = &self->bytecode.data; - throw_if_error(buffer_append(instructions, &magic_number, 4)); - throw_if_error(buffer_append(instructions, &major_version, 1)); - throw_if_error(buffer_append(instructions, &minor_version, 1)); - throw_if_error(buffer_append(instructions, &patch_version, 1)); -} - static void add_intermediates(BytecodeCompilerContext *self) { Ssa *ssa; Buffer *instructions; SsaNumber *intermediate; SsaNumber *intermediates_end; + u32 intemediates_size; ssa = self->parser->ssa; instructions = &self->bytecode.data; intermediate = buffer_begin(&ssa->intermediates); intermediates_end = buffer_end(&ssa->intermediates); - throw_if_error(buffer_expand(instructions, - sizeof(u16) + (sizeof(u8) + sizeof(u64)) * ssa->intermediates.size)); - throw_if_error(buffer_append(instructions, &ssa->intermediates.size, sizeof(u16))); + intemediates_size = (sizeof(u8) + sizeof(u64)) * buffer_get_size(&ssa->intermediates, SsaNumber); + throw_if_error(buffer_expand(instructions, sizeof(u32) + intemediates_size)); + throw_if_error(buffer_append(instructions, &intemediates_size, sizeof(u32))); for(; intermediate != intermediates_end; ++intermediate) { throw_if_error(buffer_append(instructions, &intermediate->type, sizeof(u8))); + /* TODO: Store value using an encoding that will save space when using low numbers */ throw_if_error(buffer_append(instructions, &intermediate->value.integer, sizeof(u64))); } } @@ -108,12 +85,18 @@ void add_strings(BytecodeCompilerContext *self) { Buffer *instructions; BufferView *string; BufferView *strings_end; + u16 num_strings; u32 strings_size; ssa = self->parser->ssa; instructions = &self->bytecode.data; string = buffer_begin(&ssa->strings); strings_end = buffer_end(&ssa->strings); + if(strings_end - string > UINT16_MAX) { + amal_log_error("Too many strings in the program"); + throw(-1); + } + num_strings = strings_end - string; strings_size = 0; for(; string != strings_end; ++string) { @@ -121,7 +104,8 @@ void add_strings(BytecodeCompilerContext *self) { } string = buffer_begin(&ssa->strings); - throw_if_error(buffer_expand(instructions, sizeof(u32) + strings_size)); + throw_if_error(buffer_expand(instructions, sizeof(u16) + sizeof(u32) + strings_size)); + throw_if_error(buffer_append(instructions, &num_strings, sizeof(u16))); throw_if_error(buffer_append(instructions, &strings_size, sizeof(u32))); for(; string != strings_end; ++string) { throw_if_error(buffer_append(instructions, &string->size, sizeof(u16))); @@ -383,17 +367,19 @@ static void add_instructions(BytecodeCompilerContext *self) { } #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); - add_ins3(self, AMAL_OP_MOVI, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "movi r%d, i%d"); + 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); - add_ins3(self, AMAL_OP_MOVD, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "movd r%d, s%d"); + add_ins6(self, AMAL_OP_MOVD, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "movd r%d, s%d"); break; } case SSA_ASSIGN_REG: { @@ -479,7 +465,7 @@ static void add_instructions(BytecodeCompilerContext *self) { /* Prepend instructions with its size */ { u32 instructions_size; - instructions_size = self->bytecode.data.size - num_instructions_index; + instructions_size = self->bytecode.data.size - num_instructions_index - sizeof(instructions_size); /* Remove the count itself from the size of the instructions size */ am_memcpy(&self->bytecode.data.data[num_instructions_index], &instructions_size, sizeof(instructions_size)); } @@ -488,7 +474,6 @@ static void add_instructions(BytecodeCompilerContext *self) { } void generate_bytecode_from_ssa(BytecodeCompilerContext *self) { - add_header(self); add_intermediates(self); add_strings(self); /* TODO: Also add strings in ssa, so we can index them */ |