Commit Graph
429 Commits
Author SHA1 Message Date
TermiNexus 05d5bfbf37 fix(tpv): 修 CreateProcessA 重定向未启动外部命令,并把捕获输出移到 error 之前
主因:_run_cmd_wait 置 STARTF_USESTDHANDLES 时只设了 hStdOutput/hStdError,hStdInput 仍是 memset 后的 NULL(0);Windows 要求三个句柄都有效且可继承,故 CreateProcessA 直接返回 0(表现为 exit=4294967295 即 -1,且 .llc.log 恒空、一次也没有 llc 输出)。日志文件改以 GENERIC_WRITE|GENERIC_READ 打开并令 hStdInput 同指该文件(llc 不读 stdin),三态句柄均不泄漏;无重定向时不置 USESTDHANDLES、退回继承控制台的行为不变。

另在 CreateProcessA 失败处立即取 w32.win32base.GetLastError 并以 VLogger.warning 打印错误码+命令+重定向文件路径(warning 而非 error:error 会 sys.exit,而此处运行在 llc worker 线程内)。

同时修正一处使功能完全失效的顺序问题:_log_captured_output 原先排在 VLogger.error 之后,而 error 内部 sys.exit(1),故捕获到的 llc stderr|stdout 永远不会打印(这正是只看到一行 llc 编译失败、.llc.log 留空的原因)。串行 compile_ll_to_obj 与并行 run_llc_parallel 两处均改为先打印捕获输出、再报错。
2026-09-14 22:14:45 +08:00
TermiNexus 82f16127c0 fix(tpv): llc 日志文件句柄初始化改用 NULL,避免整数常量赋给指针类型
_run_cmd_wait 里 log_fh 原以 w32.win32base.INVALID_HANDLE_VALUE 初始化,而该常量是 CDefine = -1(整数),赋给 HANDLE 指针类型触发"整数隐式转指针已禁止"的 fail-fast(BuildPipeline.vp 原 595 行)。

改为以 None(NULL) 初始化;仓库既有惯例是只把 INVALID_HANDLE_VALUE 用于比较(全仓 20 余处同写法),故其余比较判断不变。因 NULL 与 INVALID 都不应参与关闭,父侧 CloseHandle 增加 None 守卫,避免对 NULL 调 CloseHandle。
2026-09-14 21:19:20 +08:00
TermiNexus 785741026f fix(tpv): llc 失败日志附带 stderr|stdout、退出码与完整命令
此前 llc 失败只打 模块sha1 与命令行:llc 的 stdout/stderr 因继承控制台而外显,程序拿不到文本,导致无法定位 verifier 报错。

_run_cmd_wait 新增可选 log_path:非空时用可继承安全属性把子进程 stdout|stderr 重定向到临时文件(不用管道:写文件不会因缓冲满阻塞、天然无死锁;且 worker 线程禁用池分配,故不复用 includes/subprocess.vp),CreateProcessA 成功后立即关闭文件句柄;log_path 为空时行为与原先逐字节一致。

LlcTask 末尾追加 LogPath/ExitCode(构造点均按 __sizeof__ 与整体 memset 处理,既有字段偏移不变);worker 记录退出码;run_llc_parallel 与串行 compile_ll_to_obj 在失败时打印 模块sha1、退出码、完整命令 与捕获输出(上限 8KB,带截断标记;输出为空/打开失败/无文件 三态如实打印,不伪造),成功时删除捕获文件、零额外输出。

包装层(compile_module_to_obj 摘要、run_pipeline 的 ErrorMsg、Phase2 PhaseB/PhaseB+ 聚合终止语)本身拿不到输出,保持不动,详情由深层打印。
2026-09-14 20:21:57 +08:00
TermiNexus 51daf28297 fix(expr): 三元表达式 else 分支按 then 的指针类型下传目标类型
VpiReader.vp:1963 的 rel_path_rt if rel_path_rt is not None else 单字符问号 触发 CastError(探针 kind=35 IfExp、val.Ty=i32、target_ty=i8*)。根因并非跨模块函数返回类型未解析:then 分支 rel_path_rt 已是 i8*(解析成功,赋值处与已有 fail-fast 均未触发,三条独立证据);真正的整数来自 else 分支——单引号单字符字面量在词法层被判定为 CONST_CHAR,而 translate_ifexp 翻译 else 时未下传目标类型上下文,遂物化为 i32(63),随后在类型对齐阶段被按 then 的指针类型 coerce,撞上整数隐式转指针的 fail-fast。

改为:仅当 then 分支是指针时,把其类型作为 else 的 target_ty 下传;单字符字面量随即走 ExprGenConst 的指针目标分支物化为 1 字符字符串(对齐 TPC 的引号推断),两分支同为 i8*,不再进入 coerce。非指针 then 不下传,既有常量物化与位宽行为逐字节不变(如 base64.vp 中 then 为 char 的两处不受影响)。

