TermiNexus
3e1e1fc1b3
fix(gen): 消除 ViperC 侧 P0 级静默截断
...
match:case 数超过 MAX_MATCH_CASES 时 fail-fast(原先 break 会静默少分支,need_case 检查也发现不了)。vtable:初始化串按真实方法表动态分配,_vtable_strcat 溢出改 fatal;VTBL_METHOD_MAX 超限不再 break(原先子类 override 静默失效)。符号名:coro_pool_/__tls_init_done_/__decor_rec_/闭包 fn_ptr 的定义与引用改为按实际长度分配,消除 96 vs 128、64 vs 128 的不对称。Stub:_PyiEmit 溢出改 VLogger.error(半截 .vpi 会被当完整文件解析);VpiReader 参数段/返回注解缓存槽放不下时 fail-fast,不再丢段导致形参注解错位。Includes:文件超过 1MiB 拒绝哈希(SHA1 冲突会让两个模块共用缓存);add_file_entry 失败不再被忽略。f-string:格式串按字面量/转换符实际长度分配,字面量与 format_spec 溢出 fail-fast。
2026-10-17 18:46:18 +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
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
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
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
d2138678ef
feat(gen): 同型聚合值 -> 同型聚合指针 允许隐式值拷贝(调用者帧溢出临时槽后取址),修裸类形参接收聚合值实参报错
2026-10-13 18:33:49 +08:00
TermiNexus
6cb1f525d9
feat(gen): 常量操作数隐式适配另一侧位宽(仅另一侧非常量时),修 u16 变量 + 字面量被抬到 i32 导致误报窄化
2026-10-13 17:01:53 +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
cb2dc4cb3a
feat(gen): 字节序 bswap 改为按目标端序判断(BigEndian/LittleEndian 都相对目标),原语改名 apply_byte_order_bswap
2026-10-13 13:29:03 +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
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
00bf7ebf38
fix(gen): 非负 define 常量按最小位宽的无符号位模式参与宽化/比较(修 range(50000) 迭代 0 次)
2026-10-12 20:52:52 +08:00
TermiNexus
54b239747e
chore(gen): 清理「按值物化」残留注释(裸类形参即 T*,非值语义槽)
2026-10-12 20:03:10 +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
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
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
5bb6538703
feat(types): 禁止隐式窄化(整数 高→低);_tb_read_whole 容量改 sizet
...
规则收紧(2026-10-10):整数位宽 高→低 隐式窄化一律 fail-fast(CastError),仅两类豁免:① 目标 i1 的真值归一化;② 源是编译期常量且值落进目标位宽。_scalar_convert_reason 的 int↔int 同步改为'目标位宽≥源位宽才 PC_OK'。BuildPipeline._tb_read_whole 去掉 ULONG(sz)+ULONG(2) 的窄化,改 sizet(sz)+2。
2026-10-10 21:57:18 +08:00
TermiNexus
c98730f717
refactor(diag): 精简 LifetimeError 报错词,去掉冗长从句
...
逃逸主报文由三段长从句压缩为「frame-local + 悬垂 + 修法」两句:
stack address escapes: `&x` is frame-local; using it at {where} hands out a dangling pointer
once this frame returns. Copy the value, or allocate on the heap (`new heap hlife ...`).
同步缩短 where 短语(return value / escaping callee|method parameter / constructor parameter stored
into a field / longer-lived field-element / module-level global)
其余冗长报文一并精简:willFree 失效、slife 手动 free/del、async slife、stack+hlife 矛盾、三处容量上限、
@life 标签实参缺失
测试只断言关键字 LifetimeError,不受文案影响(Test/*.py 已确认)。
2026-10-09 19:22:04 +08:00
TermiNexus
dd24dc670f
fix(gen): P2 失效状态改存独立槽表,不再给 VarEntry 加字段
...
现象:任何工程编译都在函数形参注册刚结束处 access-violation(pc=0,逐字节可复现)。定位:逐层探针把崩点压到 FuncGenDef 的 pre_scan 段,而该段对 Check(body 仅 if+return)应为空操作,唯一变量是 VarEntry 这个热结构被加了 Freed 字段。修法:撤销 VarEntry.Freed,改用 VarGenMixin 的独立失效槽表 _g_freed_slots(键 = 变量槽 alloca,整次翻译内唯一,故全局累积、无需按函数 reset/restore);_FreedMark/_FreedCheck/_FreedClearSlot 三个 API 替换字段读写,P2 语义不变。同时清除全部 TEMP 探针。
2026-10-09 11:51:11 +08:00
TermiNexus
b60ce06335
feat(gen): willFree 覆盖关键字实参、方法调用与取地址三条路径
...
关键字/混合实参:CallGenMixin._MarkWillFreeKwargs 按形参序(位置实参占前 can 个形参,其余按关键字名匹配)标记。方法调用:CallGenCall._translate_method_call 的 kwargs 与位置两条循环,实参链含 self 故用户第 ai 个实参对应 bit (ai+1);新增 GenApi/StructGenMixin.get_param_willfree_method(查 Class.method 并沿 MRO 回退)。取地址:ExprGenOps 的 AddrOf 分支对已失效变量 fail-fast。
2026-10-08 21:39:53 +08:00
TermiNexus
97313e9e55
feat(gen): P2 生命期标注 @life(willFree(...)) 驱动释放后使用与二次释放检查
...
标注面:@life(willFree(<形参名|0起序号>)),兼容叠加式 @willFree(...),可混用累加;序号按形参表下标、self/cls 计入。GenApi.compute_willfree_mask 解析标注并对非法标注 fail-fast。本文件表 StructGenMixin.WfTable + 跨模块 .vpi 行尾 wf=<mask>(Converter 写 / VpiReader 读 / CallGenBase 查)。调用点在实参全部翻译之后把对应实参变量槽置 VarEntry.Freed;其后的读取路径报 LifetimeError。重新赋值清除失效态。
2026-10-08 21:28:49 +08:00
TermiNexus
934708b206
fix(type): 数组退让豁免提到级数检查之前,修 [N]str 形参被误判 CastError
...
形参侧 CArray 按 C 语义退让成元素指针 str*(级数 2),实参仍是 [N]str 的数组地址(级数 1)→ _ptr_cast_reason 先查级数就判 PC_DEPTH,_pointee_convert_reason 里那条既有数组退让豁免成了死代码。元素为 i8 时级数不变所以一直没暴露,元素本身是指针才炸(现场:includes/tomllib _parse_key_path 的 segs)。
2026-10-08 20:03:42 +08:00
TermiNexus
64502471e1
feat(gen): M2.4 new 描述符语义落地(stack/heap/memgr 三来源)
...
CallGenCtor 新增 _translate_new_expr:只替换取存储一步——stack 用帧内 alloca、heap 用 malloc(sizeof)+bitcast、memgr(x) 用 x.alloc(sizeof)+bitcast;其余构造序列(__before_init__ → __init__ / 字段赋值)用合成 Call 复用原路径,因此 __init__ 的逃逸检查对 new 同样生效;结果恒为 T*。
文件级 _g_new_storage 承接描述符算出的存储,两个 ctor 入口的默认 alloca 改为有则复用;_translate_new_expr 前后保存/恢复,支持嵌套 new。
§2.4:stack+hlife 语义矛盾 fail-fast;memgr(x) 拿不到管理器类 fail-fast。ExprGenMixin 分派 ASTKind.New。
2026-10-08 17:45:39 +08:00
TermiNexus
7070bc1608
feat(gen): 栈地址逃逸检查(LifetimeError)、按值返回聚合、标量→聚合 fail-fast
...
- GenApi.fail_if_stack_addr_escape:禁止把本帧栈地址写出帧外(显式 &local,以及局部数组名退让到指针目标,如 return arr with '-> char*');裸聚合名 + 同型聚合目标是值拷贝,不在其列;err_type 记为 LifetimeError。 - StmtGenCifMixin.translate_return:按值返回聚合时,对被指类型与返回聚合类型同一的指针补 load(与多返回值 struct 的 ret 同形),修复 return 局部数组报 CastError。 - ExprGenBase.coerce_to_type:聚合目标不接受标量(旧行为落成 store i32 0, ptr,只写首元素字节并抬高对齐),改为编译期 fail-fast。
2026-10-08 12:10:13 +08:00
TermiNexus
5c1b882169
chore(gen): c.CIf 家族移除报错覆盖 CElif/CElse/CEndif,注释口径统一为 cif
...
ExprGenName / CallGenDispatch 的「已删除拼写」守卫原本只认 CIf/CIfdef/CIfndef,现补齐 CElif/CElse/CEndif 六个(与 TPC 侧一致),报文同步;StmtGenCifMixin 的头注释、docstring 与状态注释把语句统一称作 cif,内部标记仍写作 c.@CIf 族。
2026-10-07 19:10:05 +08:00
TermiNexus
2fb648d68a
feat(lang): 新增 cif/celif/celse 条件编译与值引用注解 &T/&temp T,assert 改译 testcheck.check
...
cif 三件套:StmtGenCifMixin 负责常量求值(含 defined(模块宏) 的 Attribute 形式),链式错配与含运行时变量一律 fail-fast;删掉 c.CIf 家族。值引用:TypeGenResolve 让 CRef/CTempRef 与 t.CPtr 走同一解析路径(&void 折叠为 i8*,删除 t.CNeedPtr),CallGenBase 在调用点按形参模式自动取址(ref 只接受左值,右值 fail-fast;temp 物化临时栈),跨模块经 VpiReader/StubMergerBuild 传递模式。assert:StmtGenMixin 合成 testcheck.check(cond, None, msg),Translator 检测到 assert 时自动注入 testcheck 导入(带去重与防环),深递归守卫改用 stdio.printf + stdlib.exit(Translator 无 Gen 成员)。
2026-10-07 19:03:16 +08:00
TermiNexus
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