Commit Graph
129 Commits
Author SHA1 Message Date
TermiNexus 3e1e1fc1b3 fix(gen): 消除 ViperC 侧 P0 级静默截断
match:case 数超过 MAX_MATCH_CASES 时 fail-fast(原先 break 会静默少分支,need_case 检查也发现不了)。vtable:初始化串按真实方法表动态分配,_vtable_strcat 溢出改 fatal;VTBL_METHOD_MAX 超限不再 break(原先子类 override 静默失效)。符号名:coro_pool_/__tls_init_done_/__decor_rec_/闭包 fn_ptr 的定义与引用改为按实际长度分配,消除 96 vs 128、64 vs 128 的不对称。Stub:_PyiEmit 溢出改 VLogger.error(半截 .vpi 会被当完整文件解析);VpiReader 参数段/返回注解缓存槽放不下时 fail-fast,不再丢段导致形参注解错位。Includes:文件超过 1MiB 拒绝哈希(SHA1 冲突会让两个模块共用缓存);add_file_entry 失败不再被忽略。f-string:格式串按字面量/转换符实际长度分配,字面量与 format_spec 溢出 fail-fast。
2026-10-17 18:46:18 +08:00
TermiNexus d06e665ebd fix(cdefine): stub 读取对负浮点字面量/浮点强转包裹剥壳后再注册 - 修 X: double = -100.0 走整型提取 fatal 2026-10-15 23:46:25 +08:00
TermiNexus 5460d78ff1 fix(gi): 模块级类全局按值本位存储(仅 __new__ 类用指针) - 修 CAM: V3 被包成 Ptr 致悬垂误报 2026-10-15 23:11:24 +08:00
TermiNexus 508428bbc9 fix(viperc): 浮点常量按目标类型/声明宽度直接出 f32,不再先出 double
- 浮点字面量在 f32 目标(float(1.5) / x: float = 1.5 / f32 形参)下直接物化 f32 常量,
  负号折叠(-c)同口径;去掉旧的「f64 常量 + fptrunc」
- CDefine 浮点条目记录宽度种类(1=f64 / 2=f32):define PI: float = ... 的使用处
  直接出 f32 常量,与 f32 字面量混算不再被提升成 double(现场 33 处 cvtss2sd)
- 本模块注册 / pyi·vpi 跨模块重解析 / xmod 缓存三处都按注解裁决宽度,保持跨模块一致
2026-10-15 18:35:48 +08:00
TermiNexus a143c2de0c fix(stubgen): 装饰器循环变量改名 ddi,避免与默认值处的注解声明 di 冲突
同一个函数里 di 先被 for 循环绑定为 int(i32),后面又用注解声明为 sizet(i64) 且右值是运行期 i64 值:存储类型 i32 收不下,编译器按 fail-fast 报'带注解重声明冲突'(此前 TPC 是静默丢掉 store,生成的 viperc.exe 在 list[AST*].get 越界读)。装饰器循环改用 ddi,di 保持为首次声明。
2026-10-14 21:13:03 +08:00
TermiNexus 1c3cdf3493 fix(stub): 消费模块补齐按值返回聚合的具名结构体完整体(_inject_method_declare 补 _ensure_full_value_types、_inject_class_struct_declare 补登完整定义),修 MLIR opaque 报错 2026-10-13 17:48:57 +08:00
TermiNexus a01e9280cc fix(stub,phase1): 因取消整数提升,模块属性 CDefine 的窄乘法显式加宽为 sizet(修缓冲区尺寸回绕成 0/负值) 2026-10-13 16:34:39 +08:00
TermiNexus 32599a08c1 fix(stub): .vpi 读取侧复刻字段标记判定(volatile/pointee-volatile/const/字节序),跨模块不再丢字段标记 2026-10-13 12:30:23 +08:00
TermiNexus d206abf3e1 chore: 全仓同步 w32→win32 模块改名与 range(int(...)) 显式收窄适配 2026-10-12 20:59:11 +08:00
TermiNexus 3384941cd1 chore: 改名同步 TransPyV -> ViperC(源码/配置内的纯替换) 2026-10-12 15:06:28 +08:00
TermiNexus 4e46a25ab1 fix(gen): define 位宽/整数提升/移位/AugAssign 规则收敛,修 va_list 与 traceback 卡死
- define 位宽:cdefine_decl_bits 单一裁决(注解 → 右侧强转 → 值最小可存宽度),定义方与 VpiReader 两处跨模块注册共用;lookup_cdefine_bits 取最后一条非零记录;存储即截断;使用侧改按声明位宽;通用求值器加编译期除零/移位越界 fail-fast
- 消除对无符号强转加宽方向的依赖:define_min_width 改 (value>>32)==0,截断改左移+算术右移,修 TPC/TPV 判定不一致导致 0x80000000 误判 64 位
- 整数提升:算术/移位、比较、一元 +/-/~ 提升到 i32;位运算保持同宽不提升
- AugAssign:y 有效宽度须 <= x、禁 y 显式有符号而 x 无符号;移位计数静态范围检查
- 函数入口复位 va_list 状态与 willFree 失效槽表(FuncGenDef/FuncGenMixin/VarGenMixin 等)
- BuildPipeline:traceback 逐行扫描改 span 判定,去掉对全文 strlen 的 O(n^2)
2026-10-12 12:37:48 +08:00
TermiNexus 3c0d3d13b5 fix(narrow): 清理注解式整数窄化(Converter/TypeGenCType/CallGenLeafKit/ClassGenEnum)
CDefine 查询返回 int64 处按下游用法定型:回传给 int 的用显式 int(...),流入 int64 目标的加宽为 int64;sizet 数组元素赋给 int 的用 int(...)
2026-10-11 09:51:08 +08:00
TermiNexus f2cbb658e1 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 的重复调用随之移除。
2026-10-10 14:00:41 +08:00
TermiNexus 6da8e2e095 feat(gen): 落地 @life(ret(...)) 返回值生命期契约(A2)
- GenApi:新增 compute_life_anno / _RetKindFromTag 与 RET_KIND_* 编码,
  提供 get_ret_kind / get_ret_kind_method / lookup_ret_kind_via_vpi;
  _WillFreeMergeTag 不再拦截 ret(改由 compute_life_anno 收集校验)。
