Commit Graph
73 Commits
Author SHA1 Message Date
TermiNexus 81ad712475 fix(Handles): 多继承字段展平按继承源去重,消除菱形重复
Generator 同时继承 ClassGenMixin/ClassGenEnum/ClassGenGeneric/ClassGenVTable/ClassGenDef/ClassGenBase,而前 5 个都继承 ClassGenBase → ClassGenBase 41 字段被重复展平 6 次(struct 707 元素),class_members 索引与 struct 布局错位 → 跨 Mixin 方法 this_adjust 失效 → is_exception_name 读错位内存 strcmp 越界(ASAN heap-buffer-overflow)。

修复:HandlesClassDef 与 DeclarationGenerator 的多继承展平改为递归按继承源去重(每类只展平一次,只取自有字段;同名字段如 TempDir 跨非继承 Mixin 仍各自保留,避免 2026-08-10 历史去重缺陷回归)。
2026-08-18 13:13:25 +08:00
TermiNexus 2922af79f1 fix(LLVMCG): 禁止对 null 指针常量做 load 转 int 字段
_coerce_value 中 target 为 IntType 且 val 为 PointerType 时,若
val 是 null 常量且 pointee.width == target.width,此前直接
builder.load(null) 生成 load i32, i32* null,运行时 ASAN
access-violation。根因场景:Generator.__init__ 里
self.ClassMetaKinds = None(字段注解 t.CInt | t.CPtr,联合类型
退化为 i32 槽位,None 解析为 i32* null)。修复:null 常量赋 int
字段直接返回 0;_store 的 null 分支同步补 IntType 处理。
2026-08-18 12:50:31 +08:00
TermiNexus 0e80019033 fix(subscript): 泛型 T|t.CPtr 指针槽变量优先走 i8** load,修 8fbba list[str].get 返回类型不匹配
TPC 编译 TPV 时 _list.vp 泛型方法体 elem_ptr: T|t.CPtr = t.CPtr(...):
T 未解析时 var_struct_class[elem_ptr] 误注册 llvmlite.Value →
_HandleSubscriptLlvm 的 elem_class 推断为 Value → cast Value* → 与
get 声明 i8* 不匹配(llc 报错)。修复:
1. _is_struct_ptr_union 放宽——泛型参数 Name(单字母大写)也判定指针槽
   联合(标量 T 退化为 Ptr(i32) 不命中 i8 分支,安全)
2. _HandleSubscriptLlvm 的 var_ptr_element 分支提前到 elem_class 推断
   之前——T|t.CPtr 指针槽变量优先 i8** load i8*(8 字节)
