typedef struct AstPolyParam AstPolyParam;
typedef struct AstPolySolution AstPolySolution;
+typedef struct AstSolidifiedFunction AstSolidifiedFunction;
typedef struct AstPolyProc AstPolyProc;
typedef struct AstPackage AstPackage;
Ast_Flag_Private_File = BH_BIT(6),
// Global flags
- Ast_Flag_Global_Stack_Top = BH_BIT(7),
- Ast_Flag_Global_Stack_Base = BH_BIT(8),
+ Ast_Flag_Global_Stack_Top = BH_BIT(7), // These can go away for something better,
+ Ast_Flag_Global_Stack_Base = BH_BIT(8), // like just checking the pointers since they will be unique.
// Function flags
Ast_Flag_Intrinsic = BH_BIT(10),
// Expression flags
Ast_Flag_Expr_Ignored = BH_BIT(13),
- Ast_Flag_Param_Use = BH_BIT(14),
+ Ast_Flag_Param_Use = BH_BIT(14), // Unneeded, just use a bool on AstParam
Ast_Flag_Address_Taken = BH_BIT(15),
// Type flags
Ast_Flag_Type_Is_Resolved = BH_BIT(16),
// Enum flags
- Ast_Flag_Enum_Is_Flags = BH_BIT(17),
+ Ast_Flag_Enum_Is_Flags = BH_BIT(17), // Unneeded, just use a bool on AstEnum
// Struct flags
- Ast_Flag_Struct_Is_Union = BH_BIT(18),
+ Ast_Flag_Struct_Is_Union = BH_BIT(18), // Unneeded, just a usea bool on AstStruct
Ast_Flag_No_Clone = BH_BIT(19),
Ast_Flag_Cannot_Take_Addr = BH_BIT(20),
- Ast_Flag_Struct_Mem_Used = BH_BIT(21),
+ Ast_Flag_Struct_Mem_Used = BH_BIT(21), // Unneeded, just a usea bool on AstStructMember
// HACK: NullProcHack
Ast_Flag_Proc_Is_Null = BH_BIT(22),
Ast_Flag_From_Polymorphism = BH_BIT(23),
+
+ Ast_Flag_Incomplete_Body = BH_BIT(24),
} AstFlags;
typedef enum UnaryOp {
AstTyped* value;
};
};
+struct AstSolidifiedFunction {
+ AstFunction* func;
+ Scope* poly_scope;
+};
struct AstPolyProc {
AstNode_base;
bh_arr(AstPolySolution) known_slns;
AstFunction* base_func;
- bh_table(AstFunction *) concrete_funcs;
+ bh_table(AstSolidifiedFunction) concrete_funcs;
};
struct AstOverloadedFunction {
AstTyped_base;
AstTyped* ast_reduce(bh_allocator a, AstTyped* node);
AstNode* ast_clone(bh_allocator a, void* n);
AstFunction* clone_function_header(bh_allocator a, AstFunction* func);
+void clone_function_body(bh_allocator a, AstFunction* dest, AstFunction* source);
void promote_numlit_to_larger(AstNumLit* num);
b32 convert_numlit_to_type(AstNumLit* num, Type* type);
bh_table_clear(scope->symbols);
}
+static void ensure_polyproc_cache_is_created(AstPolyProc* pp) {
+ if (pp->concrete_funcs == NULL) {
+ bh_table_init(global_heap_allocator, pp->concrete_funcs, 16);
+ }
+}
+
static void insert_poly_slns_into_scope(Scope* scope, bh_arr(AstPolySolution) slns) {
bh_arr_each(AstPolySolution, sln, slns) {
AstNode *node = NULL;
}
AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual, OnyxFilePos pos) {
- if (pp->concrete_funcs == NULL) {
- bh_table_init(global_heap_allocator, pp->concrete_funcs, 8);
- }
+ ensure_polyproc_cache_is_created(pp);
char *err_msg = NULL;
bh_arr(AstPolySolution) slns = find_polymorphic_slns(pp, pp_lookup, actual, &err_msg);
return key_buf;
}
-AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxFilePos pos) {
- if (pp->concrete_funcs == NULL) {
- bh_table_init(global_heap_allocator, pp->concrete_funcs, 8);
- }
-
- // NOTE: Check if a version of this polyproc has already been created.
- char* unique_key = build_poly_slns_unique_key(slns);
- if (bh_table_has(AstFunction *, pp->concrete_funcs, unique_key)) {
- return bh_table_get(AstFunction *, pp->concrete_funcs, unique_key);
- }
-
- Scope* poly_scope = scope_create(semstate.node_allocator, pp->poly_scope, pos);
- insert_poly_slns_into_scope(poly_scope, slns);
-
- AstFunction* func = (AstFunction *) ast_clone(semstate.node_allocator, pp->base_func);
- bh_table_put(AstFunction *, pp->concrete_funcs, unique_key, func);
+b32 add_solidified_function_entities(AstSolidifiedFunction solidified_func, b32 header_already_processed) {
+ solidified_func.func->flags |= Ast_Flag_Function_Used;
+ solidified_func.func->flags |= Ast_Flag_From_Polymorphism;
- func->flags |= Ast_Flag_Function_Used;
- func->flags |= Ast_Flag_From_Polymorphism;
+ EntityState header_start_state = Entity_State_Resolve_Symbols;
+ if (header_already_processed) header_start_state = Entity_State_Code_Gen;
Entity func_header_entity = {
- .state = Entity_State_Resolve_Symbols,
+ .state = header_start_state,
.type = Entity_Type_Function_Header,
- .function = func,
+ .function = solidified_func.func,
.package = NULL,
- .scope = poly_scope,
+ .scope = solidified_func.poly_scope,
};
entity_bring_to_state(&func_header_entity, Entity_State_Code_Gen);
- if (onyx_has_errors()) {
- onyx_report_error(pos, "Error in polymorphic procedure header generated from this call site.");
- return NULL;
- }
+ if (onyx_has_errors()) return 0;
Entity func_entity = {
.state = Entity_State_Resolve_Symbols,
.type = Entity_Type_Function,
- .function = func,
+ .function = solidified_func.func,
.package = NULL,
- .scope = poly_scope,
+ .scope = solidified_func.poly_scope,
};
entity_heap_insert(&semstate.program->entities, func_header_entity);
entity_heap_insert(&semstate.program->entities, func_entity);
- return func;
+
+ return 1;
+}
+
+AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxFilePos pos) {
+ ensure_polyproc_cache_is_created(pp);
+
+ // NOTE: Check if a version of this polyproc has already been created.
+ char* unique_key = build_poly_slns_unique_key(slns);
+ if (bh_table_has(AstSolidifiedFunction, pp->concrete_funcs, unique_key)) {
+ AstSolidifiedFunction solidified_func = bh_table_get(AstSolidifiedFunction, pp->concrete_funcs, unique_key);
+
+ if (solidified_func.func->flags & Ast_Flag_Incomplete_Body) {
+ clone_function_body(semstate.node_allocator, solidified_func.func, pp->base_func);
+
+ if (!add_solidified_function_entities(solidified_func, 1)) {
+ onyx_report_error(pos, "Error in polymorphic procedure header generated from this call site.");
+ return NULL;
+ }
+
+ solidified_func.func->flags &= ~Ast_Flag_Incomplete_Body;
+ }
+
+ return solidified_func.func;
+ }
+
+ AstSolidifiedFunction solidified_func;
+ solidified_func.poly_scope = scope_create(semstate.node_allocator, pp->poly_scope, pos);
+ insert_poly_slns_into_scope(solidified_func.poly_scope, slns);
+
+ solidified_func.func = (AstFunction *) ast_clone(semstate.node_allocator, pp->base_func);
+ bh_table_put(AstSolidifiedFunction, pp->concrete_funcs, unique_key, solidified_func);
+
+ if (!add_solidified_function_entities(solidified_func, 0)) {
+ onyx_report_error(pos, "Error in polymorphic procedure header generated from this call site.");
+ return NULL;
+ }
+ return solidified_func.func;
}
// NOTE: This can return either a AstFunction or an AstPolyProc, depending if enough parameters were
new_pp->flags = pp->flags;
new_pp->poly_params = pp->poly_params;
- // POTENTIAL BUG: Copying this doesn't feel right...
- if (pp->concrete_funcs == NULL) {
- bh_table_init(global_heap_allocator, pp->concrete_funcs, 8);
- }
+ ensure_polyproc_cache_is_created(pp);
new_pp->concrete_funcs = pp->concrete_funcs;
new_pp->known_slns = NULL;
bh_arr(AstPolySolution) slns = find_polymorphic_slns(pp, pp_lookup, actual, NULL);
if (slns == NULL) return NULL;
- Scope* poly_scope = scope_create(semstate.node_allocator, pp->poly_scope, (OnyxFilePos) { 0 });
- insert_poly_slns_into_scope(poly_scope, slns);
+ ensure_polyproc_cache_is_created(pp);
+
+ char* unique_key = build_poly_slns_unique_key(slns);
+ if (bh_table_has(AstSolidifiedFunction, pp->concrete_funcs, unique_key)) {
+ AstSolidifiedFunction solidified_func = bh_table_get(AstSolidifiedFunction, pp->concrete_funcs, unique_key);
+ return solidified_func.func;
+ }
// NOTE: This function is only going to have the header of it correctly created.
// Nothing should happen to this function's body or else the original will be corrupted.
// - brendanfh 2021/01/10
- AstFunction* new_func = clone_function_header(semstate.node_allocator, pp->base_func);
- new_func->flags |= Ast_Flag_From_Polymorphism;
+ AstSolidifiedFunction solidified_func;
+ solidified_func.poly_scope = scope_create(semstate.node_allocator, pp->poly_scope, (OnyxFilePos) { 0 });
+ insert_poly_slns_into_scope(solidified_func.poly_scope, slns);
+
+ solidified_func.func = clone_function_header(semstate.node_allocator, pp->base_func);
+ solidified_func.func->flags |= Ast_Flag_Incomplete_Body;
+ solidified_func.func->flags |= Ast_Flag_From_Polymorphism;
Entity func_header_entity = {
.state = Entity_State_Resolve_Symbols,
.type = Entity_Type_Function_Header,
- .function = new_func,
+ .function = solidified_func.func,
.package = NULL,
- .scope = poly_scope,
+ .scope = solidified_func.poly_scope,
};
entity_bring_to_state(&func_header_entity, Entity_State_Code_Gen);
return NULL;
}
- return new_func;
+ bh_table_put(AstSolidifiedFunction, pp->concrete_funcs, unique_key, solidified_func);
+ return solidified_func.func;
}
char* build_poly_struct_name(AstPolyStructType* ps_type, Type* cs_type) {