From: Brendan Hansen Date: Fri, 26 Jun 2020 19:57:42 +0000 (-0500) Subject: MAJOR bug fix with binop code generation X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=cceb7b76a6f8361962ebe9fe3d0d0f4e58514f42;p=onyx.git MAJOR bug fix with binop code generation --- 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 9ce36fd1..13423200 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/test.onyx b/progs/test.onyx index db4a5d46..b0b72f5b 100644 --- a/progs/test.onyx +++ b/progs/test.onyx @@ -36,10 +36,17 @@ export main :: proc { x = 0; while x < 5 { + if x == 3 { + x = x + 1; + continue; + } + print_i32((x + y * 5) % 10); x = x + 1; } + if y > 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);