Commit Graph
100 Commits
Author SHA1 Message Date
TermiNexus d8648176e9 feat(asm): op=/clobber= 支持裸枚举名(CLOBBER_MEMORY) - 等价 ASM_DESCR.XXX 2026-10-16 15:26:17 +08:00
TermiNexus e796314a24 fix(gi): 模块级空数组字面量 = [] 改走 zeroinitializer - 修大数组被逐元素展开(元素过多+池耗尽) 2026-10-16 13:02:38 +08:00
TermiNexus 7e9ed22dff revert(main): POOL_SIZE 回退 1GiB - 2GiB 触发 MemBuddy 内部索引溢出(_fl_push 在 __init__ 崩) 2026-10-16 12:13:02 +08:00
TermiNexus c57c931099 fix(cdefine): 支持浮点常量表达式(define X = 160.0 * 4) - 含浮点字面量时按浮点求值登记 double 2026-10-16 11:23:41 +08:00
TermiNexus 832b0a5706 chore(diag): [VAR-DIAG] 增加 alloca 地址打印 - 定位 pos/npos 共享存储(值语义被破坏) 2026-10-16 00:12:06 +08:00
TermiNexus 6196bdfe56 fix(gi): 模块级负浮点字面量按浮点初始化(不再送整型提取器) - 修 double = -100.0 报错 2026-10-16 00:03:21 +08:00
TermiNexus d06e665ebd fix(cdefine): stub 读取对负浮点字面量/浮点强转包裹剥壳后再注册 - 修 X: double = -100.0 走整型提取 fatal 2026-10-15 23:46:25 +08:00
TermiNexus 5460d78ff1 fix(gi): 模块级类全局按值本位存储(仅 __new__ 类用指针) - 修 CAM: V3 被包成 Ptr 致悬垂误报 2026-10-15 23:11:24 +08:00
TermiNexus 9d0a43d5e6 chore(diag): [GVAR-DIAG] 模块级全局类型决策(hasnew/hasvtable/isoop) - 定位 CAM 被包成 Ptr 2026-10-15 23:06:20 +08:00
TermiNexus 15a210bede chore(diag): 变量声明槽类型 [VAR-DIAG] - 定位 class 标注是否被解析成 ptr 2026-10-15 23:00:04 +08:00
TermiNexus 59c032f135 chore(diag): CTOR-DIAG 打印构造类型与目标类型的真实 LLVM 文本 - 定位 CAM 全局值本位 2026-10-15 22:53:23 +08:00
TermiNexus 23236c88ea fix(lifetime): 裸构造判值拷贝不再依赖类型打印比较 - 修 CAM = V3(...) 全局赋值误报 2026-10-15 22:26:17 +08:00
TermiNexus d1dd6de070 fix(lifetime): 目标为值类型即判 LIFE_VALUE(不再要求源非指针) - class 局部变量内部为指针槽,修 stars 误报 2026-10-15 21:59:39 +08:00
TermiNexus cbadc356f9 chore(diag): life 判定加全量诊断 [LIFE-DIAG]/[RT-DIAG] - 定位 return col 误判 2026-10-15 21:54:08 +08:00
TermiNexus 5dc483e256 fix(lifetime): 值类型变量按值拷贝判据改为双非指针(不再依赖类型打印比较),堆/静态登记优先 2026-10-15 21:47:30 +08:00
TermiNexus 6b86f846ca fix(lifetime): 值类型局部变量在同型聚合目标位置按值拷贝(LIFE_VALUE) - 修 return col 被误判 stack address escapes 2026-10-15 21:40:30 +08:00
TermiNexus 217f5f021d fix(viperc): 解引用赋值补位拷贝(*a = *b 按位重解释,不做数值转换)
现场(math.vp sin/cos):
    u: uint64 = 0; xv: double = x
    *&u = *&xv        # 位拷贝,应为 movq %xmm0, %rax
    ef: uint64 = (u >> 52) & 0x7FF
生成:404084 cvttsd2si %xmm0, %rax ← 把 double 数值截断成 int64
代价:u 成了数值截断结果 ⇒ ef/neg 全错;x 为负时(-1.5 → u = -1)ef 命中 0x7FF
⇒ 直接 return x - x = NaN ⇒ sin/cos 负参全废。

VPC 的 `*p = v` 目标路径无条件 coerce_to_type(rhs, pointee);TPC 侧早有该判据
(HandlesAssign.py:592 调 HandlesSpecialCall.EmitRawCopyLlvm,注释明确"位拷贝,绝不转换"),
VPC 漏了 ⇒ 本次按同口径补齐。

- RHS 为 UnaryOp(Deref)(`*p`)且两侧是**等宽标量**时:按**源自身类型** load(类型与槽的
  存储类型一致),再 bitcast 成目的类型存回 —— 不做任何数值转换;
- 不用"按目的类型重解释的 load"(`load i64, ptr %xv`):文本层 T2「store→load 转发」按**名字**
  替换,会把 `store double %x, ptr %xv` 的 %x 顶进这条 i64 行,报
  `use of value '%x' expects different type than prior uses: 'i64' vs 'f64'`;
