From 7212ea877ed85d3b85af90c902639df44fc493f2 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 24 Aug 2019 00:48:40 +0200 Subject: Add exported variable (only functions for now), export main func, start execution from main func --- include/bytecode/bytecode.h | 60 ++++++++++++++++++++++++++++----------------- include/program.h | 16 ++++++------ include/ssa/ssa.h | 11 +++++++-- include/tokenizer.h | 1 + 4 files changed, 56 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/bytecode/bytecode.h b/include/bytecode/bytecode.h index 1e4c35d..64b54b4 100644 --- a/include/bytecode/bytecode.h +++ b/include/bytecode/bytecode.h @@ -25,7 +25,7 @@ 6.1 Opcode(u8) + register(i8) + offset(i16)\ 6.2 Opcode(u8) + register(i8) + intermediate(u16)\ 6.3 Opcode(u8) + register(i8) + data(u16)\ - 6.4 Opcode(u8) + num_param_reg(u8) + num_local_var_reg(u16) + 6.4 Opcode(u8) + flags(u8) + num_local_var_reg(u16) 7. 5 bytes: Opcode(u8) + index(u16) + num_args(u8) + register(i8) # Registers Registers have a range of 128. Local variables start from register 0 and increment while parameters start from -1 @@ -33,30 +33,42 @@ */ 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 */ - AMAL_OP_MOV, /* mov dst, src - Move src register to dst register */ - AMAL_OP_MOVI, /* movi dst, src - Move src intermediate to dst register */ - AMAL_OP_MOVD, /* movd dst, src - Move src data to dst register */ - AMAL_OP_ADD, /* add dst, reg1, reg2 - Add reg1 and reg2 and put the result in dst */ - AMAL_OP_SUB, /* sub dst, reg1, reg2 - Substract reg2 from reg1 and put the result in dst */ - AMAL_OP_IMUL, /* imul dst, reg1, reg2 - Signed multiplication */ - AMAL_OP_MUL, /* mul dst, reg1, reg2 - Unsigned multiplication */ - AMAL_OP_IDIV, /* idiv dst, reg1, reg2 - Signed division */ - AMAL_OP_DIV, /* div dst, reg1, reg2 - Unsigned division */ - 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_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_CMP, /* cmp dst, reg1, reg2 - Set dst to 1 if reg1 equals reg2, otherwise set it to 0 */ - AMAL_OP_JZ, /* jz reg, offset - Jump to offset if reg is zero. offset is i16 */ - AMAL_OP_JMP, /* jmp offset - Unconditional jump to offset. offset is i16 */ - AMAL_OP_RET, /* ret reg - Return from the function with reg result */ - AMAL_OP_FUNC_START, /* func_start num_param_reg, num_local_var_reg - Start of a function which has num_param_reg parameter registers allocated and num_local_var_reg local variable registers allocated. num_param_reg 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_SETZ, /* setz reg - Set register value to 0 */ + AMAL_OP_MOV, /* mov dst, src - Move src register to dst register */ + AMAL_OP_MOVI, /* movi dst, src - Move src intermediate to dst register */ + AMAL_OP_MOVD, /* movd dst, src - Move src data to dst register */ + AMAL_OP_ADD, /* add dst, reg1, reg2 - Add reg1 and reg2 and put the result in dst */ + AMAL_OP_SUB, /* sub dst, reg1, reg2 - Substract reg2 from reg1 and put the result in dst */ + AMAL_OP_IMUL, /* imul dst, reg1, reg2 - Signed multiplication */ + AMAL_OP_MUL, /* mul dst, reg1, reg2 - Unsigned multiplication */ + AMAL_OP_IDIV, /* idiv dst, reg1, reg2 - Signed division */ + AMAL_OP_DIV, /* div dst, reg1, reg2 - Unsigned division */ + 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_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_CMP, /* cmp dst, reg1, reg2 - Set dst to 1 if reg1 equals reg2, otherwise set it to 0 */ + AMAL_OP_JZ, /* jz reg, offset - Jump to offset if reg is zero. offset is i16 */ + AMAL_OP_JMP, /* jmp offset - Unconditional jump to offset. offset is i16 */ + 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 */ } AmalOpcode; +#define AMAL_BYTECODE_MAGIC_NUMBER (u32)0xdec05eba +#define AMAL_BYTECODE_MAJOR_VERSION 1 +#define AMAL_BYTECODE_MINOR_VERSION 0 +#define AMAL_BYTECODE_PATCH_VERSION 0 + +#define AMAL_BYTECODE_NUM_REGISTERS 256 + +typedef enum { + FUNC_FLAG_NONE = 0, + FUNC_FLAG_EXPORTED = (1 << 1) +} amal_func_flag; + typedef u8 AmalOpcodeType; typedef struct { @@ -71,6 +83,8 @@ typedef struct { CHECK_RESULT int bytecode_init(Bytecode *self, ArenaAllocator *allocator); +CHECK_RESULT int buffer_append_header(Buffer *program_data); + /* longjump to self->env on failure */ void generate_bytecode_from_ssa(BytecodeCompilerContext *self); diff --git a/include/program.h b/include/program.h index 075bfca..e3a4ac9 100644 --- a/include/program.h +++ b/include/program.h @@ -31,13 +31,10 @@ #define AMAL_PROGRAM_INSTRUCTION_INVALID_EXTERN_FUNC_INDEX -19 #define AMAL_PROGRAM_NO_SUCH_EXTERNAL_FUNCTION -20 #define AMAL_PROGRAM_EXTERN_FUNC_ALREADY_EXISTS -21 - -#define AMAL_PROGRAM_MAGIC_NUMBER (u32)0xdec05eba -#define AMAL_PROGRAM_MAJOR_VERSION 1 -#define AMAL_PROGRAM_MINOR_VERSION 0 -#define AMAL_PROGRAM_PATCH_VERSION 0 - -#define AMAL_PROGRAM_NUM_REGISTERS 256 +#define AMAL_PROGRAM_INVALID_EXPORTED_FUNCTIONS -22 +#define AMAL_PROGRAM_INVALID_EXPORTED_FUNCTIONS_SIZE -23 +#define AMAL_PROGRAM_INSTRUCTION_INVALID_EXPORTED_FUNC_INDEX -24 +#define AMAL_PROGRAM_NO_MAIN_FUNC -25 #define AMAL_PROGRAM_ARGS_SIZE_VARARGS -1 @@ -53,12 +50,17 @@ typedef struct { u8 *intermediates_start; /* Reference inside @data */ u8 *strings_start; /* Reference inside @data */ u8 *extern_funcs_start; /* Reference inside @data */ + u8 *exported_funcs; /* Reference inside @data */ + u8 *exported_funcs_end; /* Reference inside @data */ + usize read_index; + u32 main_func_instruction_offset; u16 num_intermediates; u16 num_strings; u16 num_functions; u16 num_extern_functions; + u16 num_exported_functions; ArenaAllocator allocator; /* Owned. Used by @extern_funcs_map */ HashMapType(BufferView, ProgramExternFunc) extern_funcs_map; diff --git a/include/ssa/ssa.h b/include/ssa/ssa.h index b2c8065..ed147bf 100644 --- a/include/ssa/ssa.h +++ b/include/ssa/ssa.h @@ -49,11 +49,17 @@ typedef struct { BufferView name; } SsaExternFunc; +typedef struct { + FunctionSignature *func_sig; + BufferView name; +} SsaExportFunc; + typedef i16 JumpOffset; typedef i16 SsaRegister; typedef u16 SsaIntermediateIndex; typedef u16 SsaStringIndex; typedef u16 SsaExternFuncIndex; +typedef u16 SsaExportFuncIndex; typedef u16 SsaFuncIndex; typedef struct { @@ -64,9 +70,11 @@ typedef struct { Buffer/*BufferView*/ strings; HashMapType(BufferView, SsaExternFuncIndex) extern_funcs_map; Buffer/*SsaExternFunc*/ extern_funcs; + Buffer/*SsaExportFunc*/ export_funcs; SsaIntermediateIndex intermediate_counter; SsaStringIndex string_counter; SsaExternFuncIndex extern_func_counter; + SsaExportFuncIndex export_func_counter; SsaRegister reg_counter; SsaRegister param_counter; SsaFuncIndex func_counter; @@ -85,8 +93,7 @@ typedef struct { } SsaInsForm2; typedef struct { - SsaFuncIndex func_index; - u16 num_params_regs; + u8 flags; u16 num_local_vars_regs; } SsaInsFuncStart; diff --git a/include/tokenizer.h b/include/tokenizer.h index 16123cc..57ed9de 100644 --- a/include/tokenizer.h +++ b/include/tokenizer.h @@ -38,6 +38,7 @@ typedef enum { TOK_ELSE, TOK_WHILE, TOK_EXTERN, + TOK_EXPORT, TOK_RETURN } Token; -- cgit v1.2.3