另经核查:模块级函数返回类型并无静默默认 i32 的问题——「依赖已就绪却解析不到」已是 fail-fast(CallGenMixin 跨模块函数路径与方法侧 _fail_method_ret_ty 同构),保留 i32 的仅是多遍收敛中间态的占位,故本次不动。
2026-09-14 19:26:46 +08:00
TermiNexus 7fabf886fc fix(vpi): 返回注解索引重建的键长常量拼写修正为 VPI_KEY_LEN
_vpi_rebuild_ret_idx 里把键长写成了不存在的 VPI_RET_KEY_LEN(参数侧另有 VPI_PARAM_KEY_LEN=224,本文件仅定义 VPI_KEY_LEN=224 与 VPI_PARAM_KEY_LEN)。此前该未定义标识符被旧规则按类型零值兜底编成 0,使重放偏移 ri*0 恒为 0(每条键都从第 0 条键位置读取),返回注解索引重建结果错误;因探测用 live 键比较,表现为未命中回退线性扫描——结果仍正确但索引形同无效。

这解释了此前实测中 _lookup_vpi_ret_annot 加索引后仍有约 913K 次 strcmp(返回侧索引一直未生效),而参数侧索引生效并从榜单消失。改为本文件既有且返回侧一致使用的 VPI_KEY_LEN(malloc/memset/查找/写入各处均用该常量)。
2026-09-14 16:54:36 +08:00
TermiNexus a46391bf42 fix(expr): coerce_to_type 拓宽方向判定改传 builder.Pool,修正未定义实参 pool
coerce_to_type 作用域内并无 pool(其参数是 builder),L425 却把 pool 作为第 1 个实参传给 _zext_or_sext_val。此前该实参翻译失败会被静默按类型零值兜底,使传给 ExprGenOps.should_zext_widen 的池为空、变量注解符号性判定失效,从而在无符号拓宽时错走 sext(即该处注释所述的无符号扩展缺陷根因)。

改为传 builder.Pool(与同函数内 llvmlite.const_int64(builder.Pool, 0) 等一致,是共同值所处的池)。该未定义实参由本会话新增的「实参翻译失败即 fail-fast」规则暴露。
2026-09-14 15:48:09 +08:00
TermiNexus b918321f77 perf(callgen): text.ll 存在性改属性查询 + 返回类型按模块一次性缓存
第 1 项:_dep_text_ll_exists 原以 fileio.File(MODE.R) 只读打开探测存在性(33,244 次调用,占总 create_file_utf8 46.6%,每次约 57us 的开句柄成本)。改用 GetFileAttributesA 并显式排除目录(对齐 IncludesScanner._PathExistsA 先例),无输出缓冲、零句柄。

第 2 项:_LookupMethodRetTyFromTextLL(29,974 次、约 380,505 tick/次、self 11.41e9 即 8.9%)原每次重开加重读加逐字节重扫整份 text.ll(实测约 2.47 tick/字节,均值 154KB)。新增 PermPool 缓存表(mangled 名 到 返回类型文本):某模块 text.ll 首次成功读入时登记其全部 define 行,同模块后续查询 O(1);命中后用调用方 pool 经 _ParseLLVMRetTyStr 重建类型,与原路径等价。

关键安全点:只存返回类型文本、绝不存会随每文件 reset_to 失效的 LLVMType*;同名只记首次(保持首个匹配优先);仅成功读到文件后才回写,未找到或文件暂不存在绝不缓存(Phase A 顺序生成依赖,负缓存会出错);缓存或分配失败一律回退原扫描。原扫描逻辑一字未改,保留为未命中路径。
2026-09-14 15:26:10 +08:00
TermiNexus ce612c8e57 perf(lookup): 恢复名字索引可信未命中即确无的短路(Ty 索引保持停用)
4ed7f39 因 Ty 索引不等价,把名字索引的未命中短路一并回退了,导致 find_struct(8.25M)/lookup_ctypedef(5.64M) 等又回到全表扫描。

经逐处自证不变量后仅恢复名字键索引:名字或键只在注册时写入一次(中和仅置空名,空名查询显式回退扫描);索引在所有写入路径同步维护,判据 Built==Count 失败即失效回退;探测用 live 键且同键条目沿链按注册顺序排列(无空槽夹层)⇒ 可信未命中即原线性扫描亦无所获,短路逐字节等价。

恢复点:StructGenMixin.find_struct、TypeGenCType.lookup_ctypedef、CallGenLeafKit.find_func_in_table/find_func_entry_global、TypeGenCDef.lookup_cdefine_{constant,double,string}、VpiReader._lookup_vpi_param_annots/_lookup_vpi_ret_annot(后者保留泛型特化归一化兜底)。

find_struct_by_type 的 Ty 索引判定保持停用(事故根因);首字符预筛、Function.NameLen/FUNC_SIZE、includes 均未改动。
2026-09-14 12:59:27 +08:00
TermiNexus 4ed7f3909a fix(lookup): 索引未命中一律回退原线性扫描,停用不可信的 Ty 索引判定
降低「索引可信且未命中即判定确无」语义带来的风险面(该语义是本轮构建 fail-fast 的最高嫌疑):索引只用于加速命中,未命中一律回退原线性扫描,使各查找函数在所有输入上的返回值与优化前逐字节一致。

