Added exports to WASM Module and other bug fixes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 9 Jun 2020 13:01:20 +0000 (08:01 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 9 Jun 2020 13:01:20 +0000 (08:01 -0500)
include/onyxparser.h
include/onyxwasm.h
onyx
progs/minimal.onyx
src/onyx.c
src/onyxparser.c
src/onyxwasm.c

index d61f5b19c466555ceb0863bc2e9e22389c945c97..f210da90d0a419f9fcb7d6dacfae010a3c058bc8 100644 (file)
@@ -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 {
index e7808e75bce6ecac08967ef77077b8e0bdc6ccee..feebeddd595eb64205dd6584339b7018e8b5f927 100644 (file)
@@ -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 802912fcda459d7d00a6b0b5bf66102f79dbddfe..4aeca7028e2e568d81dccda14301128053fa197c 100755 (executable)
Binary files a/onyx and b/onyx differ
index b228c2309463e6a426cf97fcd47f30b757439dbb..3b3499fe2a9f94204e71094b6db7f8d638261d25 100644 (file)
@@ -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;
 }
index 20edcb87081f6826a9654bbea722cc8fecd2d110..731688bb0dbac30c5e2fc25427b55c2af01b25e5 100644 (file)
@@ -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);
index 103d8e3c095338eb05c0aeebaf3176a712076e2c..646e6e0622209d0b2a8d2ad97cfdc07162e752b9 100644 (file)
@@ -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;
 }
index ab9d349789df5d21a3e8391296ff8aba9f92710c..c0b91ad202b981dac058fec57d3bcecc8657d092 100644 (file)
@@ -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) {