From 16aaaa19a3ef4220726007d3e644ced0c9e06513 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 9 Sep 2019 01:08:34 +0200 Subject: Allow referencing code in imported file (right now for function calls, allow calling a function in another file) --- include/bytecode/bytecode.h | 46 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) (limited to 'include/bytecode') diff --git a/include/bytecode/bytecode.h b/include/bytecode/bytecode.h index b1b5dda..c495d7a 100644 --- a/include/bytecode/bytecode.h +++ b/include/bytecode/bytecode.h @@ -26,11 +26,15 @@ 6.2 Opcode(u8) + register(i8) + intermediate(u16)\ 6.3 Opcode(u8) + register(i8) + data(u16)\ 6.4 Opcode(u8) + flags(u8) + num_local_var_reg(u16) - 7. 5 bytes: Opcode(u8) + index(u16) + num_args(u8) + register(i8) + 7. 5 bytes: Opcode(u8) + index(u8) + index(u16) + num_args(u8) # Registers Registers have a range of 128. Local variables start from register 0 and increment while parameters start from -1 and decrement. Registers have the scope of functions and reset after instructions reach a new function (AMAL_OP_FUNC_START). + + If import index for call and calle is 0, then that means the function resides in the same file the function call + is being called from. Which means that import index 1 is actually import index 0 into the import list. */ +/* Important: The number of fields in this enum can't exceed 255 */ typedef enum { AMAL_OP_NOP, /* No operation (do nothing). This can be used for patching code */ AMAL_OP_SETZ, /* setz reg - Set register value to 0 */ @@ -46,16 +50,17 @@ typedef enum { AMAL_OP_PUSH, /* push reg - Push register onto stack */ AMAL_OP_PUSHI, /* pushi int - Push intermediate onto stack */ AMAL_OP_PUSHD, /* pushd data - Push data onto stack */ - AMAL_OP_CALL, /* call fi, num_args, dst - Call a function using function index (fi) and num_args arguments. The result is stored in register dst. fi is u16 and num_args is u8 */ + AMAL_OP_PUSH_RET, /* push_ret reg - Push register onto stack as a return value of the next function call */ + AMAL_OP_CALL, /* call ii, fi, num_args - Call a function in imported file (ii, import index) using function index (fi) and num_args arguments. ii is u8, fi is u16 and num_args is u8 */ AMAL_OP_CALLR, /* callr reg, num_args - Call a function using a register. Used for function pointers. num_args is u8 */ - AMAL_OP_CALLE, /* calle efi, num_args, dst - Call an extern function using extern function index (efi) and num_args arguments. The result is stored in register dst. efi is u16 and num_args is u8 */ + AMAL_OP_CALLE, /* calle ii, efi, num_args - Call an extern function in imported file (ii, import index) using extern function index (efi) and num_args arguments. ii is u8, efi is u16 and num_args is u8 */ AMAL_OP_CMP, /* cmp dst, reg1, reg2 - Set dst to 1 if reg1 equals reg2, otherwise set it to 0 */ AMAL_OP_JZ, /* jz reg, label - Jump to label in the current function if reg is zero. label is u16 */ AMAL_OP_JMP, /* jmp label - Unconditional jump to label in the current function. label is u16 */ AMAL_OP_RET, /* ret reg - Return from the function with reg result */ AMAL_OP_FUNC_START, /* func_start flags, num_local_var_reg - Start of a function which has @num_local_var_reg local variable registers allocated and has the flag @flag. @flag is u8 and @num_local_var_reg is u16 */ AMAL_OP_FUNC_END, /* func_end - End of a function. Implementation should do a ret here */ - AMAL_OP_LABEL, /* label - Label. This is the target of a jump instruction. Jump instructions only jump to labels in the same function scope */ + AMAL_OP_LABEL /* label - Label. This is the target of a jump instruction. Jump instructions only jump to labels in the same function scope */ } AmalOpcode; #define AMAL_BYTECODE_MAGIC_NUMBER (u32)0xdec05eba @@ -63,6 +68,8 @@ typedef enum { #define AMAL_BYTECODE_MINOR_VERSION 0 #define AMAL_BYTECODE_PATCH_VERSION 0 +#define AMAL_BYTECODE_SECTION_MAGIC_NUMBER (u32)0x004005e4 /* "section\0" in ascii */ + #define AMAL_BYTECODE_NUM_REGISTERS 256 typedef enum { @@ -72,13 +79,40 @@ typedef enum { typedef u8 AmalOpcodeType; +/* TODO: Make sure this pragma pack works on all platforms */ +#pragma pack(push, 1) +typedef struct { + u32 func_offset; + u8 num_params; + u32 params_num_pointers; + u32 params_fixed_size; + + u8 num_return_types; + u32 return_types_num_pointers; + u32 return_types_fixed_size; +} BytecodeHeaderFunction; +#pragma pack(pop) + +/* TODO: Make sure this pragma pack works on all platforms */ +#pragma pack(push, 1) typedef struct { + u32 function_index; + #define parser_index function_index + u32 extern_function_index; +} BytecodeHeaderImport; +#pragma pack(pop) + +struct Bytecode { Buffer/**/ data; -} Bytecode; + usize import_index; /* Reference inside @data where imports start */ + u32 funcs_index; /* Reference inside @data where funcs start */ + u32 extern_funcs_index; /* Reference inside @data where extern funcs start */ + u32 offset; /* Offset that this bytecode starts from in the final program (all bytecodes combined) */ +}; typedef struct { jmp_buf env; - Bytecode bytecode; + Bytecode *bytecode; Parser *parser; /* borrowed */ } BytecodeCompilerContext; -- cgit v1.2.3