StructGenMixin.find_struct:去掉「索引可信且查询名非空则跳过 O(n) 扫描」分支,未命中恢复原精确匹配全表扫描。

StructGenMixin.find_struct_by_type:整体停用 Ty 索引判定 —— 条目 Ty 会被深拷贝改写,槽按注册时 Ty 落位,改写后与 live 键脱钩,命中不保证是原线性首命中(不等价),故恢复原线性精确扫描;get_class_name_by_type(REnum.kind 识别路径)、register_struct 去重、lookup_field 首遍随之回到优化前语义。

CallGenLeafKit.find_func_in_table/find_func_entry_global、TypeGenCType.lookup_ctypedef、TypeGenCDef.lookup_cdefine_{constant,double,string}、VpiReader._lookup_vpi_param_annots/_lookup_vpi_ret_annot:可信未命中不再直接返回,一律落入原线性扫描。

未触碰:Function.NameLen/FUNC_SIZE、各处首字符预筛、includes/string.vp。
2026-09-14 12:41:27 +08:00
TermiNexus e7f47735ed perf(callgen): find_func_in_module 以 function_get_name_len 替代 strlen 热点
第二趟后缀匹配对每个函数节点调用 strlen(cur_name)(实测 2373 万次、占全程序 strlen 73.7%)改为读取 Function.NameLen;两处替换点:CallGenBase 约 563 与 597。

并在外部函数返回类型白名单登记 function_get_name_len 返回 i64(CSizeT),避免 stub 未注入时按默认 i32 导致签名不一致。匹配语义与返回顺序不变。
2026-09-14 08:26:18 +08:00
TermiNexus cb430bf00a perf(gen): 结构体/CTypedef 查名加索引,热点线性查名补首字符预筛
StructGenMixin.find_struct:索引可信且查询名非空时,未命中即判定确无同名条目,跳过 O(n) 精确扫描(此前索引只短路命中、未命中仍全表扫描,实测 527 万次逐条 strcmp 即源于此)。

TypeGenCType:新增 CTypedef 名索引(开放寻址、槽存 index+1、Built==len 才可信、不可信或未命中回退线性扫描、clear_ctypedefs 同步复位),消除 lookup_ctypedef 约 445 万次 strcmp。

补首字符预筛:StubMergerIR._FindSha1ByModName、CallGenBase._ensure_method_declare、VarGenMixin.find_var、CallGenLeafKit.find_func_entry_in_table(_owned)(首字符不等即判不等,匹配结果与顺序不变)。
2026-09-14 04:15:36 +08:00
TermiNexus e8db102b9e perf(gen): 结构体按模块查找与 ctypedef 跨度查找加首字节预筛
StructGenMixin.find_struct_by_module 的名与 ModuleSha1 两次 strcmp、TypeGenCType.lookup_ctypedef_span 的逐项名比较,均加首字符/首字节必要条件短路(首字节不等即判不等),并省去原逐项 strlen。匹配结果与返回顺序逐字节不变。
2026-09-14 00:09:06 +08:00
TermiNexus 16472a61d9 perf(lookup): 热点线性查找表加开放寻址名索引,O(n) 降为期望 O(1)
VpiReader 参数/返回注解键表(查表 + 写去重共用)、CallGenLeafKit 全局函数表、TypeGenCDef CDefine 表:由线性扫描改为开放寻址索引,对应热点约 117M + 17.8M + 10.5M 次 strcmp。

索引槽只存下标+1(不存键/节点指针),键表 realloc/移动后槽下标仍有效,无悬空指针;可信判据 Built==count,每次注册同步维护,不可信或未命中一律回退原线性扫描(正确性保证)。每次注册占一槽以保持首注册优先(探测链首个键相等者即原首个命中)。CallGenLeafKit 快速路径仅限 owner_sha1 为 None 的全局表查询,保持 owner 优先语义不变。
2026-09-14 00:05:12 +08:00
TermiNexus a9819e4123 fix(gen): 方法分派与 list 内建判定改用接收者实际特化名,根治 list[int].get 截断
_translate_method_call 原以注解来源 class_name 构造被调名;同一函数作用域内同名变量被声明/赋值两次时该名退化(get_class_name_by_type 的类型后缀匹配会把 list[sha.AST] 误判为元素类 AST),使 list[ast.ASTptr].get 被误绑为 list[int].get(返回 i32)后 inttoptr 截断指针,读垃圾 AST 节点崩溃(MatchGenMixin._handle_renum_match / _handle_simple_match)。

现统一以接收者实际 LLVM 结构体类型名(IR 真值)为准:基名为泛型模板时,含类型实参则以实际特化名覆盖;退化为裸泛型基类则 fail-fast(D25 口径,禁止静默默认 list[int])。

