Commit Graph
100 Commits
Author SHA1 Message Date
TermiNexus c0d56b127d chore(comments): includes 头注释英文化(R11 收尾)
把 includes 下 64 个 .vp 的文件头注释(含 traceback.vp 第 13-427 行的整块文件级说明)以及 2 处漏网的正文中文注释(ast/lexer.vp、json/__writer.vp)与 1 处中文 docstring(memhub.vp)逐行译为英文;同步把 fltk/gen_ffi.py 的生成模板与其自身注释英文化,使重新生成仍为英文。

只改注释/文档串文字:行数与代码逐字节不变(骨架比对 140 文件漂移 0),运行时中文字符串字面量 305 处保持原样。验证:三重重编 SUCCESS(170.21s)+ 全量 77/77 顺序回归通过 + VET 编译 SUCCESS / --search-paths 7 条 exit 0。
2026-10-06 09:42:25 +08:00
TermiNexus 14ba84db8e chore(syntax): R1 typedef 右值改用 T*(21 处)
编译器已支持 typedef 右值类型位(305242aa),故解除 R1 的 typedef 右值例外:stdint.vp 19 处(INTPTR/BYTEPTR/CHARPTR/WCHARPTR/*PTR 等)、stdarg.vp 1 处(va_list)改为 T*,AST 与 T | t.CPtr 逐字段同形。
2026-10-05 20:58:38 +08:00
TermiNexus af59a752cd chore(syntax): R16 完整 C 式 const/volatile 迁移
把剩余 t.CConst | X 全部改写为前缀描述符 const X(AST 逐字段同形):

- t.CConst | VOIDPTR -> const VOIDPTR(win32console/win32file/win32memory 共 7 处);

- char | t.CConst* -> const str(winsock2 x2);t.CConst | BYTEPTR -> const BYTEPTR(zinflate);

- typedef 右值:LPCSTR = const str、LPCWSTR = const uint16*(stdint/win32base);

- parser.vp:typedef 右值按类型位解析(_IsCTypedefAnnotation),typedef X = T 语法糖同一条。
2026-10-05 20:36:35 +08:00
TermiNexus 03450a71ff fix(mlirlite): 局部窥孔优化每个函数体只执行一次
PrintModule 会按 STUB/TEXT/FULL 三次 dump 同一模块,而 FunctionPrint 每次都跑 _peephole_opt;T2(entry-slot store→load 转发)不是幂等变换,第二遍会误删仍有 load 指向的 entry alloca,留下悬空 SSA 名(mlir-opt: op using value defined outside the region)。给 Function 加 PeepDone 守卫,优化只作用于 builder 产出的原始文本。
2026-10-05 19:58:39 +08:00
TermiNexus c4170871c2 refactor: 去 t.CPtr(&a) 冗余包装(R15)
规范第 15 行:&a 已返回 T*,无需再 t.CPtr 强转。仅改单参且操作数为普通变量名的形态(t.CPtr(v) / t.CPtr(0) 等非取地址形态保留)。includes 5 文件 / 23 行:w32/fileio.vp、os/_posix.vp、os/_win32.vp、shutil.vp、subprocess.vp。验证:TPC 自举三重重编 SUCCESS;全量 77 项顺序回归通过。
2026-10-05 17:55:43 +08:00
TermiNexus 0055ab7ea7 refactor: rawptr[T] -> T* 与 t.CConst 前缀迁移(R14/R16)
R14:rawptr[X] -> X*(41 文件 / 2037 行改动),X 含模块限定名与嵌套下标(rawptr[GSList[NameEntry]] -> GSList[NameEntry]*)。保留 6 处 rawptr[t.CPtr](规范例外:存纯裸指针);# 注释与字符串里的 rawptr[...] 属元语法描述,未动。 R16(保守子集):t.CConst | str/bytes -> const str/bytes,t.CConst | char | t.CPtr -> const str;typedef 右值位置豁免(const str 在该处无法注册,与 R1 同源)。 验证:TPC 自举三重重编 SUCCESS;TransPyV.exe 全量 77/77 顺序回归通过。
2026-10-05 17:38:21 +08:00
TermiNexus 0ef4ba9634 refactor(includes): R12 收尾——再改 48 处可确定安全的计数 while 循环
在 R12 保守判定基础上放宽两处(仍保证语义等价):1) 允许 <= 条件,改写为 range(expr + 1)(while 结束后计数器为 n+1、for range 后为 n,已被「循环后不引用计数器」守卫覆盖);2) 初始化行只要求是「同块内最近一次对计数器的写入」,不再要求紧贴 while(中间不得读写该计数器)。

其余守卫不变:界表达式必须裸(无 and/or/比较)、体内无 continue、体内仅末尾一次 += 1、无嵌套重绑定、无 while-else、循环后同一函数内不再引用计数器。TransPyV 侧同步 12 处。

验证:bootstrap 三重重编 SUCCESS(无 vast_c 解析回退);全量 77/77 顺序回归通过。
2026-10-05 16:36:36 +08:00
TermiNexus e71daeea0e docs(includes): R11 注释英文化——75 个文件的中文注释改写为英文短注释
按规范「注释只讲解作用,不掺杂历史原因,尽量英文」:把 includes 下 75 个 .vp 的中文 # 注释与三引号 docstring 改写为英文,每个注释块压到 2 行以内。

保留要点:作用、约束、危险警告(不得/必须/注意)、ABI 与类型约定(如 BYTEPTR | t.CPtr = i8** 的跨模块坍缩坑)、位宽/长度约定、fail-fast 要求、内存与句柄所有权。

未动:文件头注释(规范豁免,仍是中文)、运行时中文字符串常量(printf / fatal_error / MlirFail 等用户可见消息,属代码字面量)。

验证:独立脚本比对 HEAD 与工作区的代码骨架(剥离 # 注释与三引号 docstring 后的非空行)——75 个文件逐字节一致;行尾 CRLF/LF 未被改动;全文剩余中文仅 547 行头注释、0 条行尾注释。bootstrap 三重重编 SUCCESS;全量 77/77 顺序回归通过。
2026-10-05 16:18:44 +08:00
TermiNexus 27121f56a7 refactor(includes): R12 下标 while 循环改 for range,R13 c.Set 迁移为赋值
R12(wiki/新规范 L27-39):把「i: int = 0 与 while i < N: … i += 1」形式的下标循环改写为「for i in range(N):」。保守判定:仅当条件为裸 NAME < EXPR、循环体无 continue、NAME 在体内无其它赋值、无嵌套重绑定、循环后同层不再引用 NAME 时才改写。共 269 处 / 48 文件。

R13:c.Set 是正在退化的路径——c.Set(*p, v) 期望写作 *p = v,c.Set(a, b) 等于 a = b。本次把 includes 内 45 处 c.Set 全部迁移为赋值,includes 已无 c.Set 调用。

验证:bootstrap 三重重编 SUCCESS(无 vast_c 解析回退);全量 77/77 顺序回归通过;ZlibTest 内部断言 79 passed / 0 failed。
2026-10-05 15:33:52 +08:00
TermiNexus 3e1ed0992b fix(ast): 修正实参位前导 * 的优先级,*p + n 解析为 (*p) + n
规范 rule 5 允许把 c.Deref(x) 写作 *x,但语法分析器在实参位置对前导 * 取整条表达式作为操作数:*buf + *length 被解析成 *(buf + *length),*length + data_len 成 *(length + data_len),多解引用一层。表现为 zlib decompressobj 全部失效(decompress 返回 0 字节、eof 恒 0、unused_data 取不到),requests/download 同类语句亦受影响。

改为:实参位 *expr 只按 _parse_factor 取紧绑定操作数,经新增 Parser.starred_seed 挂起,由 _parse_factor 顶部接手,再交由上层续接二元运算。*p[0](即 *(p[0]))、*p**2(即 *(p**2))等结合性保持原 C/Python 语义。

验证:全量 77/77 顺序回归一次通过;ZlibTest 内部断言由 74 passed / 6 failed 变为 79 passed / 0 failed。
2026-10-05 15:04:01 +08:00
TermiNexus e80284a6d5 refactor: 全量迁移 includes 到新规范语法
按根目录 新规范 迁移 R1/R2/R3/R4/R6/R7/R8/R9:指针 T* 后缀、内建类型短别名、c.Addr/c.Deref 单目化、c.Asm 改 __asm__、t.CDefine 改 define 软关键字、t.CEnum 改 enum。R4 对内建 cast 多参实参保留 c.Deref 原写法(单目化会致 TPC 类型退化)。验证:includes 52/52 编译通过,TransPyV 自举产物顺序回归 77/77 全通过。
2026-10-05 09:04:46 +08:00
TermiNexus aecdf27132 feat(mlirlite): 新增调用点记录 API 供 --traceback 旁文件(关闭时零开销)
新增 DebugSetEnabled / DebugNoteFunc / DebugClearFunc / DebugNoteLine /
DebugResetFunc / DebugTakeText 与内部 _DebugNoteCall;build_call 在启用时把
(调用方, 被调方, 当前源行) 追加到可增长文本缓冲,供每模块 DebugTakeText 取出
写 .vpcall。默认(未开 --traceback)不启用,输出不变。
2026-10-04 22:38:07 +08:00
TermiNexus 5dad869a40 fix(mlir): 全局初值 region 草稿缓冲改为单次 PrintModule 复用,修子池耗尽
每个全局初值 region 逐全局 alloc leaf/ins 各 32 KiB、每个初值节点 alloc
4 KiB 类型/符号草稿且从不释放:结构体/vtable 全局多的模块(MLIRLiteTest
#12)在约 2 MiB 模块子池上耗尽,报"零初值类型缓冲分配失败"。

改为按 PrintModule 惰性分配一组复用草稿(leaf/ins/类型/符号/路径栈),
跨全局、跨节点共享;PrintModule 入口 MlirGvResetScratch 使上次草稿失效,
下次按当前池重建(绝不复用已释放/被复用地址的池,避免悬空写穿 canary)。
下标路径改按递归深度分槽的复用栈,不再逐节点分配。
2026-10-04 21:09:36 +08:00
TermiNexus 68fe839da9 fix(mlir): 类型文本缓冲成对扩容(scratch 尺寸 + 各处 cap)
重编 TransPyV 自身时触发类型文本截断护栏:
  [MLIR-FAIL] MLIR 渲染: 类型文本超出输出缓冲被截断(该处缓冲过小,需按类型长度增大)
  (PhaseA ./TransPyV/App/lib/core/CompilerFactory.vp)

根因:内联具名结构体在使用处展开完整字段体,类型文本可达数百字节,而
_append_cstr / MlirTypeText / TypePrint / _MlirTypePrintDepth 的定长
cap(256/512/1024/2048)与对应 scratch 缓冲偏小。

修复(cap 与底层缓冲**成对**放大,保证 cap ≤ 缓冲,绝不越界):
- _MlirTablesInit:_SC_Ty/_SC_Ty2/_SC_Mt/_SC_Buf/_SC_B1/_SC_B2 512→4096、
  _SC_Tmp2/_SC_IdxT 1024→4096、_SC_ArgTs 2048→8192、_SC_Tmp 4096→8192;
- 以"别名 → 缓冲尺寸"追踪脚本放大各调用点 cap(77 处,含被当作 cap 缓冲使用的
  pool.alloc 同步 512/1024→4096),如 _MlirGep 的 idxt/bmt、_MlirCall 的
  argts/rmt/vftys、_MlirNamedStructAppend/TypePrint 的 tmp/rfb/tmp3 等;
- __builder.vp 的 _TY_TEXT_CAP 512→2048(类型文本内嵌缓冲 + cap;arg_cap 由它
  推导,不宜过高以免多参调用单次分配逼近模块池单块上限)。
2026-10-04 19:56:42 +08:00
TermiNexus bca0107240 fix(mlir): 模块缩进辅助缓冲改为池可服务的最大单块 1048560(1 MiB − 16)
256 KiB 对个别大函数偏小,触发自己加的截断护栏:
  [MLIR-FAIL] MLIR 渲染: 输出文本超出缓冲被截断(需增大 dump_ir/FunctionPrint 的缓冲)

模块池(~2 MiB 子池)max_order=15 ⇒ 单个 buddy 块最大 1 MiB,减去 16 字节块头
⇒ 单次 alloc 请求上限 = 1048560。取该值:既不再因 order 16 结构性失败
(1048576 会失败),又给足单函数文本(内联具名结构体使文本显著变长)。
若仍超出,截断由 FunctionPrint/LLVMModulePrint 的截断检查响亮报错。
2026-10-04 18:25:57 +08:00
TermiNexus 1cf7186824 fix(mlir): 模块缩进辅助缓冲 1 MiB → 256 KiB(1 MiB 超出模块池 buddy 上限)
Test 6(ModulePrint)运行期分配失败:
  [MEM] alloc 失败 size=1048576 needed=1048592 order=16 max_order=15
        池容量=2096864

模块池是 ~2 MiB 子池(SUB_POOL_SIZE 2097136),max_order=15 ⇒ 单个 buddy 块
≤ 1 MiB;再加上 16 字节块头,单次 alloc 请求必须 ≤ 1 MiB − 16。请求 1048576
被判需 order 16 ⇒ **结构性失败**(与池内剩余空间多少无关)。

改为 256 KiB:实测最大单成员文本仅 ~54 KB(670 KB 模块 / 12296 行 / 最大函数
991 行,平均 ~54 B/行),余量 ~4.7×;且只需 order 14(512 KiB 块)。
截断仍由 FunctionPrint/LLVMModulePrint 的截断检查响亮报错。
2026-10-03 22:28:34 +08:00
TermiNexus 1860259659 fix(mlir): 具名结构体统一按模块登记定义渲染(同名同体)
mlir-opt 报:
  error: identified type already used with a different body
      %110 = llvm.getelementptr %109[0, 1] : (!llvm.ptr) -> !llvm.ptr,
             !llvm.struct<"0ba5c56e78e3ff23.ParamNode", ()>

同一具名结构体在模块内出现两种体:多数处是 `(!llvm.ptr, !llvm.ptr)`(2 字段),
两处是 `()`(0 字段)。MLIR 的 identified type 要求**同名同体**。

根因:跨模块 stub 构造的**0 字段占位类型对象**被 TypePrint 内联成 `()` 体;
而 `_MlirTypeAppend` 对 `!` 前缀文本(`!llvm.struct<"name", …>`)原样直通,
也不回查登记表。

修复:新增 `_MlirNamedBodyFromTable`(按名字回查登记表,用**模块登记定义**渲染),
两条路径都先回查:
- `_MlirTypeAppend`:`!llvm.struct<"name", …>` 文本命中登记表则改用登记定义重渲;
- `TypePrint` 的 Struct 分支:命中登记表则用登记字段(含 packed 标记)替代自身字段。
未登记(独立 TypePrint / 外在类型)保持原行为(按自身字段内联)。

README §2.10 补"同名同体"硬性约束说明。
2026-10-03 22:18:29 +08:00
TermiNexus f95eb8016b fix(mlir): i1 常量物化用裸布尔关键字(true/false 不带 : i1)
mlir-opt 报:
  error: expected ')'
      %c7 = llvm.mlir.constant(false : i1) : i1

`true`/`false` 是 MLIR 的裸布尔关键字,不能再带类型后缀(其余标量必须写
`值 : 类型`)。

修复两处常量物化:
- `_MlirEmitOneConst`(函数内常量);
- `_MlirGvEmitConst`(全局初值 region 叶子 op)。

README §2.3 常量表补 i1 行。
2026-10-03 22:11:45 +08:00
TermiNexus a7aaed01f4 fix(mlir): LLVM intrinsic 调用改走 llvm.call_intrinsic,声明不输出
mlir-translate 是**程序化构造** LLVM IR,不像 LLVM 的 IR 解析器那样把旧式
intrinsic 名 upgrade 成带类型后缀的形式。原先 `@llvm.va_start` 走普通
llvm.call,且 declare 被原样输出为 `llvm.func @llvm.va_start`,降级得到未
mangle 的 `@llvm.va_start`,LLVM 校验报:

  Intrinsic name not mangled correctly for type arguments!
  Should be: llvm.va_start.p0
  ptr @llvm.va_start

修复:
- `_MlirCall`:裸符号名以 `llvm.` 开头(且非 `llvm.mlir.*`)的调用改渲染为
  `llvm.call_intrinsic "llvm.xxx"(...) : (...) -> ...`,由 mlir-translate
  按操作数类型自动 mangle 名字(llvm.va_start -> llvm.va_start.p0);
- `FunctionPrint`:intrinsic 的 declare **不输出**(否则残留的
  `llvm.func @llvm.va_start` 仍会触发同一校验错误)。

README §2.1 映射表补 intrinsic 行,§2.9 新增 ③′ 说明。
2026-10-03 22:05:30 +08:00
TermiNexus 31fe1bae58 fix(mlir): 补 _MlirModOutTrunc 声明(截断标志此前未落盘)
LLVMModulePrint 已在 bff0f20 使用 global _MlirModOutTrunc,但模块级声明
未随之提交,补上 `_MlirModOutTrunc: int`(否则模块输出截断检查无法编译)。

本文件同时包含一次行尾规范化(mixed -> CRLF),使 diff 显示为全文改动;
忽略空白后实际仅此 1 行内容变化。
2026-10-03 21:33:56 +08:00
TermiNexus aa94d67183 fix(mlir): GEP 常量索引写字面量并修正类型列表
mlir-opt 的 llvm.getelementptr 要求“索引到结构体”的索引必须是常量字面量,
而 _MlirGep 原先把常量索引经 _MlirOperand 物化成 SSA 操作数(%cN),
触发 verifier:
  error: 'llvm.getelementptr' op expected index 1 indexing a struct to be constant

按 MLIR LLVMDialect 的定义修正为官方形态:
- 常量索引 -> 整数字面量([0, 1]),不物化、不占类型位;
- 仅 SSA 索引物化为操作数,其类型进入 (...) 类型列表。

同步修正 README §2.1 映射表(原 [%c0, %c1] : (!llvm.ptr, i32, i32) 形态错误),
并在 §2.3 补充“常量必须物化”的 GEP 索引例外说明。
2026-10-03 21:33:25 +08:00
TermiNexus bff0f20f51 fix(mlir): 模块/函数输出缓冲截断响亮报错 + 缩进辅助缓冲 64 KiB → 1 MiB
dump_ir 的输出缓冲(8/16 MB)此前用 _append_cstr **静默**丢内容 —— MLIR 文本因
内联具名结构体完整字段体而明显长于 LLVM IR,一旦超出就得到被截断的半截模块,
mlir-opt 只会报难以定位的语法错。

- __module.vp:_append_cstr 写入被截断时置 _MlirModOutTrunc;LLVMModulePrint
  结束前检查并 MlirFail;模块缩进辅助缓冲 64 KiB → 1 MiB(tmp_cap),并把该
  缓冲分配失败也改为响亮报错(否则会静默漏印全部模块成员)
- __function.vp:_append_cstr 写入被截断时置 _MlirOutTrunc;FunctionPrint
  三个出口(declare / 无基本块 / 正常结束)均检查并 MlirFail
2026-10-03 21:15:34 +08:00
TermiNexus a502c7242f fix(mlir): 类型文本缓冲按长度给足 + 截断响亮报错(系统性)
根因:MLIR 把具名结构体内联为完整字段体(`!llvm.struct<"名", (i32, !llvm.ptr, …)>`),
单个类型文本可达数百字节,远长于 LLVM 形态的 `%"名"` 引用(十几字节);而 builders
仍按旧的短类型尺寸分配(128/256),指令行里的类型被截断 → 畸形 MLIR。
实测:alloca 行类型被 128 字节缓冲截断,mlir-opt 报
"unbalanced '(' character in pretty dialect name"。

- __types.vp:新增截断溢出标志 _MlirTypeTrunc(_strappend/_MlirAppendN 写入
  被截断时置位),TypePrint / MlirTypeText 渲染后检查并 MlirFail —— 任何截断
  都不再静默产出畸形 MLIR
- __builder.vp:新增 _TY_TEXT_CAP(512)/_LINE_CAP(2560),全部指令行缓冲(alloca
  /ret/load/store/各类 cast/gep/icmp/fcmp/select/atomicrmw/cmpxchg/va_arg/switch
  /case/inline_asm…)改为 _LINE_CAP;build_call / build_call_indirect 的实参表
  与行缓冲按实参个数与实际长度动态分配(原固定 1024/2048 会在两个以上结构体
  实参时静默截断)
- __values.vp:ValuePrint 的类型缓冲 256 → 512
2026-10-03 21:07:55 +08:00
TermiNexus 33d5737f0c feat(mlir): 补齐 f16/f128 浮点位模式物化
ConstFloat 现按类型宽度产出位模式:f16 → 0x%04x(t.CFloat16T 按 half 舍入后取
2 字节)、f32 → 0x%08x、f64 → 0x%016llx、f128 → 高低两个 64 位字拼成 32 位
十六进制(t.CFloat128T 为 double 的无损扩展;c.Load 的宽度取源指针 pointee,
故源显式转成 u64*,避免按 16 字节写入 8 字节目标而越界)。name_buf 由 32 增至
64(f128 文本需 35 字节)。

- _MlirFloatLiteral 接受 f16/f128 原样直通,并新增“位模式位数与类型是否相符”
  强校验(f16/f32/f64/f128 ↔ 4/8/16/32 位十六进制;MLIR 按类型宽度解释该十六进制值)
- README §2.3 常量表 / §5 打印阶段转换说明同步
2026-10-03 20:52:02 +08:00
TermiNexus 597e0e5c4a fix(mlir): ConstFloat 的 f32 位模式改取 float 编码(原取 double 低 32 位)
ConstFloat 以 CDouble 形参接收值,原先 f_bits==32 时直接取 double 位模式的低
32 位当作 f32 位模式 —— 这是错的:3.14 的 double 是 0x40091EB851EB851F,
低 32 位为 0x51EB851F,而 f32 编码应为 0x4048F5C3。
影响以 Float(32) 为类型调用 ConstFloat 的路径(如模块级 t.CFloat 全局初始化
器,TranslatorGenMixin.vp:1014 传 var_ty);指令里的浮点字面量恒以 Double(pool)
创建,不受影响。

- f_bits==32:先 t.CFloat(val) 按 f32 舍入,再 Load 其 4 字节编码
- 更新函数注释:Name 为位模式文本,MLIR FloatAttr 按底层二进制位解释

已知残留(未改,下游会响亮报错):f16/f128 仍按 64 位格式化,宽度与类型不符。
2026-10-03 20:38:27 +08:00
TermiNexus f813c0543b fix(mlir): 浮点常量位模式原样直通,消除 %e 截断精度
MLIR FloatAttr 语法支持十六进制位模式(Builtin Dialect:
`hexadecimal-literal ':' float-type`,按底层二进制位解释),故 ConstFloat 产出的
`0x…` 无需转十进制。此前 _MlirFloatLiteral 把它转成 `%e`(默认 7 位有效数字):
3.141592653589793 → 3.141593e+00,静默截断,与 __values.vp 选位模式的初衷相悖。

- _MlirFloatLiteral:hex 且 mt 为 f32/f64 → 原样返回(无损);
  f16/f128 仍响亮报错(ConstFloat 只产出 64 位位模式,宽度与该两类型不符)
- 删除因此失效的 _MlirParseHexU64
- README §2.3 常量表 / §5 打印阶段转换说明同步
2026-10-03 20:35:37 +08:00
TermiNexus 751e7e7ef7 fix(mlir): 全局嵌套数组/聚合类型前缀走 region;补 MLIR 形态内层前缀剥离
生产者 TranslatorGenMixin._build_array_initializer_text 的嵌套数组初始化器写作
`[!llvm.array<16 x i8>[i8 0, …], …]`(内层类型前缀来自 mlirlite.TypePrint)。
两处缺口叠加导致渲染失败:
1) _MlirGlobalInitNeedsRegion 只按 '@'/'{' 判定是否走 region,嵌套数组被送进
   属性路径 _MlirArrayDenseAt —— 该路径只能表达"值 : 标量类型"的稠密数组,
   内层类型前缀与子 zeroinitializer 都无法表达;
2) _MlirGvWalk 只剥离 LLVM 形态前缀([N x T] / {…}),不认 MLIR 形态
   `!llvm.…` 前缀,元素被当叶子 → 报"全局初值叶子形态 v1 不支持"。

- _MlirGvHasSymOrStruct → _MlirGvArrayNeedsRegion:增认 '!' 前缀,路由到 region
- _MlirGvWalk:新增 MLIR 形态聚合类型前缀剥离(类型记号后紧跟 '[' / '{')
- README §2.5 同步初值两条路径与新增表项
2026-10-03 20:32:56 +08:00
TermiNexus b519269398 fix(mlir): 全局初值支持结构体类型前缀 {…} {…}
_MlirGvWalk 已处理数组类型前缀 `[N x TY][…]`,但 llvm.global_ctors 这类元素写成
`{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }` 时,首个花括号组
(类型)被误当字面量解析,报
[MLIR-FAIL] 全局初值叶子形态 v1 不支持:', void ()*, i8* } { i32 65535, … }]'。

- 新增 _MlirGvIsStructType:按深度配平读完首个花括号组(跳过引号内文本),
  其后非空白记号仍是 '{' ⇒ 前一花括号组是类型前缀(同一元素的花括号组之后
  只会是 ',' / ']' / '}' / 结束,故判据无歧义)
- _MlirGvWalk 增加对应的前缀剥离(与数组类型前缀同款处理)
2026-10-03 20:21:19 +08:00
TermiNexus d37d8520c2 fix(mlir): 类型文本转换直通 MLIR 浮点标量 f16/f32/f64/f128
builders 经 TypePrint 输出的内嵌类型已是 MLIR 形态(见本文件 TypePrint 段说明),
但 _MlirTypeAppend 只对 '!' 前缀原样直通,浮点标量落到兜底 fail:实测
`%0 = alloca f64` 报 [MLIR-FAIL] 无法转换为 MLIR 类型文本(v1 未覆盖该形态):'f64'。

- 补 'f' + 全数字直通(与 LLVM 形态 half/float/double/fp128 分支不冲突)
- 订正函数头注释与 MlirTypeText docstring:中间文本两种形态都接受
  (MLIR 常态直通 / LLVM 形态转写)
2026-10-03 20:12:48 +08:00
TermiNexus 07033094b7 refactor(backend): 删除 includes/llvmlite(单端 MLIR,发射器只留 mlirlite)
- TransPyV 全树已改为 import mlirlite;includes 内无任何模块 import llvmlite,删除后无悬空引用

- mlirlite 的注释保留对 llvmlite 的历史引用(同形孪生来源)
2026-10-03 19:27:11 +08:00
TermiNexus a99e44863d fix(gep): GEP 下标 zext 下沉到 build_gep/build_gep_array(唯一真源),修复窄整数下标被符号扩展导致越界 2026-10-03 13:35:31 +08:00
TermiNexus 99c1ad44c4 fix(mlirlite): 结构体字段链改用 ParamNode 访问器,消除 ParamNode*→Param* CastError
__module.vp 的 _MlirGvWalkStruct 遍历 LLVMType.Struct 字段链(cur 是 ParamNode*),却调用了 __function 的 param_get_ty/param_get_next(形参是 Param*)→ 触发编译器的「非基本类型指针间禁隐式转换」CastError(MLIRLiteTest 根因)。ParamNode(类型树字段节点)与 Param(函数参数,带名/属性)是两个刻意区分的类,不可合并。改为导入并使用 __types 的 paramnode_get_ty/paramnode_get_next;移除 __module.vp 中已无引用的 Param/param_get_ty/param_get_next 导入。未做指针强转(避免掩盖真实类型错误)。
2026-10-03 12:21:33 +08:00
TermiNexus 7bd4cda5be fix(llvmlite): 打印端跳过被同模块定义取代的 external global(消除 redefinition of global)
模块内不变量:同一符号名不得同时打印 external 声明与定义,否则 llc 报 redefinition of global(SysLibTest os/__init__ 的 _mbuddy:循环 import 使 LoadDepVpiIntoModule 把本模块自身 vpi 注入自身 → 先发 external,handle_module_level_var 再发定义)。新增 _module_has_initializer_global:OUTPUT_FULL/STUB/TEXT 三模式对无初值 GV,若模块内存在同名带初值定义则跳过。只处理本模块内同名声明+定义,依赖模块的合法 external(本模块无同名定义)一律保留,不做跨模块去重(与 TransPyC Phase2Translator 合并期 external 去重同构)。
2026-10-03 12:17:39 +08:00
TermiNexus 7f3b3dea1a feat(parser): switch 的 case/default 支持 if 守卫
_parse_switch_case / _parse_switch_default 解析可选 `if <cond>` 并传入 MatchCase.guard(原为直接报错 / 写死 None),与 _parse_match_case 同款写法。
2026-10-03 10:58:53 +08:00
TermiNexus 7b006c96a0 feat(mlirlite): 补齐 Debug Info 同形 API,导出名集与 llvmlite 一致(215=215)
- __module.vp: 新增 DINode/DINamedMeta 类、LLVMModule 追加 6 个 DI 字段(96->144B)、module_add_di_node/module_add_named_metadata 及实例方法、DI_NODE_SIZE/DI_NAMED_SIZE

- __function.vp: Function 追加 DbgRef(80->88B) + function_set_dbg

- __builder.vp: IRBuilder 追加 DbgLoc(32->40B) + set/clear_debug_location 方法 + 顶层 builder_set/clear_debug_location

- __init__.vp: 导出上述 7 个 DI 名字,恢复与 llvmlite 的逐名同形(215=215)

- MLIR 打印阶段忽略 DI:LLVMModulePrint 不输出 !N 元数据、_emit 不读 DbgLoc,保持 MLIR 语法合法(DI 只记录不输出)

- README: 记录 DI 为「同形保留/只记录不输出」,名字数更新为 215
2026-10-03 07:43:03 +08:00
TermiNexus 1e6082afe9 fix(switch): case 标签支持裸名(按值引用)并给出常量标签 fail-fast
- 裸名在 match 里是捕获模式(MatchAs),switch 里对齐 C 的 `case NAME:` 语义,
  三端解析均归一为 MatchValue(Name);`_` 仍作通配(等价 default)
- includes/ast/parser.vp、lib/vast/Parser.py、lib/vast_c/vast_c.c 同步实现
- HandlesMatch:case 标签求值非编译期常量时 fail-fast(原先会因取 .constant 崩成
  AttributeError),报文明确“case 标签必须是编译期常量”
2026-10-03 00:14:51 +08:00
TermiNexus 2c5b39456b feat(ast): 新增 switch 关键字与 switch 语句,match 完全禁止 fallthrough
- tokens.vp:Keyword 表尾追加 Switch / FallThrough,并 intern "switch"/"fallthrough"(既有编号不变)
- stmts.vp:Match 增加 is_switch 字段(switch 语法糖 desugar 的标记);FallThrough 注释改为仅 switch 合法
- parser.vp:match / fallthrough 改为硬关键字分派(去掉软关键字 lookahead);新增 _parse_switch(case 常量/枚举变体/多值 + default:)
- lexer.vp:局部变量 match 改名 Matched(match 已为硬关键字)
2026-10-02 23:15:13 +08:00
TermiNexus b85f49ab35 feat(ast): 新增 fallthrough 软关键字语句节点 FallThrough
- base.vp:ASTKind 末尾追加 FallThrough(append 保持既有枚举值不变)
- stmts.vp:FallThrough 语句节点(kind / type_name / dump)
- parser.vp:语句位置识别裸 `fallthrough`(仅整条语句命中;fallthrough = 1 /
  fallthrough(x) / d.fallthrough 等作标识符的写法不受影响)
- __init__.vp:导出 FallThrough
2026-10-02 22:33:15 +08:00
TermiNexus 1566df068f feat(stub): 以 viperbuild.vpnci 替换 project_build.vpnci
viperbuild 是编译器内建宏库(与 t / c / ctraits 同级),存根仅供 Vipeye 解析;
文件名与 import 名保持一致,注释改为英文,并移除旧的 project_build.vpnci。
2026-10-02 22:07:01 +08:00
TermiNexus 7384d9a57c fix(parser): 类型注解位的 __attribute__(...) 只解析调用本身,不再吞掉后续 []T
原实现用 _parse_test 解析 __attribute__(...) —— 那是通用表达式解析器,解析完调用后
会继续吃 postfix trailer,把紧随的 C 风格前置数组 `[]T` 的 `[]` 当作**合法空下标**
吞掉(_parse_slice 显式支持空下标 T[],见其注释)。后果:ac_node 不再是 Call ⇒
描述符循环 break(markers 一个都没收集),且 _match_op(Lsqb) 此时看到的是元素类型
⇒ 数组分支被跳过 ⇒ 整个注解退化成裸元素类型,且**全程零报错**。

现场:TransPyV/App/main.vp:44
  V_TPV_VERSION: __attribute__(section(".PRVERSN")) []char = "0.0.5-dev.479"
被解析成 `char`:stub 记 `V_TPV_VERSION: char`、IR 出
`@g = global i8 getelementptr ...`(opt: got 'ptr' but expected 'i8')、段名 ".PRVERSN" 丢失。

改为:_advance 过 `__attribute__` 后用 _parse_call 解析 `( 实参表 )`,postfix 不再被
误吃,`[]char` 交回数组分支脱糖为 t.CArray[char, None] → i8*。
2026-10-02 17:29:58 +08:00
TermiNexus c27ebc1b69 feat(struct): 新增 struct 关键字(class 同形,纯数据类型)
语义(用户 2026-10-01 定):与 class 同形,但只能表示数据类型:
  ① 禁止 virtual / novirtual 修饰(struct 天然无虚表);
  ② 禁止在 struct 内定义 def;
  ③ 允许在 REnum 内作为变体(与 class 一样);
  ④ 允许 struct 内再写 struct(与 class 内写 class 同口径,语法层不额外禁止)。

实现(双端同一套表示,零新增下游判据):
  · tokens.vp:Keyword 枚举**表尾**追加 Struct(既有 kw_subtype 编号逐字不变)
    + _kw_intern("struct");struct 在 .vp 源码中不作标识符。
  · parser.vp:新增 _parse_structdef + _RecordStructErr,复用 class 的
    基类/类型参数/类体解析路径,解析期合成 `@t.NoVTable` 伪装饰器并**追加**
    `t.CStruct` 标记基类(真实父类仍在 bases[0])——与手写
    `@t.NoVTable class X(t.CStruct):` 逐字段同形;类体解析后检查直接子节点,
    遇 FunctionDef 即 fail-fast。
  · parser.vp:_ParseVirtualModified 显式拦截 `virtual struct` / `novirtual struct`。

验证:struct 内 def / virtual struct 均报错;`struct = 5` 仍按普通赋值解析。
2026-10-01 23:07:11 +08:00
TermiNexus 85f67b5558 fix(w32/condition/rwlock): SRWLOCK / CONDITION_VARIABLE 建模为不透明结构体
二者在 Windows 头文件里都是"单个 PVOID 的结构"(sizeof 8),API 收的是**存储地址**。
原先声明成 VOIDPTR(i8*)⇒ `c.Addr(self.cond_var)` 得到 i8**(多一层),与形参 i8* 层数
不符(指针隐式转换收紧后报 CastError,现场 includes/condition.vp:27)。

- win32sync.vp:新增 class SRWLOCK / class CONDITION_VARIABLE(Ptr: VOIDPTR,8 字节);
  5 个 SRWLock extern 与 5 个条件变量 extern 的形参由 VOIDPTR 改为对应结构体指针
- condition.vp:cond_var 由 VOIDPTR 改为 CONDITION_VARIABLE
- rwlock.vp:lock 由 VOIDPTR 改为 SRWLOCK

布局与运行期语义均不变(都是 8 字节、对齐 8,传的仍是那块存储的地址)。
2026-10-01 19:24:07 +08:00
TermiNexus 6ff26a16b9 refactor(_list): 清理未使用导入,append 的 new_data 改用 rawptr
- 去掉未使用的 `import t, c` / `import stdio` / `from stdint import *`
- new_data 由 t.CPtr 改为 rawptr(与 __data__ 字段同为裸指针),顺带对齐
2026-10-01 18:30:44 +08:00
TermiNexus 2af230bdd1 fix(argparse): argv 取值改用直接下标 argv[idx],避开 TPC 赋值路径对 i8** 右值的自动解引用
原写法 `entry = str*(uint64(argv) + idx * 8)` 的右值是 i8**,TPC 的 HandlesAssign 赋值路径
会对"指针的指针"右值再 load 一次 → entry 变成 argv[idx] 本身,entry[0] 又去读字符串头 8 字节
→ 野指针(ASan: access-violation 0xffffffffffffffff @ ArgumentParser.parse_args)。
改为 argv[idx] 后右值是 i8*(1 级),不触发该路径;顺带去掉了 uint64 往返。
2026-10-01 18:29:53 +08:00
TermiNexus 7f513b86aa style(_list): 元素访问统一改为 *elem_ptr 前缀解引用写法
append/get/__getitem__/set/__setitem__/pop/__next__ 共 7 处 `elem_ptr[0]` 改为 `*elem_ptr`,
与其他裸指针解引用写法(如 _dict.vp 的 `*int_ptr` / `return *val_ptr`)保持一致,语义不变。
2026-10-01 18:09:39 +08:00
TermiNexus 14221b9414 refactor(includes): 适配新指针口径与语法,rawptr[T] → T* / t.CPtr → rawptr
- json/__init__.vp、math.vp:rawptr[T] 改为 T*
- ast/base.vp、ast/stmts.vp:@t.CVTable 改为 virtual class
- argparse.vp:t.CPtr(...) 改为 str*(...)
- stdarg.vp:arg(type: t.CType) 改为 t.CPtr
- stdint.vp:FSIZE_t/LBA_t 换成 LPCSTR
- memhub.vp:import 整理、去掉 t.CDefine 前缀、t.CPtr 改 rawptr、格式对齐
- ast/parser.vp、math.vp、linkedlist.vp:对齐与格式清理
2026-10-01 18:05:05 +08:00
TermiNexus d8c02cff73 refactor(_dict): 元素地址运算去掉 uint64 往返,改用裸指针字节偏移
裸指针 rawptr 即 i8*,其上的 + 按 1 字节缩放,与 uint64(base) + n 再强转回指针逐字等价。
_find/__getitem__/_set_variant_raw/get/get_vtype/__next__/to_json 共 13 处偏移统一为此口径,
与 _list.vp bb05e11 保持一致。承接 f69e71b 中遗留的裸指针 uint64 手动计算待重新处理。
2026-10-01 18:04:45 +08:00
TermiNexus bb05e112ec refactor(_list): 元素地址运算去掉 uint64 往返,改用 i8* 指针加法
rawptr 即 i8*,指针加法按 pointee(1 字节) 缩放,与 uint64(ptr)+n 再强转回指针逐字等价。
元素步长仍显式由 __elem_size__ 给出,故不能改成下标访问(list[int](pool,8) / list[str](tp,64) 依赖显式步长)。
承接 0f92426 中遗留的裸指针 uint64 手动计算待重新处理。
2026-10-01 18:00:57 +08:00
TermiNexus 3c29b9bd13 将 lock.vp 的 c.Addr(self.cs) 替换为 &self.cs 2026-09-30 13:52:40 +08:00
TermiNexus 0f924264ea 将 _list 的部分写法升级到最新范式,裸指针 uint64 手动计算便宜还需要重新处理,暂时如此,后续还需要再更新 2026-09-30 00:36:50 +08:00
TermiNexus f69e71b198 将 _dict 的部分写法升级到最新范式,裸指针 uint64 手动计算便宜还需要重新处理,链表暂未做 linkedlist 范式化 2026-09-30 00:34:40 +08:00
TermiNexus ef61975165 修正 _fakeduck.vp 表达含义 2026-09-30 00:25:55 +08:00
TermiNexus 3135f62141 略微清理了 stdarg.vp,但受限于 Vipeye、编译器缺陷未能完整整理 2026-09-29 17:01:08 +08:00
TermiNexus 8d345ece04 略微清理了 sys.vp 2026-09-29 17:00:36 +08:00
TermiNexus 76c021ae26 给 this.vp 增加了一个空格 2026-09-29 17:00:20 +08:00
TermiNexus 9914e150ef 将 vector 整理 2026-09-29 16:59:46 +08:00
TermiNexus bc6c32b1da 清理了 viperio 2026-09-29 16:59:21 +08:00
TermiNexus 53ae1b7864 略微清理了 viperlib,受限于 Vipeye 缺陷暂缓 2026-09-29 16:59:09 +08:00
TermiNexus 4c6877a87f 将 vipersimd.vp 的注解描述得更准确(t.CPtr -> double*) 2026-09-29 16:58:40 +08:00
TermiNexus 4fed54aa8b 去除了 vthreading 的 c.Addr 2026-09-29 16:47:50 +08:00
TermiNexus 9cef4d8b56 将 zipfile 改为最简洁形式 2026-09-29 16:47:20 +08:00
TermiNexus 4957ba5661 fix(includes): _fakeduck.split 的返回注解补上指针(list[str] → list[str] | t.CPtr)
【类别 c 源码违规】返回注解写成了值类型,实际返回的是堆对象指针。

现象:
  编译 includes/_fakeduck.vp 报
  CastError: 非基本类型的值/指针隐式转换已禁止(构造物化除外):不能把指针类型
  隐式转为非基本类型值(Foo* → Foo);源类型 %"….list[str]"* → 目标值类型 %"….list[str]";
  出错表达式: Name 'result'(_fakeduck.vp:295 `return result`)。

判据(无需强转,问题在注解层):
  · list[T] 是堆分配对象(_list.vp:31 的 __new__ 走 pool.alloc),本仓库惯例一律以指针
    传递/返回:_list.vp:88 `def __iter__(self) -> list[T] | t.CPtr`;全仓 list 型的
    变量/形参/返回共 383 处用指针写法(`list[X]*` 或 `list[X] | t.CPtr`)。
  · 本处 `-> list[str]` 是**全仓唯一**的「list 值类型返回注解」写法。
  · `result = list[str](self.__mbuddy__)` 拿到的是指针,`return result` 即「指针 → 值」;
    该转换仅当右值本身是构造调用(构造物化)时豁免,return 处不豁免 ⇒ fail-fast 正确,
    且报文已指明根因类别(非基本类型的值/指针隐式转换)。

改动:_fakeduck.vp:274  `-> list[str]` → `-> list[str] | t.CPtr`(与 _list.vp:88 同写法)
2026-09-29 16:00:49 +08:00
TermiNexus 31b0f79ed2 Revert "fix(includes): llvmlite/mlirlite/torch 的分配器形参放宽到基类 MemManager"
This reverts commit 9b1399b627.
2026-09-29 15:48:06 +08:00
TermiNexus 9b1399b627 fix(includes): llvmlite/mlirlite/torch 的分配器形参放宽到基类 MemManager
【类别 c 源码违规(库侧接口过窄)】编译器判据没错——兄弟类指针相转本就该禁;
错在库侧把「分配器」形参写死成了具体类,比它实际需要的契约窄一层。

现象:
  编译 Test/LLvmLiteTest/App/main.vp 报
  CastError: 指针隐式转指针已禁止:被指类型是非基本类型;源类型
  %"c8dff2457a2f7a42.MemPool"* → 目标类型 %"c8dff2457a2f7a42.MemBuddy"*
  现场:`pool: memhub.MemPool | t.CPtr = memhub.MemPool(pool_mem, POOL_SIZE)`
  之后 `test_type_print(pool)` → 传进 llvmlite 的 `pool: memhub.MemBuddy*` 形参。
  (MLIRLiteTest 同理,也传 memhub.MemPool。)

根因:项目自身约定是「分配器参数写基类」,只有这两个 lite 模块写成了具体类:
  · includes/ast/* 全库:`pool: rawptr[memhub.MemManager]`(base.vp/astaux.vp/exprs.vp…)
  · includes/vector.vp:13:`def __init__(self, pool: memhub.MemManager*, ...)`
  · 而 includes/llvmlite/* 128 处、includes/mlirlite/* 141 处、includes/torch/* 3 处
    写的是 `pool: memhub.MemBuddy*`。

判据(全部可取证,非猜测):
  1. `MemManager`(memhub.vp:321 `@t.CVTable`)声明虚接口 alloc/free/reset
     (:333 / :337 / :341),注释明写 "Virtual functions (overridden by subclasses)";
  2. `MemPool`(:420/:437/:441)、`MemSlab`(:552/:574/:590)、`MemBuddy`(:1454/:1696/:1846)
     各自覆盖,故基类指针 + 虚分派对三种分配器都成立;
  3. 这三个模块对 pool 只调用 alloc/free(llvmlite 124/2、mlirlite 173/2、torch 4/0),
     两者都在基类虚接口上,没有任何 MemBuddy 专有方法(无 alloc_tagged/realloc);
  4. 三个模块内 `memhub.MemBuddy` 除该形参外**无其它出现形态**(已逐行分类核对,
     无 __mbuddy__ 字段、无 MemBuddy(...) 构造)。

修法:272 处类型放宽 `pool: memhub.MemBuddy*` → `pool: memhub.MemManager*`
  llvmlite 128(__builder 45 / __types 27 / __module 16 / __function 15 /
    __init__ 12 / __values 7 / __verify 6)
  mlirlite 141(__builder 44 / __types 37 / __module 18 / __function 17 /
    __init__ 12 / __values 7 / __verify 6)
  torch 3(__init__.vp)
  其中 8 处是「持有 pool 的字段/模块级单例」声明,由已放宽的形参直接赋值
  (self.Pool = pool / ptr.Pool = pool / _MLIR_Pool = pool / _MlirGvPool = pool),
  必须同步放宽,否则赋值本身会变成下转:
    llvmlite __builder.vp:32 / __types.vp:314 / __init__.vp:354 的 `Pool:`
    mlirlite __builder.vp:32 / __types.vp:316 / __init__.vp:363 的 `Pool:`
    mlirlite __function.vp:1153 `_MLIR_Pool` / __module.vp:881 `_MlirGvPool`

这是**放宽**(接受基类)而非放宽判据:原调用方(TransPyV 等一律传 MemBuddy)不受影响
(MemBuddy* → MemManager* 是继承上转,合法),MemPool*/MemSlab* 调用方变为合法。
未动 argparse 的 2 处 `pool: memhub.MemBuddy* = None`(其调用方传 MemBuddy,无过窄证据),
也未动各处 `_mbuddy: memhub.MemBuddy*` 全局单例(由 main 显式赋 MemBuddy 实例)。

实测:`git diff` 272 增 / 272 删,逐行核对**全部**为 pool/Pool 类型行,无其它改动混入。
2026-09-29 15:37:28 +08:00
TermiNexus 0212bd942c fix(includes): 槽视图改为 cast 到声明类型(地址 → 二级指针不再隐式转换)
【类别 c 源码违规】`slot: <A> = t.CPtr(addr)` 把一级指针(i8*)隐式塞进二级注解
(i8** / X**),违反 2026-09-28 收紧的「指针级数必须相同」。TransPyV 侧 coerce
没有「值侧是显式 cast」豁免(ExprGenBase._ptr_cast_reason 先比层数),故回归测试
在 includes/llvmlite/__function.vp:950 首爆:
  指针隐式转指针已禁止:指针层数不同(源 1 级 → 目标 2 级);源类型 i8* → 目标 i8**。

判据(按注解层数分类,不枚举调用点):
  · str / bytes 本身即 i8*(含一层),再 | t.CPtr ⇒ i8**(槽里存的是 str)
  · str* / bytes* 同 str | t.CPtr(i8**)
  · T | t.CPtr:T 为指针特化时 ⇒ X**(如 list[X*]、list[str])
  · A | t.CPtr | t.CPtr:逐层叠加 ⇒ 二级(如 hashtable 的 value 槽)
  一级注解(int | t.CPtr = i32*、t.CUInt64T | t.CPtr = i64*、类名 | t.CPtr = X*)
  与 i8* 同级且 i8* 是通用指针通配 ⇒ 本可编译,一律保持原样不动。

修法:RHS 改为**cast 到声明类型**,即「注解写什么就 cast 什么」——
  `t.CPtr(addr)` / `(t.CPtr)(addr)` / `rawptr(addr)` → `(A)(addr)`;
  `str*` 注解沿用 sys.vp 既有写法 `str*(addr)`(等价于 `str | t.CPtr` 强转)。
显式写明目标类型后,层数与被指类型均由程序员给出,编译器无需任何豁免。
与 TransPyV/App CallGenCBuiltin.vp 的 `cl_ptr: str | t.CPtr = (str | t.CPtr)(cl_addr)`
以及 includes/vector.vp 的 `dst: T* = (T*)offset` 同一写法。

本仓改动 27 处 / 5 文件:
  _list.vp 7
  _dict.vp 9(8 处槽视图 + L63 的 `key_ptr: str* = rawptr(...)`)
  hashtable.vp 6(含 3 处 …|t.CPtr|t.CPtr)
  llvmlite/__function.vp 2
  mlirlite/__function.vp 3(2 处槽视图 + _mlir_slotp 的 return:该函数返回注解
  即 str | t.CPtr,其 return 同属「i8* → 二级」)

未动其它一级注解站点,例如 _dict.vp 的 int/float/t.CDouble/t.CInt | t.CPtr、
hashtable.vp 的 t.CUInt64T | t.CPtr、argparse.vp:168 的 Argument | t.CPtr。
2026-09-29 15:10:33 +08:00
TermiNexus db47b92983 revert(includes): 回滚 3 个跨模块链表访问器(GlobalVariable/PhiIncoming/SwitchCase)
回滚 832e570。这三个访问器是为"绕开继承字段名解析"的 TransPyV 侧规避而新增的;
该规避已随 TransPyV aa52cf1 一并回滚 —— 缺陷本体改由 TPC 侧修复
(e6451a07 继承展平沿继承链取真实字段名),源码恢复裸字段访问。

既有访问器(paramnode_get_next / value_get_next / function_get_next / param_get_next)
不动:它们在本次改动之前就已被多处使用。llvmlite 与 mlirlite 同步回滚,
保持"逐名同形"镜像不变量。
2026-09-28 21:49:39 +08:00
TermiNexus 832e570e1a feat(includes): 新增 3 个跨模块链表访问器(GlobalVariable/PhiIncoming/SwitchCase)
GlobalVariable.Next / PhiIncoming.Next / SwitchCase.Next 均继承自泛型基类
GSListNode[T],泛型特化体不在任何 .vpi 中 ⇒ 导入侧 class_members 只有
__inherited_N 占位名,裸字段访问在严格属性解析下 fail-fast。

沿用既有约定(paramnode_get_next / value_set_next 等)在**定义模块内**补同名同义
访问器(None 守卫 + x.Next,零行为变化):
· llvmlite/__module.vp:   globalvariable_get_next(读)
· llvmlite/__builder.vp:  phiincoming_set_next / switchcase_set_next(写)
· mlirlite 同形镜像同步(保持"逐名同形"不变量,MLIR 侧 llvmlite.→mlirlite. 重命名可编译)
并在两库 __init__.vp 的 from-import 列表登记导出。
2026-09-28 21:20:41 +08:00
TermiNexus 987f91ce32 feat(static): 注解位置的 static 不再支持(响亮失败),存储类标记一律前置
_parse_type_ann:删掉注解位置 static 脱糖成 t.CStatic 的分支,改为 _RecordDescriptorErr 报错并提示改成前置形式(static 名字: 类型),消费该 token 后继续解析类型

_IsStaticDescriptorKeyword 改述为旧位置误用识别(仍只由 _parse_type_ann 调用,无死代码);_parse_type_ann 的 docstring 同步:合法写法只剩两种同源形态——语句起始 static 名字: 类型(pending_static 通道)与装饰器 @t.CStatic

报错而非忽略的理由写进注释:不消费时 static 会退化成叫 static 的类,被建成 opaque 结构体(llvm-link 报 invalid type for null constant),报错点远离根因
2026-09-28 13:49:29 +08:00
TermiNexus 677dd13320 fix(traceback): 撤掉 caller_ret([RBP+8] 在 .vp 帧里不是返回地址)
实测 _TypePrintDepth:RBP = rsp+0x70(locals base),入参返回地址在 RBP+0x38;[RBP+8] 只是无关局部量(值落在 .data 区),打印它会误导。调用者一律以 .stackmap 走栈结果为准

文档第十四节 C 同步;regs/av_addr 两条保留
2026-09-28 12:21:26 +08:00
TermiNexus 1379b8814c feat(traceback): 崩溃转储再补 caller_ret(出错帧 [RBP+8]),可独立反汇编核对走栈首帧真伪
不依赖 .stackmap 的原始返回地址:用来判定 dbghelp 给出的第一个调用者帧是真帧还是 unwind 假帧(本轮 map 与反汇编对不上时唯一能定案的数据);读不到就不打该行,不留假 0

文档第十四节 C 同步
2026-09-28 12:14:00 +08:00
TermiNexus 1fabb46e8c feat(traceback): 崩溃转储补出错帧实参寄存器与 AV 数据地址(一次拿全现场)
Trigger 行新增 av_kind/av_addr(EXCEPTION_RECORD 的 ExceptionInformation[0/1]:0=读 1=写 8=执行、数据地址;仅访问违规有效,但崩溃现场就该给原始数字)

新增 regs 行:rcx/rdx/r8/r9/r12(Win64 前 4 个整型实参 + 出错帧解引用用的寄存器),用于区分「实参传错」与「实参对、指针所指内容错」,避免多一轮重编

文档第十四节 C 同步输出形状与这两行的用途
2026-09-28 12:13:13 +08:00
TermiNexus 7651da8ac9 feat(traceback): 崩溃也要有栈——挂 SetUnhandledExceptionFilter 做未处理异常转储
动机:实测同一处崩溃开 ASan=0x80000003(int3)、关 ASan=0xC0000005(AV),两者都没有任何堆栈(ASan 过了报告窗口就不再输出)

Install 追加注册 SetUnhandledExceptionFilter(CrashHandler)(与 SetConsoleCtrlHandler 并列,均在 _State.Installed=1 之前挂好);CrashHandler/DumpCrashThread 在出错线程上转储:EXCEPTION_POINTERS/EXCEPTION_RECORD 一律经 ReadProcessMemory 读取,OS 的 CONTEXT 先拷进 ContextBuf 再走栈(StackWalk64 会回写它遍历的记录,直接传 OS 的记录会改坏异常上下文)

恒返回 EXCEPTION_CONTINUE_SEARCH:本路径只补栈,绝不吞异常(退出码/WER/ASan 报告行为原样保留);走栈 dbghelp 优先(崩溃点通常在系统 DLL 里)→ RBP 链 → 栈扫描,与 Ctrl+C 转储共用同一把重入锁

抽出 DbgHelpUsable() 与 PrintFrames() 给两条路径共用(DumpMainThread 同步改用,行为不变)

win32process.vp 新增 SetUnhandledExceptionFilter 声明 + EXCEPTION_POINTERS/EXCEPTION_RECORD 布局注释;traceback.vp 新增第十四节,第一/二/六节文档同步
2026-09-28 12:03:15 +08:00
TermiNexus 923f7e3099 fix(w32): 补回 CONTEXT 缺失的 LastBranchToRip/LastBranchFromRip(修 dbghelp 写穿 ContextBuf)
winnt.h(AMD64) 在 DebugControl(0x4A8) 之后还有 LastBranchToRip(0x4B0)/LastBranchFromRip(0x4B8),本仓结构漏了这两个字段 ⇒ sizeof(CONTEXT) 只有 0x4C0=1216,而系统/dbghelp 按 0x4D0=1232 读写

现场:dbghelp!StackWalk64 每走一帧都把 0x4D0 的 CONTEXT 写回传入的 ContextRecord,ASan 抓成 heap-buffer-overflow WRITE of size 1232(0 bytes after 1216-byte region,区域由 Install 的 calloc 分配);GetThreadContext 同样按 0x4D0 回写(内核写入 ASan 看不到,属同类静默越界)

同步布局注释与合计尺寸为 0x4D0=1232,并注明这两个字段必须保留
2026-09-28 11:53:28 +08:00
TermiNexus bdf2463dfc fix(traceback): DbgHelp 与 ASan 是状态共享而非互斥,改为探针裁决后启用 StackWalk64
Install:SymInitialize 被拒时(DbgHelp 已被 ASan 运行时占用,进程级状态按句柄唯一)改为调用 SymRefreshModuleList 刷新共享模块表,再由 SymGetModuleBase64(主模块) 探针裁决 SymReady;探针为 0 则回退 0 并打印原因,不静默 0 帧

DumpMainThread:删除 AsanPresent 强制 DbgUsable=0 的一票否决,降级原因串去掉 dbghelp_conflict_with_asan;ASan 探测只保留在诊断行

win32dbghelp.vp:新增 SymRefreshModuleList 声明与用途注释

实测依据:Ctrl+C 现场 RBP=0x0、RIP 在系统 DLL(阻断原因 rbp_zero,不是 ret_out_of_module),帧指针开关救不了这条链;.vp 目标文件已含 .pdata/.xdata,StackWalk64 可穿过系统帧还原真实 .vp 调用链;文档第十一节 B、第十二节 C 同步
2026-09-28 00:23:47 +08:00
TermiNexus ba50433cd5 fix(traceback): 补回 RbpFrames 声明(45d9b55 只带上了门槛改动,编译报未定义名称)
dbghelp 门槛已改写为 if RbpFrames <= 1,但 RbpFrames: int = Frames 的声明未随该提交落盘 -> TPV 重编时 NameError: 未定义名称 RbpFrames(traceback.vp:1635)
2026-09-27 19:13:32 +08:00
TermiNexus 45d9b55931 fix(traceback): 栈扫描挤掉 dbghelp 反走栈 + 系统 RIP 被误查表成假帧
1) dbghelp 门槛 Frames<=1 误用扫描后的帧数:RBP=0 时链只出 RIP 帧、扫描再补 1 帧 -> Frames=2 使 StackWalk64 被静默跳过(唯一能穿过无帧指针的 ntdll/kernel32 帧的路径)。改用 RbpFrames(RBP 链自身产出)作门槛

