From: Brendan Hansen Date: Sat, 18 Jul 2020 22:12:29 +0000 (-0500) Subject: Slight refactoring and improvements X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=ba391b58ffcf9b1b11433c6871fbc23cff6205a0;p=onyx.git Slight refactoring and improvements --- diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index f2976489..fcd257d4 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -271,16 +271,37 @@ struct AstOverloadedFunction { bh_arr(AstTyped *) overloads; }; -// NOTE: Simple data structure for storing what comes out of the parser -typedef struct ParserOutput { - bh_arr(AstBinding *) top_level_bindings; - bh_arr(AstNode *) nodes_to_process; - bh_arr(AstFunction *) functions; - bh_arr(AstGlobal *) globals; -} ParserOutput; +// NOTE: An Entity represents something will need to be +// processed later down the pipeline. +typedef enum EntityType { + Entity_Type_Unknown, + Entity_Type_Function, + Entity_Type_Overloaded_Function, + Entity_Type_Global, + Entity_Type_Expression +} EntityType; + +typedef struct Entity { + EntityType type; + union { + AstFunction* function; + AstOverloadedFunction* overloaded_function; + AstGlobal* global; + AstTyped* expr; + }; +} Entity; + + +// NOTE: Simple data structure for storing what comes out of the parser +typedef struct ProgramInfo { + bh_arr(AstBinding *) bindings; + bh_arr(Entity) entities; + u32 foreign_func_count; + u32 foreign_global_count; +} ProgramInfo; diff --git a/include/onyxir.h b/include/onyxir.h index 97e0a3cb..5a506da1 100644 --- a/include/onyxir.h +++ b/include/onyxir.h @@ -53,6 +53,6 @@ typedef struct IrContext { IrContext ir_context_create(bh_allocator allocator); void ir_context_free(IrContext* context); -void ir_generate(IrContext* context, ParserOutput parse_output); +void ir_generate(IrContext* context, ProgramInfo parse_output); #endif // #ifndef ONYXIR_H diff --git a/include/onyxlex.h b/include/onyxlex.h index 87e957e7..24168862 100644 --- a/include/onyxlex.h +++ b/include/onyxlex.h @@ -50,7 +50,10 @@ typedef enum TokenType { typedef struct OnyxFilePos { const char* filename; char* line_start; - u32 line, column; + u32 line; + + // NOTE: This assumes that no line is no longer than 2^16 chars + u16 column, length; } OnyxFilePos; typedef struct OnyxToken { diff --git a/include/onyxsempass.h b/include/onyxsempass.h index c9227a04..af2766f2 100644 --- a/include/onyxsempass.h +++ b/include/onyxsempass.h @@ -23,13 +23,13 @@ typedef struct SemState { } SemState; // NOTE: Resolving all symbols in the tree -void onyx_resolve_symbols(SemState* state, ParserOutput* program); +void onyx_resolve_symbols(SemState* state, ProgramInfo* program); // NOTE: Inferring and checking types in the tree -void onyx_type_check(SemState* state, ParserOutput* program); +void onyx_type_check(SemState* state, ProgramInfo* program); // NOTE: Full semantic pass SemState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs); -void onyx_sempass(SemState* state, ParserOutput* program); +void onyx_sempass(SemState* state, ProgramInfo* program); #endif diff --git a/include/onyxwasm.h b/include/onyxwasm.h index 55be4e15..fe6aa6b4 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -279,10 +279,11 @@ typedef struct OnyxWasmModule { bh_allocator allocator; OnyxMessages* msgs; + // NOTE: Mapping ptrs to function / global indicies + bh_imap index_map; + // NOTE: Mapping from local ast node ptrs to indicies bh_imap local_map; - bh_imap global_map; - bh_imap func_map; // NOTE: Maps from ast node pointers to the function index // NOTE: Used internally as a map from strings that represent function types, // 0x7f 0x7f : 0x7f ( (i32, i32) -> i32 ) @@ -292,19 +293,21 @@ typedef struct OnyxWasmModule { bh_arr(u8) structured_jump_target; bh_arr(WasmFuncType*) types; // NOTE: This have to be pointers because the type is variadic in size - bh_arr(WasmImport) imports; - bh_table(WasmExport) exports; - bh_arr(WasmGlobal) globals; - bh_arr(WasmFunc) funcs; - - u16 next_type_idx; - u16 next_func_idx; - u16 next_global_idx; - u16 export_count; + bh_arr(WasmImport) imports; + bh_table(WasmExport) exports; + bh_arr(WasmGlobal) globals; + bh_arr(WasmFunc) funcs; + + u32 next_type_idx; + u32 export_count; + u32 next_func_idx; + u32 next_foreign_func_idx; + u32 next_global_idx; + u32 next_foreign_global_idx; } OnyxWasmModule; OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs); -void onyx_wasm_module_compile(OnyxWasmModule* module, ParserOutput* program); +void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program); void onyx_wasm_module_free(OnyxWasmModule* module); void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file); diff --git a/onyx b/onyx index b356f8a4..0791ddf0 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyx.c b/src/onyx.c index 127b8247..028eafc8 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -41,29 +41,6 @@ typedef struct OnyxCompileOptions { const char* target_file; } OnyxCompileOptions; -typedef enum CompilerProgress { - ONYX_COMPILER_PROGRESS_FAILED_READ, - ONYX_COMPILER_PROGRESS_FAILED_PARSE, - ONYX_COMPILER_PROGRESS_FAILED_SEMPASS, - ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN, - ONYX_COMPILER_PROGRESS_FAILED_OUTPUT, - ONYX_COMPILER_PROGRESS_SUCCESS -} CompilerProgress; - -typedef struct CompilerState { - OnyxCompileOptions* options; - - bh_arena ast_arena, msg_arena, sp_arena; - bh_allocator token_alloc, ast_alloc, msg_alloc, sp_alloc; - - bh_table(bh_file_contents) loaded_files; - bh_arr(const char *) queued_files; - - OnyxMessages msgs; - ParserOutput parse_output; - OnyxWasmModule wasm_mod; -} CompilerState; - static OnyxCompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *argv[]) { OnyxCompileOptions options = { .allocator = alloc, @@ -106,6 +83,75 @@ static void compile_opts_free(OnyxCompileOptions* opts) { bh_arr_free(opts->files); } + + + + +typedef enum CompilerProgress { + ONYX_COMPILER_PROGRESS_FAILED_READ, + ONYX_COMPILER_PROGRESS_FAILED_PARSE, + ONYX_COMPILER_PROGRESS_FAILED_SEMPASS, + ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN, + ONYX_COMPILER_PROGRESS_FAILED_OUTPUT, + ONYX_COMPILER_PROGRESS_SUCCESS +} CompilerProgress; + +typedef struct CompilerState { + OnyxCompileOptions* options; + + bh_arena ast_arena, msg_arena, sp_arena; + bh_allocator token_alloc, ast_alloc, msg_alloc, sp_alloc; + + bh_table(bh_file_contents) loaded_files; + bh_arr(const char *) queued_files; + + OnyxMessages msgs; + ProgramInfo prog_info; + OnyxWasmModule wasm_mod; +} CompilerState; + +static void compiler_state_init(CompilerState* compiler_state, OnyxCompileOptions* opts) { + compiler_state->options = opts; + + bh_arr_new(global_heap_allocator, compiler_state->prog_info.bindings, 4); + bh_arr_new(global_heap_allocator, compiler_state->prog_info.entities, 4); + + bh_arena_init(&compiler_state->msg_arena, opts->allocator, 4096); + compiler_state->msg_alloc = bh_arena_allocator(&compiler_state->msg_arena); + + bh_table_init(opts->allocator, compiler_state->loaded_files, 15); + + onyx_message_create(compiler_state->msg_alloc, &compiler_state->msgs, &compiler_state->loaded_files); + + compiler_state->token_alloc = opts->allocator; + + // NOTE: Create the arena where AST nodes will exist + // Prevents nodes from being scattered across memory due to fragmentation + bh_arena_init(&compiler_state->ast_arena, opts->allocator, 16 * 1024 * 1024); // 16MB + compiler_state->ast_alloc = bh_arena_allocator(&compiler_state->ast_arena); + + bh_arena_init(&compiler_state->sp_arena, opts->allocator, 16 * 1024); + compiler_state->sp_alloc = bh_arena_allocator(&compiler_state->sp_arena); + + bh_arr_new(opts->allocator, compiler_state->queued_files, 4); + + // NOTE: Add all files passed by command line to the queue + bh_arr_each(const char *, filename, opts->files) + bh_arr_push(compiler_state->queued_files, (char *) *filename); +} + +static void compiler_state_free(CompilerState* cs) { + bh_arena_free(&cs->ast_arena); + bh_arena_free(&cs->msg_arena); + bh_arena_free(&cs->sp_arena); + bh_table_free(cs->loaded_files); + onyx_wasm_module_free(&cs->wasm_mod); +} + + + + + static ParseResults parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) { // NOTE: Maybe don't want to recreate the tokenizer and parser for every file if (compiler_state->options->verbose_output) @@ -121,6 +167,49 @@ static ParseResults parse_source_file(CompilerState* compiler_state, bh_file_con return onyx_parse(&parser); } +static void merge_parse_results(CompilerState* compiler_state, ParseResults* results) { + bh_arr_each(AstUse *, use_node, results->uses) { + char* formatted_name = bh_aprintf( + global_heap_allocator, + "%b.onyx", + (*use_node)->filename->text, (*use_node)->filename->length); + + bh_arr_push(compiler_state->queued_files, formatted_name); + } + + bh_arr_each(AstBinding *, binding_node, results->bindings) + bh_arr_push(compiler_state->prog_info.bindings, *binding_node); + + bh_arr_each(AstNode *, node, results->nodes_to_process) { + Entity ent = { Entity_Type_Unknown }; + + AstKind nkind = (*node)->kind; + switch (nkind) { + case Ast_Kind_Function: + ent.type = Entity_Type_Function; + ent.function = (AstFunction *) *node; + break; + + case Ast_Kind_Overloaded_Function: + ent.type = Entity_Type_Overloaded_Function; + ent.overloaded_function = (AstOverloadedFunction *) *node; + break; + + case Ast_Kind_Global: + ent.type = Entity_Type_Global; + ent.global = (AstGlobal *) *node; + break; + + default: + ent.type = Entity_Type_Expression; + ent.expr = (AstTyped *) *node; + break; + } + + bh_arr_push(compiler_state->prog_info.entities, ent); + } +} + static CompilerProgress process_source_file(CompilerState* compiler_state, char* filename) { if (bh_table_has(bh_file_contents, compiler_state->loaded_files, filename)) return ONYX_COMPILER_PROGRESS_SUCCESS; @@ -143,21 +232,7 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* fc = bh_table_get(bh_file_contents, compiler_state->loaded_files, (char *) filename); ParseResults results = parse_source_file(compiler_state, &fc); - - bh_arr_each(AstUse *, use_node, results.uses) { - char* formatted_name = bh_aprintf( - global_heap_allocator, - "%b.onyx", - (*use_node)->filename->text, (*use_node)->filename->length); - - bh_arr_push(compiler_state->queued_files, formatted_name); - } - - bh_arr_each(AstBinding *, binding_node, results.bindings) - bh_arr_push(compiler_state->parse_output.top_level_bindings, *binding_node); - - bh_arr_each(AstNode *, node, results.nodes_to_process) - bh_arr_push(compiler_state->parse_output.nodes_to_process, *node); + merge_parse_results(compiler_state, &results); if (onyx_message_has_errors(&compiler_state->msgs)) { return ONYX_COMPILER_PROGRESS_FAILED_PARSE; @@ -166,37 +241,6 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* } } -static void compiler_state_init(CompilerState* compiler_state, OnyxCompileOptions* opts) { - compiler_state->options = opts; - - bh_arr_new(global_heap_allocator, compiler_state->parse_output.top_level_bindings, 4); - bh_arr_new(global_heap_allocator, compiler_state->parse_output.nodes_to_process, 4); - bh_arr_new(global_heap_allocator, compiler_state->parse_output.functions, 4); - bh_arr_new(global_heap_allocator, compiler_state->parse_output.globals, 4); - - bh_arena_init(&compiler_state->msg_arena, opts->allocator, 4096); - compiler_state->msg_alloc = bh_arena_allocator(&compiler_state->msg_arena); - - bh_table_init(opts->allocator, compiler_state->loaded_files, 15); - - onyx_message_create(compiler_state->msg_alloc, &compiler_state->msgs, &compiler_state->loaded_files); - - compiler_state->token_alloc = opts->allocator; - - // NOTE: Create the arena where AST nodes will exist - // Prevents nodes from being scattered across memory due to fragmentation - bh_arena_init(&compiler_state->ast_arena, opts->allocator, 16 * 1024 * 1024); // 16MB - compiler_state->ast_alloc = bh_arena_allocator(&compiler_state->ast_arena); - - bh_arena_init(&compiler_state->sp_arena, opts->allocator, 16 * 1024); - compiler_state->sp_alloc = bh_arena_allocator(&compiler_state->sp_arena); - - bh_arr_new(opts->allocator, compiler_state->queued_files, 4); - - // NOTE: Add all files passed by command line to the queue - bh_arr_each(const char *, filename, opts->files) - bh_arr_push(compiler_state->queued_files, (char *) *filename); -} static i32 onyx_compile(CompilerState* compiler_state) { @@ -216,7 +260,7 @@ static i32 onyx_compile(CompilerState* compiler_state) { bh_printf("[Checking semantics]\n"); SemState sp_state = onyx_sempass_create(compiler_state->sp_alloc, compiler_state->ast_alloc, &compiler_state->msgs); - onyx_sempass(&sp_state, &compiler_state->parse_output); + onyx_sempass(&sp_state, &compiler_state->prog_info); if (onyx_message_has_errors(&compiler_state->msgs)) { return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS; @@ -228,7 +272,7 @@ static i32 onyx_compile(CompilerState* compiler_state) { bh_printf("[Generating WASM]\n"); compiler_state->wasm_mod = onyx_wasm_module_create(compiler_state->options->allocator, &compiler_state->msgs); - onyx_wasm_module_compile(&compiler_state->wasm_mod, &compiler_state->parse_output); + onyx_wasm_module_compile(&compiler_state->wasm_mod, &compiler_state->prog_info); if (onyx_message_has_errors(&compiler_state->msgs)) { return ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN; @@ -249,14 +293,6 @@ static i32 onyx_compile(CompilerState* compiler_state) { return ONYX_COMPILER_PROGRESS_SUCCESS; } -static void compiler_state_free(CompilerState* cs) { - bh_arena_free(&cs->ast_arena); - bh_arena_free(&cs->msg_arena); - bh_arena_free(&cs->sp_arena); - bh_table_free(cs->loaded_files); - onyx_wasm_module_free(&cs->wasm_mod); -} - int main(int argc, char *argv[]) { bh_scratch_init(&global_scratch, bh_heap_allocator(), 16 * 1024); // NOTE: 16 KB diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 709a7682..e1c215ca 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -361,7 +361,7 @@ CHECK(array_access, AstArrayAccess* aa) { if (!type_is_pointer(aa->addr->type)) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - aa->addr->token->pos, + aa->token->pos, "expected pointer type for left of array access"); return 1; } @@ -370,7 +370,7 @@ CHECK(array_access, AstArrayAccess* aa) { || (aa->expr->type->Basic.flags & Basic_Flag_Integer) == 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - aa->expr->token->pos, + aa->token->pos, "expected integer type for index"); return 1; } @@ -625,16 +625,30 @@ CHECK(node, AstNode* node) { } } -void onyx_type_check(SemState* state, ParserOutput* program) { - bh_arr_each(AstNode *, node, program->nodes_to_process) { - check_node(state, *node); +void onyx_type_check(SemState* state, ProgramInfo* program) { + bh_arr_each(Entity, entity, program->entities) { + switch (entity->type) { + case Entity_Type_Function: + if (entity->function->flags & Ast_Kind_Foreign) program->foreign_func_count++; - if ((*node)->kind == Ast_Kind_Function) { - bh_arr_push(program->functions, (AstFunction *) *node); - } + if (check_function(state, entity->function)) return; + break; + + case Entity_Type_Overloaded_Function: + if (check_overloaded_function(state, entity->overloaded_function)) return; + break; + + case Entity_Type_Global: + if (entity->global->flags & Ast_Kind_Foreign) program->foreign_global_count++; + + if (check_global(state, entity->global)) return; + break; + + case Entity_Type_Expression: + if (check_expression(state, entity->expr)) return; + break; - if ((*node)->kind == Ast_Kind_Global) { - bh_arr_push(program->globals, (AstGlobal *) *node); + default: DEBUG_HERE; break; } } } diff --git a/src/onyxlex.c b/src/onyxlex.c index 1c6edea8..8a1da57b 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -107,7 +107,7 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { tk.pos.line_start = tokenizer->line_start; tk.pos.filename = tokenizer->filename; tk.pos.line = tokenizer->line_number; - tk.pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1; + tk.pos.column = (u16)(tokenizer->curr - tokenizer->line_start) + 1; if (tokenizer->curr == tokenizer->end) { tk.type = Token_Type_End_Stream; @@ -220,6 +220,7 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { INCREMENT_CURR_TOKEN(tokenizer); token_parsed: + tk.pos.length = (u16) tk.length; bh_arr_push(tokenizer->tokens, tk); return &tokenizer->tokens[bh_arr_length(tokenizer->tokens) - 1]; diff --git a/src/onyxmsgs.c b/src/onyxmsgs.c index 15768a38..2ca0e761 100644 --- a/src/onyxmsgs.c +++ b/src/onyxmsgs.c @@ -56,11 +56,12 @@ static void print_detailed_message(OnyxMessage* msg, bh_file_contents* fc) { bh_printf("| %b\n", msg->pos.line_start, linelength); char* pointer_str = bh_alloc_array(global_scratch_allocator, char, linelength); - memset(pointer_str, 0, linelength); - memset(pointer_str, '~', msg->pos.column - 1); + memset(pointer_str, ' ', linelength); + memset(pointer_str + msg->pos.column, '~', msg->pos.length - 1); pointer_str[msg->pos.column - 1] = '^'; + pointer_str[msg->pos.column + msg->pos.length - 1] = 0; - bh_printf("|~%s\n", pointer_str); + bh_printf("| %s\n", pointer_str); } void onyx_message_print(OnyxMessages* msgs) { diff --git a/src/onyxsempass.c b/src/onyxsempass.c index 6d793680..e19cfcb0 100644 --- a/src/onyxsempass.c +++ b/src/onyxsempass.c @@ -16,7 +16,7 @@ SemState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMe return state; } -void onyx_sempass(SemState* state, ParserOutput* program) { +void onyx_sempass(SemState* state, ProgramInfo* program) { onyx_resolve_symbols(state, program); if (onyx_message_has_errors(state->msgs)) return; diff --git a/src/onyxsymres.c b/src/onyxsymres.c index c9779517..179dc9a1 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -291,35 +291,7 @@ static void symres_overloaded_function(SemState* state, AstOverloadedFunction* o } } -static void symres_top_node(SemState* state, AstNode** node) { - switch ((*node)->kind) { - case Ast_Kind_Call: - case Ast_Kind_Unary_Op: - case Ast_Kind_Binary_Op: - case Ast_Kind_Literal: - case Ast_Kind_Symbol: - symres_expression(state, (AstTyped **) node); - break; - - case Ast_Kind_Global: - symres_global(state, (AstGlobal *) *node); - break; - - case Ast_Kind_Function: - symres_function(state, (AstFunction *) *node); - break; - - case Ast_Kind_Overloaded_Function: - symres_overloaded_function(state, (AstOverloadedFunction *) *node); - break; - - default: - DEBUG_HERE; - break; - } -} - -void onyx_resolve_symbols(SemState* state, ParserOutput* program) { +void onyx_resolve_symbols(SemState* state, ProgramInfo* program) { state->global_scope = scope_create(state->node_allocator, NULL); scope_enter(state, state->global_scope); @@ -339,9 +311,17 @@ void onyx_resolve_symbols(SemState* state, ParserOutput* program) { symbol_basic_type_introduce(state, &basic_type_f64); symbol_basic_type_introduce(state, &basic_type_rawptr); - bh_arr_each(AstBinding *, binding, program->top_level_bindings) + bh_arr_each(AstBinding *, binding, program->bindings) if (!symbol_introduce(state, (*binding)->token, (*binding)->node)) return; - bh_arr_each(AstNode *, node, program->nodes_to_process) - symres_top_node(state, node); + bh_arr_each(Entity, entity, program->entities) { + switch (entity->type) { + case Entity_Type_Function: symres_function(state, entity->function); break; + case Entity_Type_Overloaded_Function: symres_overloaded_function(state, entity->overloaded_function); break; + case Entity_Type_Global: symres_global(state, entity->global); break; + case Entity_Type_Expression: symres_expression(state, &entity->expr); break; + + default: break; + } + } } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index fcb14543..d8040ae7 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -319,7 +319,7 @@ COMPILE_FUNC(assignment, AstBinaryOp* assign) { WID(WI_LOCAL_SET, localidx); } else if (lval->kind == Ast_Kind_Global) { - i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) lval); + i32 globalidx = (i32) bh_imap_get(&mod->index_map, (u64) lval); compile_expression(mod, &code, assign->right); WID(WI_GLOBAL_SET, globalidx); @@ -553,7 +553,7 @@ COMPILE_FUNC(call, AstCall* call) { compile_expression(mod, &code, arg->value); } - i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) call->callee); + i32 func_idx = (i32) bh_imap_get(&mod->index_map, (u64) call->callee); bh_arr_push(code, ((WasmInstruction){ WI_CALL, func_idx })); *pcode = code; @@ -653,7 +653,7 @@ COMPILE_FUNC(expression, AstTyped* expr) { case Ast_Kind_Global: { - i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) expr); + i32 globalidx = (i32) bh_imap_get(&mod->index_map, (u64) expr); WID(WI_GLOBAL_GET, globalidx); break; @@ -880,7 +880,7 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) { if (fd->flags & Ast_Flag_Exported) { token_toggle_end(fd->exported_name); - i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) fd); + i32 func_idx = (i32) bh_imap_get(&mod->index_map, (u64) fd); WasmExport wasm_export = { .kind = WASM_FOREIGN_FUNCTION, @@ -931,7 +931,7 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) { bh_imap_clear(&mod->local_map); } -static void compile_global_declaration(OnyxWasmModule* module, AstGlobal* global) { +static void compile_global(OnyxWasmModule* module, AstGlobal* global) { WasmType global_type = onyx_type_to_wasm_type(global->type); if (global->flags & Ast_Flag_Foreign) { @@ -955,7 +955,7 @@ static void compile_global_declaration(OnyxWasmModule* module, AstGlobal* global if ((global->flags & Ast_Flag_Exported) != 0) { token_toggle_end(global->exported_name); - i32 global_idx = (i32) bh_imap_get(&module->func_map, (u64) global); + i32 global_idx = (i32) bh_imap_get(&module->index_map, (u64) global); WasmExport wasm_export = { .kind = WASM_FOREIGN_GLOBAL, @@ -992,6 +992,7 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) { .funcs = NULL, .next_func_idx = 0, + .next_foreign_func_idx = 0, .exports = NULL, .export_count = 0, @@ -1000,6 +1001,7 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) { .globals = NULL, .next_global_idx = 0, + .next_foreign_global_idx = 0, .structured_jump_target = NULL, }; @@ -1016,55 +1018,63 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) { bh_table_init(global_heap_allocator, module.type_map, 61); bh_table_init(global_heap_allocator, module.exports, 61); - bh_imap_init(&module.local_map, global_heap_allocator, 16); - bh_imap_init(&module.func_map, global_heap_allocator, 16); - bh_imap_init(&module.global_map, global_heap_allocator, 16); + bh_imap_init(&module.index_map, global_heap_allocator, 128); + bh_imap_init(&module.local_map, global_heap_allocator, 16); return module; } -void onyx_wasm_module_compile(OnyxWasmModule* module, ParserOutput* program) { - bh_arr_each(AstFunction *, function, program->functions) { - if ((*function)->flags & Ast_Flag_Foreign) { - bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++); - } - } +void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program) { - bh_arr_each(AstGlobal *, global, program->globals) { - if ((*global)->flags & Ast_Flag_Foreign) { - bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++); - } - } + module->next_func_idx = program->foreign_func_count; + module->next_global_idx = program->foreign_global_count; - bh_arr_each(AstFunction *, function, program->functions) { - if ((*function)->flags & Ast_Flag_Foreign) continue; + // NOTE: First, assign indicies to all functions / globals + bh_arr_each(Entity, entity, program->entities) { + switch (entity->type) { + case Entity_Type_Function: { + if (entity->function->flags & Ast_Flag_Intrinsic) break; - if (((*function)->flags & Ast_Flag_Intrinsic) == 0) - bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++); - } + u64 func_idx; + if ((entity->function->flags & Ast_Flag_Foreign) != 0) + func_idx = module->next_foreign_func_idx++; + else + func_idx = module->next_func_idx++; - bh_arr_each(AstGlobal *, global, program->globals) { - if ((*global)->flags & Ast_Flag_Foreign) continue; + bh_imap_put(&module->index_map, (u64) entity->function, func_idx); + break; + } - bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++); - } + case Entity_Type_Global: { + u64 global_idx; + if ((entity->global->flags & Ast_Flag_Foreign) != 0) + global_idx = module->next_foreign_global_idx++; + else + global_idx = module->next_global_idx++; - // NOTE: Then, compile everything - bh_arr_each(AstGlobal *, global, program->globals) - compile_global_declaration(module, *global); + bh_imap_put(&module->index_map, (u64) entity->global, global_idx); + break; + } - bh_arr_each(AstFunction *, function, program->functions) - compile_function(module, *function); + default: break; + } + } - // bh_arr_each(AstGlobal *, global, program->globals) - // compile_global_declaration(module, *global); + // NOTE: Then, compile everything + bh_arr_each(Entity, entity, program->entities) { + switch (entity->type) { + case Entity_Type_Function: compile_function(module, entity->function); break; + case Entity_Type_Global: compile_global(module, entity->global); break; + default: break; + } + } } void onyx_wasm_module_free(OnyxWasmModule* module) { bh_arr_free(module->types); bh_arr_free(module->funcs); bh_imap_free(&module->local_map); - bh_imap_free(&module->func_map); + bh_imap_free(&module->index_map); bh_table_free(module->type_map); bh_table_free(module->exports); }