549 Commits
Author SHA1 Message Date
TermiNexus e33792a9ad feat(linker): TPC 支持 project.vpj 静态链接 .a/.obj
- Config.py 读取 linker.static_libs(相对 vpj 目录解析为绝对路径)

- Phase2Translator 新增 static_libs 参数,并入 extra_link_files 参与链接(位于 -o 之后、-l 之前)
2026-09-01 20:15:17 +08:00
TermiNexus ca1e58f6fa feat(linker): TPC 支持 project.vpj 静态链接 .a/.obj,ViperFLProject 配置 fltk
- Config.py 读取 linker.static_libs(相对 vpj 目录解析为绝对路径)

- Phase2Translator 新增 static_libs 参数,并入 extra_link_files 参与链接

- ViperFLProject 改为 fltk GUI 测试:static_libs 链接 cfltk2 + FLTK 静态库

- 新增 FLTK 所需系统库 flags(comdlg32/comctl32/ole32/uuid/winmm/gdi32)
2026-09-01 20:15:02 +08:00
TermiNexus 6892183cc9 feat(fltk): 新增 FLTK 1.4 纯 extern FFI 绑定库(对接 cfltk C API)
- 生成 24 个 _cfl*.vp(10327 条 extern 声明)+ _types/_enums 常量

- __init__.vp 提供 Fl/Fl_Widget/Fl_Window/Fl_Button/Fl_Input/Fl_Text_Buffer/Fl_Group/Fl_Menu_Bar/Fl_Native_File_Chooser 等包装类

- 回调(Fl_Callback)按 bytes 不透明处理,菜单回调位传 t.CPtr(0)

- 新增 examples/hello.vp、dialog.vp 冒烟样例,26 个 .vp 全部通过 vast parse

- 内嵌 cfltk(C API 封装)与 FLTK 1.4 完整源码,构建目标 cfltk2
2026-09-01 19:53:54 +08:00
TermiNexus 2b5286ea11 fix(ast): parse_expression 返回注解改为 Expression | t.CPtr
- parse_expression 实际返回 Expression 包装节点(body 字段为实际表达式),
  原注解 AST | t.CPtr 类型不精确——调用方需强转才能访问 body
- 源头修正返回类型,调用方直接 expr_node.body 即可
2026-08-29 07:26:06 +08:00
TermiNexus 8c82629b0a test(vpt): 类型系统收敛测试——别名反查/typedef 链/__sizeof__ 联动
- T6: from-import 别名反查(MyInt/MyByte)+ typedef 值引用别名(MyWord=MyInt)
- T7: 库 typedef 裸名解析(BYTE/DWORD/MyDword 链)+ t/c 核心特判保留(CBool)
- T8: __sizeof__ 库 typedef 尺寸联动(BYTE=1/DWORD=4/MyWord=4/CBool=1)
- T9: typedef 联合(BYTE|t.CPtr)指针包装 + * 解引用
2026-08-29 06:22:36 +08:00
TermiNexus 65dd4a5e3e docs(_Type): 类型系统收敛方案阶段 1/2/3 实施完成 2026-08-29 06:15:09 +08:00
TermiNexus 103c6ae865 docs(_Type): 标记泛型特化名分裂完成(问题 7),状态更新为 2/4/7/8 已完成 2026-08-29 05:51:55 +08:00
TermiNexus 3ff0db2953 docs(_Type): 标记窄化截断诊断完成(问题 8),状态更新为问题 2/4/8 已完成 2026-08-29 05:48:20 +08:00
TermiNexus 90a74e4e2c fix(tpv): 支持 PEP 701 同引号嵌套 f-string 并记录解析错误位置
- lexer.vp: _read_string 增加 f-string {} 深度跟踪,跳过表达式块内嵌套字符串字面量(含 {{/}} 转义、跨行报错)
- parser.vp: _parse_fstring 表达式扫描同步跳过块内嵌套字符串,三条 error_count 路径补 _record_parse_err(消除'第 0 行 0 列'不可读错误)
2026-08-28 12:50:38 +08:00
TermiNexus bc017d0a61 feat(tpc): 解析错误记录具体 token 位置(消除'第 0 行 0 列'不可读错误) 2026-08-28 12:25:38 +08:00
TermiNexus 60dbdfe8d2 fix(tpc): 方法调用虚分派——变量与模块短名同名时不误入模块函数路径(base.kind 折叠根因) 2026-08-28 10:23:26 +08:00
TermiNexus db80178d2e fix(tpc): is_instance_var 判定豁免与子模块短名同名的已注册变量(base.kind 误判为模块路径) 2026-08-28 08:23:08 +08:00
TermiNexus 63bc435723 feat(tpc): 注解支持 C 风格指针后缀 T*(int* → int | t.CPtr 多级展开) 2026-08-28 08:01:03 +08:00
TermiNexus 0230385891 feat(tpc): 新增单目 * / & 运算符(Deref/AddrOf)AST 节点与 LLVM 翻译 2026-08-28 07:34:58 +08:00
TermiNexus d6150bd595 工作提交,增加 Test 2026-08-28 05:59:47 +08:00
TermiNexus e376b949c9 fix(memhub): 移除 free 记录前标记校验——合并重分配误报(与 w0/w1 同类)
下溢写误报实锤:1024B free 块 hdr=0x0、同 ptr 仅一条 F 记录、前标记被写零——块合并进更大块后新分配用户区覆盖旧记录前标记区而旧块头仍为 0,前标记校验原理性不可靠(SlotsBugTest 1024B 块误报例)。