2) EmitFrame 只判 Addr<Base:线程阻塞在系统 DLL 时 RIP 远在 Base 之上却仍去查表,floor 搜索返回最后一条记录 -> 打印出看似合理的 File/line/函数名(实证假的 line 13)。补上界 Addr>=Base+TRACEBACK_MODULE_MAX(与 WalkRbpChain/ScanStack 同一模块边界),归为 external

3) dbghelp 接管会清空既有帧:改为保存全部已收帧(栈上局部数组),dbghelp 产出为 0 时全量恢复,避免门槛放宽后反而丢帧
2026-09-27 19:04:53 +08:00
TermiNexus fc56f10935 fix(traceback): _DumpLock 标记 export 用裸名(@_DumpLock)
AtomicTryEnterDump 的内联汇编把 &_DumpLock 作 AsmInp 内存操作数 [{...}],SHA1 前缀名 45098e5ade6cd73d._DumpLock 以数字开头,LLVM MC 无法在 [...] 内解析(llc Unexpected offset)

裸名导出后符号为 @_DumpLock:_asm_name_is_mangled 判定通过,且与 gdt/gp/idt/_sched_ptr 等既有 asm 互操作全局同口径

依赖 includes f854f7e 新增的 export 变量语法糖(TPC 侧 6fce79d5 同步)
2026-09-27 18:31:01 +08:00
TermiNexus 9011878459 fix(ast): export/extern 变量 AnnAssign 固定 simple=1,Equal 判定显式 != 0 2026-09-27 17:57:15 +08:00
TermiNexus f854f7e99a feat(ast): 支持 export/extern 变量声明语法糖
export NAME: T [= v] → NAME: T | t.CExport [= v](裸名导出,不加模块 SHA1 头)

