From cceb7b76a6f8361962ebe9fe3d0d0f4e58514f42 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Fri, 26 Jun 2020 14:57:42 -0500 Subject: [PATCH] MAJOR bug fix with binop code generation --- include/bh.h | 68 ++++----- include/onyxparser.h | 24 ++-- include/onyxwasm.h | 322 ++++++++++++++++++++++--------------------- onyx | Bin 201320 -> 202248 bytes progs/test.onyx | 7 + src/onyxwasm.c | 50 ++++++- 6 files changed, 263 insertions(+), 208 deletions(-) diff --git a/include/bh.h b/include/bh.h index f528ad26..455c7963 100644 --- a/include/bh.h +++ b/include/bh.h @@ -470,49 +470,49 @@ typedef struct bh__arr { } bh__arr; #ifndef BH_ARR_GROW_FORMULA -#define BH_ARR_GROW_FORMULA(x) ((x) > 0 ? ((x) << 1) : 4) +#define BH_ARR_GROW_FORMULA(x) ((x) > 0 ? ((x) << 1) : 4) #endif #define bh_arr(T) T* -#define bh__arrhead(arr) (((bh__arr *)(arr)) - 1) +#define bh__arrhead(arr) (((bh__arr *)(arr)) - 1) #define bh_arr_allocator(arr) (arr ? bh__arrhead(arr)->allocator : bh_heap_allocator()) -#define bh_arr_length(arr) (arr ? bh__arrhead(arr)->length : 0) +#define bh_arr_length(arr) (arr ? bh__arrhead(arr)->length : 0) #define bh_arr_capacity(arr) (arr ? bh__arrhead(arr)->capacity : 0) -#define bh_arr_size(arr) (arr ? bh__arrhead(arr)->capacity * sizeof(*(arr)) : 0) -#define bh_arr_valid(arr, i) (arr ? (i32)(i) < bh__arrhead(arr)->length : 0) +#define bh_arr_size(arr) (arr ? bh__arrhead(arr)->capacity * sizeof(*(arr)) : 0) +#define bh_arr_valid(arr, i) (arr ? (i32)(i) < bh__arrhead(arr)->length : 0) -#define bh_arr_pop(arr) ((arr)[--bh__arrhead(arr)->length]) -#define bh_arr_last(arr) ((arr)[bh__arrhead(arr)->length - 1]) -#define bh_arr_end(arr, i) ((i) >= &(arr)[bh_arr_length(arr)]) +#define bh_arr_pop(arr) ((arr)[--bh__arrhead(arr)->length]) +#define bh_arr_last(arr) ((arr)[bh__arrhead(arr)->length - 1]) +#define bh_arr_end(arr, i) ((i) >= &(arr)[bh_arr_length(arr)]) #define bh_arr_new(allocator_, arr, cap) (bh__arr_grow((allocator_), (void**) &(arr), sizeof(*(arr)), cap)) #define bh_arr_free(arr) (bh__arr_free((void**) &(arr))) #define bh_arr_copy(allocator_, arr) (bh__arr_copy((allocator_), (arr), sizeof(*(arr)))) -#define bh_arr_grow(arr, cap) (bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), cap)) +#define bh_arr_grow(arr, cap) (bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), cap)) #define bh_arr_shrink(arr, cap) (bh__arr_shrink((void **) &(arr), sizeof(*(arr)), cap)) -#define bh_arr_set_length(arr, n) ( \ +#define bh_arr_set_length(arr, n) ( \ bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), n), \ bh__arrhead(arr)->length = n) -#define bh_arr_insertn(arr, i, n) (bh__arr_insertn((void **) &(arr), sizeof(*(arr)), i, n)) +#define bh_arr_insertn(arr, i, n) (bh__arr_insertn((void **) &(arr), sizeof(*(arr)), i, n)) -#define bh_arr_insert_end(arr, n) ( \ +#define bh_arr_insert_end(arr, n) ( \ bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + n), \ bh__arrhead(arr)->length += n) -#define bh_arr_push(arr, value) ( \ +#define bh_arr_push(arr, value) ( \ bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + 1), \ arr[bh__arrhead(arr)->length++] = value) -#define bh_arr_is_empty(arr) (arr ? bh__arrhead(arr)->length == 0 : 1) -#define bh_arr_clear(arr) (arr ? (bh__arrhead(arr)->length = 0) : 0) +#define bh_arr_is_empty(arr) (arr ? bh__arrhead(arr)->length == 0 : 1) +#define bh_arr_clear(arr) (arr ? (bh__arrhead(arr)->length = 0) : 0) -#define bh_arr_deleten(arr, i, n) (bh__arr_deleten((void **) &(arr), sizeof(*(arr)), i, n)) -#define bh_arr_fastdelete(arr, i) (arr[i] = arr[--bh__arrhead(arr)->length]) +#define bh_arr_deleten(arr, i, n) (bh__arr_deleten((void **) &(arr), sizeof(*(arr)), i, n)) +#define bh_arr_fastdelete(arr, i) (arr[i] = arr[--bh__arrhead(arr)->length]) -#define bh_arr_each(T, var, arr) for (T* var = (arr); !bh_arr_end((arr), var); var++) +#define bh_arr_each(T, var, arr) for (T* var = (arr); !bh_arr_end((arr), var); var++) b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap); b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap); @@ -570,26 +570,26 @@ typedef struct bh__table { #ifdef BH_TABLE_SIZE_SAFE #define bh_table_init(allocator_, tab, hs) bh__table_init(allocator_, (bh__table **)&(tab), hs) #define bh_table_free(tab) bh__table_free((bh__table **)&(tab)) - #define bh_table_put(T, tab, key, value) (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = (T) value)) - #define bh_table_has(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), (bh__table_has((bh__table *) tab, sizeof(T), key))) - #define bh_table_get(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_get((bh__table *) tab, sizeof(T), key)))) - #define bh_table_delete(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), bh__table_delete((bh__table *) tab, sizeof(T), key)) - #define bh_table_clear(tab) (bh__table_clear((bh__table *) tab)) - - #define bh_table_iter_setup(T, tab) (assert(sizeof(T) == sizeof(*(tab))), bh__table_iter_setup((bh__table *) tab, sizeof(T))) - #define bh_table_iter_key(it) ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16)))) + #define bh_table_put(T, tab, key, value) (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = (T) value)) + #define bh_table_has(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), (bh__table_has((bh__table *) tab, sizeof(T), key))) + #define bh_table_get(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_get((bh__table *) tab, sizeof(T), key)))) + #define bh_table_delete(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), bh__table_delete((bh__table *) tab, sizeof(T), key)) + #define bh_table_clear(tab) (bh__table_clear((bh__table *) tab)) + + #define bh_table_iter_setup(T, tab) (assert(sizeof(T) == sizeof(*(tab))), bh__table_iter_setup((bh__table *) tab, sizeof(T))) + #define bh_table_iter_key(it) ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16)))) #define bh_table_iter_value(T, it) (*(T *)it.entry) #else #define bh_table_init(allocator_, tab, hs) bh__table_init(allocator_, (bh__table **)&(tab), hs) #define bh_table_free(tab) bh__table_free((bh__table **)&(tab)) - #define bh_table_put(T, tab, key, value) (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = (T) value) - #define bh_table_has(T, tab, key) (bh__table_has((bh__table *) tab, sizeof(T), key)) - #define bh_table_get(T, tab, key) (*((T *) bh__table_get((bh__table *) tab, sizeof(T), key))) - #define bh_table_delete(T, tab, key) (bh__table_delete((bh__table *) tab, sizeof(T), key)) - #define bh_table_clear(tab) (bh__table_clear((bh__table *) tab)) - - #define bh_table_iter_setup(T, tab) (bh__table_iter_setup((bh__table *) tab, sizeof(T))) - #define bh_table_iter_key(it) ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16)))) + #define bh_table_put(T, tab, key, value) (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = (T) value) + #define bh_table_has(T, tab, key) (bh__table_has((bh__table *) tab, sizeof(T), key)) + #define bh_table_get(T, tab, key) (*((T *) bh__table_get((bh__table *) tab, sizeof(T), key))) + #define bh_table_delete(T, tab, key) (bh__table_delete((bh__table *) tab, sizeof(T), key)) + #define bh_table_clear(tab) (bh__table_clear((bh__table *) tab)) + + #define bh_table_iter_setup(T, tab) (bh__table_iter_setup((bh__table *) tab, sizeof(T))) + #define bh_table_iter_key(it) ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16)))) #define bh_table_iter_value(T, it) (*(T *)it.entry) #endif diff --git a/include/onyxparser.h b/include/onyxparser.h index 94e934bc..521a195f 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -110,18 +110,18 @@ typedef enum OnyxUnaryOp { } OnyxUnaryOp; typedef enum OnyxBinaryOp { - ONYX_BINARY_OP_ADD, - ONYX_BINARY_OP_MINUS, - ONYX_BINARY_OP_MULTIPLY, - ONYX_BINARY_OP_DIVIDE, - ONYX_BINARY_OP_MODULUS, - - ONYX_BINARY_OP_EQUAL, - ONYX_BINARY_OP_NOT_EQUAL, - ONYX_BINARY_OP_LESS, - ONYX_BINARY_OP_LESS_EQUAL, - ONYX_BINARY_OP_GREATER, - ONYX_BINARY_OP_GREATER_EQUAL, + ONYX_BINARY_OP_ADD = 0, + ONYX_BINARY_OP_MINUS = 1, + ONYX_BINARY_OP_MULTIPLY = 2, + ONYX_BINARY_OP_DIVIDE = 3, + ONYX_BINARY_OP_MODULUS = 4, + + ONYX_BINARY_OP_EQUAL = 5, + ONYX_BINARY_OP_NOT_EQUAL = 6, + ONYX_BINARY_OP_LESS = 7, + ONYX_BINARY_OP_LESS_EQUAL = 8, + ONYX_BINARY_OP_GREATER = 9, + ONYX_BINARY_OP_GREATER_EQUAL = 10, } OnyxBinaryOp; struct OnyxAstNodeBinOp { diff --git a/include/onyxwasm.h b/include/onyxwasm.h index f73d1b1b..b86e2c5a 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -27,170 +27,170 @@ typedef enum WasmInstructionType { // NOTE: Control flow WI_BLOCK_START = 0x02, - WI_BLOCK_END = 0x0B, // NOTE: These ends are not unique - WI_LOOP_START = 0x03, - WI_LOOP_END = 0x0B, - WI_IF_START = 0x04, - WI_ELSE = 0x05, - WI_IF_END = 0x0B, - WI_JUMP = 0x0C, - WI_COND_JUMP = 0x0D, - WI_JUMP_TABLE = 0x0E, - WI_RETURN = 0x0F, - WI_CALL = 0x10, - WI_CALL_INDIRECT = 0x11, + WI_BLOCK_END = 0x0B, // NOTE: These ends are not unique + WI_LOOP_START = 0x03, + WI_LOOP_END = 0x0B, + WI_IF_START = 0x04, + WI_ELSE = 0x05, + WI_IF_END = 0x0B, + WI_JUMP = 0x0C, + WI_COND_JUMP = 0x0D, + WI_JUMP_TABLE = 0x0E, + WI_RETURN = 0x0F, + WI_CALL = 0x10, + WI_CALL_INDIRECT = 0x11, // NOTE: Parametric instructions - WI_DROP = 0x1A, - WI_SELECT = 0x1B, + WI_DROP = 0x1A, + WI_SELECT = 0x1B, // NOTE: Variable instructions - WI_LOCAL_GET = 0x20, - WI_LOCAL_SET = 0x21, - WI_LOCAL_TEE = 0x22, - WI_GLOBAL_GET = 0x23, - WI_GLOBAL_SET = 0x24, + WI_LOCAL_GET = 0x20, + WI_LOCAL_SET = 0x21, + WI_LOCAL_TEE = 0x22, + WI_GLOBAL_GET = 0x23, + WI_GLOBAL_SET = 0x24, // NOTE: Memory instructions - WI_I32_LOAD = 0x28, - WI_I64_LOAD = 0x29, - WI_F32_LOAD = 0x2A, - WI_F64_LOAD = 0x2B, - WI_I32_LOAD_8_S = 0x2C, - WI_I32_LOAD_8_U = 0x2D, - WI_I32_LOAD_16_S = 0x2E, - WI_I32_LOAD_16_U = 0x2F, - WI_I64_LOAD_8_S = 0x30, - WI_I64_LOAD_8_U = 0x31, - WI_I64_LOAD_16_S = 0x32, - WI_I64_LOAD_16_U = 0x33, - WI_I64_LOAD_32_S = 0x34, - WI_I64_LOAD_32_U = 0x35, - WI_I32_STORE = 0x36, - WI_I64_STORE = 0x37, - WI_F32_STORE = 0x38, - WI_F64_STORE = 0x39, + WI_I32_LOAD = 0x28, + WI_I64_LOAD = 0x29, + WI_F32_LOAD = 0x2A, + WI_F64_LOAD = 0x2B, + WI_I32_LOAD_8_S = 0x2C, + WI_I32_LOAD_8_U = 0x2D, + WI_I32_LOAD_16_S = 0x2E, + WI_I32_LOAD_16_U = 0x2F, + WI_I64_LOAD_8_S = 0x30, + WI_I64_LOAD_8_U = 0x31, + WI_I64_LOAD_16_S = 0x32, + WI_I64_LOAD_16_U = 0x33, + WI_I64_LOAD_32_S = 0x34, + WI_I64_LOAD_32_U = 0x35, + WI_I32_STORE = 0x36, + WI_I64_STORE = 0x37, + WI_F32_STORE = 0x38, + WI_F64_STORE = 0x39, WI_I32_STORE_8 = 0x3A, - WI_I32_STORE_16 = 0x3B, + WI_I32_STORE_16 = 0x3B, WI_I64_STORE_8 = 0x3C, - WI_I64_STORE_16 = 0x3D, - WI_I64_STORE_32 = 0x3E, + WI_I64_STORE_16 = 0x3D, + WI_I64_STORE_32 = 0x3E, WI_MEMORY_SIZE = 0x3F, WI_MEMORY_GROW = 0x40, // NOTE: Numeric Instructions - WI_I32_CONST = 0x41, - WI_I64_CONST = 0x42, - WI_F32_CONST = 0x43, - WI_F64_CONST = 0x44, - - WI_I32_EQZ = 0x45, // NOTE: Autoincremented from here - WI_I32_EQ, - WI_I32_NE, - WI_I32_LT_S, - WI_I32_LT_U, - WI_I32_GT_S, - WI_I32_GT_U, - WI_I32_LE_S, - WI_I32_LE_U, - WI_I32_GE_S, - WI_I32_GE_U, - - WI_I64_EQZ, - WI_I64_EQ, - WI_I64_NE, - WI_I64_LT_S, - WI_I64_LT_U, - WI_I64_GT_S, - WI_I64_GT_U, - WI_I64_LE_S, - WI_I64_LE_U, - WI_I64_GE_S, - WI_I64_GE_U, - - WI_F32_EQ, - WI_F32_NE, - WI_F32_LT, - WI_F32_GT, - WI_F32_LE, - WI_F32_GE, - - WI_F64_EQ, - WI_F64_NE, - WI_F64_LT, - WI_F64_GT, - WI_F64_LE, - WI_F64_GE, - - WI_I32_CLZ, - WI_I32_CTZ, - WI_I32_POPCNT, - WI_I32_ADD, - WI_I32_SUB, - WI_I32_MUL, - WI_I32_DIV_S, - WI_I32_DIV_U, - WI_I32_REM_S, - WI_I32_REM_U, - WI_I32_AND, - WI_I32_OR, - WI_I32_XOR, - WI_I32_SHL, - WI_I32_SHR_S, - WI_I32_SHR_U, - WI_I32_ROTL, - WI_I32_ROTR, - - WI_I64_CLZ, - WI_I64_CTZ, - WI_I64_POPCNT, - WI_I64_ADD, - WI_I64_SUB, - WI_I64_MUL, - WI_I64_DIV_S, - WI_I64_DIV_U, - WI_I64_REM_S, - WI_I64_REM_U, - WI_I64_AND, - WI_I64_OR, - WI_I64_XOR, - WI_I64_SHL, - WI_I64_SHR_S, - WI_I64_SHR_U, - WI_I64_ROTL, - WI_I64_ROTR, - - WI_F32_ABS, - WI_F32_NEG, - WI_F32_CEIL, - WI_F32_FLOOR, - WI_F32_TRUNC, - WI_F32_NEAREST, - WI_F32_SQRT, - WI_F32_ADD, - WI_F32_SUB, - WI_F32_MUL, - WI_F32_DIV, - WI_F32_MIN, - WI_F32_MAX, - WI_F32_COPYSIGN, - - WI_F64_ABS, - WI_F64_NEG, - WI_F64_CEIL, - WI_F64_FLOOR, - WI_F64_TRUNC, - WI_F64_NEAREST, - WI_F64_SQRT, - WI_F64_ADD, - WI_F64_SUB, - WI_F64_MUL, - WI_F64_DIV, - WI_F64_MIN, - WI_F64_MAX, - WI_F64_COPYSIGN, - - WI_I32_FROM_I64 = 0xA7, + WI_I32_CONST = 0x41, + WI_I64_CONST = 0x42, + WI_F32_CONST = 0x43, + WI_F64_CONST = 0x44, + + WI_I32_EQZ = 0x45, + WI_I32_EQ = 0x46, + WI_I32_NE = 0x47, + WI_I32_LT_S = 0x48, + WI_I32_LT_U = 0x49, + WI_I32_GT_S = 0x4a, + WI_I32_GT_U = 0x4b, + WI_I32_LE_S = 0x4c, + WI_I32_LE_U = 0x4d, + WI_I32_GE_S = 0x4e, + WI_I32_GE_U = 0x4f, + + WI_I64_EQZ = 0x50, + WI_I64_EQ = 0x51, + WI_I64_NE = 0x52, + WI_I64_LT_S = 0x53, + WI_I64_LT_U = 0x54, + WI_I64_GT_S = 0x55, + WI_I64_GT_U = 0x56, + WI_I64_LE_S = 0x57, + WI_I64_LE_U = 0x58, + WI_I64_GE_S = 0x59, + WI_I64_GE_U = 0x5a, + + WI_F32_EQ = 0x5b, + WI_F32_NE = 0x5c, + WI_F32_LT = 0x5d, + WI_F32_GT = 0x5e, + WI_F32_LE = 0x5f, + WI_F32_GE = 0x60, + + WI_F64_EQ = 0x61, + WI_F64_NE = 0x62, + WI_F64_LT = 0x63, + WI_F64_GT = 0x64, + WI_F64_LE = 0x65, + WI_F64_GE = 0x66, + + WI_I32_CLZ = 0x67, + WI_I32_CTZ = 0x68, + WI_I32_POPCNT = 0x69, + WI_I32_ADD = 0x6a, + WI_I32_SUB = 0x6b, + WI_I32_MUL = 0x6c, + WI_I32_DIV_S = 0x6d, + WI_I32_DIV_U = 0x6e, + WI_I32_REM_S = 0x6f, + WI_I32_REM_U = 0x70, + WI_I32_AND = 0x71, + WI_I32_OR = 0x72, + WI_I32_XOR = 0x73, + WI_I32_SHL = 0x74, + WI_I32_SHR_S = 0x75, + WI_I32_SHR_U = 0x76, + WI_I32_ROTL = 0x77, + WI_I32_ROTR = 0x78, + + WI_I64_CLZ = 0x79, + WI_I64_CTZ = 0x7a, + WI_I64_POPCNT = 0x7b, + WI_I64_ADD = 0x7c, + WI_I64_SUB = 0x7d, + WI_I64_MUL = 0x7e, + WI_I64_DIV_S = 0x7f, + WI_I64_DIV_U = 0x80, + WI_I64_REM_S = 0x81, + WI_I64_REM_U = 0x82, + WI_I64_AND = 0x83, + WI_I64_OR = 0x84, + WI_I64_XOR = 0x85, + WI_I64_SHL = 0x86, + WI_I64_SHR_S = 0x87, + WI_I64_SHR_U = 0x88, + WI_I64_ROTL = 0x89, + WI_I64_ROTR = 0x8a, + + WI_F32_ABS = 0x8b, + WI_F32_NEG = 0x8c, + WI_F32_CEIL = 0x8d, + WI_F32_FLOOR = 0x8e, + WI_F32_TRUNC = 0x8f, + WI_F32_NEAREST = 0x90, + WI_F32_SQRT = 0x91, + WI_F32_ADD = 0x92, + WI_F32_SUB = 0x93, + WI_F32_MUL = 0x94, + WI_F32_DIV = 0x95, + WI_F32_MIN = 0x96, + WI_F32_MAX = 0x97, + WI_F32_COPYSIGN = 0x98, + + WI_F64_ABS = 0x99, + WI_F64_NEG = 0x9a, + WI_F64_CEIL = 0x9b, + WI_F64_FLOOR = 0x9c, + WI_F64_TRUNC = 0x9d, + WI_F64_NEAREST = 0x9e, + WI_F64_SQRT = 0x9f, + WI_F64_ADD = 0xA0, + WI_F64_SUB = 0xA1, + WI_F64_MUL = 0xA2, + WI_F64_DIV = 0xA3, + WI_F64_MIN = 0xA4, + WI_F64_MAX = 0xA5, + WI_F64_COPYSIGN = 0xA6, + + WI_I32_FROM_I64 = 0xA7, WI_I32_FROM_F32_S = 0xA8, WI_I32_FROM_F32_U = 0xA9, WI_I32_FROM_F64_S = 0xAA, @@ -207,18 +207,18 @@ typedef enum WasmInstructionType { WI_F32_FROM_I32_U = 0xB3, WI_F32_FROM_I64_S = 0xB4, WI_F32_FROM_I64_U = 0xB5, - WI_F32_FROM_F64 = 0xB6, + WI_F32_FROM_F64 = 0xB6, WI_F64_FROM_I32_S = 0xB7, WI_F64_FROM_I32_U = 0xB8, WI_F64_FROM_I64_S = 0xB9, WI_F64_FROM_I64_U = 0xBA, - WI_F64_FROM_F32 = 0xBB, + WI_F64_FROM_F32 = 0xBB, - WI_I32_REINTERPRET_F32 = 0xBC, - WI_I64_REINTERPRET_F64 = 0xBD, - WI_F32_REINTERPRET_I32 = 0xBE, - WI_F64_REINTERPRET_I64 = 0xBF, + WI_I32_REINTERPRET_F32 = 0xBC, + WI_I64_REINTERPRET_F64 = 0xBD, + WI_F32_REINTERPRET_I32 = 0xBE, + WI_F64_REINTERPRET_I64 = 0xBF, } WasmInstructionType; typedef union { @@ -250,8 +250,8 @@ typedef struct WasmFunc { } WasmFunc; typedef enum WasmForeignKind { - WASM_FOREIGN_FUNCTION = 0x00, - WASM_FOREIGN_TABLE = 0x01, + WASM_FOREIGN_FUNCTION = 0x00, + WASM_FOREIGN_TABLE = 0x01, WASM_FOREIGN_MEMORY = 0x02, WASM_FOREIGN_GLOBAL = 0x03, } WasmForeignKind; @@ -273,6 +273,8 @@ typedef struct OnyxWasmModule { // NOTE: Mapping from local ast node ptrs to indicies bh_imap local_map; + bh_arr(u8) structured_jump_target; + // NOTE: Used internally as a map from strings that represent function types, // 0x7f 0x7f : 0x7f ( (i32, i32) -> i32 ) // to the function type index if it has been created. diff --git a/onyx b/onyx index 9ce36fd1abca2cc2cf9e0f4ffedaf81a7e5a9ce4..1342320070f7dec55390d54d1e1f8bfc7d38de45 100755 GIT binary patch delta 41600 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 2 { break; } + y = y + 1; } } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index eec71c03..01c369f0 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -241,6 +241,28 @@ static void compile_block(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeBlock* bh_arr_push(func->code, ((WasmInstruction){ WI_BLOCK_END, 0x00 })); } +static void compile_structured_jump(OnyxWasmModule* mod, WasmFunc* func, b32 jump_backward) { + i32 labelidx = 0; + u8 wanted = jump_backward ? 2 : 1; + b32 success = 0; + + i32 len = bh_arr_length(mod->structured_jump_target) - 1; + for (u8* t = &bh_arr_last(mod->structured_jump_target); len >= 0; len--, t--) { + if (*t == wanted) { + success = 1; + break; + } + + labelidx++; + } + + if (success) { + bh_arr_push(func->code, ((WasmInstruction){ WI_JUMP, labelidx })); + } else { + assert(("Invalid structured jump", 0)); + } +} + static void compile_statement(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* stmt) { switch (stmt->kind) { case ONYX_AST_NODE_KIND_SCOPE: break; @@ -248,6 +270,8 @@ static void compile_statement(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* case ONYX_AST_NODE_KIND_ASSIGNMENT: compile_assignment(mod, func, stmt); break; case ONYX_AST_NODE_KIND_IF: compile_if(mod, func, (OnyxAstNodeIf *) stmt); break; case ONYX_AST_NODE_KIND_WHILE: compile_while(mod, func, (OnyxAstNodeWhile *) stmt); break; + case ONYX_AST_NODE_KIND_BREAK: compile_structured_jump(mod, func, 0); break; + case ONYX_AST_NODE_KIND_CONTINUE: compile_structured_jump(mod, func, 1); break; case ONYX_AST_NODE_KIND_CALL: compile_expression(mod, func, stmt); break; case ONYX_AST_NODE_KIND_BLOCK: compile_block(mod, func, (OnyxAstNodeBlock *) stmt); break; @@ -269,6 +293,8 @@ static void compile_if(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeIf* if_no compile_expression(mod, func, if_node->cond); bh_arr_push(func->code, ((WasmInstruction){ WI_IF_START, 0x40 })); + bh_arr_push(mod->structured_jump_target, 0); + if (if_node->true_block) { // NOTE: This is kind of gross, but making a function for this doesn't feel right @@ -297,6 +323,8 @@ static void compile_if(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeIf* if_no } } + bh_arr_pop(mod->structured_jump_target); + bh_arr_push(func->code, ((WasmInstruction){ WI_IF_END, 0x00 })); } @@ -308,10 +336,16 @@ static void compile_while(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeWhile* bh_arr_push(func->code, ((WasmInstruction){ WI_I32_EQZ, 0x00 })); bh_arr_push(func->code, ((WasmInstruction){ WI_COND_JUMP, 0x01 })); + bh_arr_push(mod->structured_jump_target, 1); + bh_arr_push(mod->structured_jump_target, 2); + forll (OnyxAstNode, stmt, while_node->body->body, next) { compile_statement(mod, func, stmt); } + bh_arr_pop(mod->structured_jump_target); + bh_arr_pop(mod->structured_jump_target); + bh_arr_push(func->code, ((WasmInstruction){ WI_JUMP, 0x00 })); bh_arr_push(func->code, ((WasmInstruction){ WI_LOOP_END, 0x00 })); @@ -357,7 +391,13 @@ static void compile_binop(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeBinOp* } WasmType operator_type = onyx_type_to_wasm_type(binop->left->type); - WasmInstructionType binop_instr = binop_map[binop->operation][operator_type]; + i32 optype = 0; + if (operator_type == WASM_TYPE_INT32) optype = 0; + else if (operator_type == WASM_TYPE_INT64) optype = 1; + else if (operator_type == WASM_TYPE_FLOAT32) optype = 2; + else if (operator_type == WASM_TYPE_FLOAT64) optype = 3; + + WasmInstructionType binop_instr = binop_map[(i32) binop->operation][optype]; if (binop_instr == WI_NOP) { assert(("Invalid type and operation", 0)); @@ -368,7 +408,7 @@ static void compile_binop(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeBinOp* // the signed equivalent if (is_sign_significant) { if (binop->left->type->is_unsigned) { - binop_instr += 1; + binop_instr = (WasmInstructionType) ((i32) binop_instr + 1); } } @@ -677,12 +717,18 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) { .imports = NULL, .next_import_func_idx = 0, + + .structured_jump_target = NULL, }; bh_arr_new(alloc, module.functypes, 4); bh_arr_new(alloc, module.funcs, 4); bh_arr_new(alloc, module.imports, 4); + // NOTE: 16 is probably needlessly large + bh_arr_new(bh_heap_allocator(), module.structured_jump_target, 16); + bh_arr_set_length(module.structured_jump_target, 0); + bh_table_init(bh_heap_allocator(), module.type_map, 61); bh_table_init(bh_heap_allocator(), module.exports, 61); -- 2.25.1