Commit Graph
753 Commits
Author SHA1 Message Date
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 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 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 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
TermiNexus 96dad309ac fix(classdef): 值类型字段补完整结构体定义,修复跨模块嵌套结构体 unsized 导致 llc GEP 报错
现场:Test/ThreadingTest 编译 includes/condition.vp 时 llc 报「base element of getelementptr must be sized」:getelementptr %Condition, %Condition* %1, i32 0, i32 1。

根因:ClassGenDef 定义类时对字段类型一律只调 module_ensure_opaque_for_type(仅 opaque 声明)。当字段是**值类型**跨模块结构体时,本类体内嵌的成员在 IR 中仍是 opaque ⇒ 成员 unsized ⇒ 本类 unsized ⇒ 本模块内对本类做带字段下标的 GEP 时 llc 报错。现场物证:condition.vp 的 .ll 里 CONDITION_VARIABLE/CRITICAL_SECTION = type opaque,而 Condition = type {CV, CS}。

修复:指针字段维持 opaque(指向物无需在本模块有体);非指针(值类型结构体/结构体数组)改调 ensure_struct_def_in_module 复制完整定义,并配合 _ensure_field_types_in_module 覆盖数组元素。
2026-10-03 15:58:48 +08:00
TermiNexus 28b7437e21 fix(generic): 泛型类构造 Call 实参推断同步收紧,抽出共用精确映射
CallGenCtor._infer_generic_ctor_type_arg 的 Call 分支此前与泛型函数路径同款名字子串猜测(含 Int→int、Float→double),把 CUInt64T/CInt16T 静默归成 int=i32、CFloat32T 猜成 double。改为:把被调表达式交给注解解析器,命中标量才据精确位宽映射;非标量/不可解析仍 fail-fast(保持原有"明确的类型意图却无法解析"报错)。

新增 ClassGenGeneric.infer_scalar_type_arg_from_llvm_ty 作为两处共用的唯一入口(内部走 _infer_scalar_type_name_from_spec),泛型函数路径一并改为调用它,消除重复的 arena/SpecFromLLVMType 样板,保证两处同口径。
2026-10-03 15:51:12 +08:00
TermiNexus 9a80f1df6c fix(generic): 泛型函数 Call 实参推断改为精确类型解析,移除名字子串猜测
原实现按被调名子串猜类型实参(含 Int→int、Float→double 等),把 CUInt64T/CInt16T 一律归成 int=i32,静默窄化/扩宽位宽(禁止静默默认原则);CFloat32T 也会被猜成 double。

改为:把被调表达式本身交给注解解析器 resolve_annotation_type,命中**标量**才据其精确位宽经 _infer_scalar_type_name_from_spec(唯一真源)映射;非标量(构造/普通函数调用)或不可解析一律返回 None,由调用方汇总后 fail-fast 提示显式标注。行为变化:CUInt64T(x)/CInt16T(x) 等无等位宽裸名的转换实参不再被静默猜成 int。
2026-10-03 15:49:58 +08:00
TermiNexus e196d6a28a fix(类型): 模块限定注解支持 from-import 重导出解析
现场:Test/ThreadingTest/App/main.vp:184 `lock: vthreading.Lock = vthreading.Lock()` 报「变量类型注解解析失败」。vthreading.Lock 是重导出(includes/vthreading.vp `from lock import Lock`),Lock 真定义在 lock.vp;普通模块的 from-import 重导出不像包 __init__ 那样登记别名 entry(VpiReader._inject_reexport_class_declare 仅对包 __init__ 触发),故按 vthreading sha1 查 Lock 恒落空。

resolve_annotation_type 的 Attribute 模块限定分支此前未做真定义模块校正:先按原 sha1 查(既有命中情形逐字不变),未命中时再经 _class_true_def_sha1(唯一真源,已在 _normalize_type_name 规则 4b 使用)校正后重查一次,无证据时原样返回不改变行为。
2026-10-03 15:44:49 +08:00
TermiNexus c035a82394 fix(类型): str/bytes 聚合指针检查豁免字符数组衰减,并统一判据真源
误报现场:includes/os/_win32.vp:207 `name: str = find_data.cFileName`。WIN32_FIND_DATAA.cFileName 是 [260 x i8],字段访问得到 Ptr(Array(i8,260)),其指针在 C 语义下天然衰减为 char*/str,属合法赋值,原判据把 Ptr(Array) 一律当真而误杀。