- 源操作数限定非调用形状,避免与前面 rhs_val 的求值重复;源不是指针 ⇒ fail-fast;
- 两侧位宽不等或含聚合 ⇒ 不做位拷贝,交回 coerce 路径(等价改动前行为,聚合位拷贝未支持)。
2026-10-15 20:16:50 +08:00
TermiNexus 5ea0ce094e fix(viperc): 恢复一元负号字面量按目标类型直出 f32(位宽根因已修,路径不再有风险)
背景:负号字面量(float(-10.0) / x: float = -3.5)此前回退过——当时 MLIR 渲染报
「f32 类型配 16 位文本」,原因是 mlirlite.ConstFloat 用 snprintf 打印位型时,
高位置位的 32 位值会被按符号扩展后的 64 位打印。该根因已在 includes/mlirlite 侧修死
(提交 8dbad70:十六进制位数只由 MlirTypeText(ty) 定,与 MLIR 渲染器同源,构造上一致),
故此路径恢复为「正确路径」:f32 目标下直接物化 f32 常量,去掉 f64 常量 + fptrunc 的绕行。

- ExprGenOps.translate_unaryop 增加 target_ty 形参:目标为 32 位浮点时折叠直接出 f32 常量;
- ExprGenMixin 把 target_ty 透传给 translate_unaryop。
2026-10-15 19:43:15 +08:00
TermiNexus 3e52baa209 fix(viperc): 回退一元负号字面量的 f32 直出,保留正号字面量与 CDefine 的 f32 直出
- 现场二分定位:float(-10.0) / -float(10.0) 走「按目标类型直出 f32 常量」后,
  MLIR 渲染阶段报 float 位模式位宽不匹配(VKernel 整个编不过);同一份 gfx.vp
  只把负号字面量换成正号就渲染通过,故该路径回退为改动前行为(按操作数自身类型
  出常量,f64 常量 + 使用处 fptrunc)。
- 保留两条已验证有效的修复:
  1) 正号浮点字面量在 f32 目标下直接物化 f32 常量(translate_constant);
  2) CDefine 记宽度种类(1=f64 / 2=f32),define PI: float = ... 的使用处直出 f32
     常量(含 -PI —— 折叠按操作数类型出常量,操作数已是 f32,故仍是 f32)。
- define 常量补 ': int' 注解:无注解 define 按值的最小可存宽度物化(1/2 -> i8),
  直接当实参传给 list[int].append(x: int) 会落成 i8 != i32 被 mlir-opt 拦下
  (自举编译 TypeGenCDef 时必现)。
2026-10-15 19:25:49 +08:00
TermiNexus 508428bbc9 fix(viperc): 浮点常量按目标类型/声明宽度直接出 f32,不再先出 double
- 浮点字面量在 f32 目标(float(1.5) / x: float = 1.5 / f32 形参)下直接物化 f32 常量,
  负号折叠(-c)同口径;去掉旧的「f64 常量 + fptrunc」
- CDefine 浮点条目记录宽度种类(1=f64 / 2=f32):define PI: float = ... 的使用处
  直接出 f32 常量,与 f32 字面量混算不再被提升成 double(现场 33 处 cvtss2sd)
- 本模块注册 / pyi·vpi 跨模块重解析 / xmod 缓存三处都按注解裁决宽度,保持跨模块一致
2026-10-15 18:35:48 +08:00
TermiNexus 3a687db0bb feat(viperc): 静态常量算式补上除法/整除/取模折叠(与运行期 sdiv/srem 同口径)
此前纯常量折叠只覆盖 + - * | & ^ << >>,Div/FloorDiv/Mod 一律落到运行期 sdiv/udiv/srem/urem。现按同一维护口径补上:以精确值折叠,再由既有逻辑按结果值自动提升位宽(不无故抬宽,避免把 A/1 这类算式整体抬成 i64)。语义与运行期一致:Div/FloorDiv → sdiv(向零截断)、Mod → srem(余数符号随被除数)——宿主侧 // 与 % 正是这两个语义,无须额外修正;无符号位型常量按规范恒为非负,与运行期 udiv/urem 取值一致。除零不交给宿主(会打挂编译器):先关掉折叠再 fail-fast,诊断文本与 AssignGenMixin 的常量求值器保持一致。
2026-10-14 22:28:43 +08:00
TermiNexus 38a277a914 feat(viperc): 纯常量折叠补上 / // %,与 + - * 同口径(精确值 + 按值自动提升位宽)
口径与 AssignGenMixin 的常量求值器逐字对齐:①除零先关折叠再 fail-fast(同一条诊断文案,避免交给宿主 Python 打挂编译器);②结果按精确值自动提升位宽,不无故抬宽;③负数语义待定 ⇒ 本轮只折叠两侧都非负的情形(此时 sdiv 与 udiv 结果相同、无歧义),含负操作数的算式不折叠,照旧走运行期 sdiv/udiv/srem/urem。
2026-10-14 22:27:55 +08:00
TermiNexus dc4468593c fix(viperc): CDefine 常量按位宽处理时不再把可容正值翻转成负数,修常量算式折错
现场:Gargantua _start 的 string.memset(fb, 0, GW * GH * 4)(GW=160, GH=90)应折叠为 57600,实际生成 movl \(= -34560)作为 memset 长度 → 从 0x457ca0 写 4GB → 越界写撞到映射区末尾 0x467000,用户态 #PF err=0x7(cr2 与反汇编逐字对上)。根因:define GW = 160 的位宽按值推断为 8(无符号可容),而 _cdefine_bits_value/_normalize_cdefine_bits 无条件 '(value<<56)>>56' 重解释为有符号 → 160 变 -96(=-96*90*4=-34560)。现只在两种解释都装不下时才截断;位型不变(const_int 本就按位宽截断),仅不再翻转可容正值的语义。
2026-10-14 22:20:52 +08:00
TermiNexus a143c2de0c fix(stubgen): 装饰器循环变量改名 ddi,避免与默认值处的注解声明 di 冲突
同一个函数里 di 先被 for 循环绑定为 int(i32),后面又用注解声明为 sizet(i64) 且右值是运行期 i64 值:存储类型 i32 收不下,编译器按 fail-fast 报'带注解重声明冲突'(此前 TPC 是静默丢掉 store,生成的 viperc.exe 在 list[AST*].get 越界读)。装饰器循环改用 ddi,di 保持为首次声明。
2026-10-14 21:13:03 +08:00
TermiNexus 7da9d7cb0d fix(viperc): 位宽探测循环改为固定 64 次上界,修主编译器死循环
- 现象:Phase1 编译到 viperlib.vp 时卡死,栈顶停在 ExprGenOps.vp:1362(我新加的位宽探测 while)