抽出 CallGenProp._strip_module_sha1_prefix / _resolve_generic_receiver_name / _is_list_builtin_receiver 共用实现;CallGenDispatch 8 处 list 内建判据同步改为基于接收者实际类型(真实 list 命中与 __elem_size__/hit_box 行为不变,实际类型不可得时保留注解名回退)。lookup_name 缓冲改为按精确长度分配。
2026-09-13 21:11:33 +08:00
TermiNexus 76df3f0225 perf(gen): 结构体/类型查找去线性化并守卫全量遍历残量
StructGenMixin: 加「名 | Ty 指针值 -> 首注册下标」索引,find_struct/find_struct_by_module/find_struct_by_type 走 O(1) 快速路径;每次注册占槽保序,中和/改名后键不等自然跳过,未命中或索引不可信回退原扫描。并补 _struct_name_hash/_struct_ty_hash(32 位 FNV,常量均小于 2^63 以避开大十进制字面量解析风险)。

TypeSpec.InternSpec: 加「文本键 -> 驻留下标」开放寻址索引,去重由 O(n) 降为期望 O(1);命中返回原同一实例,注册顺序/容量 fail-fast 语义不变。

register_struct/lookup_field/get_class_name_by_type 的按 Ty 指针首匹配改走 find_struct_by_type;CallGenLeafKit/CallGenCall 的按序号全量遍历补守卫注释(避免后续误改为按名查找)。
2026-09-13 18:56:16 +08:00
TermiNexus 0dd7511a9b fix(tpv): 修常量折成0致alloc(0)与多处fail-fast,并落地热点优化
TypeGenCDef: CDefine 表名深拷贝(vpi 注入名为零拷贝指针且 vpi_buf 提前释放,悬空名致常量查出错误值 0)

VpiReader: 模块级 SHA1_LEN(16) 改名 SHA1_HEX_LEN,消除与 Phase1.SHA1_LEN(17) 的跨模块同名冲突

CallGenCall: 实参翻译失败/漏传必需实参改 fail-fast,禁用零值兜底(堵住 SHA1_LEN 未解析变 alloc 0 的通路)

MatchGenMixin: 序列 match 的 case _ 分支补容量守卫(原先会越界写穿 pool 块、破坏空闲链)

Phase1Main/Phase1Scan: 预扫描缓冲分配失败改 fail-fast;加临时取证打点

CallGenBase: find_func_in_module 4 趟链表扫描合并为 2 趟

ImportsGenMixin: import 查找加哈希索引(键为 NUL 结尾副本,未命中回退原扫描)

TypeGenBase/TypeGenResolve: 库 typedef 按模块一次性门禁与缓存

VpiReader: vpi 注解解析补 rowptr[T] 分支
2026-09-13 17:50:03 +08:00
TermiNexus af2c66e7d7 chore(tpv): 永久池扩容至 1 GiB
PERM_POOL_SIZE 由 512MB (536871176) 调整为 1 GiB (1073741824),为 REnum 注册表挂到 PermPool 后留足余量。
2026-09-12 23:14:52 +08:00
TermiNexus eef84657a1 fix(tpv): 修正 REnum 表按名查找与 match 分派,恢复 str() 指针强转
str() 对整数(sizet/i64)走 snprintf 十进制格式化(Python 语义),不是 i8* 强转;用它读 sizet|t.CPtr 联合表元素再 strcmp 永不相等 => _is_renum_class_name 恒 0、变体名查不到(__types.vp:407 bits / :159 Void 根因)。IR 实证 output/a8891afb66d3eda4.text.ll L5551-5558。

- ClassGenEnum: RenumClassNames/RenumVariantNames 读侧统一改 (str)(t.CVoid(x, t.CPtr));新增 _is_renum_by_entry 与 RenumTableDump;REnum 注册静默早退改 fail-fast

- MatchGenMixin/CallGenMixin: match 分派 2a/2b 与变体构造入口并上 by_entry 判据

- TypeGenResolve: 泛型下标 Phase B 解析不出特化时 fail-fast

- CallGenProp: 泛型特化名末段按括号外点切分

- CompilerFactory/ClassGenBase: REnum 注册表改挂编译期单例

