fix(tpv): 兄弟 Mixin 兜底支持跨模块——修复自身 text.ll 永久 pending 死锁 - ClassGenVTable._mangle_name 定义在 FuncGenBase(跨模块 Mixin,调用类不继承它),兄弟 Mixin 兜底只在本地 IR 找 define 未命中 → ret_anc_sha1 停在调用类自身 sha1 → _dep_text_ll_exists(自身) 恒 0(Phase A 翻译中自身 text.ll 未生成)→ _deps_pending=1 死锁,Phase A 永不收敛 - 修复:兜底遍历已注册 struct 时增加跨模块查找(get_struct_sha1 + _LookupMethodRetTyFromTextLL 查该模块 text.ll),命中即锁定定义类(ret_anc_sha1/ret_anc_name/返回类型),跳过 text.ll/vpi/pending 重查段,按 {定义类sha1}.{定义类}.{方法} 构造调用名
This commit is contained in:
1 parent
27f2a53c15
commit
146b9a9652
1 file changed
+36
-2
@@ -640,10 +640,17 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 普通方法调用在 found_func 未命中时会误绑定到 list 特化函数,
|
||||
# this 按 list 布局前移 sizeof(list) → 运行期读 -1 崩溃
|
||||
# (Config.vp Load_project_config root.__getitem__ 根因)。
|
||||
# 跨模块兄弟 Mixin 兜底命中记录:方法定义类在另一文件(如
|
||||
# FuncGenBase._mangle_name——调用类 ClassGenVTable 不继承它),
|
||||
# 本地 IR 无 define,需经候选类模块 sha1 查 text.ll 返回类型。
|
||||
mixin_hit: int = 0
|
||||
mixin_ret_ty: llvmlite.LLVMType | t.CPtr = None
|
||||
mixin_anc_name: str = None
|
||||
mixin_anc_sha1: str = None
|
||||
if found_func is None:
|
||||
sc_i: int = 0
|
||||
sc_n: int = self.Gen.StructGen.get_struct_count()
|
||||
while sc_i < sc_n and found_func is None:
|
||||
while sc_i < sc_n and found_func is None and mixin_hit == 0:
|
||||
cand_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen._get_struct_entry(sc_i)
|
||||
if cand_entry is not None and cand_entry.Name is not None:
|
||||
cand_name: str = cand_entry.Name
|
||||
@@ -661,6 +668,24 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if cand_func is not None:
|
||||
found_func = cand_func
|
||||
mc_anc = cand_name
|
||||
else:
|
||||
# 跨模块 Mixin(定义类在另一文件,本地 IR 无 define):
|
||||
# 用候选类模块 sha1 查 text.ll 返回类型,命中即锁定定义类,
|
||||
# 后续 ret_anc_* 据此构造 {sha1}.{class}.{method} 调用名。
|
||||
# 否则 ret_anc_sha1 停在调用类自身 sha1,_dep_text_ll_exists
|
||||
# 查自身 text.ll(Phase A 翻译中未生成)→ 永久 pending 死锁
|
||||
# (ClassGenVTable._mangle_name → 7871cc1aabebfc33 根因)。
|
||||
if mixin_hit == 0:
|
||||
cand_sha1_cx: str = self.Gen.StructGen.get_struct_sha1(cand_name)
|
||||
if cand_sha1_cx is not None \
|
||||
and self._dep_text_ll_exists(pool, cand_sha1_cx) != 0:
|
||||
cand_ret_cx: llvmlite.LLVMType | t.CPtr = self._LookupMethodRetTyFromTextLL(
|
||||
pool, cand_sha1_cx, cand_name, method_name)
|
||||
if cand_ret_cx is not None:
|
||||
mixin_hit = 1
|
||||
mixin_ret_ty = cand_ret_cx
|
||||
mixin_anc_name = cand_name
|
||||
mixin_anc_sha1 = cand_sha1_cx
|
||||
sc_i += 1
|
||||
|
||||
# 确定调用名(默认 "ClassName.method";found_func 未命中时沿 MRO 用
|
||||
@@ -725,6 +750,13 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
ret_anc_sha1 = mc_entry.ModuleSha1
|
||||
else:
|
||||
ret_anc_sha1 = self.Gen.StructGen.get_struct_sha1(class_name)
|
||||
# 跨模块兄弟 Mixin 兜底命中:定义类锁定为候选类(如 FuncGenBase),
|
||||
# 返回类型与调用名前缀以其模块 sha1 为准,避免 ret_anc_sha1 停在
|
||||
# 调用类自身 sha1 → 查自身 text.ll(未生成)→ 永久 pending 死锁
|
||||
if mixin_hit != 0:
|
||||
ret_anc_name = mixin_anc_name
|
||||
ret_anc_sha1 = mixin_anc_sha1
|
||||
call_ret_ty = mixin_ret_ty
|
||||
if ret_anc_sha1 is None:
|
||||
# 沿 MRO 找第一个有 SHA1 的类
|
||||
mro_s0: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
|
||||
@@ -810,7 +842,9 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
call_ret_ty = frt_g
|
||||
found_func = spec_found_g
|
||||
gen_done = 1
|
||||
if gen_done == 0:
|
||||
# mixin_hit:跨模块 Mixin 兜底已锁定定义类与返回类型,跳过
|
||||
# text.ll/vpi/pending 重查段,直接构造 {sha1}.{class}.{method} 调用名
|
||||
if gen_done == 0 and mixin_hit == 0:
|
||||
# 尝试从 text.ll 查找实际返回类型
|
||||
# 避免指针返回值被默认 i32 导致 inttoptr 截断
|
||||
looked_up_ty = self._LookupMethodRetTyFromTextLL(
|
||||
|
||||
Reference in new issue
Block a user