- 原因:`while t != 0 { t = t >> 1 }`(t 为 int64)在生成代码里不收敛(疑似 i64 移位/比较被按窄宽度处理)→ 死循环;改为 `while i < 64 and t > 0` 的固定上界写法,两处(ExprGenOps 运行期常量折叠 / AssignGenMixin 静态求值)一起改

- 遗留待查:该 while 为何不收敛(i64 >> / != 0 的代码生成),属同类“最小宽度”问题面
2026-10-14 19:54:29 +08:00
TermiNexus d09b79995d fix(viperc): 运行期纯常量整型算式按精确值折叠并按值定宽,禁止最小宽度回绕
- 现场:`1024 * 1024 * 4` 在表达式侧按最小宽度(i16)运算,1024×1024 先回绕成 0 ⇒ 常量变 0(WINBUF_MAX_BYTES=0 ⇒ 窗口缓冲只剩几字节 ⇒ 内核 memcpy 240KB 越界读 → 三重故障)

- 在 translate_binop 取到操作数类型后加入纯常量折叠:+ - * | & ^ << >> 两侧都是编译期整型常量时按精确值求结果,并按“能精确容纳该值的最小合法宽度(下限取操作数较宽者)”定宽、向上取 8/16/32/64;只有装不下才加宽(与 61f23d9 的静态求值器同口径)

- 与 61f23d9 合起来:静态 define 求值与运行期常量算式都不再按最小宽度回绕
2026-10-14 19:39:11 +08:00
TermiNexus 61f23d99a1 fix(viperc): 静态常量求值对 + - * << 按结果值加宽,杜绝 define 算式静默回绕
- 现象:Gargantua 的 define V3_POOL_SIZE=8192 / V3_POOL_BYTES=V3_POOL_SIZE*24+512 在运行时变成 512(正好是表达式里的 +512),等价于 8192*24=196608 被按 16 位回绕成 0 → 池只剩 512B → 每像素 trace 立刻 OOM 刷屏

- 根因:extract_cdefine_int_value_bits 的 BinOp 位宽规则只“取较宽”,而 + - * << 会增长结果位宽 → define 物化时按 16 位截断

- 现在:操作数的声明宽度仍保持最小(不提升);基准取较宽者;若精确结果装不进基准宽度,则按结果值加宽(向上取 8/16/32/64)—— 静态计算不再回绕;基准未知(纯字面量算式)时保持“未知”,仍由物化端按值推断

- 顺带:未知 BinOp 算子恢复 fail-fast(重构后原落空分支若留着会静默返回 0)
2026-10-14 19:18:52 +08:00
TermiNexus 813b59e25f fix(viperc): 修正 (expr).method() 接收者误入 get_attribute_ptr 导致的 strcmp(_,0x1) 崩溃
- 表达式接收者分支(L1236 设计上可收 BinOp/Subscript/Call)在接收者求值非指针时会调 get_attribute_ptr;该 API 只接受 Attribute,内部直接强转成 ast.Attribute 并读 .attr,对别的节点会命中偏移 9 的字段:BinOp 的 op(OpKind.Sub=1)、Name 的 ctx(ASTCtx.Store=1)等,于是把整数 1 当字符串传给 strcmp → ASan access-violation on 0x1

- 现在仅当接收者确为 ast.Attribute 时才走“取字段地址”,其余节点保持已翻译的接收者值(与旧实现的回退结果一致)

- 现场:Test/OopInheritTest/App/main.vp 的 (a3 * 2.0 - a4).cross(a5),接收者 BinOp 的 op=Sub=1
2026-10-14 17:57:01 +08:00
TermiNexus ee3337f3c4 revert(viperc): 回退闭包变量取址的放行,仅保留“实参级报错定位”
- 回退 a060e1d 中 ExprGenOps 的闭包取址改动与 TypeGenErr 的临时打印移除:&_on_submit 仍按级数不符报 CastError(source level 2 -> target level 1),语义不变、不放行

