From: Brendan Hansen Date: Tue, 9 Jun 2020 13:01:20 +0000 (-0500) Subject: Added exports to WASM Module and other bug fixes X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=1711b7ce950717606dc9e104abb1fe63357f7ac2;p=onyx.git Added exports to WASM Module and other bug fixes --- diff --git a/include/onyxparser.h b/include/onyxparser.h index d61f5b19..f210da90 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -118,7 +118,7 @@ struct OnyxAstNodeLocal { OnyxTypeInfo *type; OnyxAstNodeLocal *prev_local; OnyxAstNode *shadowed; - OnyxAstNode *unused; + ptr unused; }; // NOTE: Needs to have shadowed in the same position as OnyxAstNodeLocal @@ -129,7 +129,7 @@ struct OnyxAstNodeParam { OnyxTypeInfo *type; OnyxAstNodeParam *next; OnyxAstNode *shadowed; - u64 param_count; + ptr unused; }; struct OnyxAstNodeScope { diff --git a/include/onyxwasm.h b/include/onyxwasm.h index e7808e75..feebeddd 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -6,7 +6,7 @@ #include "onyxparser.h" -typedef char WasmType; +typedef u8 WasmType; extern const WasmType WASM_TYPE_INT32; extern const WasmType WASM_TYPE_INT64; @@ -21,11 +21,23 @@ typedef struct WasmFuncType { WasmType param_types[]; } WasmFuncType; + typedef struct WasmFunc { - i32 idx; i32 type_idx; } WasmFunc; +typedef enum WasmExportKind { + WASM_EXPORT_FUNCTION, + WASM_EXPORT_TABLE, + WASM_EXPORT_MEMORY, + WASM_EXPORT_GLOBAL, +} WasmExportKind; + +typedef struct WasmExport { + WasmExportKind kind; + i32 idx; +} WasmExport; + typedef struct OnyxWasmModule { bh_allocator allocator; @@ -34,10 +46,13 @@ typedef struct OnyxWasmModule { // to the function type index if it has been created. bh_hash(i32) type_map; i32 next_type_idx; - // NOTE: This have to be pointers because the type is variadic in size bh_arr(WasmFuncType*) functypes; + bh_arr(WasmFunc) funcs; + i32 next_func_idx; + + bh_hash(WasmExport) exports; } OnyxWasmModule; OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* program); diff --git a/onyx b/onyx index 802912fc..4aeca702 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/minimal.onyx b/progs/minimal.onyx index b228c230..3b3499fe 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -3,9 +3,13 @@ export add :: proc (a i32, b i32) -> i32 { return a + b; } +export foo :: proc () -> i32 { + return 10 as i32; +} + export mul :: proc (a i32, b i32) -> i64 { // Typechecked - c: const i64 = ((a as i64) - (b as i64)); + c: const = a - b; // Don't love this syntax, but it's easy to parse so whatever // Inferred type, but constant @@ -14,5 +18,5 @@ export mul :: proc (a i32, b i32) -> i64 { e: i32 = 10 as i32; - return ((c as i32) * d) as i64; + return (c * d) as i64; } diff --git a/src/onyx.c b/src/onyx.c index 20edcb87..731688bb 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -7,6 +7,7 @@ #include "onyxmsgs.h" #include "onyxparser.h" #include "onyxutils.h" +#include "onyxwasm.h" int main(int argc, char *argv[]) { bh_file source_file; @@ -59,7 +60,53 @@ int main(int argc, char *argv[]) { bh_printf("\nNo errors.\n"); } + OnyxWasmModule wasm_mod = onyx_wasm_generate_module(alloc, program); +#if 1 + // NOTE: Ensure type table made correctly + + bh_printf("Type map:\n"); + bh_hash_iterator type_map_it = bh_hash_iter_setup(i32, wasm_mod.type_map); + while (bh_hash_iter_next(&type_map_it)) { + const char* key = bh_hash_iter_key(type_map_it); + i32 value = bh_hash_iter_value(i32, type_map_it); + + bh_printf("%s -> %d\n", key, value); + } + + bh_printf("Type list:\n"); + WasmFuncType** func_type = wasm_mod.functypes; + while (!bh_arr_end(wasm_mod.functypes, func_type)) { + for (int p = 0; p < (*func_type)->param_count; p++) { + bh_printf("%c ", (*func_type)->param_types[p]); + } + bh_printf("-> "); + bh_printf("%c\n", (*func_type)->return_type); + + func_type++; + } +#endif + +#if 1 + // NOTE: Ensure the export table was built correctly + + bh_printf("Function types:\n"); + for (WasmFunc* func_it = wasm_mod.funcs; !bh_arr_end(wasm_mod.funcs, func_it); func_it++) { + bh_printf("%d\n", func_it->type_idx); + } + + bh_printf("Exports:\n"); + bh_hash_iterator export_it = bh_hash_iter_setup(WasmExport, wasm_mod.exports); + while (bh_hash_iter_next(&export_it)) { + const char* key = bh_hash_iter_key(export_it); + WasmExport value = bh_hash_iter_value(WasmExport, export_it); + + bh_printf("%s: %d %d\n", key, value.kind, value.idx); + } +#endif + + + onyx_wasm_module_free(&wasm_mod); main_exit: // NOTE: Cleanup, since C doesn't have defer bh_arena_free(&msg_arena); bh_arena_free(&ast_arena); diff --git a/src/onyxparser.c b/src/onyxparser.c index 103d8e3c..646e6e06 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -544,15 +544,12 @@ static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { } OnyxAstNodeParam* first_param = NULL; - u64 param_count = 0; - OnyxAstNodeParam* curr_param = NULL; OnyxAstNodeParam* trailer = NULL; OnyxToken* symbol; while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { if (parser->curr_token->type == TOKEN_TYPE_SYM_COMMA) parser_next_token(parser); - param_count++; symbol = expect(parser, TOKEN_TYPE_SYMBOL); @@ -568,8 +565,6 @@ static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { trailer = curr_param; } - first_param->param_count = param_count; - parser_next_token(parser); // Skip the ) return first_param; } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index ab9d3497..c0b91ad2 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -1,23 +1,31 @@ #include "onyxwasm.h" +// NOTE: Allows easier testing of types since most of the characters +// corresponding to these values are not printable +#if 0 const WasmType WASM_TYPE_INT32 = 0x7F; const WasmType WASM_TYPE_INT64 = 0x7E; const WasmType WASM_TYPE_FLOAT32 = 0x7D; const WasmType WASM_TYPE_FLOAT64 = 0x7C; +#else +const WasmType WASM_TYPE_INT32 = 'A'; +const WasmType WASM_TYPE_INT64 = 'B'; +const WasmType WASM_TYPE_FLOAT32 = 'C'; +const WasmType WASM_TYPE_FLOAT64 = 'D'; +#endif static WasmType onyx_type_to_wasm_type(OnyxTypeInfo* type) { if (type->is_bool) return WASM_TYPE_INT32; - if (type->is_int) { + else if (type->is_int) { if (type->size == 4) return WASM_TYPE_INT32; if (type->size == 8) return WASM_TYPE_INT64; } - if (type->is_float) { + else if (type->is_float) { if (type->size == 4) return WASM_TYPE_FLOAT32; if (type->size == 8) return WASM_TYPE_FLOAT64; } // TODO: Should produce an error message if this isn't successful - // TODO: Also, this should be able to handle a "void" type return WASM_TYPE_INT32; } @@ -59,6 +67,24 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* type_idx = mod->next_type_idx; mod->next_type_idx++; } + + WasmFunc wasm_func = { + .type_idx = type_idx + }; + bh_arr_push(mod->funcs, wasm_func); + i32 func_idx = mod->next_func_idx++; + + if (fd->flags & ONYX_AST_FLAG_EXPORTED) { + onyx_token_null_toggle(*fd->token); + + WasmExport wasm_export = { + .kind = WASM_EXPORT_FUNCTION, + .idx = func_idx, + }; + bh_hash_put(WasmExport, mod->exports, fd->token->token, wasm_export); + + onyx_token_null_toggle(*fd->token); + } } OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* program) { @@ -67,15 +93,19 @@ OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* progra .type_map = NULL, .next_type_idx = 0, - .functypes = NULL, + .funcs = NULL, + .next_func_idx = 0, + + .exports = NULL, }; bh_arr_new(alloc, module.functypes, 4); bh_arr_new(alloc, module.funcs, 4); bh_hash_init(bh_heap_allocator(), module.type_map); + bh_hash_init(bh_heap_allocator(), module.exports); OnyxAstNode* walker = program; while (walker) {