diagnose(tpv): Phase A pending 置位点全量 [DEPDBG] 诊断 + 别名解析修复 - 9 处 _deps_pending 置位点加 [DEPDBG] printf(CallGenCall×4/CallGenMixin/CallGenDispatch×2/CallGenProp/ExprGenName),一次构建即可定位 ClassGenVTable 永久 pending 的具体调用点 - StubMergerStore 新增 LookupSha1ByAlias:经 from_imports 别名映射(import X as Y → Y:X)解析模块 SHA1 - LoadDepVpiIntoModule 与 Phase A 依赖探针接入别名解析,HT 等改名别名不再误报未解析
This commit is contained in:
1 parent
6cd8adc54c
commit
27f2a53c15
8 files changed
+118
-6
No files matched your search
@@ -740,6 +740,9 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
im_dp_sha1: str = StubMergerStore.LookupSha1ByModName(im_dp_buf)
|
||||
if im_dp_sha1 is None:
|
||||
im_dp_sha1 = StubMergerStore.LookupSha1ByModNameSuffix(im_dp_buf)
|
||||
if im_dp_sha1 is None:
|
||||
# 改名别名(import X as Y):从 _from_imports 查 Y→X 再查 SHA1
|
||||
im_dp_sha1 = StubMergerStore.LookupSha1ByAlias(tr_a._from_imports, im_dp_buf)
|
||||
im_dp_resolved: int = 0
|
||||
im_dp_missing: int = 0
|
||||
if im_dp_sha1 is not None:
|
||||
|
||||
@@ -1204,6 +1204,12 @@ def LoadDepVpiIntoModule(pool: memhub.MemBuddy | t.CPtr,
|
||||
# 用 LookupSha1ByModName 查找模块的 SHA1
|
||||
sha1_val: str = StubMergerStore.LookupSha1ByModName(mod_nm_buf)
|
||||
|
||||
# 改名别名(import X as Y,如 HT→lib.core.Handles.HandlesTranslator):
|
||||
# 精确/包名回退均失败时从 from_imports 查别名映射再查 SHA1,
|
||||
# 否则该类模块的 vpi/stub 不注入 → 跨模块符号解析失败
|
||||
if sha1_val is None and from_imports is not None:
|
||||
sha1_val = StubMergerStore.LookupSha1ByAlias(from_imports, mod_nm_buf)
|
||||
|
||||
# 如果精确查找失败,尝试包名回退(如 "ast" → "ast.__init__")
|
||||
# LookupSha1ByModName 内部已处理包名回退,此处无需重复
|
||||
|
||||
|
||||
@@ -18,19 +18,15 @@ import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
import lib.Projectrans.Utils as Utils
|
||||
import lib.Projectrans.Config as Config
|
||||
|
||||
|
||||
import lib.Stub.StubMerger.StubMergerCollect as StubMergerCollect
|
||||
import lib.Stub.StubMerger.StubMergerTopo as StubMergerTopo
|
||||
import lib.Stub.StubMerger.StubMergerIR as StubMergerIR
|
||||
import lib.Stub.StubMerger.StubMergerBuild as StubMergerBuild
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
|
||||
|
||||
# ============================================================
|
||||
# StubMergerStore - StubMerger 拆分(阶段 E):StubMergerStore
|
||||
#
|
||||
# 直接移动模式:函数实现迁至此模块,原 StubMerger.vp 仅保留
|
||||
# 常量/全局变量;调用方经本模块前缀访问。全局变量跨模块经
|
||||
# StubMerger._xxx 访问(main.vp 先例)。
|
||||
# ============================================================
|
||||
|
||||
# ============================================================
|
||||
@@ -273,6 +269,64 @@ def LookupSha1ByModNameSuffix(mod_suffix: str) -> str:
|
||||
return StubMerger._sha1_store_arr + sidx_rev_sf
|
||||
return None
|
||||
# ============================================================
|
||||
# LookupSha1ByAlias - 从 from_imports 别名映射解析模块 SHA1
|
||||
#
|
||||
# from_imports 条目格式: "local:module" 或 "local:module:orig"(空格分隔),
|
||||
# 由 ImportsGenMixin.add_from_import 写入(import X as Y → "Y:X")。
|
||||
# 命中 local==alias 时,对 module 执行 LookupSha1ByModName 返回 SHA1。
|
||||
#
|
||||
# Returns:
|
||||
# SHA1 字符串指针(指向全局存储器内部),None 未找到
|
||||
# ============================================================
|
||||
def LookupSha1ByAlias(from_imports: str, alias: str) -> str:
|
||||
"""从 from_imports 别名映射解析模块 SHA1(改名别名 import X as Y 场景)"""
|
||||
if from_imports is None or alias is None:
|
||||
return None
|
||||
alias_len: t.CSizeT = string.strlen(alias)
|
||||
if alias_len == 0:
|
||||
return None
|
||||
total_len: t.CSizeT = string.strlen(from_imports)
|
||||
ci: t.CSizeT = 0
|
||||
while ci < total_len:
|
||||
# 跳过前导空格
|
||||
while ci < total_len and from_imports[ci] == ' ':
|
||||
ci += 1
|
||||
if ci >= total_len:
|
||||
break
|
||||
# 条目起点 ci,找 ':'(local_name 结束)
|
||||
colon: t.CSizeT = ci
|
||||
while colon < total_len and from_imports[colon] != ':' and from_imports[colon] != ' ':
|
||||
colon += 1
|
||||
local_len: t.CSizeT = colon - ci
|
||||
if colon < total_len and from_imports[colon] == ':' and local_len == alias_len:
|
||||
# 比较 local_name == alias
|
||||
match: int = 1
|
||||
li: t.CSizeT = 0
|
||||
while li < alias_len:
|
||||
if from_imports[ci + li] != alias[li]:
|
||||
match = 0
|
||||
break
|
||||
li += 1
|
||||
if match == 1:
|
||||
# 提取 module(colon+1 到下一个 ':' 或空格)
|
||||
m_start: t.CSizeT = colon + 1
|
||||
m_end: t.CSizeT = m_start
|
||||
while m_end < total_len and from_imports[m_end] != ':' and from_imports[m_end] != ' ':
|
||||
m_end += 1
|
||||
if m_end > m_start:
|
||||
mbuf: str = stdlib.malloc(m_end - m_start + 1)
|
||||
if mbuf is not None:
|
||||
string.strncpy(mbuf, from_imports + m_start, m_end - m_start)
|
||||
mbuf[m_end - m_start] = '\0'
|
||||
res: str = LookupSha1ByModName(mbuf)
|
||||
stdlib.free(mbuf)
|
||||
return res
|
||||
return None
|
||||
# 跳到下一条目
|
||||
while ci < total_len and from_imports[ci] != ' ':
|
||||
ci += 1
|
||||
return None
|
||||
# ============================================================
|
||||
# PopulateIncludesDeps - 将 includes 文件的依赖存入内存
|
||||
#
|
||||
# Phase B+ 前用 declare_only 翻译 includes 文件,提取 _imported_modules
|
||||
@@ -371,7 +425,7 @@ def GetSha1StoreArr(out_sha1_arr: t.CPtr, out_mod_arr: t.CPtr, out_rel_arr: t.CP
|
||||
return -1
|
||||
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_mod is None or StubMerger._sha1_store_rel is None:
|
||||
return -1
|
||||
sp: t.CPtr = (t.CPtr | t.CPtr)(t.CVoid(out_sha1_arr, t.CPtr))
|
||||
sp: t.CPtr = (t.CPtr | t.CPtr)(t.CVoid(out_sha1_arr, t.CPtr)) # 存疑
|
||||
if sp is not None:
|
||||
sp[0] = StubMerger._sha1_store_arr
|
||||
mp: t.CPtr = (t.CPtr | t.CPtr)(t.CVoid(out_mod_arr, t.CPtr))
|
||||
@@ -381,6 +435,7 @@ def GetSha1StoreArr(out_sha1_arr: t.CPtr, out_mod_arr: t.CPtr, out_rel_arr: t.CP
|
||||
if rp is not None:
|
||||
rp[0] = StubMerger._sha1_store_rel
|
||||
return StubMerger._sha1_store_count
|
||||
|
||||
# ============================================================
|
||||
# LookupSha1RelPath - 通过 SHA1 查找相对路径
|
||||
#
|
||||
|
||||
@@ -362,6 +362,11 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
and self._dep_text_ll_exists(pool, cls_sha1) == 0):
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:方法返回类型解析依赖未就绪即 pending 的根因(用后移除)
|
||||
dbg_ms1: str = trans.ModuleSha1 if (trans is not None and trans.ModuleSha1 is not None) else "?"
|
||||
stdio.printf("[DEPDBG] pending(method_ret): mod=%s cls=%s method=%s sha1=%s\n",
|
||||
dbg_ms1, class_name, method_name,
|
||||
cls_sha1 if cls_sha1 is not None else "none")
|
||||
# 依赖未就绪:保持默认 i32(build_call(Void) 返回 None 会
|
||||
# 破坏表达式翻译;pending 文件本遍不写盘,下遍重译)
|
||||
call_ret_ty = llvmlite.Int32(pool)
|
||||
@@ -867,6 +872,12 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
and self._dep_text_ll_exists(pool, ret_anc_sha1) == 0):
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:方法祖先模块依赖未就绪即 pending 的根因(用后移除)
|
||||
dbg_ms2: str = trans.ModuleSha1 if (trans is not None and trans.ModuleSha1 is not None) else "?"
|
||||
stdio.printf("[DEPDBG] pending(mro_ret): mod=%s cls=%s method=%s ret_sha1=%s text=%d\n",
|
||||
dbg_ms2, class_name, method_name,
|
||||
ret_anc_sha1 if ret_anc_sha1 is not None else "none",
|
||||
self._dep_text_ll_exists(pool, ret_anc_sha1) if ret_anc_sha1 is not None else -1)
|
||||
# 依赖未就绪:保持默认 i32 继续而非 Void——build_call(Void)
|
||||
# 返回 None,方法调用结果喂进表达式(if 条件/比较)时 fatal
|
||||
# "if 条件表达式翻译失败"(ExprGenAttr._get_cderef_attr_base
|
||||
@@ -898,6 +909,12 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if anc_missing_p2 != 0:
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:MRO 祖先模块依赖未就绪即 pending 的根因(用后移除)
|
||||
dbg_ms3: str = trans.ModuleSha1 if (trans is not None and trans.ModuleSha1 is not None) else "?"
|
||||
stdio.printf("[DEPDBG] pending(mro_anc): mod=%s cls=%s method=%s anc=%s anc_sha1=%s\n",
|
||||
dbg_ms3, class_name, method_name,
|
||||
anc_p2 if anc_p2 is not None else "none",
|
||||
anc_sha1_p2 if anc_sha1_p2 is not None else "none")
|
||||
# 依赖未就绪:保持默认 i32(同上,build_call(Void) 返回
|
||||
# None 会破坏表达式翻译,pending 文件本遍不写盘)
|
||||
call_ret_ty = llvmlite.Int32(pool)
|
||||
@@ -1523,6 +1540,12 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
or self._dep_text_ll_exists(pool, anc_sha1_sp) == 0:
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:特殊方法依赖未就绪即 pending 的根因(用后移除)
|
||||
dbg_ms4: str = trans.ModuleSha1 if (trans is not None and trans.ModuleSha1 is not None) else "?"
|
||||
stdio.printf("[DEPDBG] pending(special_ret): mod=%s cls=%s method=%s sha1=%s\n",
|
||||
dbg_ms4, anc if anc is not None else "?",
|
||||
method_name,
|
||||
anc_sha1_sp if anc_sha1_sp is not None else "none")
|
||||
# 依赖未就绪:保持默认 i32(build_call(Void) 返回 None
|
||||
# 会破坏表达式翻译;pending 文件本遍不写盘,下遍重译)
|
||||
ret_ty_sp = llvmlite.Int32(pool)
|
||||
|
||||
@@ -1097,6 +1097,11 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# 中断多遍收敛(对齐追加77/77b 类 defer 原则)。
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:方法返回类型解析依赖未就绪即 pending 的根因(用后移除)
|
||||
dbg_ms6: str = trans.ModuleSha1 if (trans is not None and trans.ModuleSha1 is not None) else "?"
|
||||
stdio.printf("[DEPDBG] pending(dispatch_ret): mod=%s cls=%s method=%s sha1=%s\n",
|
||||
dbg_ms6, cls_nm2, func_name,
|
||||
sha1_fc if sha1_fc is not None else "none")
|
||||
# 依赖未就绪:保持默认 i32(build_call(Void)
|
||||
# 返回 None 破坏表达式翻译;本遍不写盘)
|
||||
ret_ty3 = llvmlite.Int32(pool)
|
||||
@@ -1121,6 +1126,10 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if obj_ptr4 is not None:
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:特殊方法依赖未就绪即 pending 的根因(用后移除)
|
||||
dbg_ms7: str = trans.ModuleSha1 if (trans is not None and trans.ModuleSha1 is not None) else "?"
|
||||
stdio.printf("[DEPDBG] pending(dispatch_sp): mod=%s cls=%s method=%s\n",
|
||||
dbg_ms7, cls_nm2, func_name)
|
||||
if hit_box is not None:
|
||||
hit_box[0] = 1
|
||||
return self.Gen.CallGenCall._translate_method_call(
|
||||
|
||||
@@ -1164,6 +1164,12 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
else:
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:跨模块函数依赖未就绪即 pending 的根因(用后移除)
|
||||
dbg_ms5: str = trans.ModuleSha1 if (trans is not None and trans.ModuleSha1 is not None) else "?"
|
||||
stdio.printf("[DEPDBG] pending(cross_fn): mod=%s call=%s sha1=%s text=%d\n",
|
||||
dbg_ms5, call_name,
|
||||
cf_sha1 if cf_sha1 is not None else "none",
|
||||
self._dep_text_ll_exists(pool, cf_sha1) if cf_sha1 is not None else -1)
|
||||
cf_dbg: str = VLogger.fmt_buf()
|
||||
if cf_dbg is not None:
|
||||
viperlib.snprintf(
|
||||
|
||||
@@ -125,6 +125,11 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
or self._dep_text_ll_exists(pool, cls_sha1_rt) == 0:
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:属性方法依赖未就绪即 pending 的根因(用后移除)
|
||||
dbg_ms8: str = trans.ModuleSha1 if (trans is not None and trans.ModuleSha1 is not None) else "?"
|
||||
stdio.printf("[DEPDBG] pending(prop_ret): mod=%s cls=%s method=%s sha1=%s\n",
|
||||
dbg_ms8, class_name, method_name,
|
||||
cls_sha1_rt if cls_sha1_rt is not None else "none")
|
||||
# 依赖未就绪:保持默认 i32(build_call(Void) 返回 None
|
||||
# 会破坏表达式翻译;pending 文件本遍不写盘,下遍重译)
|
||||
call_ret_ty = llvmlite.Int32(pool)
|
||||
|
||||
@@ -337,6 +337,11 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# lexer 先于 tokens 翻译必然误报 "stub 未注入"。
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:全局 stub 未注入即 pending 的根因(用后移除)
|
||||
dbg_ms9: str = trans.ModuleSha1 if (trans is not None and trans.ModuleSha1 is not None) else "?"
|
||||
stdio.printf("[DEPDBG] pending(global_stub): mod=%s name=%s mod_src=%s sha1=%s\n",
|
||||
dbg_ms9, nm_id, fi_mod_cut2,
|
||||
StubMergerStore.LookupSha1ByModName(fi_mod_cut2) if fi_mod_cut2 is not None else "none")
|
||||
return None
|
||||
if ref_fi is not None and ref_fi.Ty is not None:
|
||||
lty_fi: llvmlite.LLVMType | t.CPtr = ref_fi.Ty.Pointee
|
||||
|
||||
Reference in new issue
Block a user