- ClassGenDef: CEnum/REnum 分派歧义 fail-fast
2026-09-12 23:14:23 +08:00
TermiNexus e0e024ee93 fix(tpv): 注解裸名按 from-import 归属查找(D26 闭环)
stub 注入注解时 trans.ModuleSha1 是正在翻译的文件,而注解里的类归属 stub 源模块;仅靠当前模块 sha1 加全局可见性在 App 严格模式下查不到(AsyncGenMixin 未 import ast.Expression),导致 ast/__init__.vpi 的 parse_expression -> rowptr[Expression] 返回类型解析失败 fail-fast。TypeGenResolve 的 Name 分支在 own 之后、可见性之前插入 from_imports 归属查找(LookupModNameByAlias 到 LookupSha1ByModName 到 find_struct_by_module)。TPV 自举 Phase1 从 28/53 推进到 40/53
2026-09-12 19:37:55 +08:00
TermiNexus ea2abba574 refactor(tpv): 删除 _deps_pending 置位面与 Phase A pending 多遍收敛机制
69 个工程成功编译且 _phaseA_pending.log 恒 0 字节,证实 14 个置位点全部零命中。删除 14 个 _MarkDepsPending 调用点(原「依赖未就绪」分支保留默认类型或原报错路径);删除 _MarkDepsPending 与 _AppendPhaseAPending 及 _phaseA_pending.log 读写;删除 Phase A 出口「pending 则不写盘、回滚 MethodsEmitted、continue」整段;删除 _deps_pending 与 _pf_dbg_pend_flagged 字段及全部读取分支;清理遗留探针 [PF-DBG] 与 [METHDBG]。16 files changed, +37 / -558
2026-09-12 19:24:52 +08:00
TermiNexus 17f109e204 fix(tpv): 修复 vpi 重导出包前缀与 D25 变量名悬垂,补齐 fatal_error 刷盘
VpiReader 包 __init__ 重导出补包前缀,类注册与方法声明两遍化,按需注入依赖 vpi(先登记后注入防环,失败撤销登记);VarGenMixin 的 add_var 深拷贝变量名,符号表条目不再依赖 AST tree 生命周期;CallGenCall 的 list 内建与泛型基类判定类名来源回退到接收者实际 struct 名;TypeGenErr 的 fatal_error 退出前 fflush;StubMergerBuild 每模块重置 vpi 注入去重表
2026-09-12 19:00:19 +08:00
TermiNexus 626f79cbd1 fix(tpv): vpi 相对导入补回包前缀(D26)
- vpi 只存 module=base(前导点记在 level),from-import 映射写字面 base 时,解析端按精确 LookupSha1ByModName 查不到 ast.base ⇒ 裸类名(AST 等)解析失败 ⇒ rowptr[AST] 等注解 fail-fast(TPV→TPV 自举 includes/ast/parser.vp parse 根因)

- 按 stub 自身相对路径还原包名(ast/parser.vp → ast),level==1 拼成 ast.base 再登记;_stub_add_imported 与 _stub_add_from 两处同步
2026-09-12 15:59:37 +08:00
TermiNexus 3c45895878 fix(tpv): alloca 退化守卫收窄到「裸泛型模板基类」形态(避免误杀同名重声明换类型)
- parser.vp:964 'node: rowptr[AST] = Slice(...)' 命中上一版守卫(旧 alloca 是 Tuple*)——但 Tuple* vs AST* 是同名重声明换具体类,两者都是 8 字节指针槽,属合法用法,不该 fatal

- 收窄判据:仅当旧 alloca 的 pointee 是**裸泛型模板基类**(剥 sha1 前缀后不含 '[' 且 _find_generic_template 命中)时才 fail-fast —— 这正是 D25 的退化形态(丢类型实参 → 方法调用按错误元素类型特化 → 截断)
2026-09-12 15:24:23 +08:00
TermiNexus 590a6a2bbe fix(tpv): 复用的 alloca 与注解类型不一致时 fail-fast(D25 alloca 退化根治)
- get_or_create_sym 只用「名字+作用域」复用(ty 不参与判定),可能命中类型不同的旧 alloca(同名重声明 / 退化 alloca,如裸 list* 对上 list[ast.ASTptr]*)→ alloca 类型与使用点注解类型分裂 → 方法调用按错误元素类型特化 → inttoptr 截断

- 只比较「双方都是指针且 pointee 都是结构体」这一最典型退化形态:结构体名不同即 fatal_error,报出变量名与两个类型,直接暴露退化点(不兜底)
2026-09-12 15:13:41 +08:00
TermiNexus b206e7d9c1 fix(tpv): 泛型类型实参禁止静默默认 int(D25 fail-fast 两处)
- CallGenMixin: 裸名泛型构造推断不出类型实参时不再默认 int,改 fatal(与 _infer_generic_ctor_type_arg 注释「绝不默认 int」对齐)

- CallGenCall._translate_method_call: 泛型模板基类(剥 sha1 前缀后不含 '[')上的非 list 内建方法调用改 fatal —— 此前静默按默认 list[int] 特化,元素按 i32 处理 → 方法返回 i32 → inttoptr 截断指针 → 读垃圾 AST 节点(D21/D25 崩溃族)

- list 内建方法仍走内联路径(运行时 __elem_size__),不受影响
2026-09-12 14:52:23 +08:00
TermiNexus ced50bd78b fix(tpv): 注解 mangled 名算键统一——补回丢失的 from_imports(D25 根因第 1 步)
- extract_class_name_from_annotation 的 Subscript 分支递归取 base 时漏传 from_imports(同函数其余调用点都传了),导致同一注解在「派发名 / 查表键 / 注册键」三处算出不同 mangled 名

