fix(stubgen): vpi 落盘入口统一重建文件级名字窗口,修复 FileFuncNames 悬垂野读崩溃

Phase1 1b-pre / 1b 兜底 / BuildPipeline / Repl 为生成 vpi 各自重新 parse 出独立 AST,但不走 register_file_funcs,导致 is_file_func(range)(_PushInductionEntry)仍读到上一个文件的表 + 已被 reset 的池 → 悬垂指针,ASan access-violation 崩在 HashTable._slot_hash。将 reset_file_name_window + register_file_func_names 收敛到 _GeneratePyiFromAst 唯一入口,覆盖全部 vpi 落盘调用点;Phase2 的重复调用随之移除。
This commit is contained in:
TermiNexus committed 2026-10-10 14:00:41 +08:00
1 parent c1d3f62bf0
commit f2cbb658e1
2 files changed
+12 -6

No files matched your search

+10
View File
@@ -708,6 +708,16 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf
# an absolute path (fatal_error opens it directly). Set once at entry to cover all branches.
if rel_path is not None: GenApi.set_current_file_type(rel_path)
# 文件级名字窗口:本函数是 vpi 落盘的**唯一入口**,而各调用方只为落盘各自重新 parse 出
# 独立 AST、**不走** register_file_funcs。但 _PyiFunction → compute_escape_summary →
# _ScanEscapes → _PushInductionEntry 会问 is_file_func("range")("本文件自己定义过 range
# 就放弃区间推断")。若不清窗口再重建表,就会读到"上一个文件的表 + 已被 reset 的池" =
# 悬垂指针(ASan access-violation 崩在 HashTable._slot_hash / 非 ASan 静默错答)。
# 契约见 StructGenMixin.reset_file_name_window:任何文件级入口必须先清再重建。
# 收敛到本入口可一次性覆盖 Phase1 1b-pre / Phase1 1b 兜底 / BuildPipeline / Repl / Phase2。
GenApi.reset_file_name_window()
GenApi.register_file_func_names(mb, tree)
pos: sizet = 0
# Pre-pass: register this file's CDefines into the _g_pyi cache in declaration order