TermiNexus
a6e1957768
feat(gen): 控制流汇合 Meet(M2.2)
...
- VarGenMixin:life_capture/life_restore/life_join(作用域链快照,池上 [count,(entry,life)…] 数组)。 - StmtGenCifMixin.translate_if:进分支前快照、then 末快照、else 前复位、出口按 min 合并。 - StmtGenMixin:while/for 统一在语句分派处 capture→run→join(一处覆盖全部迭代形态与解糖,含 0 次迭代路径)。
2026-10-08 12:35:59 +08:00
TermiNexus
ec47401151
feat(gen): 生命期标签(LifeTag)与借用传播(M2.1)
...
- GenTypes:新增 define LIFE_VALUE/FRAME/HEAP/STATIC/UNKNOWN 与 VarEntry.Life。 - VarGenMixin:set_var_life/get_var_life/life_meet;add_var 初始化 Life=UNKNOWN。 - AssignGenMixin:life_of_expr(&local、数组退让、变量 Life 读取)、propagate_life(赋值传播)、fail_if_life_escapes(汇点检查,LifetimeError);在 AnnAssign 与单 Name Assign 处挂传播。 - GenApi.fail_if_stack_addr_escape 改为薄壳并委托 fail_if_life_escapes;原 (a)(b) 语法判据并入 life_of_expr。于是 s: str = l; return s 被拦截。
2026-10-08 12:22:10 +08:00
TermiNexus
7070bc1608
feat(gen): 栈地址逃逸检查(LifetimeError)、按值返回聚合、标量→聚合 fail-fast
...
- GenApi.fail_if_stack_addr_escape:禁止把本帧栈地址写出帧外(显式 &local,以及局部数组名退让到指针目标,如 return arr with '-> char*');裸聚合名 + 同型聚合目标是值拷贝,不在其列;err_type 记为 LifetimeError。 - StmtGenCifMixin.translate_return:按值返回聚合时,对被指类型与返回聚合类型同一的指针补 load(与多返回值 struct 的 ret 同形),修复 return 局部数组报 CastError。 - ExprGenBase.coerce_to_type:聚合目标不接受标量(旧行为落成 store i32 0, ptr,只写首元素字节并抬高对齐),改为编译期 fail-fast。
2026-10-08 12:10:13 +08:00
TermiNexus
2ab6342d3c
fix(gen): arg 糖支持转发形态的 va_list
...
_translate_arg_sugar 原本在 trans._va_list_ptr 为 None 时(非变参的 vprintf 式包装函数,如 vsnprintf(buf,size,fmt,args))直接返回 0,转发下来的 va_list 因此读不到;现增加回退:按名 args 取形参 alloca 并 load 出槽内的 va_list 指针(自身变参形态仍用 trans._va_list_ptr,不 load)。点号形式 stdarg.arg(...) 经 ExprGenBase.get_func_name 取属性短名,已天然命中同一分派,未改动。
2026-10-07 20:15:40 +08:00
TermiNexus
c20bd4734b
feat(gen): 值引用自动取址接入虚分派/构造/属性/静态等全部方法调用路径
...
CallGenBase 新增 _vpi_auto_addr_mode(把原先埋在 _coerce_args_to_def_params 里的 vpi 注解解析抽成唯一实现,两处共用)与 _apply_auto_addr_to_call_args(同模块先查 AutoAddrModes,跨模块回退 vpi 注解)。接入原先完全不查表的路径:虚分派(原在 vpi 取址前 return)、_call_method_on_ptr 覆盖的构造 __new__/__init__(含泛型)与 dunder 分派、属性 getter/setter/deleter、静态/类方法、super()、FakeDuck;属性 setter 由 AssignGenMixin 传入 rhs AST 以支持 &T 取左值地址。
2026-10-07 19:59:52 +08:00
TermiNexus
5c1b882169
chore(gen): c.CIf 家族移除报错覆盖 CElif/CElse/CEndif,注释口径统一为 cif
...
ExprGenName / CallGenDispatch 的「已删除拼写」守卫原本只认 CIf/CIfdef/CIfndef,现补齐 CElif/CElse/CEndif 六个(与 TPC 侧一致),报文同步;StmtGenCifMixin 的头注释、docstring 与状态注释把语句统一称作 cif,内部标记仍写作 c.@CIf 族。
2026-10-07 19:10:05 +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
ce50daa87a
refactor(build): 构建产物目录去掉 _mlir 后缀(temp/output)
...
TempDir/OutputDir 回归 {BuildDir}/temp 与 {BuildDir}/output,与 TPC 及项目脚本预期一致;mlir_dir_suffix() 仅保留给 includes 二进制缓存(其布局为 sha1 子目录,与 TPC 的扁平 obj 缓存不同,合并会混淆)。
2026-10-07 19:03:02 +08:00
TermiNexus
3b4bd1c6dc
fix(gen): 跨模块函数作值时不再伪造同名外部全局
...
`serial.puts` 这类模块属性指向的是函数(elf.vp 的 _resolve_symbol 返回它作
函数指针),属性兜底路径却为它造了一个 llvm.mlir.global external @<sha1>.puts,
与已有的 llvm.func @<sha1>.puts 同名,mlir-opt 报 redefinition of symbol named。
改为在伪造之前先精确匹配函数符号(目标模块 sha1 前缀过的函数名与 Function.Name
逐字符相等,避免误命中他模块同名函数),命中则返回函数符号引用本身
(@<mangled>,类型 Ptr(Func),与同模块 &f 分支同一形态),并让属性读路径跳过
对该值的 load(函数地址即值,load 会去读函数体)。
EOF
2026-10-07 15:59:54 +08:00
TermiNexus
edca6c3760
chore(detsite): 类型文本 4096 缓冲补插桩
...
19 处 TypePrint(..., 4096, ...) 对应的 pool.alloc(4096) 全部改用 alloc_tagged
(AssignGenMixin/ClassGenVTable/FuncGenDef/ExprGenBase/ExprGenCdef/CallGenLeafKit/
TypeGenCType/TypeGenResolve/CallGenCBuiltin/ExprGenOps),tag 33..51 见 memhub.vp。
detection==0 时 alloc_tagged 直接转发,无布局与性能变化。
2026-10-07 15:16:52 +08:00
TermiNexus
f3628a797a
fix(global): 修复存储结构体字段零值文本的池缓冲溢出
...
_stg_field_zero_text 分配 160 字节,却用 snprintf(buf, 576, ...) 写出,长类型文本
(如 !llvm.array<8 x i8> zeroinitializer)可越界 415 字节,写穿相邻空闲块的元数据,
触发 [MEM] _fl_pop / [FREEFRAME] 空闲块被写穿(内核编译在 PhaseA 45/50 处中断)。
按实际类型文本长度分配(strlen+24),并把 snprintf 上限与分配对齐。
本文件同时含 3 处 DETSITE 插桩(elem_ty_str_n / ty_str / ty_buf_v)。
2026-10-07 15:16:47 +08:00
TermiNexus
12b15958c6
feat(global): 支持模块级符号地址初始化器
...
新增 init_kind=5(符号地址):分类阶段识别 UnaryOp(AddrOf, Name),不再把它
误送进整数常量提取器;发射阶段取模块作用域里该全局的引用文本(@mangled /
@mangled 带引号两种形式)作为初始化器,MLIR 层渲染为 llvm.mlir.addressof。
类型/操作数/引用目标不合法时按 fail-fast 报错。
复现:_v: int = 1 / _p: rawptr = &_v
修复前报 CDefine value extraction failed(该分支原假设所有 UnaryOp 都是负数/取反字面量)
2026-10-07 14:54:44 +08:00
TermiNexus
5993affd9c
fix(type): const 等限定联合不再被误判为 str*/bytes*
...
_is_ptr_element_annotation 原先只要注解联合里出现 str/bytes 就返回 1(按 i8** 处理,
8 字节元素步长),于是 const str(t.CConst | str,实际仍是 i8*)的下标取到的是指针。
现在要求联合必须带 CPtr 标记(真正的 str*/bytes*)才判定;模块级全局的同一处逻辑
(TranslatorGenMixin)同步收紧。新增 _annotation_has_cptr_marker 供两处复用。
复现:def F(p: str) -> int: / path: const str = p / ch: char = path[i]
-> CastError 指针转整数(形参位置的 const str 一直正常,仅局部/全局错)
2026-10-07 14:35:25 +08:00
TermiNexus
36d23d2f42
feat(build): 实现 Qt 运行时依赖部署(runtime.qt6_path / qt6_dlls / qt6_plugins)
...
背景:project.vpj 里的 runtime 块此前只是声明(编译器不读取),Qr 程序运行时报 Could not find the Qt platform plugin "windows"。
实现:链接成功后(Phase2 的 PhaseC 成功点)调用 BuildPipeline.deploy_runtime_deps(exe_path)——把 qt6_dlls 各项从 <qt6_path>/bin 复制到 exe 同目录;把新增的可选字段 qt6_plugins 各项从 <qt6_path>/plugins 复制到 <exe 目录>/<相对路径>(父目录不存在则 mkdir)。Config.vp 新增 Qt6Path/Qt6Dlls/Qt6Plugins 读取(口径同 LinkerStaticLibs)。
fail-fast:声明了但源文件不存在 / 复制失败 / mkdir 失败 => VLogger.error 并中止构建;三字段全未声明则整段跳过。
验证:重编 SUCCESS(210.11s);ViperMNIST 产物含 7 个 Qt6*.dll + platforms/qwindows.dll,实跑 stderr 无插件报错;ViperAIChat / ViperQtHelloWorld 同样 OK 并完成部署。
2026-10-07 09:08:35 +08:00
TermiNexus
848dc0ab38
fix(compiler): 跨模块调用补全 int→ptr 转换与别名默认参数;类型文本缓冲 512→4096
...
1) CallGenMixin.vp(跨模块 extern 实参提升):指针目标形参改为无条件走 coerce_to_type——原守卫按整数位宽比较,而指针类型的 bits 恒为 0,整段提升被跳过,致 VirtualAlloc(0,...) 以 i32 传入指针形参、mlir-opt 报 operand type mismatch(ViperAIChat 失败)。
2) CallGenMixin.vp(默认参数限定键):改用 StructGen._resolve_module_sha1 解析模块 SHA——原只精确匹配模块名,import x as y 这类别名取不到真实 SHA,默认值表落空、跨模块调用实参数目不符(ViperRequestsTest 失败)。
3) 11 个文件的 TypePrint 类型文本缓冲 512→4096(分配与传入 size 成对修改):48 字段类(如 MNIST 的 Net)的 MLIR 结构体类型文本超过 512 被截断并 fail-fast。
2026-10-07 08:48:09 +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
0cf80632c1
feat(gen): typedef 源文本归一 C 式 const/T*(R16)
...
TPV 的 typedef 注册走裸源码扫描,需与 TPC 同形:_parse_typedef_line 把右值的前导 const/volatile 归一为 t.CConst | / t.CVolatile |、末尾 * 归一为 | t.CPtr;register_ctypedef_from_source 的缓冲 320->512 以容纳展开后的文本。
2026-10-05 20:36:40 +08:00
TermiNexus
374921623b
fix(gen): 补全新语法 &/* 的取地址与解引用路径
...
(*p).attr 属性基址:_get_cderef_attr_base 增加 UnaryOp(Deref) 分支(读写都要求 GEP 指针本身,而非加载后的结构体值)。_is_addrlike_call 增加 AddrOf/Deref 分支:指针型右值不应走模块全局的『静态存储对象拷贝』分支。
2026-10-05 19:58:45 +08:00
TermiNexus
df2de5ecfa
refactor: 去 t.CPtr(&a) 冗余包装(R15)
...
TransPyV 4 文件 / 7 行:Phase/BuildPipeline.vp、core/Gen/AssignGenMixin.vp、core/Gen/TranslatorGenMixin.vp。验证:自举三重重编 SUCCESS + 全量 77 项顺序回归通过。
2026-10-05 17:55:52 +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
aeb4e8e54c
refactor(gen): R12 收尾同步——12 处计数 while 循环改 for range
...
与 includes 同步:<= 条件转 range(expr + 1),并放宽初始化行的紧贴要求(同块内最近一次写即为初始化即可)。其余保守守卫不变。
验证:bootstrap 三重重编 SUCCESS;全量 77/77 顺序回归通过。
2026-10-05 16:36:36 +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
a7b8118ce8
fix(call): c.Set 支持 Starred 解引用目标(*p 在实参位被解析为 Starred)
...
新规范把 c.Set(c.Deref(p), v) 改写成 c.Set(*p, v),而实参位的 '*' 由 ast/parser.vp 解析为 Starred(value=p, ctx=Load),translate_c_set 只认 c.Deref/Call 与 Name 形态 ⇒ 整条 store 被静默丢弃。
后果:zlib 侧 includes 全部 47 处 c.Set(*out_len/*out/*length/*cap/*buf/*best_dist/*p_done, ...) 失效 —— 压缩结果长度恒为 0(decompress 报 Z_DATA_ERROR -3),ZlibTest 运行期 0xC0000005。现按 UnaryOp/Deref 与 Starred 两种形态统一走解引用写入,并对非指针目标 fail-fast。
2026-10-05 14:35:50 +08:00
TermiNexus
87b24c2445
fix(type): resolve_typedef_or_map 补齐裸内建别名,修复 int(x, t.CPtr) 类型解析
...
裸名 str/bytes/int/char/bool/float/double/void 在 map_t_type 中只有 t.CXXX 拼写,导致 _tc_h4 的双参指针包装分支拿不到 bare_ty,落回外部函数返回类型兜底并 fail-fast(argparse.vp:93 c.Deref(int(uint64(ptr), t.CPtr)) 报 TypeError: int)。
2026-10-05 14:14:29 +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
a2874a14e6
chore(tpv): 移除 --allow-multiple-definition 兜底并同步缺省链接参数
...
main.vp 的缺省 linker flags 与 ViperBuild 内置 _c_linker 默认值去掉 -Wl,--allow-multiple-definition,与 project.vpj 同口径;Phase2 三处引用该 flag 的注释改为描述链接器选 main / 链接前按路径去重的实际机制。重建验证:跨模块内联优化完成、链接成功 139.17s。
2026-10-05 09:22:58 +08:00
TermiNexus
e79ea010b0
fix(tpv): 消除 PYI_BUF_SIZE 跨模块重复全局并去掉 --allow-multiple-definition 兜底
...
Phase1 与 BuildPipeline 各自把 PYI_BUF_SIZE 声明为模块级全局,模块级全局走裸名符号(类 C extern 全局语义),两模块各发一份强定义 @PYI_BUF_SIZE,llvm-link 报 symbol multiply defined 并回退到单独编译。改为编译期宏 define PYI_BUF_SIZE = 262144(与同文件 define SRC_BUF_SIZE 同口径,不产生符号),同步更新引用该符号的非 CDefine 示例注释。project.vpj 移除 -Wl,--allow-multiple-definition 兜底。验证:跨模块内联优化完成,最终链接无该 flag 成功(161.70s);TransPyV 自举产物顺序回归 77/77 全通过。
2026-10-05 09:16:12 +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
9717ce0107
feat(traceback): 运行期调用栈显示 callsite 行号(编译器旁文件 + 链接后 objdump 归一)
...
MLIR 后端下 mlirlite 只记录 DI 不输出、且 mlir-translate 不产 !dbg(实测),
导致我方 .vp 函数在最终 exe 无任何 .debug_line(<exe>.stackmap 只剩 mingw CRT
的 C 源记录)→ 用户代码帧只能显示 line 0。
改为 Route A:--traceback 时编译器记录每函数(F)与每次调用(C,含调用点行),
写 <sha1>.vpcall;链接后 WriteStackMap 用 llvm-objdump 反汇编,把 callq 的
返回地址 RVA 按 (调用方,被调方,出现序号) 匹配到调用点行,并在函数入口写定义行
兜底;合并进现有 .stackmap 格式。运行期 traceback.vp 不改。
验收:PtrOpProbe --traceback 生成 427 条我方记录(抽查 main 的 malloc/printf
等行号与源码逐一吻合);非 --traceback 构建零旁文件、产物与运行结果不变。
2026-10-04 22:38:02 +08:00
TermiNexus
4236127956
fix(tpv): f-string 隐式 snprintf 声明形参 buf/fmt 用 i8* 而非裸 i8
...
f-string 降级为 snprintf 时按"隐式提供"原则在使用点补 declare,但三段固定
参数里的 buf/fmt 误写成数组元素类型 i8(应为指针 i8*),与调用侧传入的
buf_ptr/fmt_ptr(i8*)不匹配 → MLIR 'llvm.call' operand type mismatch
'!llvm.ptr' != 'i8'(ZlibDbg 编译失败根因)。改为 Ptr(i8)。
2026-10-04 20:51:38 +08:00
TermiNexus
68cd5f2f90
fix(tpv): __new__ 截断条件放宽到 nn_pc>=1(源侧 __new__ 可无参数)
...
OopInheritTest 报:
error: 'llvm.call' op incorrect number of operands (4) for callee (expecting: 1)
%16 = llvm.call @"...Vec3.__new__(%0, %5, %10, %15) : (!llvm.ptr, f64, f64, f64) -> !llvm.ptr
源码 `def __new__() -> 'Vec3' | CPtr:` 无参数(TransPyV 只注入 self),
__init__(self, x, y, z) 才收 x/y/z。上一提交的截断条件写成 nn_pc > 1,
nn_pc == 1 时被跳过 ⇒ 仍多传 3 个。放宽为 nn_pc >= 1(裁到只传 self)。
验证(均已跑通):
- OopInheritTest:PhaseB 编译完成 → PhaseC 产出 OopInheritTest.exe → 完成
- SlotsBugTest:同上(无回归)
2026-10-04 20:15:37 +08:00
TermiNexus
58cfe2346e
fix(tpv): __new__ 调用按被调方签名截掉多余尾参
...
mlir-opt 报:
error: 'llvm.call' op incorrect number of operands (8) for callee (expecting: 7)
%245 = llvm.call @a959d1abdb31a471.FunctionDef.__new__(%35, %239, %240,
%241, %242, %243, %is_async, %244) : (...) -> !llvm.ptr
定义/声明侧(ast/stmts.vp vpi 核实):
FunctionDef.__new__(self, pool, name, args, decorator_list, returns, is_async)
= 7 个形参(非-self 6)
FunctionDef.__init__(..., is_async, type_params = None)
= 8 个形参(非-self 7,多出的 type_params 有默认值)
根因:构造器路径把 ctor 实参**全量**转发给 __new__,而 __new__ 的签名比
__init__ 短(无 type_params)⇒ 调用点传了 7 个非-self 实参,声明只收 6 个。
(临时探针实测:mdf_param_count=6 正确、封参逻辑未触发,extra_count=7 才是不匹配源。)
修复:_call_method_on_ptr 中对 method_name == "__new__" 且已找到 declare 时,按被调方
非-self 形参数截掉多余**尾参**(这些尾参 __new__ 本就不接收,语义上由 __init__
消费;__new__ 只负责分配存储)。探针已删除。
验证:python ./TransPyC/Projectrans.py --project ./TransPyV/project.vpj --clean
--rebuild-includes --clear-cache 重编通过;
./TransPyV/output/TransPyV.exe --project ./Test/SlotsBugTest/project.json
PhaseB 编译完成 → PhaseC 产出 SlotsBugTest.exe → TransPyV 完成。
2026-10-04 20:09:21 +08:00
TermiNexus
6a6cae2a44
fix(tpv): 模块限定调用优先用 vpi 定义侧形参类型,Win32 白名单降为兜底
...
mlir-opt 报:
error: 'llvm.call' op operand type mismatch for operand 2: 'i64' != 'i32'
%5 = llvm.call @VirtualAlloc(%c6, %2, %3, %4) : (!llvm.ptr, i64, i64, i64) -> !llvm.ptr
声明(真值):extern def VirtualAlloc(VOIDPTR, sizet, ULONG, ULONG) -> VOIDPTR
⇒ llvm.func @VirtualAlloc(!llvm.ptr, i64, i32, i32)
根因:调用点 found_func 为 None 时用 `_get_external_func_param_ty` 硬编码白名单,
它把 Win32 API 的**所有**非指针参数一律当 i64(注释依据"DWORD/ULONG 在 stubs 里
被映射为 i64"的旧口径),而现实中 ULONG → i32 ⇒ 字面量被 sext 到 i64,与声明
i32 不匹配。
修复:CallGenMixin 的参数 coerce 分支(found_func is None)改为**模块限定调用
先用定义侧 vpi 形参注解**(`_resolve_vpi_param_annot_seg`,模块级函数段下标 ==
形参下标)取真实类型;拿不到注解才回退白名单。CallGenLib 的该函数补注释,
标明它是**兜底专用**且 Win32 口径已过时。
2026-10-04 18:17:51 +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
94b174c8a0
fix(tpv): 补齐 asm_arg_cap 声明与嵌套数组 element 预算漏改
...
上一条提交(3426139)中两处改动实际未落盘(编辑动作报告成功但文件内容未变),
导致 TransPyC 编译报 NameError: 未定义名称 'asm_arg_cap'。
- CallGenCBuiltin:补 asm_arg_cap 声明(按操作数个数给足内联汇编实参表容量),
args_buf 改用该容量分配(此前 4 处用法已改为 asm_arg_cap,声明却缺席)
- TranslatorGenMixin:嵌套数组 element 预算 192 → 768(含子数组类型前缀)
2026-10-03 21:17:41 +08:00
TermiNexus
3426139d03
fix(mlir): TypePrint 输出缓冲按 MLIR 类型长度放大;初始化器文本按类型长度给足
...
MLIR 类型文本内联具名结构体完整字段体(可达数百字节),旧的短缓冲会截断类型
文本、产出畸形 MLIR(mlirlite 侧 TypePrint 现已对截断响亮报错,此处补齐容量)。
- 10 处 TypePrint 调用点及其缓冲统一放大到 512:
AssignGenMixin / TranslatorGenMixin / CallGenCBuiltin(×2) / CallGenLeafKit /
ClassGenVTable / ExprGenBase / ExprGenOps(×4) / FuncGenDef / TypeGenResolve(×2)
- TranslatorGenMixin:
- _stg_field_zero_text 缓冲 160 → 576(元素 = 类型前缀 + 值)
- _default_val_const_text 缓冲 48 → 576
- 嵌套数组 element 预算 192 → 768(含子数组类型前缀)
- storage 结构体 element 预算 160 → 576
- CallGenCBuiltin:内联汇编实参表按操作数个数分配(原固定 512,一个结构体
操作数即溢出)、汇编行缓冲按实际长度分配
2026-10-03 21:08:30 +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
cbf76cd468
fix(callgen): text.ll 返回类型回退支持 MLIR 形态 llvm.func
...
- _CacheModuleRetTyTexts 同时认 define 行与 mlirlite 的 llvm.func 行(含缩进/void 省略 ->/变参)
- 缓存值以 '#' 前缀标记 MLIR 形态,命中时用新增 _ParseMlirRetTyStr 解析
- _ParseMlirRetTyStr 覆盖 none/iN/f16..f128/!llvm.ptr/!llvm.array/!llvm.struct(具名按登记表回查,未登记返回 None 不臆造)
- 背景:单端 MLIR 后 text.ll 无 define 行,回退恒空 ⇒ 指针返回值退回默认 i32 被 inttoptr 截断
2026-10-03 19:45:47 +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
1dcd29db9c
fix(phaseb): llc 并行失败按阶段定位,不再一律报 llc 编译失败
...
- LlcTask 追加 FailStage 字段(0=未失败/1=mlir-opt/2=mlir-translate/3=ASan opt/4=llc),worker 在各步失败时写入
- run_llc_parallel 按 FailStage 打印真正失败的阶段名与对应命令:MLIR 后端下 mlir-opt/mlir-translate 失败此前被误指为 llc(现场 .ll 含 LLVM IR 时 mlir-opt 报 unexpected character,日志却指向 llc)
- 字段追加在结尾,所有 stride/memset 均按 LlcTask.__sizeof__() 计算,既有偏移不变
2026-10-03 19:01:50 +08:00
TermiNexus
cda4cca805
refactor(generic): 类型实参符号判定复用 spec_sign_of_annot
...
- 两处 Call 推断由 SpecSignFromTypeNameSpan 改为 TypeGenCType.spec_sign_of_annot,复用注解侧唯一真源(精确名白名单 + CTypedef 链逐层展开)
- 收益:别名(uint64/size_t/WCHAR->WORD->uint16 等)也能判出符号性,不再是裸白名单的 UNKNOWN
2026-10-03 18:20:42 +08:00
TermiNexus
2ac412c11a
feat(generic): 泛型实参推断补齐全部内建标量位宽的精确票名
...
- 整型按 位宽×符号性 全覆盖:i8 -> t.CUInt8T/char、i32 -> t.CUInt32T/int,i16/i64 维持 t.CUInt16T/t.CInt16T、t.CUInt64T/t.CInt64T
- 浮点补 half -> t.CFloat16T、fp128 -> t.CFloat128T(原仅 float/double,其余返回 None)
- 票名与 TypeGenResolve.map_t_type 的可解析名一一对应;无符号一律不走裸名(避免静默变号),位宽无裸名别名且符号未知时返回 None(宁缺毋错)
2026-10-03 18:19:53 +08:00
TermiNexus
f9ba391236
feat(generic): 无符号 i32 泛型实参改发精确票名 t.CUInt32T
...
- _infer_scalar_type_name_from_spec 对 i32 增加符号性分支:无符号(CUInt32T/CSizeT/CUIntPtrT 等)发 t.CUInt32T,有符号/未知保持裸名 int(位宽无误且与历史逐字一致)
- 修复 CUInt32T 实参经泛型推断被静默变号为 int 的问题
2026-10-03 18:18:21 +08:00
TermiNexus
21436b2690
feat(generic): 泛型实参推断为无裸名别名的整型位宽补精确票名
...
- _infer_scalar_type_name_from_spec 支持 i64/i16 -> t.CUInt64T/t.CInt64T、t.CUInt16T/t.CInt16T;符号性未知时不猜(返回 None)
- infer_scalar_type_arg_from_llvm_ty 增加 sign 参数:LLVM 类型层无法区分 iN/uN,符号性由被调名源码文本经 SpecSignFromTypeNameSpan 判定
- 泛型函数与泛型类构造两处 Call 推断同步传符号性,修复 GenericOopTest fxi2 第 3 个类型实参(CUInt64T)推断失败
2026-10-03 17:12:47 +08:00
TermiNexus
ddb1e6cc2a
fix(类型): get_type_size_bytes 补浮点位宽,修复浮点泛型实参的 __sizeof__ 尺寸解析
...
现象:Test/VectorGenericTest/App/vectortest.vp:32 vector.Vector[CFloat64T] 特化时 vector.vp:12 T.__sizeof__() 报 "NameError: 未定义名称 T(当前泛型上下文: 类型形参 1 个 / 类型实参 1 个)" —— 新增诊断证明上下文是好的(T 能换成 CFloat64T),故问题在 __sizeof__ 快径没接住。
根因:get_type_size_bytes 只用 get_llvm_type_bits 取位宽,而该函数只认整数(Float/Double/Half/FP128 一律返回 0)⇒ 浮点 typedef(CFloat64T 经 map_t_type 已正确解析为 Double)被判"尺寸未知"返回 0 ⇒ CallGenDispatch._tc_h5_sizeof_len_isinst 的尺寸表也不含 CFloat64T(只有 CInt/CDouble/CFloat 等)⇒ 落回"回退 2"把接收者 Name(T) 当实例翻译 → NameError。同文件第 15 行 Vector[CInt] 走整数路径正常,故只有浮点特化暴露(不对称现象由此解释)。
修复:整数位宽为 0 时再取 get_llvm_float_bits(浮点位宽),两者皆 0 才返回 0。
2026-10-03 16:50:42 +08:00
TermiNexus
3a4323e288
feat(generic): 特化上下文自检 fail-fast + NameError 附泛型上下文诊断
...
背景:VectorGenericTest 在第 32 行 vector.Vector[CFloat64T] 特化时仍报 "NameError: 未定义名称 T"(8af967d 的类模板 tp 名补缺只能覆盖 tp 名缺失那一种,这里 tp 名在场)。静态读完 6 个 _specialize_generic_class 调用点与 ClassGenDispatch 的 __sizeof__ 快径后,无法确定是"上下文没建"还是"建了装不上",故加两处诊断。
1) ClassGenGeneric._specialize_generic_class 在 set_generic_context 之后立刻自检:类型实参个数必须等于模板类型形参个数,且首形参必须能解析成具体类型名;否则 fatal_error 点出类名与特化键(含实参),替代下游 12 行之外那句脱节的未定义名称。
2) ExprGenName 未定义名称报文追加当前泛型上下文(类型形参 N 个 / 类型实参 M 个):形参 0 个=上下文没建,形参>0 且实参 0 个=实参表丢了,皆>0=上下文在但该名不在其中,一眼可分。
2026-10-03 16:38:01 +08:00
TermiNexus
da18dd39a4
fix(classdef): 已注册类早退路径补字段类型完整定义
...
上一条(96dad30)只改了"全新定义"路径的字段扫描循环,但 includes 在 Phase A 预注册、Phase B 重新翻译时走的是 existing 早退分支(ClassGenDef 117-167,只 module_add_named_type 后即 return 0),字段循环根本不执行 ⇒ includes/condition.vp 的 Condition 仍内嵌 opaque 成员、自身 unsized,llc 仍报 base element of getelementptr must be sized。
物证:同一构建里 ThreadingTest 的 main.vp(fb785af4a2aa1a46.ll)因按需调 ensure_struct_def_in_module,已正确拷入 CRITICAL_SECTION/CONDITION_VARIABLE/SRWLOCK 的完整定义;而定义它们的 condition.vp 自身(de351f55b29d33a3.ll)没有 ⇒ 只有定义模块自身体内 GEP 时才暴露。
修复:早退分支在 module_add_named_type 后补调 _ensure_field_types_in_module(Struct/Array 值类型递归补完整定义、Ptr 补 opaque),与全新定义路径同口径。
2026-10-03 16:05:24 +08:00