移除 free 记录全部校验,只保留 active 记录前/后标记校验(存活块独占,header LSB=1 不会合并,可靠)。
2026-08-25 17:21:27 +08:00
TermiNexus c9ccea4014 feat(memhub): 下溢写打印增强——块头/记录index/上下文/同ptr记录
SlotsBugTest 越过 can 问题后新信号:free 块前标记(block+8..9)被写零(前标记区是安全区,子块边界2^n>=32永不落此,free-list写只在block+0..7)→ 真实下溢/UAF写。

增强打印:hdr 块头值(判断 free-list 状态)、记录 index、±3 上下文记录、同 ptr 记录(F/A 标注),一次运行定位写入者。
2026-08-25 17:17:29 +08:00
TermiNexus 3ac48282a3 feat(callgenctor): 构造参数列表头+槽位 0xCDCD 诊断
ASAN 崩溃 node=0xCDCDCDCDCDCDCDCD(_translate_struct_ctor → translate_value)确认:is_alive(cargs) 只验列表结构体,get() 读的是 __data__ 数组——两者都可能未初始化(MEMBUDDY_FILL_GUARD 无条件填 0xCD)或悬空。

新增:读取列表头(__data__@0 __count__@8 __capacity__@16),命中 0xCDCD 打印定位 fail-fast;预检每个实参槽位 0xCDCD 并打印 ai/can/data/count/cap。区分列表未初始化 vs 槽位悬空两种根因分支。
2026-08-25 16:29:48 +08:00
TermiNexus 7c7629852a perf(memhub): detection 采样探测,O(n²) 降为 O(n²/256)
每次 alloc 全表扫描(分配重叠 + _det_probe)是 O(n) ,2M 次 alloc = O(n²),detection 模式过慢。

改为每 MEMBUDDY_DET_PROBE_PERIOD(256) 次 alloc 采样扫描一次;记录追加保持 O(1)。损坏是持久性的,不依赖即时扫描,检测能力不损失。
2026-08-25 16:21:34 +08:00
TermiNexus b777d7c925 fix(memhub): 移除 free 记录 0xCD 完整性校验,消除 buddy 自写误报
free 记录 w0/w1 校验验证 free 后用户区 0xCD 完整,但 buddy 分配器 free 后会把 next 指针/子块头合法写进 free 块(free 块用户区即管理区),0xCD 必然被破坏 → 持续误报(SlotsBugTest 4352B 块首 8B=0x400000000、前标记完好的误报例)。

