TermiNexus
|
c86ecb0c89
|
refactor(LLVMCG/Handles): 直建 ir.Function 点全部收敛到幂等入口,3 处不再吞 fail-fast
类别:a 编译器缺陷(同一根因的其它变体收口:函数声明创建的唯一入口 + fail-fast 不被吞)
背景(前几轮已修两处):llvmlite 的 `Function.__init__` 不是事务性的(名字在 `_set_name`
就进 module.scope,之后建 Argument/ReturnValue 才断言类型,最后才 add_global),中途失败会
留下悬空名字;本仓已加两道防线:全局守卫 `InstallFuncCreateGuard()`(回滚名字 + 带调用点的
FailFastError)与唯一幂等入口 `_CreateOrReuseFuncDecl`(创建前自检、同名同类型复用、异类型
带两侧签名 fail-fast)。但仍有 20+ 处**绕过入口直建**(同名时抛裸 DuplicatedNameError、且
名字被占/半注册时只能看到没有上下文的名字),以及若干处 `except Exception` 会把这颗
FailFastError 吞掉(声明静默缺失、真因丢失)。
改动:
1. 创建点收敛(21 处,行为等价或更严)——`X = ir.Function(<gen>.module, <fty>, name=<N>)`
→ `X = <gen>._CreateOrReuseFuncDecl(<N>, <fty>)`:
· Handles:HandlesAnnAssign[llvm.memcpy]、HandlesAssign[llvm.memcpy.p0i8.p0i8.i64 ×2]、
HandlesBase[GetOrCreateFuncDecl / GetOrCreateStubFuncDecl]、
HandlesExpr[malloc]、HandlesExprBuiltin[strlen / llvm.memcpy]、
HandlesExprCall[llvm.* 与普通 / win32 API / strlen / llvm.memcpy]、
HandlesAsyncFunctions[malloc / create_* / resume_* / CRT 声明 / free]、
HandlesExprLambda[lambda 包装]、HandlesFunctions[_replace_function_decl 的 old_func=None 分支]、
HandlesImports[output stub 按需加载]
· LLVMCG:BaseGen[_DeclareExternalFunc 与 6 处 --hotspot-sites 内部符号]、
ExprGen[llvm.pow.f64]、VaArg[llvm.va_start / llvm.va_end]
原有 globals/functions 预检查与随后的 `Gen.functions[...] = X` 赋值一律保留。
注:`_DeclareExternalFunc` 收敛后外部声明会同时登记进 `self.functions`(幂等入口固有行为,
与既有 `get_or_declare_c_func` 一致;该路径仅 --hotspot-sites 调试特性使用)。
2. fail-fast 不再被吞(3 处):在包裹创建的 `except Exception` 首部加
`isinstance(_e, FailFastError) → raise`:
· HandlesExpr[malloc 的 null 回退分支]、HandlesExprBuiltin[strlen]、HandlesExprCall[strlen]
(其余异常维持原行为,本轮不扩大 fatal 面。)
另有 HandlesFunctions / HandlesImports 的同类 handler 前几轮已具备 FFE 重抛,本次未重复改。
验证:13 个改动文件 `py_compile` 全部 EXIT=0;冒烟 4 例通过——同名同类型复用同一对象、
异签名 → FailFastError(报文含两侧签名 i64/i32)、名字被非函数全局占用 → FailFastError、
`llvm.va_start` 幂等。另:`ir.Function(` 在 lib 内仅剩 `BaseGen._CreateOrReuseFuncDecl` 内部
这一处(豁免点);`DecoratorPass.py` 的 `module` 为外部传入(非 Gen 的模块)故其两处保持原样。
|
2026-09-30 09:53:41 +08:00 |
|
TermiNexus
|
c83fc752c6
|
fix(sizeof,parse): 尺寸链去静默兜底,解析报错可定位,补 C 解析器缺口
StructGen: _get_struct_size/_get_align 去 opaque→8/ptr_size、未知→4 兜底并补 VectorType;LiteralStructType.fields→.elements(llvmlite 无 fields,必然 AttributeError)
HandlesClassDef: union 载荷尺寸经不存在的 ir.DataLayout 静默退化成 8 字节;HandlesExprCall/ExprBuiltin: sizeof 各静默 0 分支改 fail-fast,数组元素 sizeof 统一走 _get_struct_size
HandlesFor: nonlocal struct/array 堆分配不再退化成 malloc(8)
vast/vast_c: 补一元 * / & 解析,装饰器后 extern/export 分派修复,C 侧报错带 token 与行号;StubGen.Converter: 宏展开丢尾随空行修 .pyi 缩进非法
其余为 rawptr 迁移 / fail-fast 口径等历史改动一并入库
|
2026-09-26 19:27:22 +08:00 |
|
TermiNexus
|
2021c0edb7
|
feat(hotspot): 新增 --hotspot-sites 逐调用点计数并带源码 file:line
为匹配白名单的直接 call 点插桩 internal i64 __fhs_site_<K>(call 前 +1),计数天然包含循环内放大的真实执行次数,可把热点定位到具体调用点。
新增 --hotspot-callees 覆盖白名单、--hotspot-sites-all 全量;按去 16 位 sha1 前缀后的基名匹配。Ctrl+C 落盘独立文件 hotspot_sites.txt(# sites 分段,含调用方/被调方/计数/源码位置),按计数降序;不破坏既有 hotspot.txt 格式。
在 AST->IR 生成期由 _HotspotSiteBuilder 为每条新生成的 call 指令轻量挂载 _src_file/_src_line,插桩时作为可选尾字段输出;取不到则留空不伪造。开关关闭时改用原生 ir.IRBuilder,零影响。
|
2026-09-13 23:29:32 +08:00 |
|
TermiNexus
|
8ce08493e8
|
feat(coro): M7——try/finally、异常消息、自定义异常类、帧池复用
- try/finally(无 except):正常/异常路径都执行 fbody,异常时 finally 后
重新传播(done+br exit);finally 内暂不支持 await
- 异常消息:帧加 msg 槽(i8*,index 4),raise X(msg) 存消息,await 传播,
coro_exception_msg 查询
- raise 支持自定义异常类(exception_registry 码),多 except 匹配子类码
- 帧池复用:per-type free-list 全局池,create 弹池/空则 malloc,coro_destroy
回池(帧头部存 next),避免反复 malloc/free
- 修复 ast.walk 传 list 崩溃(finalbody/For body)
- CoroTest 验证:finally 执行、MyError exc=100 msg=boom msg、3 次循环池复用
|
2026-08-21 14:46:21 +08:00 |
|
TermiNexus
|
8b9e88287a
|
feat(coro): M6——raise 异常类型 + 多 except 类型匹配
- raise 支持异常类型名/调用(EXCEPTION_CODE_MAP/exception_registry → 异常码),
普通表达式仍走值路径
- _HandleCoroTry 多 except dispatch:独立 check_bbs 链式匹配 exc 码(含子类码
集合),命中进入对应 handler,全不匹配重新终止传播;Exception/裸 except 捕获所有
- CoroTest 验证:raise ValueError 匹配 except ValueError → 1;
raise KeyError 匹配 except KeyError → 2(gather 并发)
|
2026-08-21 14:32:52 +08:00 |
|
TermiNexus
|
69447025a7
|
feat(coro): M5——协程内 try/except 捕获(raise 与 await 传播异常)
- _HandleCoroTry:except_bb/merge_bb 控制流,单 except 捕获所有异常
- 协程内 raise 与 await 子协程异常传播:处于 try 栈内时改跳 except 处理器,
栈外维持原终止语义(done=1 + br exit)
- except X as e:异常码绑定到 e(帧槽),捕获后清帧 exc
- 预扫描/_CollectFrameVars 递归 Try(handler.name 进帧槽,跨挂起存活)
- CoroTest 验证:try 捕获 await 传播异常 → coro result = 42, exc = 0
|
2026-08-21 14:28:52 +08:00 |
|
TermiNexus
|
411e0bb774
|
feat(coro): M4——异常传播(帧 exc 槽 + raise + await 传播)+ gather 并发调度
- 帧布局加固定 exc 槽(i32,0=无异常),协程内 raise 存异常码并终止
- await 子协程后检测异常并传播到父帧(父协程带异常终止,状态机短路)
- return await x:await 值直接存父帧 ret 槽(挂起前),修复 child_ret 跨块
dominate 错误;挂起不再写 ret=0(避免覆盖返回值)
- coro.coro_gather(帧...):并发推进全部协程到完成(含 coro_sleep 轮询),
返回完成数
- coro.vp 追加 coro_exception/coro_gather 占位
- CoroTest 验证:异常传播 exc=42;gather=2 r1=2 r2=3
|
2026-08-21 14:26:19 +08:00 |
|
TermiNexus
|
c979f0f94d
|
fix(coro): M3 三处修复——nonlocal 闭包、wake 空块终止、coro_run 唤醒槽按索引定位
- _PreScanExtraSlots 内嵌 _walk 闭包变量需 nonlocal(UnboundLocalError)
- coro_run wake_due_bb 补 br loop(空块导致 opt ASan 插桩解析失败)
- coro_run 内联在 main 翻译时 _coro_wake_ptr 已被恢复为 None,改为按
_coro_slot_vars 索引定位 __coro_wake_us 槽
- 验证:CoroTest ASan 模式编译+运行通过,coro result = 15
|
2026-08-21 14:20:51 +08:00 |
|
TermiNexus
|
3acf24c7d0
|
feat(coro): M3——For 内 await、coro_sleep 挂起、coro_destroy 释放帧
- For 内 await:range 迭代变换为 While(__f_idx_N/__f_len_N 帧槽),复用协程版 While
就地挂起/恢复;For 迭代目标进帧槽跨挂起存活;仅支持 range 1/2 参数
- coro_sleep(ms):帧加 __coro_wake_us(i64)唤醒槽,挂起后 coro_run 轮询
GetTickCount64,未到点 Sleep(1) 续轮询,到点自动恢复
- coro_destroy(帧):coro.coro_destroy 内联翻译为 free 释放帧内存
- coro.vp 追加 coro_sleep/coro_destroy 占位;CoroTest 用例覆盖
for+await/sleep/destroy(期望 coro result = 15)
|
2026-08-21 14:17:27 +08:00 |
|
TermiNexus
|
ff7c0457ad
|
feat(coro): M2——async 参数/嵌套 await 表达式/If-While 控制流
- 帧结构体增加参数槽与提升临时变量槽,create_<name> 带参数存入帧
- 嵌套 await(如 a = b + await f())提升为顶层临时赋值 __await_N,帧预留槽
- 协程版 If/While:条件求值 + 分支内 await 就地挂起/恢复(动态状态号恢复块)
- For 循环委托现有 handler(仅支持无 await/return,M3 扩展)
- CoroTest 用例覆盖参数/嵌套 await/while+await/if+await(期望 coro result = 30)
|
2026-08-21 13:31:37 +08:00 |
|
TermiNexus
|
a775ec9932
|
fix(coro): 帧结构体定义输出到 IR,修复 GEP base element must be sized
协程帧类型 %Coro_<name> 只存 _coro_frame_types 未注册进 Gen.structs,
StructGen.finalize 不输出其定义 → resume_<name> 的 GEP 引用 opaque
类型,opt ASan 插桩报 "base element of getelementptr must be sized"。
修复:_GetOrCreateFrameType 注册帧到 Gen.structs;finalize 追加
_coro_frame_types 兜底输出(防 _generate_structs 清空时丢定义)。
|
2026-08-21 12:41:10 +08:00 |
|
TermiNexus
|
13a8f6c1b6
|
feat(coro): 语言内协程 M1——async def + await + coro_run 状态机
TPC 新增协程生成器 AsyncFunctionHandle(lib/core/Handles/HandlesAsyncFunctions.py):
async def 编译为帧结构体 {state, done, ret, 局部变量槽} + create_<name>()(malloc
分配)+ resume_<name>()(switch 状态机,0=SUSPEND/1=DONE)。await 按顶层赋值
切分函数体:创建子帧 -> resume -> 取子帧 ret -> 存父帧槽 -> 父挂起(state 前进);
普通调用 async 函数生成 create(返回帧指针);coro.coro_run 在调用点内联翻译为
resume 循环。vast parser 已支持语法;新增 includes/coro.vp(Coroutine + 占位
运行时)与 Test/CoroTest(期望输出 coro result = 14)。
M1 限制:async 无参数、返回 i32/int;协程体仅顶层 AnnAssign/Assign/Expr/Return;
await 仅顶层赋值形式、子协程假设一次完成(无嵌套挂起);coro_run 依赖本模块
先赋值的协程变量。M2 将支持参数/嵌套 await/控制流。
|
2026-08-21 12:36:00 +08:00 |
|