2026-08-18 10:12:06 +08:00
TermiNexus 15faa1f7b1 perf(vast_c): slots 偏移直写绕过 Python _Init,解析加速 5.5x → 10.6x
- NewNode 改用 tp_new + tp_members.offset 直接写 slots 成员(绕过 Python 层 _Init 帧,_Init 201 万次 26s 是 worker 最大 tottime)
- 布局按 _fields 顺序构建并 PyCapsule 缓存(SlotsLayout);布局缺失/参数越界回退 PyObject_Vectorcall(行为与 vast 一致)
- 修正 PyCapsule_New 成功但 SetItem 失败时的双重释放
- 验证:差分 83/83 全绿;includes/ + TransPyV/App 201 文件 vast_c vs vast 结构与位置属性零差异;基准 8.69ms → 0.82ms(10.6x)
2026-08-18 07:37:30 +08:00
TermiNexus 6613542d8e perf(compile): pyi 缓存落盘改增量构建,Phase2 新增 vpi 不再全量重建
- _BuildPyiCacheFile 原每次签名变化(Phase2 过程新增 include .vpi)都全量 ast.parse 所有 vpi(prof 43 次 × 0.28s = 12.2s)
- 增量:加载旧 pkl,按 (basename, size, mtime) 复用未变化文件的 vast 树,只 parse 新增/变化文件
- 验证:147 个 vpi 新增 1 文件时仅 0.006s(原全量需数秒);无旧 pkl 时自然退化为全量
2026-08-18 07:27:02 +08:00
TermiNexus 94a065a386 perf(vast_c): 节点构造 tp_new 直构试验打平,回退 Vectorcall 并记录结论
- 实测 tp_new + 逐字段 SetAttr 与 PyObject_Vectorcall 打平(基准 0.9x,略慢):PyTuple_New(0) + _fields 缓存查询 + slots 名称线性查找开销抵消 Python 帧收益
- 回退并注释说明:要降低 _Init 19.7s 需 tp_members.offset 偏移直写(风险较高另行评估)
2026-08-18 07:23:41 +08:00
TermiNexus e37cc8d792 fix(vast_c): alias/keyword 节点补位置属性,201 文件全量对比零差异
- ParseImport/ParseImportFrom/ParseImportAlias:alias 节点缺 lineno/col_offset(vast 有),编译器符号注册可能按节点位置关联
- MakeKeyword:keyword 节点缺位置属性(4 个调用点:函数调用/类定义的 k=v 与 **kwargs)
- 修复后 includes/ + TransPyV/App 全部 201 个 .vp 文件 vast_c vs vast 的 dump 与位置属性完全一致(此前差异 6 文件 keyword + 2 文件 alias)
2026-08-18 07:07:21 +08:00
TermiNexus 6350b81307 feat(vast_c): extern/export 完整语义(注解改写+标记)并接入 vast.parse
- ParseExternDef:支持 4 种语法(extern/export [def] A(...) -> T [': pass']),返回注解改写为 <原类型> | t.State(extern)/ <原类型> | t.CExport(export),节点设 Extern=True/Export=True(对齐 vast Parser._ParseExternDef/_ParseExportDef)
- MakeTAttrNode:构造 t.Attr 注解节点(Attribute(Name('t'), attr))
- vast.parse 接入:默认走 vast_c C 加速路径(VAST_USE_C=0 禁用,=strict fail-fast 直接抛),异常回退纯 Python vast
- 差分测试 83/83 全绿(新增 7 个 extern/export 用例);includes/ 与 TransPyV/App 4 个真实 .vp 文件 C 路径与纯 Python 输出一致
2026-08-18 06:59:10 +08:00
TermiNexus d13b966604 fix(vast_c): 修复三处解析节点后未消费 token 的 bug(死循环/语法错误)
- ParseAtom 普通名字分支:MakeNameNode 前未 NextTok,'x = 1' 时 idx 恒 0 → ParseModule 死循环(True/False/None 分支有 NextTok,普通名字分支遗漏)
- ParseComparison TK_OP 分支:设置 OpName 后未 NextTok 消费 < > <= >= == != 比较符(is/in 分支有)→ 'a < b' 后比较符未消费导致 unexpected token
- ParseTarget NAME 分支:MakeNameNode 前未 NextTok → 'for i in' / 推导式 target 报 expected name

