aboutsummaryrefslogtreecommitdiff
path: root/src/bytecode
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytecode')
-rw-r--r--src/bytecode/bytecode.c51
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 */