fix(gen): 全局初始化器引用跨模块 vtable 时补 external 声明(④-a)
模块级对象全局的 storage 初始化器以符号名写入依赖类 vtable (i8* @<dep_sha1>.<Cls>.vtable),此前不建 GlobalVariable ⇒ 单模块 OUTPUT_FULL 缺该符号声明,只能靠 BuildCombinedIR 合并依赖 stub 补入。 现于写初始化器前:跨模块(ModuleSha1 != 当前模块)且模块内无该全局时, new_global_variable(..., Ptr(i8)) + module_add_global 补 external 声明 (对齐 CallGenLeafKit._make_vtable_ref_i8)。仅跨模块补,本模块类由 _generate_vtable 产出定义,避免同模块重复定义。 去 IR 化步骤④-a(生产者自足,FULL IR 自足化前置);未编译验证。
This commit is contained in:
1 parent
324a22b6d1
commit
ec9e950185
1 file changed
+16
@@ -1049,6 +1049,22 @@ novirtual class TranslatorGenMixin:
|
||||
vt_sha1 = trans.ModuleSha1
|
||||
vt_mangled: str = self.Gen.FuncGenBase._mangle_name_with_sha1(vt_sha1, vt_name_buf)
|
||||
if vt_mangled is not None:
|
||||
# 跨模块 vtable 只被本初始化器文本引用 ⇒ 模块内无对应 GlobalVariable ⇒
|
||||
# 单模块 FULL IR 缺该符号声明(旧架构靠 BuildCombinedIR 合并依赖 stub
|
||||
# 补入 external 声明)。此处补声明,使单模块 IR 自足(对齐
|
||||
# CallGenLeafKit._make_vtable_ref_i8 的跨模块分支)。
|
||||
# 仅跨模块补:本模块类由 _generate_vtable 产出定义,补声明会重复定义。
|
||||
# LLVM 22 不透明指针 ⇒ 声明 pointee 用 i8* 即可(pointee 无语义)。
|
||||
vt_cross: int = 0
|
||||
if resolved_stg_entry.ModuleSha1 is not None and trans.ModuleSha1 is not None:
|
||||
if string.strncmp(resolved_stg_entry.ModuleSha1, trans.ModuleSha1, 16) != 0:
|
||||
vt_cross = 1
|
||||
if vt_cross != 0 \
|
||||
and self.Gen.ExprGenAttr.find_global_in_module(mod, vt_mangled) is None:
|
||||
vt_decl_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
vt_gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(pool, vt_mangled, vt_decl_ty)
|
||||
if vt_gv is not None:
|
||||
llvmlite.module_add_global(mod, vt_gv)
|
||||
# 完整 struct 初始化器(LLVM 拒绝部分初始化):
|
||||
# 字段 0 = __vtable__(i8* @vtable),其余用户字段按类型零值。
|
||||
init_full_len: sizet = 16384
|
||||
|
||||
Reference in new issue
Block a user