- 症状:MatchGenMixin._handle_renum_match 两遍对同一裸 list* alloca 分别按 list[ast.ASTptr] 与 list[ast.ClassDefptr] 解释 → .get 误分派 → 节点指针被截断 → StmtGenMixin._translate_stmt_impl ASan 崩溃(D21 复发,见 Debugger/_Type.md D25)
2026-09-12 14:32:57 +08:00
TermiNexus 967095df5b refactor(tpv): _deps_pending 置位收敛到唯一入口 _MarkDepsPending(S4 第一步)
- CallGenBase 新增 _MarkDepsPending(trans,kind,cls,method,dep,extra):一处实现「置标志 + 统一格式 [DEPDBG] + 持久化 _phaseA_pending.log」三连

- 14 处置位点(D7-1 清单:attr_read/attr_write/method_ret/mro_ret/mro_anc/special_ret/prop_ret/dispatch_ret/dispatch_sp/func_ret/func_mangled/global_stub/class_parent/class_field_ty)全部改经该入口

- 行为不变;DEPDBG 行格式统一为 pending(<kind>): mod=.. cls=.. method=.. dep=.. extra=..,供下一步按 kind 统计命中数、删除死点
2026-09-12 13:53:20 +08:00
TermiNexus 7e68e76ec4 refactor(tpv): SHA1 前缀判定收敛到 GenApi 唯一真源(C10/D3 收尾)
- CallGenCall: list 泛型前缀剥离(719) 与类型名提 sha1(907/1190) 改 GenApi.sha1_prefix_len,不再盲取前 16 字节当 sha1

- CallGenCBuiltin._asm_name_is_mangled / CallGenLib._is_sha1_mangled_call: 改真源(去大写 A-F、去扫描任意位置 '.')

- CallGenFd: 类型名提 sha1 加前缀格式校验(裸名不再误取前 16 字节)

- CallGenMixin: CExport declare 前缀判定改真源

- StructGenMixin / TypeGenResolve: 类型名、模块段判定改真源;StructGenMixin 补漏掉的 GenApi import(L596/L943 引用原会 fail-fast)
2026-09-12 12:59:01 +08:00
TermiNexus 471bedbcf4 fix(tpv): 去掉条目指针数组往返,改上界/量长直写(修自举 ASan strcat -1 崩溃) 2026-09-12 12:43:08 +08:00
TermiNexus 82eea2719f refactor(tpv): rowptr[T] 迁移 + D 表定长缓冲改精确分配 + SHA1 前缀判定收敛(D1/D3/D4/D5/D6/D7/C10) 2026-09-12 11:09:35 +08:00
TermiNexus 7471cc64f9 docs(tpv): 精简 CompilerFactory 装配设计注释块 2026-09-12 10:52:00 +08:00
TermiNexus 679758c05b refactor(tpv): 删无符号判定的旧字符串兜底,真源唯一(S4 去字符串化收尾)
删 _type_name_unsigned_legacy / _annot_str_unsigned_scan / _annot_str_unsigned_legacy / _last_dot_tail / _is_simple_ident;_type_name_unsigned 与 _annot_str_unsigned 变为真源唯一(spec_sign_of_annot)。

依据:真源已含顶层 | 分段、去括号/空白、IDENT[INNER] 取元素、去模块前缀、精确名白名单、CTypedef 链展开,旧路径能力是它的真子集(S2 已把旧路径修到与真源一致),差异面就是假阳性区 —— strstr 子串扫描正是 A4/A5 根因(BYTEPTR 含 BYTE、任何含 uint32 的 mangled 名都被判无符号)。现语义:真源 UNKNOWN=不表态 => 返回 0;若日后发现漏判,补白名单/补 CTypedef,不恢复子串扫描。
2026-09-12 10:26:51 +08:00
TermiNexus cc17a8f8db refactor(tpv): 去掉函数内懒导入,改用顶层 import
Viper 的 import 是编译期的,懒导入在编译型语义下毫无作用,模块环不需要也不应该用它规避。

TypeSpec 顶层 import GenApi(GenApi→GenTypes→TypeSpec 成环但编译期无碍);CallGenLib 的既有懒导入(VpiReader)一并改顶层(VpiReader 不反向依赖 Call 层,无环)。
2026-09-12 10:23:08 +08:00
TermiNexus 7fbf69ae63 fix(tpv): InternSpec 表满改为 fatal(不再返回 None 静默丢类型信息)
表容量超限原实现只是 return None,但注释声称 fail-fast:None 会沿调用链传到 entry.Spec,条目静默失去类型信息(_entry_spec_unsigned 恒返回 0 ⇒ zext/sext 方向取错),属静默数据损坏。

改为 GenApi.fatal_error(InternalCompilerError);TypeSpec 与 GenApi 互为依赖(GenApi→GenTypes→TypeSpec),故函数内懒 import 破环(同 CallGenLib.vp:220 既有模式)。仅当 fatal_error 无 gen 通道时退化为不驻留返回完整实例,守住不返回 None 的底线。SPEC_INTERN_MAX 仍为 8192(当前未触发)。
2026-09-12 10:21:27 +08:00
TermiNexus 1039969f69 refactor(tpv): CPtr 标记语义定为注解基名精确比较(第 5 处收敛)
CallGenMixin 闭包 vs 函数指针分派:原 strstr(注解名, CPtr) 子串匹配改为 SpecTypeNameBaseIs(fp_annot, CPtr)。

