diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2025-09-19 11:13:18 +0100 |
|---|---|---|
| committer | gingerBill <gingerBill@users.noreply.github.com> | 2025-09-19 11:13:18 +0100 |
| commit | 1a4da5cb0fa5731926ba7abb7a7496be6a39831f (patch) | |
| tree | b9f45dbf5658b9b514639f93cb2428a8489a0d86 | |
| parent | 6ce889f4ebf10d44fc6c1e5fba794e412dfcf183 (diff) | |
Distribute anonymous procedure literals correctly across LLVM modules
| -rw-r--r-- | src/llvm_backend_general.cpp | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 129634ee6..57eb869fa 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -3083,7 +3083,7 @@ gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) { - // lbGenerator *gen = m->gen; + lbGenerator *gen = m->gen; ast_node(pl, ProcLit, expr); if (pl->decl->entity.load() != nullptr) { @@ -3112,8 +3112,11 @@ gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &pr e->pkg = e->file->pkg; e->scope = e->file->scope; + lbModule *target_module = lb_module_of_entity(gen, e, m); + GB_ASSERT(target_module != nullptr); + // NOTE(bill): this is to prevent a race condition since these procedure literals can be created anywhere at any time - pl->decl->code_gen_module = m; + pl->decl->code_gen_module = target_module; e->decl_info = pl->decl; e->parent_proc_decl = pl->decl->parent; e->Procedure.is_anonymous = true; @@ -3121,20 +3124,41 @@ gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &pr pl->decl->entity.store(e); - lbProcedure *p = lb_create_procedure(m, e); - GB_ASSERT(e->code_gen_module == m); - lbValue value = {}; - value.value = p->value; - value.type = p->type; + if (target_module != m) { + mutex_lock(&target_module->missing_procedures_to_check_mutex); + rw_mutex_shared_lock(&target_module->values_mutex); + lbValue *found = map_get(&target_module->values, e); + rw_mutex_shared_unlock(&target_module->values_mutex); + if (found == nullptr) { + // THIS IS THE RACE CONDITION + lbProcedure *missing_proc_in_target_module = lb_create_procedure(target_module, e, false); + array_add(&target_module->missing_procedures_to_check, missing_proc_in_target_module); + } + + mutex_unlock(&target_module->missing_procedures_to_check_mutex); - array_add(&m->procedures_to_generate, p); - if (parent != nullptr) { - array_add(&parent->children, p); + lbProcedure *p = lb_create_procedure(m, e, true); + + lbValue value = {}; + value.value = p->value; + value.type = p->type; + return value; } else { - string_map_set(&m->members, name, value); + lbProcedure *p = lb_create_procedure(m, e); + + lbValue value = {}; + value.value = p->value; + value.type = p->type; + + array_add(&m->procedures_to_generate, p); + if (parent != nullptr) { + array_add(&parent->children, p); + } else { + string_map_set(&m->members, name, value); + } + return value; } - return value; } |