只保留可靠的前标记校验(子块边界 2^n>=32 对齐永不落在 block+8)。0xCD 填充保留。探测器可推进到 Phase2 用 is_alive 抓真实 KwEntry cargs 读取型 UAF。
2026-08-25 16:16:02 +08:00
TermiNexus 0f6ebb9065 fix(memhub): detection 记录表随 reset_to/reset 截断
reset_to/reset 只把块归还 free list、从不清理 _det_records,导致 reset 后旧记录仍标 active:下一轮 alloc 复用同一块被误报为分配重叠/越界写(SlotsBugTest 7B buf + 72B Token 误报根因),探测器在 Phase1 扫描就 exit(1),永远走不到 Phase2 的真实 UAF 检查。

修复:reset_to(mark) 同步截断 _det_count=mark(与 chk_depth 等长,每次 alloc 各追加一条、free 只置标志不删),reset() 置 _det_count=0。
2026-08-25 16:05:21 +08:00
TermiNexus 74ed6f2dbc feat(memhub): 分配重叠即时检测
SlotsBugTest 崩溃实锤:同一块被重复分配(记录表同 ptr 两条,[353]sz=7 与 [10298]sz=72)——7B 字符串缓冲与 72B Token 重叠,Token 初始化覆盖 buf 导致越界写,KwEntry cargs 只写 0/40 根因。