- StructGenMixin:EscDirTable 由 3 槽扩到 4 槽(新增 ret_kind 列),
  compute_escape_summary 把契约落在 box[5] 并登记。
- Stub:.vpi 行尾新增 escr=<ret_kind>(Converter 写、VpiReader 读 _g_vpi_esd_r)。
- AssignGenMixin.life_of_expr(Call):@life(ret(...)) 声明优先于任何推断;
  frame/heap/static/borrows=none 直接映射,borrows=x 取对应实参生命期,
  方法调用按接收者静态类型解析类名。
- StmtGenCifMixin:同批移除定义端 return <本帧地址> 的 fail-fast,
  返回值去向改由调用点按被调者契约判定。
2026-10-09 22:58:33 +08:00
TermiNexus 79299ec47d feat(lifetime): 声明式指令契约落 .vpi(esce=/escn=),跨模块调用点也能最终裁决
写侧 Converter:读 compute_escape_summary 落在 box[3]/box[4] 的契约掩码,随函数头行尾写 esce=<强制逃逸位> / escn=<强制不逃逸位>;
只有指令(既无 esc/ret 也无 wf)时也补一个 "# esc=0 ret=0" 注释段——读侧是"见 # 才解析"。

读侧 VpiReader:_cache_vpi_esc_clears_text 同一次行扫描里顺带收 esce=/escn= 进 _g_vpi_esd_*(与 escg 同键 sha1[.Cls].func);
新增 _lookup_vpi_escape_dir(.., noescape);CallGenBase.lookup_escape_dir_via_vpi 包装。

调用点:模块级函数 / 方法 / 构造器三条路径在本文件指令表为空(= 跨模块)时改查对方 .vpi,
仍放在所有推断/回退之后最后套用:esc_mask = (esc_mask | esce) & ~escn。
2026-10-09 20:40:30 +08:00
TermiNexus fc797da542 feat(lifetime): @life(escape/noescape) 多形参、硬逃逸位同命精化、归纳变量区间与跨模块常量特化
- GenApi:escape/noescape 标签支持多实参;新增 compute_escape_directives 与若干委托

- StructGenMixin:硬逃逸位(box[2])、常量与归纳变量区间折叠、_PackEscapeClear/compute_escape_clears

- Call 系:调用点同命裁剪(_FrameArgsEscapeClears)+ 跨模块 escg= 查询;写侧 Converter、读侧 VpiReader

