fix(phase1): 旧 5 参 def 前补全量 includes 预注册(1a-pre),修复'无法构建 SHA1 映射'
178ea40重构把全量 includes 扫描/注册(PopulateSha1MapStore + 逐文件 import 依赖 PopulateIncludesDeps)从 Phase1Main 移除,依赖注册式 def 在 BFS 中自行登记。改用旧 5 参只读 def(调用点同步改回 5 参)后 store 无预注册 → _BuildIncludesSha1Map 返回 0 → '无法构建 SHA1 映射' 终止。 按ab0f37e1a-pre 模式补回:scan_includes 全量扫描 → PopulateSha1MapStore 登记 store → 逐文件 declare_only=2 解析 import 依赖(含 _inject_auto_container_visibility)→ PopulateIncludesDeps(文件级 mark/reset 防 OOM)。_BuildReachableResult 增加 reachable_set/count 过滤,result 只保留可达 includes 子集(1a/1b 只翻译可达文件)。
This commit is contained in:
1 parent
50d53d3ce6
commit
c35246f426
2 files changed
+117
-7
No files matched your search
@@ -244,8 +244,14 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int:
|
||||
# ScanResult 指针(stdlib 分配,调用方负责释放);失败返回 None
|
||||
# ============================================================
|
||||
def _BuildReachableResult(mb: memhub.MemBuddy | t.CPtr,
|
||||
includes_dir: str) -> IncludesScanner.ScanResult | t.CPtr:
|
||||
"""从 Sha1Store(仅可达 includes + App)构建可达 FileEntry 列表"""
|
||||
includes_dir: str,
|
||||
reachable_set: str = None,
|
||||
reachable_count: int = 0) -> IncludesScanner.ScanResult | t.CPtr:
|
||||
"""从 Sha1Store(可达 includes + App)构建可达 FileEntry 列表
|
||||
|
||||
reachable_set/reachable_count 非空时按可达集合过滤:includes 预注册是
|
||||
全量 store(PopulateSha1MapStore),1a/1b 只处理 reachable 子集。
|
||||
"""
|
||||
if mb is None:
|
||||
return None
|
||||
store_count: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count)
|
||||
@@ -264,6 +270,10 @@ def _BuildReachableResult(mb: memhub.MemBuddy | t.CPtr,
|
||||
iidx: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_INC_DIR_LEN
|
||||
if StubMerger._sha1_store_incdir[iidx] == '\0':
|
||||
continue
|
||||
# 可达过滤(预注册为全量 store,result 只保留 reachable 子集)
|
||||
if reachable_count > 0 and reachable_set is not None:
|
||||
if StubMergerCollect._is_in_sha1_set(StubMerger._sha1_store_arr + sidx, reachable_set, reachable_count) == 0:
|
||||
continue
|
||||
eaddr: t.CUInt64T = t.CUInt64T(result.Entries) + t.CUInt64T(result.Count) * entry_size
|
||||
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(eaddr, t.CPtr))
|
||||
if entry is None:
|
||||
@@ -361,6 +371,105 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
|
||||
# 悬空 → 后续 tokenize 的 _kw_lookup strcmp 访问 0x4 崩溃(1.log ASan)。
|
||||
ast._init_tables(mb)
|
||||
|
||||
# ============================================================
|
||||
# 旧 5 参 def 兼容预注册(补回 178ea40 重构时移除的 1a-pre)
|
||||
#
|
||||
# 旧 _BuildReachableSha1Set 只读全局存储器:BFS 前必须已有全量
|
||||
# includes 的 sha1→module 映射(PopulateSha1MapStore)与每文件的
|
||||
# import 依赖内存(PopulateIncludesDeps)。注册式新 def 是在 BFS 中
|
||||
# 自行登记,旧 def 没有该逻辑,故在 reachable 之前全量扫描注册。
|
||||
# ============================================================
|
||||
pp_t0: t.CUInt64T = w32.win32base.GetTickCount64()
|
||||
pp_res: IncludesScanner.ScanResult | t.CPtr = IncludesScanner.scan_includes(mb, includes_dir)
|
||||
if pp_res is None:
|
||||
VLogger.error("includes 预扫描失败(scan_includes 返回 None),终止编译", "Phase1")
|
||||
return 1
|
||||
pp_es: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
|
||||
pp_store_count: int = StubMergerStore.PopulateSha1MapStore(pp_res)
|
||||
if pp_store_count <= 0:
|
||||
VLogger.error(f"includes 预注册失败(PopulateSha1MapStore={pp_store_count}),终止编译", "Phase1")
|
||||
return 1
|
||||
pp_fail: int = 0
|
||||
pp_ok: int = 0
|
||||
for pp_i in range(pp_res.Count):
|
||||
pp_mark: t.CSizeT = mb.mark()
|
||||
pp_ea: t.CUInt64T = t.CUInt64T(pp_res.Entries) + t.CUInt64T(pp_i) * pp_es
|
||||
pp_ent: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(pp_ea, t.CPtr))
|
||||
if pp_ent is None or pp_ent.Sha1 is None or pp_ent.Path is None:
|
||||
pp_fail += 1
|
||||
mb.reset_to(pp_mark)
|
||||
continue
|
||||
pp_sha1: str = pp_ent.Sha1
|
||||
pp_f: fileio.File | t.CPtr = fileio.File(pp_ent.Path, fileio.MODE.R)
|
||||
if pp_f.closed:
|
||||
pp_fail += 1
|
||||
mb.reset_to(pp_mark)
|
||||
continue
|
||||
pp_buf: bytes = stdlib.malloc(Phase1.SRC_BUF_SIZE)
|
||||
if pp_buf is None:
|
||||
pp_f.close()
|
||||
pp_fail += 1
|
||||
mb.reset_to(pp_mark)
|
||||
continue
|
||||
pp_br: LONG = pp_f.read_all(pp_buf, Phase1.SRC_BUF_SIZE)
|
||||
pp_f.close()
|
||||
if pp_br <= 0:
|
||||
stdlib.free(pp_buf)
|
||||
pp_fail += 1
|
||||
mb.reset_to(pp_mark)
|
||||
continue
|
||||
if pp_br < Phase1.SRC_BUF_SIZE:
|
||||
pp_buf[pp_br] = 0
|
||||
else:
|
||||
pp_buf[Phase1.SRC_BUF_SIZE - 1] = 0
|
||||
pp_lx: ast.Lexer | t.CPtr = ast.new_lexer(mb)
|
||||
pp_tree: ast.AST | t.CPtr = None
|
||||
if pp_lx is not None:
|
||||
ast._lexer_init(pp_lx, pp_buf, mb)
|
||||
pp_tok: ast.Token | t.CPtr = ast.tokenize(pp_lx)
|
||||
pp_tree = ast.parse_tokens(mb, pp_tok)
|
||||
if pp_tree is None:
|
||||
stdlib.free(pp_buf)
|
||||
pp_fail += 1
|
||||
VLogger.error(f"includes 预注册解析失败: {pp_ent.Path}", "Phase1")
|
||||
mb.reset_to(pp_mark)
|
||||
continue
|
||||
pp_tr: HandlesTranslator.Translator | t.CPtr = HandlesTranslator.Translator()
|
||||
if pp_tr is None:
|
||||
stdlib.free(pp_buf)
|
||||
pp_fail += 1
|
||||
mb.reset_to(pp_mark)
|
||||
continue
|
||||
pp_tr.ModuleSha1 = pp_sha1
|
||||
pp_tr._declare_only = 2
|
||||
pp_tr.CurrentPackage = GenApi.compute_package_from_relpath(mb, pp_ent.RelPath)
|
||||
GenApi.set_current_file_type(pp_ent.Path)
|
||||
GenApi.set_current_file_imports(pp_ent.Path)
|
||||
GenApi.set_current_module_sha1(pp_sha1)
|
||||
GenApi.clear_cdefine_constants()
|
||||
GenApi.clear_ctypedefs()
|
||||
GenApi.reset_visible_structs(mb, 0)
|
||||
pp_rc: int = pp_tr.translate(pp_tree)
|
||||
if pp_rc == 0:
|
||||
pp_tr._inject_auto_container_visibility(mb, pp_tree)
|
||||
if pp_tr._imported_modules is not None:
|
||||
StubMergerStore.PopulateIncludesDeps(pp_sha1, pp_tr._imported_modules)
|
||||
pp_ok += 1
|
||||
else:
|
||||
pp_fail += 1
|
||||
VLogger.error(f"includes 预注册翻译失败: {pp_ent.Path}", "Phase1")
|
||||
if pp_tr._global_names is not None:
|
||||
stdlib.free(pp_tr._global_names)
|
||||
if pp_tr._nonlocal_names is not None:
|
||||
stdlib.free(pp_tr._nonlocal_names)
|
||||
stdlib.free(pp_buf)
|
||||
mb.reset_to(pp_mark)
|
||||
pp_t1: t.CUInt64T = w32.win32base.GetTickCount64()
|
||||
VLogger.info(f"includes 预注册: {pp_ok} 个(失败 {pp_fail},{pp_t1 - pp_t0} ms)", "Phase1")
|
||||
if pp_fail > 0:
|
||||
VLogger.error(f"includes 预注册有 {pp_fail} 个失败,终止编译", "Phase1")
|
||||
return 1
|
||||
|
||||
# 依赖图按需扫描(App 优先模型):
|
||||
# 1) 先扫 App 源文件(Config.SourceDir)的 import 依赖 → 初始队列
|
||||
# 2) BFS 沿队列按文件系统解析 includes 文件,只对可达 includes
|
||||
@@ -376,7 +485,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
|
||||
if reachable_set is not None:
|
||||
string.memset(reachable_set, 0, StubMerger.MAX_INCLUDES_SHA1 * 17)
|
||||
reachable_count = StubMergerBuild._BuildReachableSha1Set(
|
||||
mb, Config.SourceDir, temp_dir, reachable_set, None, includes_dir)
|
||||
mb, Config.SourceDir, temp_dir, reachable_set, None)
|
||||
if reachable_count < 0:
|
||||
VLogger.error("可达集合构建失败(依赖图扫描失败),终止编译", "Phase1")
|
||||
return 1
|
||||
@@ -398,7 +507,8 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
|
||||
# 从 Sha1Store(仅可达 includes + App)构造可达 FileEntry 列表:
|
||||
# 后续 1a/1b-pre/1b 直接遍历 result(incdir 非空条目=includes),
|
||||
# use_reachable 过滤幂等保留(result 即可达子集)
|
||||
result: IncludesScanner.ScanResult | t.CPtr = _BuildReachableResult(mb, includes_dir)
|
||||
result: IncludesScanner.ScanResult | t.CPtr = _BuildReachableResult(
|
||||
mb, includes_dir, reachable_set, reachable_count)
|
||||
if result is None:
|
||||
VLogger.error("可达 FileEntry 列表构建失败,终止编译", "Phase1")
|
||||
return 1
|
||||
|
||||
@@ -763,7 +763,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
do_phase1: int, do_phase2: int,
|
||||
log: VLogger.Logger | t.CPtr,
|
||||
args: argparse.ParsedArgs | t.CPtr,
|
||||
linker_static_libs: str = None,
|
||||
linker_static_libs: str = None,
|
||||
linker_dynamic_libs: str = None) -> int:
|
||||
"""多文件项目编译
|
||||
|
||||
@@ -837,7 +837,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
else:
|
||||
string.memset(rs_05, 0, StubMerger.MAX_INCLUDES_SHA1 * 17)
|
||||
rc_05: int = StubMergerBuild._BuildReachableSha1Set(
|
||||
mb, source_dir, temp_dir, rs_05, None, includes_dir)
|
||||
mb, source_dir, temp_dir, rs_05, None)
|
||||
if rc_05 < 0:
|
||||
VLogger.error("依赖图扫描失败,无法填充 Sha1Store", "project")
|
||||
elif rc_05 > 0:
|
||||
@@ -1615,7 +1615,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
if reachable_set is not None:
|
||||
string.memset(reachable_set, 0, REACHABLE_SET_SIZE)
|
||||
reachable_count = StubMergerBuild._BuildReachableSha1Set(
|
||||
mb, source_dir, temp_dir, reachable_set, app_deps_buf, includes_dir)
|
||||
mb, source_dir, temp_dir, reachable_set, app_deps_buf)
|
||||
VLogger.info(f"可达 includes SHA1: {reachable_count} 个", "PhaseB+")
|
||||
# fast-fail: 可达集合构建失败(依赖未找到),永不回退,直接终止
|
||||
if reachable_count < 0:
|
||||
|
||||
Reference in new issue
Block a user