fix(phase1): Phase 1b 按拓扑序翻译 includes,修复跨模块 vtable 误杀

vtable 生成在 Phase 1b(declare_only=0),继承方法需依赖模块的函数
TypeStr 已注册(1b 翻译时动态写入全局表)。1b 循环原先按扫描顺序
翻译(astaux.vp 在 base.vp 前),父类未先翻译导致 vtable 找不到
实现。topo_order 原在 1a 末尾释放,1b 无法复用——改为 1b 循环按
topo_order 遍历(父类文件先翻译),topo_order 释放延后到 1b 后。
This commit is contained in:
TermiNexus committed 2026-08-13 04:10:47 +08:00
1 parent 7cc501cdef
commit 5efca5b8e4
1 file changed
+30 -15
+30 -15
View File
@@ -964,17 +964,14 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
VLogger.error(fb_p1ar, "Phase1")
return 1
# 释放拓扑排序资源
# 释放拓扑排序资源(topo_order/topo_count_box 保留到 Phase 1b 结束,
# 1b 按拓扑序翻译需要它们;class/def 数组 1b 不再使用)
if class_names_buf is not None:
mb.free(class_names_buf)
if parent_names_buf is not None:
mb.free(parent_names_buf)
if def_sha1s_buf is not None:
mb.free(def_sha1s_buf)
if topo_order is not None:
mb.free(topo_order)
if topo_count_box is not None:
mb.free(topo_count_box)
if generic_file_indices is not None:
mb.free(generic_file_indices)
if generic_file_count_box is not None:
@@ -1085,14 +1082,24 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
VLogger.error(fb_p1bpre, "Phase1")
return 1
# 遍历每个文件
# 遍历每个文件(拓扑序优先:父类所在文件先翻译,确保跨模块 vtable
# 生成时依赖模块的函数 TypeStr 已注册;topo_count==0 回退扫描顺序)
translated: int = 0
skipped: int = 0
failed: int = 0
for i in range(result.Count):
# 获取 entry
entry_addr: t.CUInt64T = t.CUInt64T(result.Entries) + i * entry_size
loop_n_b: int = result.Count
if topo_count > 0:
loop_n_b = topo_count
for i in range(loop_n_b):
# 获取 entry(拓扑序:file_idx 从 topo_order 取,否则用扫描索引)
file_idx_b: int = i
if topo_count > 0:
od_addr_b: t.CUInt64T = t.CUInt64T(topo_order) + t.CSizeT(i) * 4
od_ptr_b: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(od_addr_b, t.CPtr))
if od_ptr_b is not None:
file_idx_b = od_ptr_b[0]
entry_addr: t.CUInt64T = t.CUInt64T(result.Entries) + t.CSizeT(file_idx_b) * entry_size
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry is None:
failed += 1
@@ -1103,12 +1110,14 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
failed += 1
continue
# 检查 SHA1 是否在翻译集合中(按需翻译:只翻译可达的文件)
in_set: int = 0
if use_reachable != 0:
in_set = StubMerger._is_in_sha1_set(sha1, reachable_set, reachable_count)
else:
in_set = StubMerger._is_in_sha1_set(sha1, sha1_set, set_count)
# 检查 SHA1 是否在翻译集合中(拓扑序已过滤可达;仅回退扫描顺序时检查)
in_set: int = 1
if topo_count == 0:
in_set = 0
if use_reachable != 0:
in_set = StubMerger._is_in_sha1_set(sha1, reachable_set, reachable_count)
else:
in_set = StubMerger._is_in_sha1_set(sha1, sha1_set, set_count)
if in_set == 0:
skipped += 1
continue
@@ -1372,6 +1381,12 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
VLogger.error(fb, "Phase1")
stdlib.exit(1)
# 释放 Phase 1b 使用的拓扑排序资源
if topo_order is not None:
mb.free(topo_order)
if topo_count_box is not None:
mb.free(topo_count_box)
fb: str = VLogger.fmt_buf()
if fb is not None:
viperlib.snprintf(fb, 1024, "完成: 翻译=%d 跳过=%d 失败=%d", translated, skipped, failed)