- AssignGenMixin:裸 T()(无 new、无 __new__)判为帧生命期
2026-10-09 18:44:51 +08:00
TermiNexus dd24dc670f fix(gen): P2 失效状态改存独立槽表,不再给 VarEntry 加字段
现象:任何工程编译都在函数形参注册刚结束处 access-violation(pc=0,逐字节可复现)。定位:逐层探针把崩点压到 FuncGenDef 的 pre_scan 段,而该段对 Check(body 仅 if+return)应为空操作,唯一变量是 VarEntry 这个热结构被加了 Freed 字段。修法:撤销 VarEntry.Freed,改用 VarGenMixin 的独立失效槽表 _g_freed_slots(键 = 变量槽 alloca,整次翻译内唯一,故全局累积、无需按函数 reset/restore);_FreedMark/_FreedCheck/_FreedClearSlot 三个 API 替换字段读写,P2 语义不变。同时清除全部 TEMP 探针。
2026-10-09 11:51:11 +08:00
TermiNexus be2521fe46 chore(dbg): 临时阶段日志定位 Phase A 崩溃点(定位后移除)
四个探针:PhaseA translating <path> / vpi.gen <rel_path> / TR.enter sha1 / TR.prelude.done。用于把崩溃点夹在 解析→vpi生成→模块前言→函数体翻译 四段之间。
2026-10-09 10:08:43 +08:00
TermiNexus 97313e9e55 feat(gen): P2 生命期标注 @life(willFree(...)) 驱动释放后使用与二次释放检查
标注面:@life(willFree(<形参名|0起序号>)),兼容叠加式 @willFree(...),可混用累加;序号按形参表下标、self/cls 计入。GenApi.compute_willfree_mask 解析标注并对非法标注 fail-fast。本文件表 StructGenMixin.WfTable + 跨模块 .vpi 行尾 wf=<mask>(Converter 写 / VpiReader 读 / CallGenBase 查)。调用点在实参全部翻译之后把对应实参变量槽置 VarEntry.Freed;其后的读取路径报 LifetimeError。重新赋值清除失效态。
2026-10-08 21:28:49 +08:00
TermiNexus 9e55e909a8 feat(gen): LifeTag 接到 new 描述符;vpi 文本缓存收敛为单一入口
life_of_expr 新增 ASTKind.New 分支(§2.3 矩阵):stack→LIFE_FRAME;heap/memgr 的 slife 同样按帧生命期(作用域末 RAII 释放,逃逸必悬垂);hlife→LIFE_HEAP。于是 new stack slife Foo() 的结果被赋给变量/返回时会被既有汇点判据 fail_if_life_escapes 拦住(该判据本来就是生命期驱动,无需再加语法特例)。

VpiReader 新增 _cache_vpi_annots_text 单一入口(ret/param/逃逸摘要一次喂齐),两个 vpi 加载点都改调它:从结构上消除"某个加载点漏喂某类缓存"这类静默退化(本次 EscapeXmodTest 漏检的根因类别)。
2026-10-08 18:19:15 +08:00
TermiNexus 14920c0e1e fix(vpi): 逃逸摘要在所有 vpi 加载点都喂缓存,修 EscapeXmodTest 跨模块漏检
_ensure_vpi_ret_annot_loaded 开头有"本模块 ret 注解已缓存则直接 return 1"的短路:若某模块先经 _ParseVpiIntoModuleImpl(stub 注入)加载,而该处只喂了 ret/param 缓存、没喂逃逸缓存,后续跨模块逃逸查询就会永久查空。现场:EscapeXmodTest 漏检——box.vpi 里 `# esc=2 ret=0` 落盘正确,查询侧却命中不到。在该加载点补 _cache_vpi_escape_annots_text。
2026-10-08 17:58:07 +08:00
TermiNexus cd68bb62ac feat(gen): M2.3 v3 跨模块逃逸摘要 + 全局赋值判据双保险
【v3 跨模块摘要】Converter._PyiFunction 在每个 def 签名行尾写 `# esc=<mask> ret=<ret>`(仅非零时写);VpiReader 新增逃逸摘要缓存(键 {sha1}.{Class}.{method} / {sha1}.{func},值打包 mask|ret<<32),与返回注解缓存同一次加载解析,并加"模块已加载"备忘 + 键前缀过滤避免拖慢编译;StructGenMixin 抽出 compute_escape_summary 供登记与落盘共用;CallGenBase.lookup_escape_via_vpi 按本类 + MRO 祖先模块 sha1 查询,方法/构造器/模块级函数三处调用点在本地表未命中时回退查 vpi。

【修复】Converter._PyiEnsureEscScratch 补 global(漏写导致全局仍 NULL,box 算成 0+520 → ASan WRITE on 0x208);函数内写"本文件已声明的模块全局"且无 global/nonlocal 时必须 fail-fast——原判据只看 SymTab.Root.Vars,部分时序看不到模块全局而静默建局部影子;新增 FileVarNames(register_file_funcs 预扫收集顶层变量名)+ is_file_var() 兜底,普通赋值与注解式重声明两处都接上。
2026-10-08 17:28:06 +08:00
TermiNexus b03e55bb7e fix(gen): 类归属不采信星号导入候选,收口 fatal_error 返回类型与默认值补全
TypeGenResolve._class_true_def_sha1 / CallGenBase._lookup_reexport_from_vpi 新增 allow_star 参数:类归属只采信具名 re-export。此前 `from X import *` 候选被当成类的真实定义模块,而几乎每个文件都 star-import stdint,导致 TypeGenErr 前向声明被建成 "stdint.TypeGenErr";该名字在 StructTable 里只剩一个错误 sha1 的条目,fatal_error 的跨模块返回类型解析全部落空并 fail-fast。