三处同款根因:构造节点后忘记推进 token 游标。
差分测试 76/76 全绿;基准 5.5x 加速(11.6ms -> 2.1ms/次,真实复杂源码)
2026-08-18 06:50:27 +08:00
TermiNexus 0d15e8cb7a feat(vast_c): C 版解析器阶段 0——赋值/名字/数字子集,直接构造 vast.nodes 树
- MSYS2 MinGW gcc 编译 CPython 3.12 C 扩展(_parser.pyd,-lpython312 必须置于源文件后)
- Tokenizer + 表达式/赋值/模块解析,节点通过 PyObject_Vectorcall 直接实例化 lib.vast.Nodes 类
- 输出与 vast.parse 结构完全一致(含位置属性),eval 模式复用 vast.parse 语义
- 可行性验证:200 语句文件 × 200 次基准 9.0x 加速(6.17ms -> 0.685ms/次),C 侧开销主要在节点构造,后续可继续优化
2026-08-18 05:45:11 +08:00
TermiNexus e3886a244d perf(compile): 批次加权分桶消除长尾 + 共享符号表去重复序列化 + typedef 收集走 AST 缓存
- Phase2 批次切分:原按文件数均分(batch_size=ceil(N/n)),大文件集中批次拖长尾、worker 空等;改为按源文件大小 LPT 贪心分桶,各批次总成本均匀(任务颗粒度不均匀)
- 共享符号表序列化:shared_data 同时含 symbol_table 对象与 symbol_table_bytes 双重序列化(_shared_sym.json 4.65MB 近半冗余);统一为仅传 symbol_table_bytes,worker/批次端从字节反序列化(includes 与 App 两阶段同步修改)
- Phase1 _collect_typedef_map / _process_file_pyi:直读+ast.parse 改为 parse_python_file mtime AST 缓存,Phase1 内重复收集与 Phase2 主进程解析共享同一缓存
2026-08-18 05:36:12 +08:00
TermiNexus 7917be0fa1 perf(handles): stub 索引增量重建 + vtable on-demand pyi 缓存类级化,消除 worker 重复解析
- HandlesImports._build_stub_index:以已扫描文件集合替代文件数签名,无新增文件时仅一次集合比较;新增文件只增量解析,消除每编译完一个文件即全量重扫(prof 847 次全量重建 61s)
- HandlesImports._TryLoadStructFromStub:索引命中直接返回,仅在 miss 时才触发增量扫描
- HandlesExprCall._try_register_vtable_ondemand:函数局部 pyi_cache 提升为类级 _vtable_pyi_cache / _vtable_methods_cache,437 次 open+ast.parse 同批 pyi 降为每 pyi 一次(prof 38.5s)
2026-08-18 05:27:53 +08:00
TermiNexus 043c65ee52 fix(vast): FunctionDef 槽位补 Extern/Export,修 __slots__ 回归 AttributeError
_ParseExternDef/_ParseExportDef 设置 node.Extern/node.Export(动态属性),
__slots__ 类无 __dict__ 导致 AttributeError: 'FunctionDef' object has no
attribute 'Extern'。FunctionDef/AsyncFunctionDef 的 attrs 补
Extern/Export(_FUNC_ATTRS),槽位随之包含;unparse 用 getattr 读取兼容。
extern/export 冒烟 + vast 差分 51/53 0 FAIL。
2026-08-18 05:12:09 +08:00
TermiNexus 68d180e718 perf(handles): 跨模块类声明分类/节点查找缓存,去重 _EmitExternalClassDeclLlvm
新增类级 _extern_class_classify_cache((sha1,class)->分类元组)与
_extern_class_decl_cache((sha1,class)->pyi ClassDef 节点):bases/
decorator 分类遍历提取为 _ClassifyExternalClass 纯函数并缓存,
_TryLoadClassMembersFromPyi 节点查找改走索引避免跨任务重复线性扫描
pyi_tree.body(8214 次调用热点之一)。Gen 依赖部分(字段/方法/struct
注册)保持每 Gen 执行,不做整体跳过。
2026-08-17 23:27:44 +08:00
TermiNexus b760082be8 perf(compile): pyi 树 pickle 落盘 + worker initializer 预热,消除进程间重复 parse
43 个 worker 任务分 ~16 个 spawn 进程,每进程重新 parse 全部依赖
.vpi(4479 次 vast.parse、245s)。主进程把 temp 下全部 .vpi 的 vast
AST 树 pickle 落盘 temp/_pyi_cache_v1.pkl(签名=(名,size,mtime),
变化才重建),两处 ProcessPoolExecutor 加 initializer 预热 ImportHandle
类级 _pyi_cache(优先 pickle.load,失败回退逐文件 parse)。
TPC_WORKER_WARMUP=0 可关闭对比。预计进程内首次解析尖峰降为一次 load。
2026-08-17 23:27:44 +08:00
TermiNexus 9605af8ea1 perf(vast): AST 节点类加 __slots__,去 __dict__ 提速降内存
AST 基类 __slots__=(),131 个动态节点类按 fields+attrs 生成 __slots__,
_Init 改 object.__setattr__;类默认值改为 _node_defaults 字典(原类属性
与 __slots__ 冲突)。解析提速 ~9%,实例内存 Name 由 48B+独立 dict 降为
80B 平铺,无 __dict__ 残留。Python 3.12 pickle 对 __slots__ 类开箱即用
(__reduce_ex__(2)),131 类 pickle roundtrip 全过,vast 差分 51/53 0 FAIL。
2026-08-17 23:27:43 +08:00
TermiNexus 50c0703afd feat(profiling): worker 进程导出 cProfile——TPC_WORKER_PROF 环境变量开关
主进程 cProfile 只能看到进程池等待(WaitForMultipleObjects/as_completed
约 280s),看不到 worker 进程内部 CPU 分布(vast parse 等真实热点)。
新增 _ProfileWorker 装饰器包裹 _parallel_translate_worker 与
_parallel_translate_batch:设置环境变量 TPC_WORKER_PROF 为输出目录时,
每个任务导出 worker_prof_{pid}_{seq}.prof(可用 pstats 合并分析);
未设置时零开销(原样返回函数)。
2026-08-17 22:42:14 +08:00
TermiNexus 3326c41702 perf(compile): 依赖扫描缓存键 abspath 归一化 + compute_sha1 缓存
parse_python_file/get_file_dependencies 缓存键改用 abspath 归一化:
同一文件以相对/绝对、正斜杠/反斜杠/含 .. 等形式传入会产生多条缓存
条目导致重复 open+read+ast.parse(439 次 get_file_dependencies 25.2s、
1496 次 parse 33.1s 的浪费来源)。compute_sha1 加有界结果缓存。
验证:同文件 4 种路径形式缓存合并为 1 条,find_reachable 二次调用
显著加速,相对导入解析结果不变。
2026-08-17 22:20:29 +08:00
TermiNexus 5692e9b097 perf(stubgen): pyi 转换加缓存——convert 纯函数缓存 + Phase1 mtime 缓存
Converter.convert 147 次调用 45s、_process_file_pyi 98 次 50s。convert
按 (内容, 模块名) 纯函数缓存并合并内部两次 ast.parse;Phase1 按
(绝对路径, 模块名)+mtime+size 缓存 pyi 转换结果与 docstrings,未变化
跳过 open+read+parse。缓存上限 4096 条防内存膨胀,配置变更时清空。
2026-08-17 22:20:28 +08:00
TermiNexus e25095da43 perf(vast): _At 内联 _Peek(0) 缓存逻辑 + Node 构造 __dict__ 直写
_At 被调用 1384 万次,每次经 _Peek 再取 token;内联 _Peek(0) 缓存
(_PeekCacheIdx/_PeekCacheTok)省 2300 万次函数调用,实测单文件解析
端到端提速 ~37%。_Init 的 setattr 改 __dict__ 直写(AST 节点无
__slots__/property,行为等价)。vast 差分测试 51/53 PASS 0 FAIL。
2026-08-17 22:20:28 +08:00
TermiNexus c2b04f5026 fix(compile): _LoadSha1Map 缓存补充只加载当前编译有效 sha1,修 9026a429f5e2d0e0.new_builder undefined symbol
.transpyc_cache 残留旧版 llvmlite/__builder.vp 的 9026a429f5e2d0e0.pyi/
.stub.ll(当前版本是 d9b3d06934cd1898)。_LoadSha1Map 从全局缓存补充
temp 缺失文件时不检查 sha1 有效性,把旧版 .vpi/.stub.ll 也加载进
sig_files/stub_files → 同名类 IRBuilder 按旧 sha1 前缀注册 →
new_builder 用 9026a429f5e2d0e0 前缀拼接,链接 undefined symbol。
补充逻辑移到 sha1_map 加载之后,仅补充 sha1_map 中存在的 sha1。
2026-08-17 21:51:21 +08:00
TermiNexus 401429ccdf fix(generic): 特化 T 替换判据修正——t 模块内建类型(裸名或 t. 前缀)仍用 type_name
上一提交对类类型参数改用 mangled type_arg 替换 T,但 type_name 为
't.CInt'(带 t. 前缀、不在 _BUILTIN_TYPE_NAMES 裸名集合)时被误判为
类类型,改用 type_arg='i32' 替换 → list[t.CInt] 特化方法体出现
'i32.__sizeof__'(源码无此名)→ [FATAL][__sizeof__] 类型 'i32' 无法
解析 + self 类型错乱(list[i32] 中找不到 CifEvalOk,StmtGenCifMixin
编译崩溃)。判据改为取裸名(去掉 t. 前缀)判断内建,内建仍用 type_name,
只有真正的类类型参数(AST/ast.AST 等)才用 mangled type_arg。
2026-08-17 21:44:40 +08:00
TermiNexus dd95bf5bd4 fix(handles): _try_operator_overLoad fallback 补回 SpecClass 初始化,修 UnboundLocalError 2026-08-17 21:25:25 +08:00
TermiNexus fa2cfef205 fix(generic): 特化 T 替换用 mangled 名 + operator fallback 选有 define 的特化
1. _specialize_generic_class 的 type_map 对类类型参数改用 mangled type_arg
   (如 f467978339422f32.ASTptr)替换 T,而非裸短名 type_name:模板内部嵌套
   注解(list[T].__iter__ 返回 list[T])不再被替换成裸 list[AST] 后重新特化出
   只有 declare、无方法体的错误特化 → 消除 ld.lld undefined symbol:
   7cadfe07e983fd90.list[AST].__len__/list[ClassDef].__len__。
