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:
1 parent
7cc501cdef
commit
5efca5b8e4
1 file changed
+30
-15
+30
-15
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user