TypeGenErr.fatal_error/fatal_type_error 显式 -> int(留空会解析出退化类型 i0,命中 CallGenCall 的 i0 守卫);_fail_method_ret_ty 增加失败上下文转储并并入同一条 VLogger.error(批处理下 error 即 sys.exit,其后代码全是死代码)。

CallGenMixin 模块级调用:默认值已知但重建不出时 fail-fast,不再静默产出操作数不足的 llvm.call(只会被 MLIR 校验拦下);AssignGenMixin 两处 VLogger.error 补上 category 实参。

M2.3 v1b 收尾:逃逸摘要表与扫描临时区改为只分配一次、传递闭包扫到不动点、u64 改 sizet;VpiReader 不再 free 跨阶段引用的 src_sha1(heap-use-after-free)。
2026-10-08 16:38:35 +08:00
TermiNexus 2fb648d68a feat(lang): 新增 cif/celif/celse 条件编译与值引用注解 &T/&temp T,assert 改译 testcheck.check
cif 三件套:StmtGenCifMixin 负责常量求值(含 defined(模块宏) 的 Attribute 形式),链式错配与含运行时变量一律 fail-fast;删掉 c.CIf 家族。值引用:TypeGenResolve 让 CRef/CTempRef 与 t.CPtr 走同一解析路径(&void 折叠为 i8*,删除 t.CNeedPtr),CallGenBase 在调用点按形参模式自动取址(ref 只接受左值,右值 fail-fast;temp 物化临时栈),跨模块经 VpiReader/StubMergerBuild 传递模式。assert:StmtGenMixin 合成 testcheck.check(cond, None, msg),Translator 检测到 assert 时自动注入 testcheck 导入(带去重与防环),深递归守卫改用 stdio.printf + stdlib.exit(Translator 无 Gen 成员)。
2026-10-07 19:03:16 +08:00
TermiNexus 7a9bc5ae75 chore(messages): TransPyV 运行时中文字符串英文化
把 TransPyV/App 下 57 个文件的运行时中文字符串(编译器报错/告警/日志、CLI 帮助与横幅、REPL 提示、Phase1/Phase2 流程日志、Codegen 各 Mixin 的类型与调用报错、Stub/Vpi 诊断等)共 1091 行译为英文。

口径:只改字符串字面量内部文字,行数零变化(+1092/-1092);printf 格式符与转义序列多重集合校验不变(_strcheck 异常 0);译文不引入撇号以免干扰单引号字面量解析。验证:三重重编 SUCCESS(136.20s)+ 全量 77/77 顺序回归通过 + VET 编译 SUCCESS / --search-paths 7 条 exit 0;新产物 help/日志输出已为英文。
2026-10-07 00:03:58 +08:00
TermiNexus cd55a7e214 refactor: rawptr[T] -> T*(R14)+ 修 REnum 前向占位未就地填充
R14:rawptr[X] -> X*(56 文件 / 834 行改动);保留 6 处 rawptr[t.CPtr](存纯裸指针的规范例外)。 修复:class X(t.REnum) 的变体字段写成自引用 X* 时,字段解析在变体扫描期经 ensure_forward_class 建了一个 opaque 前向占位;末尾 register_struct 按 Ty 指针去重会再建第二个同名 entry,而 find_struct 取首个(占位,0 字段)→ X.__sizeof__() == 0,报「已注册但大小为 0(字段链表未填充)」。改为注册前若命中同模块前向占位则就地填充(与 ensure_forward_class 文档口径一致)。TPC 无此问题,属 TPV 侧缺口。 验证:自举三重重编 SUCCESS;全量 77/77 顺序回归通过(修复前卡在 LLvmLiteTest)。
2026-10-05 17:38:28 +08:00
TermiNexus fb53f88893 refactor(gen): R12/R13 同步——下标 while 循环改 for range、去 c.Set
与 includes 同步执行两批源改写:R12 把「i: int = 0 与 while i < N: … i += 1」形式的计数循环改写为「for i in range(N):」;R13 把 c.Set(*p, v) 迁移为 *p = v、c.Set(a, b) 迁移为 a = b(c.Set 是正在退化的路径)。

