From 57ced833aeeb510a740060d39e9b0fd795767ec9 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 8 Jul 2020 21:46:41 -0500 Subject: [PATCH] Started working on intrinsic functions --- Makefile | 2 +- include/onyxastnodes.h | 21 ++++- onyx | Bin 210568 -> 211328 bytes progs/test.onyx | 14 ++- src/onyx.c | 9 +- src/{onyxtypecheck.c => onyxchecker.c} | 116 ++++++++++++++----------- src/onyxutils.c | 1 + src/onyxwasm.c | 86 ++++++++++++++---- 8 files changed, 177 insertions(+), 72 deletions(-) rename src/{onyxtypecheck.c => onyxchecker.c} (71%) diff --git a/Makefile b/Makefile index 259e4281..36a8fbd2 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ OBJ_FILES=\ build/onyxparser.o \ build/onyxsempass.o \ build/onyxsymres.o \ - build/onyxtypecheck.o \ + build/onyxchecker.o \ build/onyxmsgs.o \ build/onyxutils.o \ build/onyxwasm.o \ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index cdb7a71c..8b7a4d09 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -19,6 +19,7 @@ typedef struct AstNodeFunction AstNodeFunction; typedef struct AstNodeForeign AstNodeForeign; typedef struct AstNodeGlobal AstNodeGlobal; typedef struct AstNodeCall AstNodeCall; +typedef struct AstNodeIntrinsicCall AstNodeIntrinsicCall; typedef struct AstNodeArgument AstNodeArgument; typedef struct AstNodeUse AstNodeUse; @@ -43,6 +44,7 @@ typedef enum AstNodeKind { AST_NODE_KIND_PARAM, AST_NODE_KIND_ARGUMENT, AST_NODE_KIND_CALL, + AST_NODE_KIND_INTRINSIC_CALL, AST_NODE_KIND_ASSIGNMENT, AST_NODE_KIND_RETURN, @@ -233,10 +235,10 @@ struct AstNodeGlobal { struct AstNodeCall { AstNodeTyped base; - AstNode *callee; // NOTE: Function definition node AstNodeArgument *arguments; // NOTE: Expressions that form the actual param list // They will be chained down using the "next" property // unless this becomes used by something else + AstNode *callee; // NOTE: Function definition node }; struct AstNodeArgument { @@ -245,6 +247,22 @@ struct AstNodeArgument { AstNodeTyped *value; }; +typedef enum OnyxIntrinsic { + ONYX_INTRINSIC_UNDEFINED, + + ONYX_INTRINSIC_FLOAT32_SQRT, + ONYX_INTRINSIC_FLOAT64_SQRT, +} OnyxIntrinsic; + +// NOTE: This needs to have 'arguments' in the +// same position as AstNodeCall +struct AstNodeIntrinsicCall { + AstNodeTyped base; + + AstNodeArgument *arguments; + OnyxIntrinsic intrinsic; +}; + struct AstNodeUse { AstNode base; @@ -252,7 +270,6 @@ struct AstNodeUse { }; typedef struct OnyxProgram { - bh_arr(AstNodeUse *) uses; bh_arr(AstNodeGlobal *) globals; bh_arr(AstNodeFunction *) functions; bh_arr(AstNodeForeign *) foreigns; diff --git a/onyx b/onyx index 06e673ce731eb422696e94b4509f95882b577338..0d7801ec9f78940218113e72d96d622d38e674d9 100755 GIT binary patch delta 65524 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 BrltS@ delta 64447 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 F`#( bool { } sqrt_f32 :: - proc #intrinsic #inline + proc #intrinsic (val: f32) -> f32 --- // This is the entry point @@ -52,6 +52,18 @@ export main2 :: proc { } } +// Foo :: struct { +// bar : Bar; +// something : i32; +// other : i64; +// } +// +// Bar :: struct { +// x : f32; +// y : f32; +// z : f32; +// } + export main :: proc { print_f32(sqrt_f32(2.0f)); print_i32(5 * 6 + 2 * 3); diff --git a/src/onyx.c b/src/onyx.c index d843c498..f91500c8 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -144,10 +144,12 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* bh_arr(AstNode *) top_nodes = parse_source_file(compiler_state, &fc); + bh_arr(AstNodeUse *) uses = NULL; + bh_arr_each(AstNode *, node, top_nodes) { switch ((*node)->kind) { case AST_NODE_KIND_USE: - bh_arr_push(compiler_state->program.uses, (AstNodeUse *) (*node)); + bh_arr_push(uses, (AstNodeUse *) *node); break; case AST_NODE_KIND_GLOBAL: @@ -168,7 +170,7 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* } } - bh_arr_each(AstNodeUse *, use_node, compiler_state->program.uses) { + bh_arr_each(AstNodeUse *, use_node, uses) { char* formatted_name = bh_aprintf( global_heap_allocator, "%b.onyx", @@ -177,6 +179,7 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* bh_arr_push(compiler_state->queued_files, formatted_name); } + bh_arr_free(uses); if (onyx_message_has_errors(&compiler_state->msgs)) { return ONYX_COMPILER_PROGRESS_FAILED_PARSE; @@ -188,7 +191,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->program.uses, 4); bh_arr_new(global_heap_allocator, compiler_state->program.foreigns, 4); bh_arr_new(global_heap_allocator, compiler_state->program.globals, 4); bh_arr_new(global_heap_allocator, compiler_state->program.functions, 4); @@ -287,7 +289,6 @@ int main(int argc, char *argv[]) { OnyxCompileOptions compile_opts = compile_opts_parse(global_heap_allocator, argc, argv); CompilerState compile_state = { .program = { - .uses = NULL, .foreigns = NULL, .globals = NULL, .functions = NULL diff --git a/src/onyxtypecheck.c b/src/onyxchecker.c similarity index 71% rename from src/onyxtypecheck.c rename to src/onyxchecker.c index 869e89af..27e4a4c4 100644 --- a/src/onyxtypecheck.c +++ b/src/onyxchecker.c @@ -1,19 +1,19 @@ #define BH_DEBUG #include "onyxsempass.h" -static void typecheck_function(OnyxSemPassState* state, AstNodeFunction* func); -static void typecheck_block(OnyxSemPassState* state, AstNodeBlock* block); -static void typecheck_statement_chain(OnyxSemPassState* state, AstNode* start); -static void typecheck_statement(OnyxSemPassState* state, AstNode* stmt); -static void typecheck_assignment(OnyxSemPassState* state, AstNodeAssign* assign); -static void typecheck_return(OnyxSemPassState* state, AstNodeReturn* retnode); -static void typecheck_if(OnyxSemPassState* state, AstNodeIf* ifnode); -static void typecheck_while(OnyxSemPassState* state, AstNodeWhile* whilenode); -static void typecheck_call(OnyxSemPassState* state, AstNodeCall* call); -static void typecheck_expression(OnyxSemPassState* state, AstNodeTyped* expr); -static void typecheck_global(OnyxSemPassState* state, AstNodeGlobal* global); - -static void typecheck_assignment(OnyxSemPassState* state, AstNodeAssign* assign) { +static void check_function(OnyxSemPassState* state, AstNodeFunction* func); +static void check_block(OnyxSemPassState* state, AstNodeBlock* block); +static void check_statement_chain(OnyxSemPassState* state, AstNode* start); +static void check_statement(OnyxSemPassState* state, AstNode* stmt); +static void check_assignment(OnyxSemPassState* state, AstNodeAssign* assign); +static void check_return(OnyxSemPassState* state, AstNodeReturn* retnode); +static void check_if(OnyxSemPassState* state, AstNodeIf* ifnode); +static void check_while(OnyxSemPassState* state, AstNodeWhile* whilenode); +static void check_call(OnyxSemPassState* state, AstNodeCall* call); +static void check_expression(OnyxSemPassState* state, AstNodeTyped* expr); +static void check_global(OnyxSemPassState* state, AstNodeGlobal* global); + +static void check_assignment(OnyxSemPassState* state, AstNodeAssign* assign) { if (assign->lval->kind == AST_NODE_KIND_SYMBOL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, @@ -38,7 +38,7 @@ static void typecheck_assignment(OnyxSemPassState* state, AstNodeAssign* assign) return; } - typecheck_expression(state, assign->expr); + check_expression(state, assign->expr); if (!assign->lval->type->is_known) { assign->lval->type = assign->expr->type; @@ -53,9 +53,9 @@ static void typecheck_assignment(OnyxSemPassState* state, AstNodeAssign* assign) } } -static void typecheck_return(OnyxSemPassState* state, AstNodeReturn* retnode) { +static void check_return(OnyxSemPassState* state, AstNodeReturn* retnode) { if (retnode->expr) { - typecheck_expression(state, retnode->expr); + check_expression(state, retnode->expr); if (retnode->expr->type != state->expected_return_type) { onyx_message_add(state->msgs, @@ -73,8 +73,8 @@ static void typecheck_return(OnyxSemPassState* state, AstNodeReturn* retnode) { } } -static void typecheck_if(OnyxSemPassState* state, AstNodeIf* ifnode) { - typecheck_expression(state, ifnode->cond); +static void check_if(OnyxSemPassState* state, AstNodeIf* ifnode) { + check_expression(state, ifnode->cond); if (ifnode->cond->type != &builtin_types[TYPE_INFO_KIND_BOOL]) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, @@ -83,12 +83,12 @@ static void typecheck_if(OnyxSemPassState* state, AstNodeIf* ifnode) { return; } - if (ifnode->true_block.as_if) typecheck_statement(state, (AstNode *) ifnode->true_block.as_block); - if (ifnode->false_block.as_if) typecheck_statement(state, (AstNode *) ifnode->false_block.as_block); + if (ifnode->true_block.as_if) check_statement(state, (AstNode *) ifnode->true_block.as_block); + if (ifnode->false_block.as_if) check_statement(state, (AstNode *) ifnode->false_block.as_block); } -static void typecheck_while(OnyxSemPassState* state, AstNodeWhile* whilenode) { - typecheck_expression(state, whilenode->cond); +static void check_while(OnyxSemPassState* state, AstNodeWhile* whilenode) { + check_expression(state, whilenode->cond); if (whilenode->cond->type != &builtin_types[TYPE_INFO_KIND_BOOL]) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, @@ -97,10 +97,10 @@ static void typecheck_while(OnyxSemPassState* state, AstNodeWhile* whilenode) { return; } - typecheck_block(state, whilenode->body); + check_block(state, whilenode->body); } -static void typecheck_call(OnyxSemPassState* state, AstNodeCall* call) { +static void check_call(OnyxSemPassState* state, AstNodeCall* call) { AstNodeFunction* callee = (AstNodeFunction *) call->callee; if (callee->base.kind == AST_NODE_KIND_SYMBOL) { @@ -119,6 +119,24 @@ static void typecheck_call(OnyxSemPassState* state, AstNodeCall* call) { return; } + // NOTE: If we calling an intrinsic function, translate the + // call into an intrinsic call node. + if (callee->base.flags & ONYX_AST_FLAG_INTRINSIC) { + call->base.kind = AST_NODE_KIND_INTRINSIC_CALL; + call->callee = NULL; + + onyx_token_null_toggle(callee->base.token); + char* intr_name = callee->base.token->token; + if (!strcmp("sqrt_f32", intr_name)) { + ((AstNodeIntrinsicCall *) call)->intrinsic = ONYX_INTRINSIC_FLOAT32_SQRT; + } + else if (!strcmp("sqrt_f64", intr_name)) { + ((AstNodeIntrinsicCall *) call)->intrinsic = ONYX_INTRINSIC_FLOAT64_SQRT; + } + + onyx_token_null_toggle(callee->base.token); + } + call->base.type = callee->base.type; AstNodeLocal* formal_param = callee->params; @@ -126,7 +144,7 @@ static void typecheck_call(OnyxSemPassState* state, AstNodeCall* call) { i32 arg_pos = 0; while (formal_param != NULL && actual_param != NULL) { - typecheck_expression(state, (AstNodeTyped *) actual_param); + check_expression(state, (AstNodeTyped *) actual_param); if (formal_param->base.type != actual_param->base.type) { onyx_message_add(state->msgs, @@ -160,13 +178,13 @@ static void typecheck_call(OnyxSemPassState* state, AstNodeCall* call) { } } -static void typecheck_expression(OnyxSemPassState* state, AstNodeTyped* expr) { +static void check_expression(OnyxSemPassState* state, AstNodeTyped* expr) { switch (expr->kind) { case AST_NODE_KIND_BIN_OP: expr->type = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; - typecheck_expression(state, ((AstNodeBinOp *) expr)->left); - typecheck_expression(state, ((AstNodeBinOp *) expr)->right); + check_expression(state, ((AstNodeBinOp *) expr)->left); + check_expression(state, ((AstNodeBinOp *) expr)->right); if (((AstNodeBinOp *) expr)->left->type == NULL) { onyx_message_add(state->msgs, @@ -204,17 +222,17 @@ static void typecheck_expression(OnyxSemPassState* state, AstNodeTyped* expr) { case AST_NODE_KIND_UNARY_OP: if (((AstNodeUnaryOp *) expr)->operation != ONYX_UNARY_OP_CAST) { - typecheck_expression(state, ((AstNodeUnaryOp *) expr)->expr); + check_expression(state, ((AstNodeUnaryOp *) expr)->expr); expr->type = ((AstNodeUnaryOp *) expr)->expr->type; } break; case AST_NODE_KIND_CALL: - typecheck_call(state, (AstNodeCall *) expr); + check_call(state, (AstNodeCall *) expr); break; case AST_NODE_KIND_BLOCK: - typecheck_block(state, (AstNodeBlock *) expr); + check_block(state, (AstNodeBlock *) expr); break; case AST_NODE_KIND_SYMBOL: @@ -244,7 +262,7 @@ static void typecheck_expression(OnyxSemPassState* state, AstNodeTyped* expr) { break; case AST_NODE_KIND_ARGUMENT: - typecheck_expression(state, ((AstNodeArgument *) expr)->value); + check_expression(state, ((AstNodeArgument *) expr)->value); expr->type = ((AstNodeArgument *) expr)->value->type; break; @@ -260,9 +278,9 @@ static void typecheck_expression(OnyxSemPassState* state, AstNodeTyped* expr) { } } -static void typecheck_global(OnyxSemPassState* state, AstNodeGlobal* global) { +static void check_global(OnyxSemPassState* state, AstNodeGlobal* global) { if (global->initial_value) { - typecheck_expression(state, global->initial_value); + check_expression(state, global->initial_value); if (global->base.type->is_known) { if (global->base.type != global->initial_value->type) { @@ -288,28 +306,28 @@ static void typecheck_global(OnyxSemPassState* state, AstNodeGlobal* global) { } } -static void typecheck_statement(OnyxSemPassState* state, AstNode* stmt) { +static void check_statement(OnyxSemPassState* state, AstNode* stmt) { switch (stmt->kind) { - case AST_NODE_KIND_ASSIGNMENT: typecheck_assignment(state, (AstNodeAssign *) stmt); break; - case AST_NODE_KIND_RETURN: typecheck_return(state, (AstNodeReturn *) stmt); break; - case AST_NODE_KIND_IF: typecheck_if(state, (AstNodeIf *) stmt); break; - case AST_NODE_KIND_WHILE: typecheck_while(state, (AstNodeWhile *) stmt); break; - case AST_NODE_KIND_CALL: typecheck_call(state, (AstNodeCall *) stmt); break; - case AST_NODE_KIND_BLOCK: typecheck_block(state, (AstNodeBlock *) stmt); break; + case AST_NODE_KIND_ASSIGNMENT: check_assignment(state, (AstNodeAssign *) stmt); break; + case AST_NODE_KIND_RETURN: check_return(state, (AstNodeReturn *) stmt); break; + case AST_NODE_KIND_IF: check_if(state, (AstNodeIf *) stmt); break; + case AST_NODE_KIND_WHILE: check_while(state, (AstNodeWhile *) stmt); break; + case AST_NODE_KIND_CALL: check_call(state, (AstNodeCall *) stmt); break; + case AST_NODE_KIND_BLOCK: check_block(state, (AstNodeBlock *) stmt); break; default: break; } } -static void typecheck_statement_chain(OnyxSemPassState* state, AstNode* start) { +static void check_statement_chain(OnyxSemPassState* state, AstNode* start) { while (start) { - typecheck_statement(state, start); + check_statement(state, start); start = start->next; } } -static void typecheck_block(OnyxSemPassState* state, AstNodeBlock* block) { - typecheck_statement_chain(state, block->body); +static void check_block(OnyxSemPassState* state, AstNodeBlock* block) { + check_statement_chain(state, block->body); forll(AstNodeLocal, local, block->locals->last_local, prev_local) { if (!local->base.type->is_known) { @@ -322,7 +340,7 @@ static void typecheck_block(OnyxSemPassState* state, AstNodeBlock* block) { } } -static void typecheck_function(OnyxSemPassState* state, AstNodeFunction* func) { +static void check_function(OnyxSemPassState* state, AstNodeFunction* func) { for (AstNodeLocal *param = func->params; param != NULL; param = (AstNodeLocal *) param->base.next) { if (!param->base.type->is_known) { onyx_message_add(state->msgs, @@ -343,15 +361,15 @@ static void typecheck_function(OnyxSemPassState* state, AstNodeFunction* func) { state->expected_return_type = func->base.type; if (func->body) { - typecheck_block(state, func->body); + check_block(state, func->body); } } void onyx_type_check(OnyxSemPassState* state, OnyxProgram* program) { bh_arr_each(AstNodeGlobal *, global, program->globals) - typecheck_global(state, *global); + check_global(state, *global); bh_arr_each(AstNodeFunction *, function, program->functions) - typecheck_function(state, *function); + check_function(state, *function); } diff --git a/src/onyxutils.c b/src/onyxutils.c index 7fff9577..3e55d696 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -29,6 +29,7 @@ static const char* ast_node_names[] = { "PARAM", "ARGUMENT", "CALL", + "INTRINSIC_CALL", "ASSIGN", "RETURN", diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 7f5a5061..6001f20f 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -218,6 +218,8 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstN static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeWhile* while_node); static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBinOp* binop); static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* unop); +static void compile_call(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeCall* call); +static void compile_intrinsic_call(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeIntrinsicCall* call); static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* expr); static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* cast); static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeReturn* ret); @@ -286,9 +288,14 @@ static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcod case AST_NODE_KIND_WHILE: compile_while(mod, &code, (AstNodeWhile *) stmt); break; case AST_NODE_KIND_BREAK: compile_structured_jump(mod, &code, 0); break; case AST_NODE_KIND_CONTINUE: compile_structured_jump(mod, &code, 1); break; - case AST_NODE_KIND_CALL: compile_expression(mod, &code, (AstNodeTyped *) stmt); break; case AST_NODE_KIND_BLOCK: compile_block(mod, &code, (AstNodeBlock *) stmt); break; + case AST_NODE_KIND_CALL: + case AST_NODE_KIND_INTRINSIC_CALL: + compile_expression(mod, &code, (AstNodeTyped *) stmt); + break; + + default: break; } @@ -493,6 +500,7 @@ static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, case ONYX_UNARY_OP_NOT: compile_expression(mod, &code, unop->expr); + bh_arr_push(code, ((WasmInstruction){ WI_I32_EQZ, 0x00 })); break; @@ -502,6 +510,55 @@ static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, *pcode = code; } +static void compile_call(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeCall* call) { + bh_arr(WasmInstruction) code = *pcode; + + for (AstNodeArgument *arg = call->arguments; + arg != NULL; + arg = (AstNodeArgument *) arg->base.next) { + compile_expression(mod, &code, arg->value); + } + + i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) call->callee); + bh_arr_push(code, ((WasmInstruction){ WI_CALL, func_idx })); + + *pcode = code; +} + +static void compile_intrinsic_call(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeIntrinsicCall* call) { + bh_arr(WasmInstruction) code = *pcode; + + i32 place_arguments_normally = 1; + + // NOTE: Doing this in case there becomes intrinsics that the arguments + // are not placed as they normally would be + if (0) place_arguments_normally = 0; + + if (place_arguments_normally) { + for (AstNodeArgument *arg = call->arguments; + arg != NULL; + arg = (AstNodeArgument *) arg->base.next) { + compile_expression(mod, &code, arg->value); + } + } + + switch (call->intrinsic) { + case ONYX_INTRINSIC_UNDEFINED: + assert(0); + break; + + case ONYX_INTRINSIC_FLOAT32_SQRT: + bh_arr_push(code, ((WasmInstruction){ WI_F32_SQRT, 0x00})); + break; + + case ONYX_INTRINSIC_FLOAT64_SQRT: + bh_arr_push(code, ((WasmInstruction){ WI_F64_SQRT, 0x00 })); + break; + } + + *pcode = code; +} + static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* expr) { bh_arr(WasmInstruction) code = *pcode; @@ -557,20 +614,14 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco case AST_NODE_KIND_BLOCK: compile_block(mod, &code, (AstNodeBlock *) expr); break; - case AST_NODE_KIND_CALL: - { - AstNodeCall* call = (AstNodeCall *) expr; - for (AstNodeArgument *arg = call->arguments; - arg != NULL; - arg = (AstNodeArgument *) arg->base.next) { - compile_expression(mod, &code, arg->value); - } - i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) call->callee); - bh_arr_push(code, ((WasmInstruction){ WI_CALL, func_idx })); + case AST_NODE_KIND_CALL: + compile_call(mod, &code, (AstNodeCall *) expr); + break; - break; - } + case AST_NODE_KIND_INTRINSIC_CALL: + compile_intrinsic_call(mod, &code, (AstNodeIntrinsicCall *) expr); + break; default: DEBUG_HERE; @@ -683,6 +734,9 @@ static i32 generate_type_idx(OnyxWasmModule* mod, AstNodeFunction* fd) { } static void compile_function(OnyxWasmModule* mod, AstNodeFunction* fd) { + // NOTE: Don't compile intrinsics + if (fd->base.flags & ONYX_AST_FLAG_INTRINSIC) return; + i32 type_idx = generate_type_idx(mod, fd); WasmFunc wasm_func = { @@ -880,8 +934,10 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxProgram* program) { compile_foreign(module, *foreign); } - bh_arr_each(AstNodeFunction *, function, program->functions) - bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++); + bh_arr_each(AstNodeFunction *, function, program->functions) { + if (((*function)->base.flags & ONYX_AST_FLAG_INTRINSIC) == 0) + bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++); + } bh_arr_each(AstNodeGlobal *, global, program->globals) bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++); -- 2.25.1