语义:CPtr 标记 = 注解基名精确等于 CPtr(裸 t.CPtr / from t import CPtr)。不能改用 Spec 判定——t.Callable[[A], R] 解析结果同样是 Ptr(i8)(TypeGenResolve.vp:2525-2531),与 t.CPtr 完全同型,类型层无区分度,故标记只能由注解名承载,不新增 Spec 字段。副作用:含 CPtr 子串的类名(如 CPtrHolder)不再被误判为闭包指针。已知局限(与改造前一致):Foo | t.CPtr 的 SourceName 只留 Foo,该形态判为非标记。
2026-09-12 10:12:01 +08:00
TermiNexus ae63f4f6ab refactor(tpv): 容器判断改基名精确比较(SpecTypeNameBaseIs)
TypeSpec 新增 SpecTypeNameBaseIs(name, base):基名 = 截断第一个 '[' 起的泛型实参后,取最后一个 '.' 之后(去模块名 / LLVM 注册名的模块 sha1 前缀),再精确比较;零分配,复用 _spec_name_eq。

4 处容器判断改写:StmtGenCifMixin:1133/1142/1498(读注解名)、CallGenDispatch:1685(读 LLVM 注册名)。原 strstr 子串匹配会误命中 MyDictHelper / playlist;副作用是 GSList 等用户类不再被误判为内置 list,改由 OOP __iter__/__next__ 路径处理。第 5 处 CallGenMixin:973 的 CPtr 属标记判断(SourceName 会丢掉联合里的标记),需先定标记语义,本次不动。
2026-09-12 10:10:14 +08:00
TermiNexus 19fca19ca7 refactor(tpv): get_llvm_type_bits 双副本收敛到 TSpec.SpecTypeBits
TypeSpec 新增 SpecTypeBits 作为「LLVMType → 整数位宽」块的唯一实现(对齐 SpecTypePtrLevel 的收拢先例);ExprGenBase/TypeGenErr 两份同码副本改为委托,TypeGenErr 补 TypeSpec 导入(无环)。

保留方法名与 self. 调用点:@t.NoVTable 静态绑定下 Mixin 内部大量 self.get_llvm_type_bits 依赖其存在,只换实现体不动签名。副本分叉会导致同一类型两处算出不同位宽的隐蔽不一致。
2026-09-11 23:14:51 +08:00
TermiNexus 41c5908c5e refactor(tpv): Y 类兜底改 fail-fast(vpi 声明返回/形参 + vpi 类型文本)
新增 GenApi.fatal_error:VpiReader/Converter 等模块级函数无 self.Gen,统一经此报错通道;GenApi._g_gen 为空时回退 Generator._g_gen(Phase 1 vpi 生成早于 BuildPipeline 注入 GenApi._g_gen)。

VpiReader._inject_function_declare/_inject_method_declare 共 4 处:有注解却解析不出类型 → fatal;无注解的 i32 返回/i8* 形参合法默认保留。Converter._PyiTypeStr 未知节点类型不再静默写 int。
2026-09-11 22:46:39 +08:00
TermiNexus db8220801c refactor(tpv): Z 类兜底改 fail-fast(返回类型/模块级变量/枚举成员)
- ClassGenVTable 方法返回:有注解但解析失败即 fatal;State/CExport/CExtern 标记归一为 Void
- TranslatorGenMixin 模块级变量:有注解但解析失败即 fatal(保留无注解合法默认)
- ClassGenEnum._resolve_enum_member_type 4 处:Attribute 缺失名/Name 缺失 id/两处解析失败均改 fatal
  (无注解与 t.State 标记的 i32 默认保留)