验证:bootstrap 三重重编 SUCCESS(无 vast_c 解析回退);全量 77/77 顺序回归通过(WebTest 首轮网络超时,单独重跑通过)。
2026-10-05 15:33:58 +08:00
TermiNexus 0f4aeeceff docs(tpv): R11 注释与 docstring 英文化并压缩到 2 行内
按 wiki/新规范:注释只讲作用、不掺杂历史原因、避免超长、尽可能英文(含三引号 __doc__)。全文 79 个 .vp:# 注释 16269 行(中文 13808)与 docstring(中文 1381 处)全部改英文;超 2 行的注释块(2093)与 docstring(397)全部压到 2 行。运行时可见文本未动(fatal_error/VLogger 的中文报错文案、stdio.printf 的横幅格式串)。校验:屏蔽注释与三引号后逐行比对各文件代码骨架,0 漂移。验证:自举重建 153.48s 通过(跨模块内联完成);TPV 顺序回归 77/77 全通过。
2026-10-05 13:38:22 +08:00
TermiNexus f2ef1bb240 refactor(tpv): 新语法 R10 括号内隐式续行并一行(1140 处 / 67 文件) 2026-10-05 07:14:14 +08:00
TermiNexus 4a685d478f refactor(tpv): 新语法 R10 单语句块并一行(7722 处 if/for/while 单语句体) 2026-10-05 03:10:55 +08:00
TermiNexus 30a3da4cd4 refactor(tpv): 新语法 R10(反斜杠续行合并)+ 回退 R5(语义不等价)
- 反斜杠续行合并为单行(304 处),呼应"尽可能不换行"。
- 回退 c.DerefAs(p, v) → *p = v 两处(StructGenMixin):原写法是 bitcast 后
  store 指针位,新写法按 pointee 值类型赋值,类型不符(i8* → List 值),
  语义不等价,保留 c.DerefAs。

