aboutsummaryrefslogtreecommitdiff
path: root/include/bytecode/bytecode.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/bytecode/bytecode.h')
-rw-r--r--include/bytecode/bytecode.h46
1 files changed, 40 insertions, 6 deletions
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/*<headers + instruction data>*/ 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;