2. _try_operator_overLoad 特化 fallback 改为优先选已编译方法体(define)的特化,
   全部只有 declare 时按需补发;dict 插入序不再导致 len() 选中错误特化。
2026-08-17 21:19:43 +08:00
TermiNexus bd0e541b74 fix(handles): 删除 [CD] lookup: 调试输出及无用 _is_cd_key 逻辑
删除 _HandleNameLlvm 中 4 处 [CD] lookup 调试打印(干扰编译日志)、
随之失效的 _is_cd_key 计算、以及仅用于打印的 SymbolTable.lookup 死代码。
2026-08-17 21:00:52 +08:00
TermiNexus 3b5f2af838 fix(structgen): 跨模块 struct 兜底命名改查 _struct_sha1_map,修复 7cadfe07e983fd90.Translator 前缀错位
泛型特化 _specialize_generic_class 把 Gen.module_sha1 切换到模板定义模块
(_list=7cadfe07e983fd90)的窗口内,_generate_structs Step 1 对不在
class_sha1_map 的类(因 LlvmGenerator 共享 class_methods 跨文件泄漏而
缺条目)用 _mangle_name 兜底,错误注册为 7cadfe07e983fd90.Translator 等
跨模块类型 → Translator.__before_init__ self 类型错前缀,与构造 result
(6ccfee1e5bd522ed.Translator*)不匹配,llvm 报 Type of #1 arg mismatch。
兜底改为优先查 _struct_sha1_map(Phase2 从 vpi 扫描构建的正确类→模块映射),
特化类自身仍走 _mangle_name(用模板 sha1 命名是设计意图)。
2026-08-17 20:55:47 +08:00
TermiNexus 7e710d1e9a perf(vast): _Peek(0) 增加游标缓存,命中率 87% 降低解析热点开销
TokenStream._Peek 是 cProfile 最大热点(1588 万次调用,累计 4.86s)。
递归下降解析常在同一游标位置重复窥视(_At/_AtOp/_AtName 等),
增加 _PeekCacheIdx/_PeekCacheTok 字段缓存最近一次 offset=0 结果,
命中时跳过 len() 与列表索引;游标移动后 Idx 失配自然失效。
实测大文件解析命中率 87.1%(6503 次调用仅 717 次真实访问),
vast 差分测试 51/53 通过、0 FAIL,正确性无回归。
2026-08-17 20:29:34 +08:00
TermiNexus ecdb5c34c5 Revert "refactor(compile): 完全去除多进程,翻译/编译全部改顺序阻塞执行"
This reverts commit 15e8bc7c7d.
2026-08-17 20:28:24 +08:00
TermiNexus 15e8bc7c7d refactor(compile): 完全去除多进程,翻译/编译全部改顺序阻塞执行
ProcessPoolExecutor 批次/波次子任务模型导致跨模块 struct 类型前缀错位
(7cadfe07e983fd90.Translator != 6ccfee1e5bd522ed.Translator,见 1.log),
且 cProfile 墙钟被进程池等待支配(223s 中 173s 耗在 WaitForMultipleObjects)。
删除 _parallel_translate_worker/_parallel_translate_batch、_executor_pool
及两处 llc ThreadPoolExecutor,App/includes 翻译按依赖拓扑顺序阻塞翻译,
llc 编译逐文件阻塞执行,消除 pickle 序列化共享符号表与进程池等待开销。
2026-08-17 20:22:45 +08:00
TermiNexus e5af28fa93 fix(imports): NoneType 异常静默 + struct_body 判空,减少 WARN 干扰输出
编译大量输出 "HandlesImports: 忽略异常 'NoneType' object has no attribute 'endswith'":注解/类型解析回退路径对 None 参与运算(数据缺失属正常兜底)——每文件每符号都打 WARN 淹没关键信息。

