From 5efca5b8e4685b4870bf8d7638c8a6518bfac495 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 13 Aug 2026 04:10:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(phase1):=20Phase=201b=20=E6=8C=89=E6=8B=93?= =?UTF-8?q?=E6=89=91=E5=BA=8F=E7=BF=BB=E8=AF=91=20includes=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B7=A8=E6=A8=A1=E5=9D=97=20vtable=20?= =?UTF-8?q?=E8=AF=AF=E6=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vtable 生成在 Phase 1b(declare_only=0),继承方法需依赖模块的函数 TypeStr 已注册(1b 翻译时动态写入全局表)。1b 循环原先按扫描顺序 翻译(astaux.vp 在 base.vp 前),父类未先翻译导致 vtable 找不到 实现。topo_order 原在 1a 末尾释放,1b 无法复用——改为 1b 循环按 topo_order 遍历(父类文件先翻译),topo_order 释放延后到 1b 后。 --- App/lib/core/Phase1.vp | 45 ++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/App/lib/core/Phase1.vp b/App/lib/core/Phase1.vp index 5e3c61a..8e6f32b 100644 --- a/App/lib/core/Phase1.vp +++ b/App/lib/core/Phase1.vp @@ -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)