extern NAME: T → NAME: T | t.State(仅声明 + 裸名);extern 带初始值响亮失败

新增 _is_export_extern_var lookahead(第三 token 为 : 判变量,(: / [ 判函数不影响 export def)与 _parse_export_extern_var
2026-09-27 17:56:46 +08:00
TermiNexus 46cd4b4ebf feat(ast): 新增 renum 语法糖,renum X: 等价 class X(t.REnum):
tokens.vp: 追加 Keyword.Renum(表尾,既有 kw_subtype 编号不变)并注册 renum

parser.vp: _parse_stmt 与 _parse_compound 分发 Keyword.Renum;新增 _parse_renumdef,基类固定 Attribute(Name(t), REnum),与手写 class X(t.REnum): 逐字段同形

与 enum/union 语法糖对称;成员按普通类体解析(嵌套 class 变体 + 无载荷赋值)

背景: EdgeCaseTest App main.vp 第 42 行 rnum 非关键字导致 AST 解析失败
2026-09-27 17:49:39 +08:00
TermiNexus 674282936f fix(ast): 解析失败保证有位置与原因,错误消息改单行
parse_tokens 的 error_count>0 出口此前直接 return None:解析器 40+ 处 error_count 自增并非每处都调 _record_*,缺记录时 dump_parse_traceback 只能打出 File 加 SyntaxError: 语法错误,既无行号也无原因(用户报 AST 解析失败不显示失败原因)。现于该出口用当前 token 补记 行/列 + 原因。另把 _record_parse_err_ctx 的消息由含换行的两行并成单行,便于调用方日志行内联。
2026-09-27 17:32:28 +08:00
TermiNexus 5e1180fc26 fix(ast): parser.vp 去掉不存在的 ast. 命名空间前缀
parser.vp 位于 ast 包内、并没有 import ast,写 ast.Call* / ast.ASTKind.X 会把变量注解记成模块限定名 ast.Call,走到 lookup_field_by_class 的模块限定分支就 fail-fast:类 ast.Call 未找到(模块 ast 可解析 sha1=1abcd5277fa442de,但 Call 实际注册在定义模块 5df907d3a02a0bac 下)。全部改用本文件已导入的裸名(AST / ASTKind / Call / Name / Attribute),共 36 处。
2026-09-27 16:53:47 +08:00
TermiNexus 6b88b3feff feat(parser,descriptor): static 作为注解位置描述符(名字: static T)
新增 _IsStaticDescriptorKeyword 并接入 _parse_type_ann 的描述符循环:注解位置的 static(名字: static T,ViperOS 驱动广泛写 pack_head: static uint32 = 0)与 const/volatile 同位置、顺序自由、可混写,落成同一个 t.CStatic 标记(与语句起始 static 名字: T 的 pending_static 通道、手写 t.CStatic | T 三处同源)。此前注解位置的 static 未被消费,退化成一个叫 static 的类名并被建成 opaque 结构体(@a = global 类型为 sha1.static 的 zeroinitializer,llvm-link 报 invalid type for null constant)。
2026-09-27 14:18:52 +08:00
TermiNexus 6e3231d04c feat(parser): 支持 static 修饰符(软关键字,归一为 t.CStatic 标记)
两种写法同源,最终都产出与手写 @t.CStatic / x: t.CStatic|T 逐字段同形的标记节点,故 TransPyV 侧零新增解析判据:

- static def f(...):消费 static 后合成 @t.CStatic 装饰器(与 inline def 同一套 pending_decorators 通道,见 _ParseStaticModified)。

- static x: int = 0:置 Parser.pending_static,由 _parse_type_ann 在描述符序列首位插入 t.CStatic(= 手写 t.CStatic | int),随即清零只作用于紧随的一个注解。

- 软关键字边界:只在语句起始、且后随 def 或 Name: 时命中(_IsStaticModifier);作标识符的位置(属性名/形参名/表达式内)不经过该判据。

语义(禁止跨模块使用)由 TransPyV 侧消费。
2026-09-27 12:58:44 +08:00
TermiNexus a6fe460bce feat(parser): 支持空下标 T[](无签名函数指针 t.Callable[])
_parse_slice 在 '[' 后紧跟 ']' 时不再调 _parse_expr(原本报 意外的 token ]),slice 置 None 交类型解析侧按空参数表处理。其余切片/元组/单表达式形态不变。
2026-09-27 12:25:47 +08:00
TermiNexus c392390e0d feat(ast): 支持 volatile 调用前缀与注解位置 __attribute__(...) 修饰符
- Call 新增 IsVolatile 字段(末尾追加,既有字段偏移不变),承载值位置 volatile f() / volatile S() 前缀标记。

- parser 新增 _IsVolatileCallPrefix + _parse_test 消费点:吃掉 volatile 后对解析出的 Call 置 IsVolatile=1。

- parser 注解位置新增 _IsMagicAttributeCall:描述符收集循环扩为 _IsDescriptorKeyword or _IsMagicAttributeCall,把 __attribute__(...) 的实参经 _MakeTAttrMarker 合成为 t.attr.<name> 标记贴到类型联合最左,与 const/volatile 同族语义。
2026-09-27 12:01:15 +08:00
TermiNexus 622ae03c9f feat(ast): 支持 inline def 与 @__attribute__(...) 语法糖(均 desugar 到既有装饰器)
- parser.vp:新增 inline 修饰符(软关键字,语句起始 + 后随函数定义时生效),合成 @t.attr.always_inline;inline 不进关键字表,作标识符的既有写法不受影响

- parser.vp:新增 @__attribute__(section(...), always_inline) desugar ⇒ @c.Attribute(t.attr.section(...), t.attr.always_inline);带/不带调用的属性名都支持,class/def 共用装饰器链,产出与手写形态逐字段同形
2026-09-27 11:41:09 +08:00
TermiNexus 7025982944 fix(memhub): free_lists 遍历加块地址合法性前置校验,防元数据损坏时解引用 AV
- count/free_bytes/used_bytes 三处遍历:链表头与 next 节点先过 _fl_block_ok,非法(未初始化 0xBE…/非池内对齐地址)则打印诊断并停止本阶,不再直接解引用
2026-09-27 00:19:44 +08:00
TermiNexus 3007c55d71 fix(memhub): 补齐 mark_depth 字段声明(上次编辑部分丢失致属性写入失败)
mark_depth 的 class 字段声明在上一批编辑中丢失,仅 __init__ 赋值保留,编译期报 属性写入失败: .mark_depth;补回声明,并去掉注释里的方括号避免被数组前缀脱糖等文本改写误伤

验证:memhub.vp 经 Viper 预处理 ExpandSoftKeywords + vast.parse 解析通过
2026-09-26 21:38:29 +08:00
TermiNexus 748c17dd1a fix(memhub,ast): alloc 懒建记录栈修永久漏块;OOM 整池账目/分段/双读取证;池耗尽 fail-fast
memhub.alloc: 首次 mark() 之前分配的块此前不入记录栈,事后 free 全被 _is_valid_ptr 活跃集检查拒绝而永久漏块;改为需要时懒建记录栈

memhub.dump_alive_orders: 新增整池账目(镜像存活/空闲链表/丢失)+ 前缀-vs-本窗口分段 + 4 条抽样(直读与两步式双读 + ±8 邻字探针)

memhub.mark/free: 记录 mark_free_bytes/mark_depth;free 被拒绝时逐判据打印(在池内/对齐/块头奇数/在记录窗口 + 本池 base/usable/usable_size)

memhub: 删除文件尾部重复残块(2291 行无主 INDENT 曾致整模块声明未注册)

ast/tokens + ast/lexer: Token/KwEntry/Lexer/token_set_str/indent_stack/_kw_lookup 池耗尽 fail-fast,不再留 NULL 崩在 _kw_hash_str
2026-09-26 21:25:23 +08:00
TermiNexus 534ab5a271 chore(includes): 删除误入库的 viperlib.vp.txt 副本 2026-09-26 19:28:32 +08:00
TermiNexus db3be6968f fix(memhub,gzip): 内存池 OOM 归属画像与 free 拒绝现场;gzip 注解 *= 词法粘连
memhub: alloc 失败打印归属 site/ctx 与存活块 order 分布(新增 dump_alive_orders);free 被 _is_valid_ptr 拒绝时首次打印现场;接通 big_alloc_count

gzip: ub: uchar*= buf 补空格(*= 被词法合并为单 OP,注解止于 uchar)

新增 traceback 模块;删除 dbgstack.vp;其余模块随新语法与尺寸口径同步
2026-09-26 19:27:24 +08:00
TermiNexus 093ff5f66d fix(viperlib): 浮点格式化的 inf/nan 保护失效导致 %g 死循环
根因: _check_special_float 的位双关 (把 double 位模式读成 uint64) 被 TPC 前端静默丢弃——IR 里 fbits 恒为 0 (store i64 0 后直接 load,没有把 fv 写进 fbits),函数恒返回 0,于是 %f/%e/%g/%a 的 inf/nan 保护全部失效。

后果: inf 落入 %g 的指数归一化循环 while fv>=10.0 (inf/10==inf 恒真) → 死循环,实测卡死在 vsnprintf:974(Ctrl+C 栈转储权威帧 #0)。

修复: _check_special_float 改为纯浮点语义判定 (fv!=fv 判 NaN;fv-fv!=fv-fv 判 +-inf);另给 4 处对 inf 不收敛的循环各加迭代上界 400 (正常最多约 308 次) 作纵深防御。

注: 位双关语句被静默丢弃属 TPC 前端缺陷,需另立项;va_arg(ap, double) 经生成 IR 核对是正确的 (va_arg 内建读 XMM 保存区且 gp/fp 各自推进),非本次原因。
2026-09-25 13:15:04 +08:00
TermiNexus b208eae8f3 feat(dbgstack,parser,asm): 新增按键栈转储运行时;前置数组声明符/union 语法;asm 迁移新语法
新增 includes/dbgstack.vp: 挂起主线程取 x64 CONTEXT + RBP 链逐步取证 + 栈扫描兜底(4KiB 分块 ReadProcessMemory);按 <exe>.stackmap 下界查表输出 <文件>.vp:行 (函数);控制台 ASCII 输出并双写 UTF-8 <exe>.stackdump.txt;ASan 与 DbgHelp 冲突显式降级不静默;lock cmpxchg 原子重入(不用 InterlockedCompareExchange: x64 上是编译器内部函数、无导出符号)。

新增/补 w32 头: win32dbghelp.vp(新)、SetConsoleCtrlHandler、x64 CONTEXT、ReadProcessMemory。

parser.vp/tokens.vp: [N]T/[]T/const [N]T 脱糖为 t.CArray;新增 union NAME: 语句(Keyword.Union 追加表尾);list[rawptr[AST]] elem_size 2/4 改 8;新增 _record_parse_err_ctx 把 token 类型与前后 token 并入错误消息,去掉 [AST] SyntaxError 遗留单行 printf。

asm.vp: 整文件迁移到 __asm__/asminp/asmout/裸 ASM_DESCR。
2026-09-25 13:11:15 +08:00
TermiNexus 0f556463e7 修正了部分代码的表达方式,最后可用版本,mlirlite 已基本完善 2026-09-23 17:42:03 +08:00
TermiNexus 0d77b68cc4 修复了一些错误 2026-09-18 20:01:14 +08:00
TermiNexus 61acfc2759 修复了一些问题 2026-09-17 14:52:53 +08:00
TermiNexus 88b81c04ed fix(posix): DIR 已是 t.CPtr(i8*),去掉多余的 | t.CPtr 以免多叠一层指针
opendir/readdir/closedir 三个形参与 os/_posix.listdir 的局部变量统一为 DIR(= i8*,即 C 的 DIR*):785e825 把 DIR 由 t.CVoid | t.CPtr 清成裸 t.CPtr 后,DIR | t.CPtr 合并成 i8**(双重指针),opendir 的 declare 变成 i8** 而 C 侧是 DIR*

不改动 win32file.vp 的 HANDLE | t.CPtr(PHANDLE=void**)、win32sync.vp 的 VOIDPTR | t.CPtr(PVOID*)、vqt6/_qtwidgets.vp 的 t.CPtr | t.CPtr(char**)——那些多叠一层是有意的
2026-09-16 18:16:37 +08:00
TermiNexus 785e825518 清理了 t.CVoid 2026-09-16 16:07:35 +08:00
TermiNexus 119951c5df chore: 移除 GSList/PrintModule 的临时 DBGCHAIN 护栏
linkedlist.vp: GSList.append 的 4 处 [DBGCHAIN] 链完整性护栏整块删除(含只为护栏引入的局部变量与 stdlib.exit 分支),并删除因此失效的 import stdio / import stdlib

llvmlite/__module.vp: LLVMModule.PrintModule 的两处 [DBGCHAIN] 指针合理性护栏整块删除;同函数的 [IR-DUMP] 遍历守卫与绕开 stub 字段访问的注释保留

依据: 探针自带注释「临时诊断,用后移除」,且由 commit 2992674 的临时 DBGCHAIN 护栏引入;全 Test 目录无断言或期望输出引用该文本
2026-09-16 10:32:40 +08:00