- 783/1166/1264 三处 except:AttributeError+NoneType 时静默不 WARN,其他异常保留
- 两处 is_packed 判断补 struct_body is not None 防护(源头防 None.startswith/endswith)
2026-08-17 20:07:35 +08:00
TermiNexus f66e119d1f perf(compile): App 翻译改批次子任务模型(多文件/任务 + 每文件重置 SymbolTable)
原"一文件一任务":200+ 文件每个都经 ProcessPool 调度 + worker 内创建 Phase2Translator + pickle.load 全部共享数据。改为批次模型:need_translate 按 worker 数分块,每 worker 一个批次子任务——Phase2Translator 创建 + pickle.load 仅一次,批内顺序翻译。

防污染:SymbolTable 是编译期唯一被写的共享对象,dump 时额外存 symbol_table_bytes(独立 pickle),批内每文件前 pickle.loads 出干净副本,前文件 import 写入不残留后文件(避免 7cadfe07e983fd90 类前缀错位)。includes 阶段保持拓扑单文件任务不变。
2026-08-17 20:01:33 +08:00
TermiNexus a28aacda0b fix(compile): 回退 worker 进程级复用,消除共享 SymbolTable 跨文件污染
复用后同一 worker 的 trans 处理多文件,_translate_file 编译过程会向共享 SymbolTable 写入符号(import insert/类注册),前文件符号污染后文件 → 跨模块 struct 类型前缀错位(7cadfe07e983fd90 即 _list 前缀混入 CompilerFactory/Translator/File,Type of #1 arg mismatch)。每任务从 pickle 反序列化独立副本(原实现)。

收益评估:worker 复用仅省 pickle.load ~0.5s/次 × 每 worker 12 次 ≈ 6s 并行墙钟,远小于 worker 内翻译计算(百秒级),不值得以正确性为代价。n_workers 满核优化保留。
2026-08-17 19:58:28 +08:00
TermiNexus 2dbf348329 perf(vast): 回滚 _PosInfo 增量行查找(Python while 慢于 C bisect)
新 cProfile(232s)显示 _PosInfo tottime 1.74s→2.84s:增量 while 顺延的 Python 循环开销大于 _bisect(C 级 O(log n)),且 _Make 先 start 后 end 两次调用跨行时退化。回滚为 bisect + 保留 isascii 快速路径(避免 encode 分配)。
2026-08-17 19:46:14 +08:00
TermiNexus 08e7b8d0c0 fix(handles): 带前缀类名提取 class_sha1,启用 stub 查找修复 Undefined method
ExprGenAttr 场景:ClassName 带 sha1 前缀(940e5294667daf5a.ExprGenAttr),struct_sha1_map.get(带前缀名)=None → class_sha1 为空 → _HandleMethodCallLlvm 的 stub 查找路径(if not func and class_sha1)被整体跳过 → fail-fast "Undefined method 'get_attribute_ptr'"(尽管 stub.ll 第 24 行存在该 declare)。

- 带前缀类名:class_sha1 直接取前 16 位,FullMethodName 不再拼接(避免双前缀)
- 裸类名:保持原逻辑从 _struct_sha1_map 取 sha1
2026-08-17 19:35:24 +08:00
TermiNexus 1f3c83cb6d fix(handles): MRO 查找归一化带 sha1 前缀类名,修复继承方法 Undefined method
TPC 编译 TPV 报 "Undefined method 'find_func_in_module' in class 'c9b44d17cd621a75.CallGenLib'":跨模块 ObjVal 类型反查 Gen.structs 得到带 sha1 前缀的类名,而 class_parents / ModuleSha1Map / _struct_sha1_map 键为裸类名 → _get_mro_chain 查不到父类 → MRO 回退失效 → fail-fast。

- BaseGen._get_mro_chain:查 class_parents 前剥离 "16位hex." 前缀(父类名带前缀时同样处理)
- HandlesExprCall._EnsureClassParentsLoaded:归一化后再查 class_parents / 按需加载父类信息
2026-08-17 19:11:48 +08:00
TermiNexus 3aebf402bb perf(compile): worker 进程级复用 Phase2Translator,消除每文件重复 pickle.load
cProfile 显示 ~163s 墙钟在 ProcessPool 等待(非计算)。App 阶段 200+ 文件分散到 worker,原实现每个任务都新建 Phase2Translator 并 pickle.load 2.5MB 共享符号表(_shared_sym.json)→ 每 worker 12+ 次重复反序列化。

- _parallel_translate_worker 增加进程级缓存:以 shared_sym_pickle_path 为 key,首次遇到才创建 trans + 加载 pickle,后续任务直接复用 trans._translate_file
- _translate_file 每次新建内部 TransPyC 且对 self 的写均为覆盖型(translator 引用/错误栈),复用安全
- App/includes 两阶段 pickle 路径不同,key 变化时每 worker 各自重建一次
2026-08-17 19:04:22 +08:00
TermiNexus 58ce673f01 perf(compile): TPC 编译提速——并行 worker 满核 + vast 解析器热点优化
cProfile 分析(206s 全量重编译 TPV):~163s 为 ProcessPool 等待(16 核机器仅用 8 worker),vast.parse 35.9s(1231 次)为最大 Python 计算热点。

- Phase2Translator:4 处 n_workers 上限 8 → os.cpu_count()(16 核满负荷),并行翻译/llc 编译利用率翻倍
- vast/Tokenizer._PosInfo:isascii 快速路径 + 行索引增量查找(~300 万次调用,免每次 bisect+encode)
- vast/Tokenizer._EmitOp:运算符按首字符分组,58 万次调用从 42 项全表 startswith 降到 2-3 项
- vast/Tokenizer._ScanName:内联 _IsIdentPart(70 万次循环免函数调用)
- Projectrans/Utils:find_reachable 用 deque + 后缀索引替代 pop(0)/全表扫描;topological_sort 用反向邻接表 + heapq 替代每轮 sort+全图扫描
2026-08-17 18:56:55 +08:00
TermiNexus 5d93692baa feat(vast/ast): 新增 export 软关键字声明 CExport 函数(等价 t.CExport)
允许 4 种语法(配不配 def 都一样):export def A(...) / export A(...),
与 extern 对称。返回注解改写为 <原类型> | t.CExport,复用既有 CExport
路径(符号名裸名、不加模块 SHA1 头);无 body 形式消费本行 NewLine。
TPC 侧 vast:_ParseExportDef + Unparser 还原(Export=True);
TPV 侧 includes/ast:Keyword.Export + FLAG_IS_EXPORT=16(追加末尾)+
_is_funcdef_kw/_parse_funcdef 支持。
2026-08-17 12:12:32 +08:00
TermiNexus ce568e10b7 feat(vast/ast): 新增 extern 软关键字声明 FFI 函数(等价 t.State)
TPC 侧 vast:
- extern [def] A(...) [-> T] [: pass] 四种语法解析为 FunctionDef
- 返回注解改写为 <原类型> | t.State,复用 TPC 的 IsState 外部函数路径
- 设 Extern 标记,Unparser 还原 extern 语法(round-trip 一致)

TPV 侧 includes/ast(自举前端):
- Keyword.Extern 枚举与 intern,_is_funcdef_kw 软判定
  (extern def / extern Name+'( 或 '[')
- _parse_funcdef 支持无冒号声明、FLAG_IS_EXTERN 标记、
  returns 改写为 <原类型> | t.State(vpi 含 State → 定义端裸名 + 不生成函数体)
2026-08-17 10:41:44 +08:00
TermiNexus aa9042173e fix(vast): 修复 match 类模式与 or 模式解析与 CPython 不一致
- case ClassName.attr(...) 类模式:扫描属性链末尾判断 '(',
  此前只查首 token 后 '(',LLVMType.Ptr(...) 被误解析为
  MatchValue(Call) → TPC 对 renum match 走值模式分支,对枚举
  构造表达式运行时求值生成 ptrtoint SSA,LLVM switch 报
  'case value is not a constant integer'
- case 0 | 1 值模式:字面量/符号不再消费顶层 '|',留给
  _ParsePattern 组 MatchOr(此前 ParseExpr 吞掉 '|' 成 BinOp)
2026-08-17 10:22:29 +08:00
TermiNexus d7213d2197 fix(vast): 修复 Tokenizer 行号登记与 import/f-string 位置属性与 CPython 不一致
- _ScanStringBody 三引号内引号对 Pos+=1 后未 continue,双重自增
  跳过一个字符,若恰为换行则漏登 _LineStarts 行首,导致其后所有
  行号偏移 -1、字面量 col_offset 超行尾,TPC 引号判断失败将
  单引号单字符误推断为 i8*(1.LOG 编译错误根因)
- alias 节点位置改为名称起始(asname 结束),与 CPython 一致
- f-string 内部表达式绝对偏移补上 FSTRING token 源码起始
2026-08-17 10:08:43 +08:00
TermiNexus 920c0ba677 fix(vast): 修复分号分隔语句误将 AST 节点传给 _FixLoc 导致 AttributeError
ParseModule/_ParseSuite 的分号分隔分支曾用 stmt 节点调用 _FixLoc,
应传入 Token。改为不补位置(extra 由内部解析器自设位置),
修复 'Assign' object has no attribute 'Line' 崩溃。
2026-08-17 09:38:00 +08:00
TermiNexus 6fc9e19e24 feat(vast): 新增自研 Viper/Python 语法解析器取代标准库 ast
TPC 侧取缔对 Python 标准库 ast 模块的依赖,改用 lib/vast 包:
- Nodes: 与 CPython 3.12 ast 完全同构的 131 个节点类(含抽象基类继承)
- Tokenizer: 词法分析(缩进/字符串/f-string/数字/运算符/软关键字)
- ExprParser: 表达式递归下降解析(优先级/lambda/推导式/f-string/切片)
- Parser: 语句解析(def/class/if/for/try/with/match/import/注解)
- Utils/Unparser: walk/dump/unparse/copy_location/literal_eval 等辅助
- 软关键字 fn/fun/func/function 并入解析器, 废除 ExpandSoftKeywords 预处理
- lib/_bootstrap 将 lib 目录加入 sys.path, import vast as ast 零修改替换
- 52 个文件 import ast 替换为 import vast as ast; 94 文件差分测试 0 失败
2026-08-17 09:36:38 +08:00
TermiNexus 9b190ac73e fix(TPC): --asan 假生效修复 —— opt -passes=asan 需先 forceattrs 加 sanitize_address 属性(LLVM>=20 只插桩带属性函数) 2026-08-15 13:25:12 +08:00
TermiNexus 5844e6e725 fix(TPC): range for 循环 body 以 break 终结时不再发射死代码 load(游离指令致 opt expected instruction opcode)
根因: HandlesFor.py L229-233 在 body 使 _reg_values[循环变量] 失效后,
于当前 builder 位置重新 load 循环变量(该值实际未被使用, 死代码)。
当 body 最后一条语句是 break 时当前块已带 terminator, load 落在
br for.end 之后 → 非法 IR → opt/llc 报 'expected instruction opcode'。
触发场景: 装饰器扫描循环 body 内 list[ASTptr].get 调用触发泛型特化
重入编译(_EmitFunctionLlvm L1647 整体清空 _reg_values 且不恢复)。
修复: else 分支加 is_terminated 守卫, 终结时跳过死 load(语义不变)。
2026-08-15 07:36:40 +08:00
TermiNexus fd3254cdd4 fix(TPC): 模块名与类名同名时 X.func() 按模块函数解析
import lib.core.X as X 且模块内有同名 class X 时,X.func() 此前被
is_class_name 判定拦截走 _HandleStaticMethodCallLlvm,用模块函数签名
生成带类前缀的 {sha1}.X.func 声明,而 define 是 {sha1}.func,导致
链接 undefined symbol(CompilerFactory.get_perm_pool)。现加模块别名
优先规则:SymbolTable 命中 IsModuleAlias 时跳过类静态方法路径,让位
模块函数调用;类构造 X.X(args) 仍走 struct 路径。同时移除
_HandleExternalCallLlvm 中误加的 else: return None 截断。

includes/llvmlite/__types.vp:DeepCopyType 各层分配源改由调用方传入
pool 参数(传 perm_pool 即持久),includes 层不依赖 App 工厂。
2026-08-14 04:02:22 +08:00
TermiNexus 2f0b741d55 fix(gen): TPC 治本——struct opaque 具化、多返回值 fail-fast、with MRO 修复
1. HandlesExprCall: vtable 分派前 _EnsureReceiverStructConcrete 主动具化 struct
   body(stub + class_members 双路径),消除元数据已注册、本体仍 opaque 的
   撕裂状态,失败即 fail-fast 暴露上游 stub 加载时序问题;
2. HandlesImports: stub 加载后仍 opaque 时不保留成功缓存(可重试),
   避免 opaque 状态被固化导致 vtable 分派 GEP 崩溃;
3. HandlesAssign: 跨模块多返回值 CReturnTypes 恢复(LiteralStructType 回退)
   + 解析失败 fail-fast,不再静默跳过致目标变量未初始化触发堆损坏;
4. HandlesWith: MRO 继承方法解析跳过无函数体的 stub declare(Phase1 继承
   包装声明),bitcast 目标改用函数签名参数类型避免 opaque 占位对象。
2026-08-13 07:51:27 +08:00
TermiNexus a99f126cfa feat(parser): 支持 Viper 软关键字 fn/fun/func/function 展开为 def
行首缩进+软关键字+空白+标识符形态的函数定义(fn foo(): / function bar())
展开为 def,行号不变,供 ast.parse 使用;变量名/调用/注解中的 fn 不受影响。
Converter 同步改为 stub 语法错误直接终止(fail-fast),不再生成残缺 vpi
被全局缓存命中后以 undefined symbol 形式爆发。
2026-08-13 07:51:21 +08:00
TermiNexus 6a672037c2 fix(attr): 修复联合类型转换 (X | t.CPtr)(arg) 后属性访问被丢弃
TPC 联合转换对非 CType 类(ast.Name/ast.Call 等类名)目标类型解析失败,
结果退回 Ptr(i8) 或错误类型,_handle_attr_call_result 的
find_struct_by_pointee 失败后返回 None,属性访问被静默丢弃——
((ast.Name|t.CPtr)(ov)).id 编译产物 store 0 次(TPV with 语句 asname
未绑定、pool 未定义根因)。修复:从联合 BinOp 提取真实基础类并
bitcast 到 Ptr(类) 再定位成员偏移;新增 _extract_union_base_class
辅助(跳过 CPtr/存储类/限定符修饰符)。
2026-08-13 07:44:43 +08:00
TermiNexus 8ccf5d2c18 fix(TPC/includes): 泛型特化 linkonce_odr + None 全局 common + includes 前缀
- TPC HandlesFunctions/HandlesClassDef: 泛型特化类方法(类名含 '[')设
  linkonce_odr,消除 GSList[NameEntry].__before_init__ 等 duplicate symbol
- TPC HandlesAssign: None 初值模块级全局用 common linkage,合并 _g_gen 等
  跨模块同名全局重复定义
- includes: binascii/hashlib 裸调用加 stdlib./string. 前缀(malloc/free/memset/memcpy)
- llvmlite: FunctionPrint 泛型特化方法输出 define linkonce_odr;__module 调整
- 删除 wiki/01-overview.md
2026-08-12 18:18:22 +08:00