- 保留 CallGenCall._call_method_on_ptr 的实参级 AST 节点透传:方法/构造实参转换失败时报错定位到具体实参表达式,并显示完整两帧(函数定义帧 + 错误点)
2026-10-14 17:40:53 +08:00
TermiNexus a060e1d76e fix(viperc): 闭包变量取址返回闭包指针,并让方法/构造实参转换报错定位到具体实参
- ExprGenOps 取址:嵌套 def 提升出的闭包变量在父函数里是 i8** 槽,&f 原来返回槽地址(二级),传给 callback: t.CPtr 会因级数不符报 CastError(source level 2 -> target level 1);现按闭包名表判定,返回其值 i8*(一级),与“函数名即地址(同 C)”一致

- CallGenCall._call_method_on_ptr:实参逐个转换原来统一传 node=None,失败时只能退回函数定义行(只剩一帧);现按 arg_nodes 带上每个实参自身的 AST 节点(slot 0 是 self),报错可定位到具体实参表达式并显示完整两帧

- TypeGenErr:移除定位用的 [TEMP-DIAG] 临时打印
2026-10-14 17:38:50 +08:00
TermiNexus 3c6041c97c fix(viperc/diag): 把“当前实参位置”的记录点下沉到 translate_call_arg(覆盖所有调用路径)
TEMP-DIAG 实测:node=0 curarg=0 trace=1 top=11 —— 节点是合成的(无行号),但“当前实参
位置”压根没被记录,说明该构造器调用没走 CallGenLib 的参数循环,兜底只能退回栈帧(函数定义行)。

改为在**所有调用实参的公共入口** CallGenBase.translate_call_arg 顶部记录(它持有 arg_node),
并移除 CallGenLib 里的重复挂点。这样任何调用路径(含构造器)都能把报错定位到具体实参表达式。
2026-10-14 17:13:38 +08:00
TermiNexus ca81c1185c diag(viperc): 放宽报错位置兜底判据 + 临时打印定位决策输入(定位后删除)
兜底判据改为:只要实参位置有效,且节点行号“不深于”栈最内层帧行号(或栈为空),就用实参
位置 —— 覆盖 FunctionDef 节点被传下来的情形(其行号恰好等于函数定义行、并非真实表达式)。
另加一行 [TEMP-DIAG](node/curarg/trace/top/shown),用于一次看清兜底为何未触发;
定位完成后立即删除该行。
2026-10-14 17:08:59 +08:00
TermiNexus 40ea5d6513 fix(viperc/diag): 节点行号等于函数定义行时也用实参位置兜底(定位到具体表达式)
上一版只在 lineno==0 时用 CurArg 兜底;实测该报错的节点自带行号且恰好等于当前函数定义行
(节点其实是 FunctionDef 本身,构造器内联路径把它传了下来),于是兜底没触发,错误位置与
栈帧都在定义行、被去重合并,看起来只剩一帧。

现把“节点位置不可信”判据放宽为:lineno==0,**或** lineno 等于最内层栈帧的行号(即函数
定义行)→ 两条都优先用 CurArg,报错精确指向调用处的实参表达式(如 `&_on_submit`)。
2026-10-14 17:02:16 +08:00
TermiNexus 4f45b391ea fix(viperc/diag): 保留函数定义帧,不覆盖栈帧位置(补齐“定义帧 + 出错语句帧”两帧)
上一版 B 把最内层栈帧的位置改写成“当前语句”,结果它与错误帧落在同一 file:line,
被去重合并 —— 输出只剩一帧,`_start` 那帧(函数定义)反而没了。

改为:栈帧只记录**被调函数的定义位置**(不随语句推进覆盖);“当前语句/具体表达式”
统一由错误帧给出(CurArg 兜底,见 TypeGenErr)。这样能得到完整两帧:
  File "./Apps/HelloWorld/main.vp", line 11   export def _start() -> int:   ← 定义帧
  File "./Apps/HelloWorld/main.vp", line 36   ... &_on_submit)             ← 出错语句帧
同时删除已无调用的 TypeGenBase.update_top_trace_position。
2026-10-14 16:51:51 +08:00
TermiNexus d6b87da063 fix(viperc/attr): 不再要求 import c 才认 @__attribute__(否则函数属性被静默丢弃)
ast/parser.vp 的 _DesugarMagicAttribute 会把用户写的 `@__attribute__(...)` 脱糖成
`@c.Attribute(...)`,此处看到的 `c.` 前缀是编译器自己产生的(用户并未写 `@c.Attribute`)。
原先这里要求 is_module_imported(...,"c"),用户没写 `import c` 时整条装饰器被静默丢弃,
stackrealign / always_inline 等函数属性全部失效。现去掉该守卫,与 extract_func_section
(本就没有此守卫)保持一致。
2026-10-14 16:42:16 +08:00
TermiNexus 0f2675e794 fix(viperc/codegen): Win64 变参提升按实参符号性选择 zext/sext,避免无符号值高位被填脏
变参调用把 <64 位整数提升到 i64 时原先一律 sext:uint8 0x8E 会被填成
0xFFFFFFFFFFFFFF8E,va_arg(i64) 读到脏高位(即 Debugger/VKERNELERR.md 记录的 sext 家族)。
现按实参符号性选择:无符号走 zext、有符号仍走 sext,与
CallGenVa._check_and_promote_variadic_call 同口径(复用 ExprGenOps.should_zext_widen)。
2026-10-14 16:41:58 +08:00
TermiNexus 0678cc8c48 feat(viperc/diag): 报错定位到具体表达式 + 栈帧跟踪当前语句(方案 A+B)
A:报错节点是合成节点(lineno==0,如构造器内联出的参数赋值)时,优先用“正在翻译的实参
   位置”兜底 → 报错精确指向调用处的表达式(如 `&_on_submit`),不再退回函数定义行。
   - TypeGenBase 新增 CurArgFile/CurArgLine/CurArgCol 与 set_cur_arg()
   - CallGenLib 翻译实参前调用 set_cur_arg(当前文件, arg_node 位置)
   - TypeGenErr 兜底顺序改为:节点自身行号 → CurArg → 栈最内层帧
   - 语句边界清空 CurArg,避免兜底串味到上一条语句的实参

