Commit Graph
125 Commits
Author SHA1 Message Date
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*。
last-good-0.0.5-dev.479
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