根因指向 MemBuddy free list 损坏(active 块混入 free list)。新增检测:每次 alloc 前将新块地址与 active 记录比对,命中即打印两个 size 并 exit(1),在第一次重叠处拦截,便于回溯具体分配调用。
2026-08-25 16:01:07 +08:00
TermiNexus 49feb6a2b4 feat(memhub): [DET] 越界写追加同ptr记录检测 - 扫描记录表找同一 ptr 的多条记录,验证 alloc 重叠(Token 72B 与字符串 buf 7B 共用块 → 互相覆盖),定位 size=7 块被当 Token 写的根因 2026-08-25 15:57:45 +08:00
TermiNexus d3a84c25e0 feat(memhub): [DET] 越界写追加记录表上下文 - 打印越界块前后各3条 {ptr,size},推断分配阶段(如 lexer/parser 小结构),配合越界区数据定位 size=7 块写入者 2026-08-25 15:53:44 +08:00
TermiNexus 878840a081 feat(memhub): [DET] 越界写追加打印越界区24字节 - 判断写入者写多长/方向(0x00=写穿 0xCD=未写 其它=写入值),定位 size=7 块 {10,1} 越界写源头 2026-08-25 15:51:24 +08:00
TermiNexus e48f2104ff feat(memhub): [DET] 越界写打印块内容前16字节 - 定位 size=7 块被越界写的写入者(扫描 includes 阶段,后标记被写 0x0000) 2026-08-25 15:47:04 +08:00
TermiNexus fe98b5048e fix(memhub): __init__ 显式初始化 detection 字段防默认值失效 - TPC 类字段默认值对 CDefine 常量可能不生效,detection_size=垃圾 → malloc(垃圾) 1-byte 记录区 → 扩容 realloc double-free(ASAN 捕获);显式赋值 detection_size/MEMBUDDY_DET_RECORD_SIZE + _det_arena/_det_records/_det_count/_det_cap 2026-08-25 15:43:54 +08:00
TermiNexus 40f10f6348 fix(memhub): detection 记录表满时 realloc 扩容 - 原 32MB/16B=2M 条满后新 alloc 无记录,is_alive 误报读取悬空(hdr=0x5 活跃块不在记录表);改为 stdlib.realloc 翻倍扩容(对齐 chk_stack),保证 is_alive/_det_probe 全程覆盖 2026-08-25 15:39:09 +08:00
TermiNexus b3b82a8093 feat(tpc): [DET] 读取悬空打印 cargs 指向块头 - is_alive 拦截时输出 cargs/block/hdr(0=已free UAF实锤 奇数=活跃但记录表异常 其它=非pool块),定位 KwEntry cl.args 悬空源 2026-08-25 15:35:28 +08:00
TermiNexus fefc1e8343 feat(memhub): 读取侧存活校验 is_alive - 补 detection 写入检测盲区:struct_ctor 读 cargs 前校验 cl.args 是否在记录表 active 记录中,不在即 [DET] 读取悬空 打印 cargs 值并终止;拦截 use-after-free 读取(SlotsBugTest KwEntry cargs=cl.args 悬空根因),detection==0 时 is_alive 恒返回 1 不拦截 2026-08-25 15:31:39 +08:00
TermiNexus 1de7c8d2ca chore(tpc): 移除全部临时 DBG 日志 - VDBG(ExprGenMixin)/CTORDBG(CallGenCtor)/LISTDBG(_list)/ALLOCDBG+set/get_debug_log+set/get_alloc_src(memhub)/CLDBG+[DEPDBG](CallGenMixin)/--enable-debug-log(main)/set_alloc_src(HandlesTranslator);保留 detection 机制(前后 0xCDCD 标记+记录表探测)与 MEMBUDDY_FILL_GUARD 守卫 2026-08-25 15:17:51 +08:00
TermiNexus 769ffda04f feat(memhub): detection 补前标记探测(对称拦截下溢写) - active 记录验证返回ptr-2 处 0xCDCD,free 记录同样验证前标记+用户区 0xCD;与后标记上溢检测、free 填 0xCD 的 UAF 写入检测构成完整三方覆盖 2026-08-25 15:12:48 +08:00
TermiNexus 91120ae00a feat(memhub): detection 增强 - free 后用户区填 0xCD + 记录保留并置 free 标志,探测时对仍 free 的块验证 0xCD 完整(首末 8 字节),被写穿即 [DET] UAF 写入 报警终止 - 拦截 use-after-free 写入(如 SlotsBugTest KwEntry cargs 块 free 后被部分覆盖),与后标记越界写检测互补;块被重新 alloc 后块头变奇数自动跳过旧 free 记录防误报 2026-08-25 15:02:14 +08:00
TermiNexus 0efd438bfb feat(main): --detection 命令行开关应用 MemBuddy 分配检测到双池 - 创建内存池前用 GetCommandLineA 扫描 --detection(sys._init_argv 依赖 mb 不能提前),mb(1GB) 与 perm_pool(512MB) 均传 detection 布尔;detection 数据区大小硬编码 32MB(memhub MEMBUDDY_DET_RECORD_SIZE);argparse 注册 --detection 帮助项 2026-08-25 14:59:21 +08:00
TermiNexus c559c0f2d6 feat(memhub): MemBuddy 分配检测机制(detection 开关) - alloc 布局改为 [0xCDCD][size][0xCDCD](实际多 4 字节,返回指针后移 2 字节,free/realloc 前移 2 字节回收);每次 alloc 记录 {返回ptr,size} 到独立 32MB 记录区(stdlib.malloc,默认 detection_size=32MB),随后探测全部存活块后标记——被破坏即越界写,汇报 ptr/size 并终止;free 时移除对应记录防块复用误报。定位 SlotsBugTest KwEntry cargs '存活块被部分覆盖' 的写入者(ASAN/Valgrind 对自研池透明,此机制补齐池内越界写检测盲区)。MemBuddy(arena, size, detection=1) 开启,默认 False 2026-08-25 14:56:04 +08:00
TermiNexus 21e67cac40 fix(tpc): 含 raise 函数调用参数补全排除 EH 输出参数,杜绝双重注入 - CallGenMixin 零值兜底与 CallGenCall found_func 参数数回退原将 %__eh_msg_out__/%__eh_code_out__ 计入形参数,为 raise_disk() 无参调用补 2 个 zeroinitializer 占位,_emit_eh_guarded_call 又追加真实 EH 实参 → call 4 参 vs define 2 参 → x64 ABI 错位 → 函数写 null 输出指针 0xC0000005(TestFBProject raise_disk 崩溃根因);三处计数均排除 EH 参数 2026-08-25 14:04:27 +08:00
TermiNexus 916c1284c9 fix(tpc): 虚调用 vtable 布局按接收者静态类型解析而非 this 调整后父类指针 - _do_virtual_call 原用 self_ptr.Ty 解析 vc_entry,多继承中 self 被 bitcast 成父类指针(如 ColorM*)后得到父类单槽 vtable 布局(method_index/method_count 按父类算)→ GEP 槽位 0 读到 area 而非 color_code(MultiInheritTest color_code 虚调用 FAILED 根因);改优先用 vtable_base(对象头)类型解析,未传 vtable_base 时回退 self_ptr 保持原行为 2026-08-25 13:53:56 +08:00
TermiNexus 3100bb9343 feat(memhub,list,llvmlite): 0xCD 分配守卫、诊断开关与 INT64_MIN 常量修复 - memhub.vp alloc 填充 0xCD 哨兵 + set_debug_log/get_debug_log + ALLOCDBG 分配者记录; _list.vp __init__/append 诊断; llvmlite i64 INT64_MIN 输出无符号位模式(LLVM 拒绝 -9223372036854775808 字面量)。定位 SlotsBugTest KwEntry cargs use-after-free 与常量 dump 错误 2026-08-25 13:19:08 +08:00
TermiNexus c3a43dfe76 refactor(includes): 标准库 extern 软关键字语法迁移 + _append_cstr O(1) 追加缓存
- posix/stdio 等 19 文件: def ... -> T|t.State: pass 改写为 extern def ... -> T
- llvmlite/__builder.vp: _append_cstr 加写入位置缓存(_g_last_dst/_g_last_pos,缓冲切换/重置自动回退 strlen,防 O(n^2))
2026-08-24 23:31:12 +08:00
TermiNexus 50ca560563 fix(tpc): list 联合类型方法分派保护 + str 压平条件收紧 + external global 裸名兼容
- HandlesAssign: 变量已有同 base 声明类型时不再覆盖 var_struct_class(sha1 前缀特化名覆盖裸名,导致 dbody.get 查表 miss 后 fallback 到 list[int].get,i32 返回值被截断成垃圾指针崩溃——TPC 侧根治)
- HandlesExprCall: IdentifiedStructType 真值判断改 is None(opaque 时 bool() 触发 __len__ assert)
- HandlesFunctions/HandlesImports: IsStr 压平条件加 PtrCount<=1,str|t.CPtr(i8**) 不压平;external global 正则兼容裸名格式
2026-08-24 23:31:08 +08:00
TermiNexus 3b0a73db5e fix(tpc): _translate_file 以 out_path 文件名作 sha1,修复前缀漂移链接失败 - 原实现重读文件重算 sha1 覆盖 _module_sha1:主流程收集与翻译间隙文件变化时,函数定义前缀与文件名/调用方引用前缀不一致(696d41ca86e0a29a.BuildTopoSortedIndices 被生成成 5536… 前缀)→ ld.lld undefined symbol - 改为以 out_path 文件名(主流程 sha1)为准并告警内容变化,保证链接一致 2026-08-23 14:03:34 +08:00
TermiNexus 1dc23ffdde feat(tpc): llc 编译阶段日志带进度/源文件/耗时
- 用户反馈 SUCCESS: xxx.ll 只有 sha1 看不到对应源文件与进度
- 改为 '[i/N] sha1.ll  源文件相对路径 (耗时s)'(sha1_map 反查源文件,提交时刻计时含排队)
2026-08-22 08:05:19 +08:00
TermiNexus 7b04b72d4b feat(tpc): 翻译进度日志带源文件路径与耗时——并行时不再只有 sha1
- 用户反馈并行分支日志只有 -> xxx.ll(sha1 无文件名无耗时),看不到进度
- _translate_file 加计时,打印改为 '-> xxx.ll  <源文件相对路径> (Xs)'(含仅声明分支)
2026-08-22 07:41:58 +08:00
TermiNexus ebfaacf7bf fix(tpc): worker cProfile 默认禁用——环境变量 TPC_WORKER_PROF=1 开启
- 之前 getprofile 互斥检查仍冲突(用户环境仍报 Another profiling tool is already active,viztracer --log_multiprocess 场景)
- 彻底修复:cProfile 默认不启用(TPC_WORKER_PROF=1 显式开启才启用),与 viztracer 等外部 profiler 完全解耦;开启时仍有 getprofile 让位 + enable 异常兜底双保险
- 冲突根源:Python 只允许一个 profiling tool 活跃,TPC worker cProfile.enable() 检测到 viztracer 注入的 profiler 即抛错 -> worker 崩溃 -> batch 异常 -> 编译终止
2026-08-22 07:31:06 +08:00
TermiNexus c2f07e10cd fix(tpc): worker cProfile 与 viztracer 互斥——外部 profiler 活跃时跳过
- 冲突机制:viztracer --log_multiprocess 经 sys.setprofile 注入 profiler 到 worker,TPC _ProfileWorker 的 cProfile.enable() 检测到已激活 profiler 抛 'Another profiling tool is already active' -> worker 崩溃 -> batch 0 异常 -> 编译终止
- 修复:_ProfileWorker 先查 sys.getprofile(),非 None(viztracer 等外部 profiler 活跃)时跳过 cProfile 让 viztracer 独占;正常编译(无外部 profiler)仍保留 cProfile(PROF 数据不受影响)
2026-08-22 07:16:52 +08:00
TermiNexus d092b4d31f perf(tpc): 并行 worker 决策放宽——per_worker_mb 700 降至 350
- 根因:_PickWorkerCount 按可用内存/700MB 决定 worker 数,实测翻译 worker 稳态 ~110MB/峰值 ~300MB,700 过保守——可用内存稍紧即整体降级单 worker 串行(76 文件逐个翻译 1180s vs 并行 ~400s,2-3 倍波动,用户反馈编译不稳定)
- 修复:per_worker_mb 700 -> 350(留峰值余量),更多场景走并行
2026-08-22 06:54:56 +08:00
TermiNexus c62153a685 perf(tpc): import 热路径优化——walk 结果缓存 + DebugPrint 参数惰性化
- import 兜底查找(_EmitModuleDeclarationsLlvm)每次解析失败都 os.walk 递归扫描 includes/工程目录,且多级模块名与 basename 永不匹配纯浪费:改为多级跳过 + 目录 walk 结果类级缓存(编译进程内目录不变)
- DebugPrint 调用点(HandlesTypeMerge 类型查询热路径)无条件构造 f-string 参数(含昂贵的 ast.dump),即使 DebugFile 未设置也执行:改为 getattr(DebugFile) 防护后才构造(单文件 profile:_io.open 1253 次 1.76s + DebugPrint cum 2.24s)
2026-08-22 06:05:43 +08:00
TermiNexus daf79af1cc fix(tpc): 返回 fail-fast 豁免 void 联合注解与 extern/export 声明型函数
- sprintf 误报:返回注解 t.CVoid | t.CExport(BinOp BitOr 联合)被旧判定忽略 -> 掉出末尾误报,且 [FATAL] 终止杀死 include worker -> BrokenProcessPool
- 修复:新增 _IsVoidOrDeclAnnotation 递归识别联合注解(注解中 | 表示 and):void(None/t.CVoid)+ extern/export 声明型辅助符号(State/CExport/CExtern)均豁免
- 验证:t.CVoid|t.CExport / int|t.State / t.CVoid / None -> 豁免;裸 int -> 仍 fail-fast(missing_return 用例保持命中)
2026-08-22 05:17:03 +08:00
TermiNexus 0e8283551c 修正 HandlesExprCall 的 import 2026-08-22 04:35:40 +08:00
TermiNexus 56a4b5c818 fix(tpc): stub 加载器解析全局变量声明——跨模块全局变量不再静默丢失
- 根因:_LoadDeclarationsFromStubLlvm 只解析 struct/declare,忽略全局变量声明行,TPC 编译 TPV 时跨模块全局变量(StubMerger._sha1_store_count 等)从未嵌入 Gen.module.globals
- 后果:_lookup_module_global 恒 None -> return 静默跳过 ret(HandlesReturn 的 if Val 分支)、跨模块赋值静默丢失
- 修复:逐行循环加分支解析 16hex 前缀的 external global 声明(剥离 zeroinitializer 与 align 尾部修饰),用 _parse_llvm_type 解析类型后嵌入 external GlobalVariable;.str. 内部常量与 @main 等非 16hex 前缀跳过
- 诊断脚本验证 4 种真实 stub.ll 格式(struct 指针/数组/zeroinitializer/vtable 结构体)全部解析成功
2026-08-22 04:21:04 +08:00