B:栈帧跟踪“当前语句”位置(Python traceback 口径)
   - TypeGenBase.update_top_trace_position():更新最内层帧的 lineno/col
   - translate_stmt 每条语句推进时调用 → 报错时栈帧给出的是调用点所在语句,而非函数定义行
   配合 A 即可得到“调用点 + 具体表达式”两帧。
2026-10-14 16:40:35 +08:00
TermiNexus 70c271d2a4 fix(viperc): &func 对函数指针变量应取其值(Ptr(Func) 一级),不再多一层地址
现场:Apps/HelloWorld 里 vpui.Button(..., &_on_submit) 报
  CastError: pointer level differs (source level 2 -> target level 1);
  source: level 2, pointee !llvm.ptr -> target: level 1, pointee i8

根因:嵌套函数名在符号表里是 Ptr(Func) 变量。ExprGenOps 的取址分支有一条
“变量本身就是那个对象”的规则(结构体指针变量要 load 一次、而非取变量地址),
但该 match 只覆盖了 Ptr(Ptr(Struct)),未覆盖 Ptr(Ptr(Func)) —— 于是 `&f` 落到末尾的
`return v_ao`,给出的是变量地址 Ptr(Ptr(Func))(二级),而不是函数地址 Ptr(Func)(一级)。

修改:在该 match 中补上 Ptr(Ptr(Func)) 分支,load 一次后返回 Ptr(Func),
与结构体指针变量同口径。
2026-10-14 16:37:37 +08:00
TermiNexus 9d02a3ac0b improve(viperc/diag): 指针级数不符报错补印“级数 + pointee 类型”
LLVM 不透明指针下 source/target 两边的类型文本都是 !llvm.ptr,看不出差异,现场只剩
一个 “2 -> 1”。现改为同时打印:
  source: level N, pointee <T>  ->  target: level M, pointee <U>
这样一眼能定位是哪个表达式/哪个形参触发的级数不符。
2026-10-14 16:01:09 +08:00
TermiNexus 6b180c8f59 fix(viperc/life): 进程入口豁免补上 _start(ViperOS 应用入口),消除栈逃逸误报
现象:Apps/HelloWorld/main.vp 报 LifetimeError(`master` frame-local,传给构造器参数会
悬垂)。而 `master = &root` 中 root 是 _start 的帧内 Tk,_start 是进程入口
(@__attribute__(section(".text.startup")),结尾 mainloop/process.exit),本帧返回即进程
结束 —— 与 main 同口径,确无逃逸。

_CurFuncIsEntryMain 此前只认 "main",现把 `_start` 一并视为进程入口。
2026-10-14 15:53:28 +08:00
TermiNexus a23c1bda3e fix(viperc/diag): 调用栈帧与错误点同位置时不再重复打印
现象:`_start` 定义行在 Traceback 里被打印两遍 —— 栈内最内层帧与随后的“错误点帧”
落在同一 file:line(错误的 AST 节点 lineno 为 0 时,错误点位置会回退到栈最内层帧,
于是与栈帧完全重合)。