新增 ExprGenBase._str_rejects_ptr_kind(单一真源:1=结构体/类/联合指针、2=非字符数组指针、3=函数指针、0=可接受;[N x i8] 豁免)供 fail_if_str_annot_agg_ptr 与 CallGenLib 跨模块实参检查共用,消除两处重复的 kind 判定,避免同规则两处演化。
2026-10-03 15:40:01 +08:00
TermiNexus bf2f38acd2 fix(generic): 修正 SpecToLLVMText 返回值判据倒置,恢复内建标量实参的泛型类型实参推断
_infer_scalar_type_name_from_spec 把 SpecToLLVMText 的『0=成功』误判为失败(写成 == 0 就 return None),使该函数对任何内建标量都恒返回 None —— 泛型函数隐式推断中『实参来自内建标量形参/字段』的路径(Name/Attribute 分支)永远推不出,报『无法从实参推断泛型函数 ... 禁止静默默认 int』(现场:GenericOopTest fxi 体内 fxi2(a, b, ...),a: double)。判据改为 != 0(与 ClassGenVTable 同约定)。

同时收紧位宽映射:i16/i64/f16 在 Viper 没有等位宽裸名别名(裸 int=int32、裸 float=float32),原映射 i16/i64->int、half->float 会静默窄化/扩宽位宽(i64->int 即 i64->i32),违反『禁止静默默认/兜底』原则;改为只映射位宽精确对应的形态(i1->bool、i8->char、i32->int、f32->float、f64->double),其余返回 None 交给调用方 fail-fast 提示显式标注。
2026-10-03 15:28:02 +08:00
TermiNexus 09ea7283f9 fix(类型): str/bytes 不再作通用指针通配,补齐实参/赋值/返回三处隐式转换 fail-fast
规则:void*/t.CPtr/rawptr 允许隐式转为任意指针类型,str/bytes 不允许(即便两者在 IR 层同为 i8*)。此前 coerce_to_type 的规则 1(通用指针通配)会把指向结构体/类/数组/函数的指针静默 bitcast 到 str 目标(反向亦然)。

- ExprGenBase:新增 _annot_name_is_bare_str/_annot_is_bare_str(裸 str/bytes 判定,组合段如 str|t.CPtr 不受影响)、fail_if_str_annot_agg_ptr(值是指向聚合类型的指针则 fail-fast,消息 CastError)、fail_if_str_annot_ast_agg_ptr(AST 注解入口)。

- 返回路径 StmtGenCifMixin.translate_return:在类型转换分支之前用 trans.CurFuncRetAnnot 判定,避免被规则 1 静默 bitcast。

- 赋值路径 AssignGenMixin.translate_annassign:四个分支(global / nonlocal / mod_glob / 局部)在 coerce 前用 aa.annotation 判定。

- 同模块实参 CallGenMixin.translate_call:在参数循环前一次性确保本模块 .vpi 参数注解缓存就绪(同跨模块 CallGenLib 键式:模块级函数 cls=None、段下标==形参下标),循环内按 _vpi_param_annot_seg_is 判定裸 str/bytes。
2026-10-03 14:46:57 +08:00
TermiNexus 8af967db7f fix(generic): 泛型类模板类型参数名补缺 + 空上下文 fail-fast,修复特化方法体 T 变 NameError 2026-10-03 14:34:55 +08:00
TermiNexus 98ee53340f feat(call): 跨模块实参加 str/bytes 形参的 fail-fast(str 不作通用指针通配),并加 vpi 注解段等值判定 2026-10-03 14:23:12 +08:00
TermiNexus feb29fa7a3 fix(generic-func): 发射特化调用改传符号名(callee: str)而非 Function*,修复生成空 @ 的非法 IR 2026-10-03 14:18:14 +08:00
TermiNexus df1ffa4c2a refactor(subscript): 删除调用侧下标 zext 与 _zext_index_to_i32,统一交给 build_gep(单一真源) 2026-10-03 13:35:36 +08:00