2026-09-11 22:17:45 +08:00
TermiNexus cc3359faea refactor(tpv): 形参类型注解解析失败改 fail-fast(不再静默用 i32)
- FuncGenDef 前向声明形参 / 定义签名形参:resolved is None 即 fatal
- FuncGenBase create_function 形参:同上(暴露调用方未传 trans 上下文)
- ClassGenVTable _translate_method 形参:同上(签名/调用点/实现体三方一致)
- TypeGenCDef 整数 CDefine 值缓冲分配失败改 fatal(对齐同文件浮点/字符串分支)
- FuncGenMixin._type_byte_size 类型缺失改 fatal(case _ 保留 8,注释说明无布局查询能力)
2026-09-11 22:14:10 +08:00
TermiNexus 22c71388d4 docs(tpv): 更新 TypeSpec 注释(IsPtrElement 已删,仅容器种类待后续) 2026-09-11 22:09:32 +08:00
TermiNexus a4bc5dc0ce refactor(tpv): 删除 IsPtrElement 字段,指针元素语义承载于 Spec.ElemBits
- TypeSpec 抽 _spec_clone(消除 SpecWithSign/Source/ElemBits 三处重复逐字段拷贝)
- 新增 SpecWithElemBits:覆盖元素槽位宽(独立副本不驻留,ElemBits 不在驻留键内)
- set_var_ptr_element 改写 Spec.ElemBits=64;Spec 不可承载(非指针/缺失)即 fail-fast
- 新增 var_is_ptr_element(PtrLevel>=1 且 Elem.Bits==8 且 ElemBits==64,排除真实 i64* 与纯 str)
- ExprGenName 4 处下标读写切读该入口;GenTypes 删 VarEntry.IsPtrElement
2026-09-11 22:09:18 +08:00
TermiNexus e55ec5fde0 docs(tpv): 更新 TypeSpec 设计注释至 S4 现状(TypeStr/AnnotClassName 已删) 2026-09-11 22:06:20 +08:00
TermiNexus 9e461d21cb refactor(tpv): 删除 AnnotClassName 字段,注解类名统一承载于 Spec.SourceName
- GenTypes 删 VarEntry.AnnotClassName / FieldEntry.AnnotClassName
- set_var_annot_class_name / add_field 改为写入 Spec(Spec 为 None 时建 TS_UNKNOWN 承载,
  不表态具体类型,等价原 Spec 缺失);删 1b 的 AnnotClassName 专属深拷贝
- var_annot_class_name / get_field_annot_class_name 去旧字段回退分支
- 剩余 7 处直读(StmtGenCifMixin list/dict 5 处、CallGenMixin CPtr 2 处)改走封装
2026-09-11 22:06:00 +08:00
TermiNexus 95133d8483 refactor(tpv): 变量/字段注解类名读取统一走 Spec.SourceName 封装
- VarGenMixin 新增 var_annot_class_name(SourceName 优先,回退 AnnotClassName)
- 变量侧类名恢复与诊断读取切读:ExprGenAttr(5) / ExprGenOps(6) / ExprGenName(1)
  / CallGenDispatch(3) / CallGenCall / CallGenProp / CallGenVt / ExprGenCls / AssignGenMixin / MatchGenMixin
- ExprGenAttr 字段侧直读改走 get_field_annot_class_name
2026-09-11 22:02:28 +08:00
TermiNexus 8aad248c25 fix(tpv): SpecWithSign 不复制 SourceName,避免驻留表来源名污染
InternSpec 键不含 SourceName,若带来源名的副本入表,后续同键查找会把该来源名
污染给无关条目(键相同必须语义相同 ⇒ 表内实例 SourceName 恒为 None)
2026-09-11 21:54:29 +08:00
TermiNexus 029a423f55 feat(tpv): Spec 增 SourceName 承接注解来源名(类名块基础设施)
- TypeSpec 新增 SourceName 字段:注解书写形态名(裸名/模块限定名/t.XXX attr/mangled),
  与 BaseName(LLVM 注册名)命名域不同;不参与驻留键,避免条目暴增与线性查找变慢
- 新增 SpecWithSource(独立副本、不驻留、幂等)/ SpecSourceName 读取入口 / _spec_set_source_name
- set_var_annot_class_name 与 add_field 注解侧填 SourceName
- get_field_annot_class_name 切读 SourceName 优先(3 个调用点自动生效)
2026-09-11 21:54:10 +08:00
TermiNexus 7028399366 refactor(tpv): 无符号判定切读 Spec(条目级 TS_UINT 优先)
- 新增 _entry_spec_unsigned:Spec.Kind==TS_UINT 为注解明确无符号的强信号
- _node_type_unsigned 的 Name/Subscript 分支、Attribute 字段分支切读 Spec 优先
- 只切无符号方向(TS_INT 含未表态,不可反推 SIGNED,仍走字符串真源)
2026-09-11 21:51:11 +08:00
TermiNexus 7fedf8daad feat(tpv): Spec 注解侧填符号性(SpecWithSign + 变量/字段接入)
- TypeSpec 新增 SpecWithSign:整数 TS_INT↔TS_UINT 切换 + 驻留(SpecToText 键区分符号)
- set_var_annot_class_name 接入:注解类名提取符号性,补 Spec 无符号性
- add_field 接入:字段注解类名提取符号性,补 Spec 无符号性
2026-09-11 21:48:23 +08:00
TermiNexus 0a108e6289 refactor(tpv): 删除 FuncEntry.TypeStr 旧路径,函数类型文本改由 Spec 派生
- 删 FuncEntry.TypeStr 字段、_build_func_type_str 生产者、_check_func_spec_text 闸门
- update_global_func_typestr 改名 update_global_func_spec,仅填 Spec(去 pool 参数)
- ClassGenVTable vtable 合并 func_valid 分支,统一 SpecToLLVMText 派生
- 同步 FuncGenDef/ClassGenVTable/GenApi/VpiReader 调用点
2026-09-11 21:33:58 +08:00