Diag.emit 增加两条去重规则(DIAG_DIR_UP / DIAG_DIR_DOWN 两个方向都生效):
① 连续两个位置完全相同的栈帧只印一次;
② 与紧随其后的“错误点帧”(emit_current 打印的那一帧)位置相同的栈帧不再重复印。
2026-10-14 15:53:05 +08:00
TermiNexus dc24970af2 fix(gen): 修 __before_init__ 字段默认值写入的参数次序(build_store 缺 builder/file 顺序颠倒),修编译期参数缺失报错 2026-10-13 21:46:20 +08:00
TermiNexus ea54d5685d feat(gen): virtual(HasVTable)类豁免「无 def => struct」规则,必须合成 __before_init__/__init__ 且必发 vtable;非泛型构造路径按符号存在性判定调用 2026-10-13 21:29:24 +08:00
TermiNexus 99a021ad67 fix(gen): 类合成默认构造——有方法但无显式 __init__ 的类合成空 __init__(补 undefined 符号);完全无 def 的类按 struct 处理,不合成 __init__/__before_init__ 2026-10-13 20:59:41 +08:00
TermiNexus 12da1cbfc1 fix(gen): define 复用前置声明时按源码形参名对齐签名参数名,修签名与函数体两套参数名导致 MLIR「region entry argument already in use」 2026-10-13 20:33:06 +08:00
TermiNexus bc1eeb6e38 feat(gen): REPL 会话变量的复合赋值下传槽类型作为 target_ty(复用 repl_slot_ty,缺失即 fail-fast),与二元/普通变量路径对齐 2026-10-13 20:04:34 +08:00
TermiNexus c1e5a11962 feat(gen): 复合赋值统一二元运算口径(常量无损适配另一侧、不做整数提升、RHS 按左值类型翻译),修 u16 -= 1 误报窄化 2026-10-13 20:01:16 +08:00
TermiNexus d2138678ef feat(gen): 同型聚合值 -> 同型聚合指针 允许隐式值拷贝(调用者帧溢出临时槽后取址),修裸类形参接收聚合值实参报错 2026-10-13 18:33:49 +08:00
TermiNexus 1c3cdf3493 fix(stub): 消费模块补齐按值返回聚合的具名结构体完整体(_inject_method_declare 补 _ensure_full_value_types、_inject_class_struct_declare 补登完整定义),修 MLIR opaque 报错 2026-10-13 17:48:57 +08:00
TermiNexus 377c0db5d3 fix(gen): life_of_expr 的构造分支按目标类型判定——目标为同型聚合值时判 LIFE_VALUE(值拷贝),不再误判帧逃逸 2026-10-13 17:48:35 +08:00
TermiNexus 6cb1f525d9 feat(gen): 常量操作数隐式适配另一侧位宽(仅另一侧非常量时),修 u16 变量 + 字面量被抬到 i32 导致误报窄化 2026-10-13 17:01:53 +08:00
TermiNexus a01e9280cc fix(stub,phase1): 因取消整数提升,模块属性 CDefine 的窄乘法显式加宽为 sizet(修缓冲区尺寸回绕成 0/负值) 2026-10-13 16:34:39 +08:00
TermiNexus 14d8c05a2a feat(gen): 二元运算取消 C 式整数提升(任何位宽不再默认提升到 i32),改为按 max(两侧)/目标位宽运算 2026-10-13 16:20:02 +08:00
TermiNexus 97c0a1c6fd fix(gen): 取消「宽整型 -> bool(i1)」的隐式真值归一化,改为 fail-fast(仅保留编译期常量豁免) 2026-10-13 16:07:43 +08:00
TermiNexus d7c5af9b80 fix(gen): callable[[]] 省略返回类型按 void 注册(作为值使用时报错,不再静默按 int) 2026-10-13 13:32:47 +08:00
TermiNexus cb2dc4cb3a feat(gen): 字节序 bswap 改为按目标端序判断(BigEndian/LittleEndian 都相对目标),原语改名 apply_byte_order_bswap 2026-10-13 13:29:03 +08:00
TermiNexus 444e87dd7d fix(gen): callable[[]](省略返回类型)按默认 int(i32) 注册函数指针签名,修间接调用签名缺失 fail-fast 2026-10-13 13:26:51 +08:00
TermiNexus d3997e0746 fix(gen): 函数指针变量别名(f2: rawptr = f)继承已注册的返回类型签名,修 rawptr 间接调用的签名缺失 fail-fast 2026-10-13 13:26:11 +08:00
TermiNexus 32599a08c1 fix(stub): .vpi 读取侧复刻字段标记判定(volatile/pointee-volatile/const/字节序),跨模块不再丢字段标记 2026-10-13 12:30:23 +08:00
TermiNexus 37c4b0da3b feat(gen): 字节序 bswap 代码生成——字段/局部变量/数组元素读写处成对 llvm.bswap(仅 BigEndian 且 16/32/64 位整数) 2026-10-13 12:30:05 +08:00
TermiNexus 5d15d01e21 feat(gen): 支持 t.BigEndian / t.LittleEndian 字节序描述符(注解识别 X|marker 并把字节序登记到 FieldEntry.ByteOrder,暂不生成 bswap) 2026-10-13 12:17:02 +08:00
TermiNexus 3ca2165fd9 feat(gen): 指向同型聚合的指针→同型聚合值允许隐式值拷贝(裸类形参 T* ABI 的直接赋值仍按值拷贝) 2026-10-13 10:30:15 +08:00
TermiNexus b859f8a136 fix(gen): CDefine 常量(含 mod.N 属性形态)拓宽方向单独判定——负值 sext、非负 zext,修 zlib 窗口尺寸被 sext 成负数与 Z_DEFAULT_COMPRESSION->255 2026-10-12 21:48:05 +08:00
TermiNexus 22475e0fda fix(gen): 逃逸检查把模块级(根 scope)变量判为 LIFE_STATIC,修模块级数组 return 误判帧逃逸(pyzlib_error_msg) 2026-10-12 21:23:23 +08:00
TermiNexus c0ff5c9d96 fix(gen): 复合赋值取消「右值有符号 vs 左值无符号」拦截,与二元 x = x op y 口径一致(修 sizet += int 误报) 2026-10-12 21:16:50 +08:00
TermiNexus c9562a6e04 feat(gen): 一元 +/-/~ 按符号性提升——u 类不提升(保持原位宽),i 类提升到 i32 防负数陷阱 2026-10-12 21:10:06 +08:00
TermiNexus d206abf3e1 chore: 全仓同步 w32→win32 模块改名与 range(int(...)) 显式收窄适配 2026-10-12 20:59:11 +08:00
TermiNexus ea2af739dd feat(gen): range 边界与循环变量统一提升到至少 i32(取消 u8/u16 循环变量档),u64 边界保持 i64 2026-10-12 20:57:12 +08:00
TermiNexus 00bf7ebf38 fix(gen): 非负 define 常量按最小位宽的无符号位模式参与宽化/比较(修 range(50000) 迭代 0 次) 2026-10-12 20:52:52 +08:00
TermiNexus e3743b185f fix(gen): zip/enumerate 的 range 源工作位宽随参数(仿 for-range),修 range(3) 被 i64 索引误判窄化 2026-10-12 20:24:50 +08:00
TermiNexus 54b239747e chore(gen): 清理「按值物化」残留注释(裸类形参即 T*,非值语义槽) 2026-10-12 20:03:10 +08:00
TermiNexus ae12ae8581 Revert "feat(gen): 裸类形参按值物化(值语义),调用方 ABI 不变"
This reverts commit 87914b0a51.
2026-10-12 19:56:02 +08:00
TermiNexus 001f8afc37 fix(gen): 常量适配限定为位运算,算术一律按 C 语义拓宽(修 i8 乘法回绕致 memhub 不变式误报) 2026-10-12 19:40:13 +08:00
TermiNexus e7b05c6a3d fix(gen): 三元表达式两支统一按常量无损适配,修 i8 表元素 vs 字符字面量被抬成 i32 的窄化误报 2026-10-12 19:27:58 +08:00
TermiNexus 3d638927d5 fix(gen): 移位的工作位宽不计入计数宽度,修 ushort 表达式被抬成 32 位后赋回 ushort 误报窄化 2026-10-12 19:22:36 +08:00
TermiNexus 4a66aa7fd2 feat(gen): 二元运算采用目标感知工作位宽(仿 C:算到目标位宽;移位只提升左操作数),隐式窄化仍禁止 2026-10-12 18:53:50 +08:00
TermiNexus 9d02cc4684 fix(gen): 移位按 C 语义把左操作数提升到 int,且移位数不参与常量适配(修 uchar<<8 误报) 2026-10-12 18:42:54 +08:00
TermiNexus 65c72fd55c fix(gen): 二元运算按常量无损适配另一侧位宽,修 crc(uint)^0xFFFFFFFF 被抬成 64 位 2026-10-12 18:32:55 +08:00
TermiNexus 8453698f66 chore(gen): ExprGenBase 残留清理(range(int()) 与 TPV->VPC 注释) 2026-10-12 18:25:56 +08:00
TermiNexus 74fafb3b56 fix(gen): 整型字面量宽度按值推导(新增 u32 档)+ 显式宽度严格校验 2026-10-12 18:25:38 +08:00
TermiNexus f044d94e90 fix(gen): -x/~x 对编译期常量折叠,修负字面量被隐式窄化误拦 2026-10-12 18:25:24 +08:00
TermiNexus 87914b0a51 feat(gen): 裸类形参按值物化(值语义),调用方 ABI 不变 2026-10-12 18:25:04 +08:00
TermiNexus d7a5f7e68b fix(gen): 值语义聚合槽豁免改为类型级判定,去掉易漏判的槽身份比较 2026-10-12 16:56:03 +08:00
TermiNexus 7c11c589f7 fix(gen): 值语义聚合槽允许隐式值拷贝,修 self.field = param 的 Foo* -> Foo 误报 2026-10-12 16:42:52 +08:00
TermiNexus 3384941cd1 chore: 改名同步 TransPyV -> ViperC(源码/配置内的纯替换) 2026-10-12 15:06:28 +08:00
TermiNexus d0c7b9c77c chore: 改名同步 TransPyV -> ViperC(.gitignore/文档/脚本) 2026-10-12 15:02:13 +08:00
TermiNexus 9b93586eec docs: README 随改名同步(ViperC/viperc.exe/__vpcbuild__)并纠正过时内容
- w32.* -> win32.*(中文前提条件/对比表、英文 Prerequisites/对比表 共 4 处)
- 规模数字按实测刷新:App 82 文件 63,783 行;Gen 54 文件 47,297 行;
  Phase 6/5,339;Stub 9/6,207;Projectrans 3/712