种子自举通过。
2026-10-04 22:56:27 +08:00
TermiNexus 185a2196ca refactor(tpv): 迁移新语法 R1/R2/R7/R8/R3/R4/R5(指针 T*、短别名、define、&/*、__asm__)
按 wiki/新规范:
- T | t.CPtr → T*(无 | 标准)
- t.CInt/t.CUInt64T/t.CChar/t.CDouble 等 → int/uint64/char/double 等短别名
- X: t.CDefine = Y → define X = Y
- c.Asm → __asm__,c.AsmInp/c.AsmOut → asminp/asmout,t.ASM_DESCR. → ASM_DESCR.
- c.Addr(x) → &x,c.Deref(p) → *p,c.DerefAs(p, v) → *p = v

种子自举通过(96s)。
2026-10-04 22:49:01 +08:00
TermiNexus b7e4861e6c fix(tpv): vpi 返回注解纯 marker(t.State 等)解析为 void,修 void 调用被当 i32
调用侧 `_resolve_vpi_ret_annot_str` 只把 `t.CVoid` 映射为 void,纯 `t.State`
(存储类装饰器标记)会解析失败返回 None → 调用侧回退外部函数白名单默认 i32。

现场(MLIRLiteTest):`includes/stdlib.vp` 的 `extern def exit(status: int)`
在 stdlib 的 vpi 中是 `def exit(status: int) -> t.State: pass`,于是生成
  %6 = llvm.call @exit(%c3) : (i32) -> i32
而模块声明是 `llvm.func @exit(%status: i32)`(void),mlir-opt 报
  'llvm.call' op calling function with void result must not produce values

修复:在 `_resolve_vpi_ret_annot_str` 增加"纯 marker 注解 → void"分支,与
declare 注入路径 `_inject_module_declare` 的 is_pure_marker_rt 判据同口径。
仅**纯** marker(`t.State` / `t.CExtern` / `t.CExport`,可带 t./c. 前缀)
才归 void;`HANDLE | t.State` 等含真实类型的注解仍由段循环返回真实类型。
2026-10-03 21:51:13 +08:00
TermiNexus d0434bf114 fix(repl): 片段导出符号探针改用 MLIR 形态 llvm.func;布局恢复文案改指 {sha1}.meta
- Repl.vp ⑧ 探针由 "define i32 @名(i8* %__repl_ctx__" 改为
  "llvm.func @名(%__repl_ctx__: !llvm.ptr) -> i32"(单端后 dump 出的是 MLIR 文本)
- VpiReader.vp REPL 布局恢复的注释/报错/汇总文案 .stub.ll → {sha1}.meta
  (数据源早已是 meta:_repl_stub_collect_module 读 {sha1}.meta,
   _repl_meta_scan_layout 解析 STRUCT/VTABLE;本次只改文案与注释,无逻辑改动)
2026-10-03 19:58:37 +08:00
TermiNexus 7b3e814524 refactor(backend): 单端 MLIR —— 发射器全树改名 mlirlite 并删除 --backend 开关
- App/Test 的 .vp 中 llvmlite 全部改名为 mlirlite(import、限定名、类型注解、注释)

- 删除后端开关:Config.set_backend/is_mlir_backend/alias_module_name、BackendTarget/BackendIsMlir、CLI --backend、options.backend/options.target 读取,以及 IncludesScanner/StubMergerIR 的模块别名调用

- BuildPipeline 的 mlir-opt -> mlir-translate 降级管线去掉开关门,改为恒执行

- backend_dir_suffix 改名 mlir_dir_suffix 并恒返回 _mlir:TempDir/OutputDir/includes 缓存继续落在 *_mlir,避免复用旧 LLVM 后端的 .ll/obj

- project.vpj 删除已失效的 options.target
2026-10-03 19:26:24 +08:00
TermiNexus 98ee53340f feat(call): 跨模块实参加 str/bytes 形参的 fail-fast(str 不作通用指针通配),并加 vpi 注解段等值判定 2026-10-03 14:23:12 +08:00
TermiNexus 692998820c feat(generic): 泛型函数类型实参推断与单态化
支持 def f[T](x: T) -> T 及 f(x)/f[T](x):模板注册(Phase1Scan/Phase2 顶层 FunctionDef,键 {sha1}.{name})、按形参注解对齐从实参推断类型实参(无来源即 fail-fast,不静默默认 int)、克隆模板并 set_generic_context 后翻译生成特化体(名字 {sha1}.f[int],规范化复用 _mangle_generic_class_name)、同签名去重、跨模块按模板签名补 declare。泛型函数模板不再发 vpi(模板签名含未绑定 T),也不再发射 int 兜底版本。已知限制(未静默):bound [T: bound] 解析期已被丢弃;t.CExport/t.CExtern/t.State 泛型函数、关键字/默认参数调用、mod.f[T](x) 显式下标等暂 fail-fast 或走既有报错。
2026-10-03 11:59:26 +08:00
TermiNexus 8da4550d79 fix(vpi): 全局变量注入补自注入守卫,消除同模块 external global 与定义重名
循环 import(os/__init__ 导入 os._win32/os._posix,而二者又导入包 os)使 imported_modules 含本模块包名 → LoadDepVpiIntoModule 命中本模块自身 sha1 → _inject_global_variable_declare 为本模块自己的模块级全局发射 @<sha1>.<name> = external global,随后定义端 handle_module_level_var 再发 = global … → llc redefinition of global(SysLibTest 根因)。补上 _inject_function_declare / _inject_method_declare 已有的同款自注入守卫(_declare_only==0 且 src_sha1==trans.ModuleSha1 时早退)。
2026-10-03 11:08:58 +08:00
TermiNexus 9bd3ac3dfb refactor(sidecar): 删除 BuildCombinedIR 文本合并死代码(④-d)
在线模型方案(④-a~④-c)已由 LoadFullIR 取代文本合并,BuildCombinedIR 及其专属辅助(_Seen* 去重表、_RegisterStubLines、_LoadAndAppendStub、_LoadAndAppendTextDeclares、_IsTypeDefLine/_IsIrHeaderLine/HoistTypeDefsBeforeDeclares、_collect_stub_sha1s、_stub_scan_cache_*)已无调用方,一并删除(约 1348 行);同步改写 #35/TranslatorGenMixin 中引用旧函数的注释。
2026-10-03 09:13:17 +08:00
TermiNexus cc8ea01476 feat(sidecar): 翻译点增写 {sha1}.full.ll,Phase B 改用在线 FULL 产物(④-b/④-c)
- 翻译点(Phase1Main / Phase2 PhaseA / Phase2 includes 重试)在 dump stub/text/meta 后
  追加 dump_ir(OUTPUT_FULL) → {sha1}.full.ll(FULL 缓冲 16MB = stub+text 2× 余量)
- Phase1 增量跳转新增要求 full.ll 存在(缺失即重译补写)
- 新增 StubMergerBuild.LoadFullIR(与 BuildCombinedIR 同契约:读文件到 out_buf)
- Phase B 三处调用点 BuildCombinedIR → LoadFullIR;COMBINED_IR_SIZE 4MB → 16MB
- 诊断报文/注释同步(读 full.ll 失败)

full.ll 为模型在线时产出的自足单模块 IR(类型定义在声明之前,天然满足 llc 顺序);
BuildCombinedIR 暂保留(④-d 再删)。未编译验证。
2026-10-03 08:43:03 +08:00
TermiNexus 3b0ed04e70 chore(stubmerger): 删除 StubMergerIR 中 6 个无调用方的旧 IR 文本扫描助手
删除 _IsFuncDeclaredOrDefined / _CommentOutDeclareInBuf / _CommentOutGlobalInBuf /
_HasGlobalInBuf / _CommentOutOpaqueTypeInBuf / _HasFullTypeDefinition —— 全仓无调用方
(去重判定早已迁移到 StubMergerBuild 的 _seen_* 哈希表),保留在用中的
_is_submodule_of_imported。顺带更新本模块头注释(现为 meta sidecar 工具)。

去 IR 化收尾清理;未编译验证。
2026-10-03 08:26:02 +08:00
TermiNexus 35f2070d3b feat(sidecar): meta 增写 STRUCT/VTABLE,REPL 布局恢复改读 meta
- WriteModuleFuncMeta 更名 WriteModuleMeta:追加 STRUCT <name> FIELDS n PACKED 0|1
  (opaque → STRUCT <name> OPAQUE)与 VTABLE <class> SLOTS n;数据源改为
  Module.NamedTypeHead / GlobalHead,不再有任何 IR 文本反推
- VpiReader REPL 布局改读 {sha1}.meta:新增 _meta_atoi / _repl_meta_scan_layout
  按前缀精确匹配解析 STRUCT/VTABLE 行
- 删除旧 .stub.ll 文本解析辅助 _repl_stub_take_name / _repl_stub_body_count
  及其 scratch 缓冲 ReplStubNameBuf / _REPL_STUB_NAME_CAP

去 IR 化步骤③;未编译验证。
2026-10-03 08:18:15 +08:00
TermiNexus 94d2bf5047 feat(sidecar): 落盘 {sha1}.meta 函数定义清单,声明文件判定改读结构化 sidecar
- 新增 WriteModuleFuncMeta:翻译期从 Module.FuncHead + Function.IsDeclared 产出 FUNC <mangled> DEF|DECL(与 dump_ir 的 stub/text 判据同源)
- 新增 _MetaHasDef / 重写 IsDeclOnlyModule:不再扫 text.ll 的 define 行,改读 meta
- Phase1/Phase2 落盘点紧随 text.ll 写出 meta;Phase1 增量跳转额外要求 meta 存在
- Phase2 内联 is_decl_mi 与 PhaseC 判定统一走 IsDeclOnlyModule

去 IR 化步骤①(sidecar 最小闭环),全后端统一,默认行为不变。
2026-10-03 08:06:39 +08:00
TermiNexus 0ebe2e0752 feat(backend): 新增 MLIR 后端开关/产物隔离/降级管线/模块别名(默认 llvm 逐字不变)
- Config: BackendTarget/BackendIsMlir/set_backend/is_mlir_backend/backend_dir_suffix/alias_module_name;读取 options.backend(回退 options.target)

- main.vp: 新增 --backend llvm|mlir(CLI 优先级最高,默认 llvm),加载工程后、resolve_paths 前生效

- 产物隔离: temp/output 追加 _mlir 后缀;includes 缓存追加后端后缀(.binary[_asan][_mlir])

- BuildPipeline: MLIR 降级 mlir-opt(校验) -> mlir-translate --mlir-to-llvmir,覆盖串行/并行/--phase2command,且置于 ASan opt 之前;LlcTask 增 MlirOptCmd/MlirTranslateCmd 字段

- 别名: ResolveModuleToPath 与 _FindSha1ByModName 经 Config.alias_module_name 把 llvmlite 重定向到 mlirlite(调用点零改动)
2026-10-03 07:53:04 +08:00
TermiNexus fabd92adc7 feat(switch): 新增 switch 语句并禁止 match 内 fallthrough
- MatchGenMixin:case 体按 node.is_switch 置 _in_switch_case;_has_no_break 只认 FallThrough 节点(去掉 c.NoBreak() 兼容路径)
- StmtGenDeclMixin:translate_fallthrough 只在 switch 的 case 体内合法,match/switch 之外 fail-fast
- Translator:_in_match_case 更名 _in_switch_case(语义 = 当前 case 体属于 switch)
- FuncGenDef / FuncGenMixin:函数体 / 嵌套函数 / lambda 入口隔离并恢复 _in_switch_case
- 因 match 改为硬关键字,重命名同名局部变量 match -> Matched(StubMergerStore / ImportsGenMixin / ExprGenAttr / CallGenBase)
2026-10-02 23:15:43 +08:00
TermiNexus 15b416b527 fix(type): 统一注入期类归属与导入上下文记账,修占位表爆与属性标记误解析
- StubMergerStore 新增共享导入上下文记账(AppendImportedModule / AppendFromImport /
  ImportCtx / AllocImportCtx / NotePlainImport),ImportsGenMixin 与 VpiReader 共用同一份
  口径;顺带移除 add_from_import 的 256 缓冲静默截断,VpiReader 删除两份私有副本

- 注入窗口按「名字归属」判据解析(is_module_class + CurDefModuleSha1):
  _forward_declare_ptr_from_node 的 Name 分支、resolve_annotation_type 的 Name/Attribute
  分支均补齐,使同一 stub 内先声明/先引用的类产出**具名占位**而不是 Ptr(i8),并新增
  _is_tattr_marker 让 t.attr.* 属性标记不参与类型联合竞争

- VpiReader._inject_class_struct_declare:命中前向声明占位时不再早退,改为「占位 Ty
  原地写入」(对齐 ClassGenDef.fill_fwd),修 StructTable 爆表(table full, cannot
  register Translator)

- 清除全部一次性探针:[DBG-GEN](VpiReader / StructGenMixin / ClassGenDef)、
  [DBG-ATTR](ExprGenAttr)、[MODSHA1](CallGenMixin)

根因记录:vpi 注入期漏记 `import X as Y -> from_imports "Y:X"`,使 GenTypes.VarEntry.Spec
(TSpec.TypeSpec | t.CPtr)取不到模块 SHA1、退化为 i8* 并被永久冻结
(CallGenCtor.vp:897 .PtrLevel 属性访问失败)。
2026-10-02 17:29:38 +08:00
TermiNexus 01e95b51cf debug(gen): 一次性取证插桩——Generator 结构体登记/查找全链路(用完删除)
覆盖点(全部以 [DBG-GEN] 为前缀,仅打印不改行为):
- StructGenMixin.register_struct:IN(name/sha1/ty/StructCount)、DEDUP(命中条目)
- StructGenMixin.add_field:逐字段打印写入 Generator 条目的字段名与下标
- StructGenMixin.find_struct_by_module:IN / HIT / MISS
- StructGenMixin.lookup_field(field=FuncGenBase):struct_ty 名、按 Ty 指针命中条目的
  全字段名、以及结构体表内所有含 "Generator" 的条目
- VpiReader._inject_class_struct_declare:IN / EXISTING / RENUM-SKIP / EMPTY /
  FIELD-FAIL / REGISTERED
- ClassGenDef.translate_class_def:EXISTING / REGISTER / DONE

目的:一次重建即可判定 Generator.FuncGenBase 查不到是"命中空/旧条目""Ty 错配"
还是"字段名悬空",并看清是哪条登记路径产出的条目。
2026-10-02 02:18:55 +08:00
TermiNexus f865986675 fix(stub): App 预注册注入依赖 vpi 时跳过函数/方法 declare,避免打断多遍收敛
承接上一提交(App 预注册期开始注入依赖 vpi)。注入的依赖 vpi 里,函数/方法
declare 的形参/返回注解可能引用**本遍尚未注册**的类(跨文件注册顺序:被依赖模块
的类可能排在更后,需靠下一遍收敛),resolve 落空会在 declare 注入里 fail-fast,
直接打断 Phase A-pre 的多遍收敛。现场:App 预注册 AssignGenMixin.vp 注入
Translator.vpi 时,InjectTracebackInstallCtor 形参 rawptr[Translator] 解析失败
(Translator 结构体因字段引用尚未注册的 GenTypes 类而本遍未登记)。

改动:VpiReader._ParseVpiIntoModuleImpl 新增 pre_skip_fn_declares(仅当
trans._pre_allow_dep_inject != 0 即 App 预注册时置 1),在「第一遍 B 方法 declare」
与「模块级函数 declare」两处跳过注入。预注册的唯一目的是注册 struct/enum/union
(第一遍 A)与包重导出别名(ImportFrom 段),两者均保留;方法/函数 declare 写在
预注册的瞬时模块里、随即随 mb.reset_to 丢弃,无跨遍作用。全量翻译
(_declare_only==0)不跳过,仍 fail-fast。
2026-10-02 01:47:18 +08:00
TermiNexus 57f8c655c8 chore(debug): 移除 [DBG-P7] 一次性插桩(根因已定位)
定位结论见 Debugger/debug-nested-class-struct.md 的 P7:不是别名登记失败,而是
Phase A-pre(预注册 struct/enum/union,declare_only)解析类字段注解时,被 import
模块的 vpi 一概尚未注入 ⇒ 包重导出别名 entry 不存在 ⇒ 字段侧票名保留包前缀并被
冻结进结构体布局,与阶段 A 构造函数侧的真定义前缀分裂。

删除 96c1102 / 3b8a2b2 引入的全部临时打印(VpiReader.vp / TypeGenResolve.vp /
CallGenCtor.vp 三处),代码回到插桩前状态(-108/+0)。
2026-10-02 00:59:44 +08:00
TermiNexus 3b8a2b225f debug(stub): 补全 [DBG-P7] 插桩覆盖所有票名产生路径(定位后删除)
在 96c1102 基础上把"可能产出该票名"的路径一次打全,保证一次重建即可定死根因:

- TypeGenResolve._class_true_def_sha1:MISS 时额外 dump 结构体表里所有名字含
  ClassDef 的条目(下标/名字/归属 sha1/Ty 的 IR 名前缀)——直接看出别名 entry
  到底有没有、挂在哪个 sha1 上。
- TypeGenResolve.extract_class_name_from_annotation:AnnotClassName 通道算出的
  泛型票名(含 ClassDef 才打)。
- TypeGenResolve._resolve_generic_subscript_ty:注解/字段侧算出的泛型特化名
  gen_mangled(含 ClassDef 才打)。
- CallGenCtor._extract_type_args_from_slice:构造函数侧实参串的 raw/norm 两态。
- VpiReader._inject_class_struct_declare:进入 + 各出口
  (already / renum_skip / field_unresolved / zero_fields / registered)。
- VpiReader._inject_reexport_class_declare:调用现场与四个出口
  (already / no_src_entry / alias_reg_fail / alias_ok)。
2026-10-02 00:34:38 +08:00