- 自测套件位置纠正:不在本仓库,位于工作区根 Test\(独立仓库,97 工程 129 个 .vp),
  由 Test\SequentialRegressionTest.py 驱动;删除已不存在的 Test/{App,NegativeTest,Sha1Test} 描述
- 工作区布局补 Test\ 与 exe\,修正 ViperC\ 对齐
2026-10-12 14:48:47 +08:00
TermiNexus 023a22af08 chore: 工程改名 TransPyV -> ViperC(输出 viperc.exe,构建目录 __vpcbuild__) 2026-10-12 14:28:52 +08:00
TermiNexus 4e46a25ab1 fix(gen): define 位宽/整数提升/移位/AugAssign 规则收敛,修 va_list 与 traceback 卡死
- define 位宽:cdefine_decl_bits 单一裁决(注解 → 右侧强转 → 值最小可存宽度),定义方与 VpiReader 两处跨模块注册共用;lookup_cdefine_bits 取最后一条非零记录;存储即截断;使用侧改按声明位宽;通用求值器加编译期除零/移位越界 fail-fast
- 消除对无符号强转加宽方向的依赖:define_min_width 改 (value>>32)==0,截断改左移+算术右移,修 TPC/TPV 判定不一致导致 0x80000000 误判 64 位
- 整数提升:算术/移位、比较、一元 +/-/~ 提升到 i32;位运算保持同宽不提升
- AugAssign:y 有效宽度须 <= x、禁 y 显式有符号而 x 无符号;移位计数静态范围检查
- 函数入口复位 va_list 状态与 willFree 失效槽表(FuncGenDef/FuncGenMixin/VarGenMixin 等)
- BuildPipeline:traceback 逐行扫描改 span 判定,去掉对全文 strlen 的 O(n^2)
2026-10-12 12:37:48 +08:00
TermiNexus be4db7b5d1 fix(narrow): StmtGenMixin exc_code 显式 int(cst_r.int_val)
ast.Constant.int_val 为 int64,exc_code 为 int(并传入 const_int32),改用显式 int(...)
2026-10-11 10:07:37 +08:00
TermiNexus 985983391b fix(narrow): ClassGenBase 方法元数据指针声明 int* 而非 t.CPtr
flags_ptr/flags_ptr2 被显式 (int*)(...) 赋值但声明为 t.CPtr,下标元素被判为 i8,与 i*4 的 32 位步长及位标志语义不符(且 >127 的值会读出符号错误);声明改为 int*
2026-10-11 10:04:19 +08:00
TermiNexus 3b9deb08d8 fix(narrow): ClassGenEnum RenumClassVariantCounts 元素读取改用 int(...)
n_first_v(1029) 与 vcount(1010/1055) 承接 sizet* 元素,原先 64->32 隐式窄化;改用显式 int(...) 保持原截断语义
2026-10-11 10:00:05 +08:00
TermiNexus 7468b007f7 fix(narrow): ClassGenEnum pos_max 加宽为 sizet
pos_max 承接 variant_field_sizes 的 sizet 元素,仅与 sizet 比较并流入 sizet();原 int 触发 64->32 隐式窄化
2026-10-11 09:54:18 +08:00
TermiNexus 3c0d3d13b5 fix(narrow): 清理注解式整数窄化(Converter/TypeGenCType/CallGenLeafKit/ClassGenEnum)
CDefine 查询返回 int64 处按下游用法定型:回传给 int 的用显式 int(...),流入 int64 目标的加宽为 int64;sizet 数组元素赋给 int 的用 int(...)
2026-10-11 09:51:08 +08:00
TermiNexus 966fc3b8f5 fix(narrow): BuildPipeline.ensure_dir 消除隐式窄化(int(path_len) / char(saved))
buf[i] 元素为 i8,saved 由 int 改为 char 并用 char(ch) 显式收窄;plen 由 sizet 显式 int(path_len) 收窄
2026-10-11 09:42:39 +08:00
TermiNexus 77f4a25055 fix(narrow): CallGenFd 的 fd_can 改用 int(len(...)) 消除 64->32 隐式窄化 2026-10-11 09:38:24 +08:00
TermiNexus 82ad5da7c7 fix(narrow): len() 结果赋给 int 的形参/默认值计数改用显式 int(...)
FuncGenDef 的 fd_param_count/fd_default_count/tfd_param_count/tfd_default_count 与 ClassGenVTable 的 md_param_count/md_default_count 原本直接接收 len()(sizet),触发隐式窄化;改 int(len(...)) 保持原有截断语义
2026-10-11 09:34:43 +08:00
TermiNexus d023e9932d fix(narrow): StructGenMixin 守卫候选与归纳区间常量改用 int64,消除 64->32 隐式窄化
kv/lo/hi/k 原本声明为 int 承接 int64(Scratch[...]),触发新禁止的隐式窄化;_AddGuardCand/_PackEscapeClear 的 kv 形参同步拓宽为 int64(打包范围检查需看到完整 64 位值),打包结果处显式 int() 收窄
2026-10-10 22:20:47 +08:00
TermiNexus 41772b4a0c refactor(narrow): 撤销 File.write 实参多余的 ULONG(...) 显式窄化
File.write 形参已改为 sizet,调用点不再需要显式 ULONG 包裹(覆盖 WriteCallSidecar/_phase2_write_cmd/write_ir_to_file/WriteStackMap/TranslateFileGetTrans)
2026-10-10 22:15:49 +08:00
TermiNexus 58951a29a8 fix(narrow): File.write 长度实参加显式 ULONG(...)(避免 64→32 隐式窄化)
fileio.File.write(buf, count: ULONG) 的 count 是 32 位,而实参是 sizet/int64(strlen、pos、ir_len、total 等);规则收紧后为隐式窄化,改为显式 ULONG(...)。本文件其它位置无隐式窄化。
2026-10-10 22:10:01 +08:00