TermiNexus
|
75aae26881
|
fix(codegen): arg 糖支持 vprintf 式转发的 va_list,补 stdarg 模块限定分派
_HandleArgLlvm 的回退分支原先把 Gen.variables 里的形参 alloca 直接当 va_list 用,转发形态(vsnprintf(buf,size,fmt,args))因此多一层间接、读错内存;现改为先 load 出槽里的 va_list 指针(自身变参形态仍走 _direct_values 缓冲地址、不 load)。另新增 ModulePath == 'stdarg' 分派,使 stdarg.arg/va_arg/va_start/va_end 命中与裸名相同的内建(点号形式此前会落到外部调用产生未定义符号 @arg)。同时删除 ExprCallHandle 里重复且无调用者的 _HandleArgLlvm 死代码。
|
2026-10-07 20:15:32 +08:00 |
|
TermiNexus
|
9656bb161a
|
feat(codegen): 值引用自动取址收口到 _adjust_args,补齐 vtable/方法/构造等路径
查表键统一为真实发射出的函数名:FuncGen._adjust_args 开头以 func.name 调用 _apply_auto_addr,于是 direct/vtable 虚分派/构造/静态/__call__/下标赋值/c.Addr 构造/闭包/泛型/方法兜底全部自动取址,不再依赖每个调用点手写;同时删除 16 处冗余显式取址(t.CAutoPtr 的 always 模式不幂等,重复应用会多包一层指针)。登记侧:HandlesImports 把模式登记提前到 FuncName-in-Gen.functions 早退之前并按 func.name 主键写表,_TryLoadStructFromStub 改为无条件调用;HandlesFunctions 在函数对象就绪后按真实名登记,并在 _EmitFunctionForwardDeclLlvm 把逻辑名下的模式播种到 MangledName,覆盖同模块先调用后定义的场景。
|
2026-10-07 19:59:36 +08:00 |
|
TermiNexus
|
6a7b27e14f
|
chore(c): 清理已删除的 c.CIf 家族残留
c.py 删除 CElif/CElse/CEndif 三个类及其 Library_C 登记;HandlesSpecialCall 删除无人调用的 _HandleCIfLlvm;_REMOVED_CIF_CALL_MSG 的报文补齐 CElif/CElse/CEndif 六个拼写。Converter.py 去掉已无意义的注释掉守卫与 c.CIfndef/c.CEndif 时代注释,示例改为仍在用的 c.CUndef/c.CPragma;ExprParser/ConstEvaluator/HandlesIf 的注释把内部标记统一写成 c.@CIfdef 与 cif 标记。
|
2026-10-07 19:09:59 +08:00 |
|
TermiNexus
|
2514cee4c9
|
feat(lang): 同步 cif/celif/celse、值引用注解与 assert 改译 testcheck.check
vast 双路径(Python Parser/ExprParser 与 C 扩展 vast_c.c)新增 cif-celif-celse 语句族与 &T / &temp T 参数注解解析,_parser.pyd 已同步重编。HandlesIf 改认 @CIf 标记并做编译期常量求值,含运行时变量一律 fail-fast,同时删除 c.CIf 家族(c.py)。HandlesAssert 合成 testcheck.check(cond, None, msg) 调用,非字符串字面量消息报 TypeError。FuncGen 调用点按形参模式自动取址(ref 仅接受左值,右值 fail-fast;temp 物化临时栈),SymbolUtils/TypeAnnotationResolver 提供模式识别;t.py 删除 CNeedPtr。
|
2026-10-07 19:03:29 +08:00 |
|
TermiNexus
|
07ba7a4fe5
|
fix(codegen): 新规范迁移暴露的 4 类解析/代码生成缺陷
1) HandlesExpr._HandleConstantLlvm 引号判定用 AST lineno 直查磁盘行,漏了 _inject_auto_imports 注入行的偏移 N,取到错行;改用 _DiskLineno 还原,并把 col_offset(UTF-8 字节偏移)转字符偏移后再切片。2) Phase2Translator 新增 _DedupComdatDecls:_dso.ll 由各依赖片段拼接,每片段各带同名 comdat 声明,llc 报 redefinition of comdat;在 _AddWeakComdat 入口与两处落盘点去重。3) LLVMTypeMapper._resolve_name 补存储类/类型限定符标记分支(CExport/CExtern/CConst… 返回空串,由 _resolve_bitor 取另一侧真实类型),与 _resolve_attribute 同口径。4) 短别名(int/int64/sizet/char…)在 typedef 右值与类型转换调用处解析不到:SymbolTypeResolver._resolve_typedef_from_value 与 LLVMTypeMapper.resolve_typedef_value_type 的 ast.Name 分支补 builtins typedef / BuiltinTypeMap 兜底(BaseType 可能是 CType 实例,须取 type(x).__name__),HandlesExprCall 的类型转换求值补 _lookup_builtins_typedef 回退并保留双参数 CPtr 指针包装。验证:TransPyV 自举 includes 52/52 + App 76/76 全通过;TPV 顺序回归 77/77。
|
2026-10-05 09:25:02 +08:00 |
|
TermiNexus
|
b18d57fa38
|
perf(全仓库/正则): 字面量正则全部改模块级预编译常量(15 文件 / 115 个调用点)
背景(prof 基线 PROF/20260930_224857,主进程 433.69s):正则这一族合计 ≈45s ——
`re.match`(未预编译入口)被调 1970 万次 / 自身 10.70s、它内部 `Pattern.match` 占 8.06s,
`re._compile`(缓存查找)1975 万次 / 7.19s,`re._make`(真正编译)274 万次 / 7.62s
(说明 re 的 512 条缓存已被打穿,每 7 次调用就有 1 次重新编译)。
每次 `re.match(字面量, s)` 都要做"模式串哈希 → 缓存查找";预编译后这层全省掉。
改动:把 15 个文件里 97 处"字面量当模式"的 `re.match/search/sub/subn/fullmatch/
findall/finditer/split(...)` 提升为模块级 `_RE_*: re.Pattern[str] = re.compile(...)`,
共 115 个调用点(含同字面量跨处共用)。模式串与 flags 一字未改(flags 从调用处
搬进 re.compile,含原先以**位置参数**传入的 flags)。4 处拼接型动态模式按设计不动
(FuncGen 2 处、HandlesImports 2 处)。
核验(不靠肉眼):写了 AST 指纹对拍脚本,对每个文件取 HEAD 版与新工作区版,把
"旧 re.<m>(字面量, 其余实参, 关键字) + flags" 与 "新 _RE_X.<m>(实参, 关键字) +
常量 (模式, flags)" 做多重集比对 —— 15 个文件、115 个调用点全部逐一等价(0 失败),
另查无重名常量、无遗留字面量调用、GetDiagnostics 全空。
对拍过程中查出一处子代理抄写错误:`_RE_GLOBAL_DSOLOCAL_MULTILINE` 丢了行首锚 `^`
(原文注释明确"使用 ^ + MULTILINE 避免匹配字符串常量内容中的 define/declare"),已修正。
同轮经查证后**未做改动**的两项(避免把假热点当真事修):
- VLogger 的 `re.sub` 6.43s:profile 当时的 VLogger 版本里根本没有 `import re`
(`git show 3658ab06:lib/core/VLogger.py` 已确认),属 C 帧错挂,不做。
- tokenize 274 万次:那是 `_generate_tokens_from_c_tokenizer` 的 **token 产出次数**
(≈350 个整文件的词法量),SymbolUtils 的 4 个 tokenize 调用点 nc 仅数百,且已有
`_EXPAND_CACHE` 去重;再加一层 token 缓存无收益,不做。
|
2026-09-30 23:47:36 +08:00 |
|
TermiNexus
|
ab906f2cde
|
fix(HandlesExprCall): 构造的 self 按 callee 形参类型解析(同名类消歧),并合并"sha1 全名键"分支
类别:a(编译器缺陷)
现象(用户重跑后仍复现):includes/ast/parser.vp:1774
`kw: rawptr[AST] = KwNode(ps.pool, None, val)` 报
FailFastError: 指针隐式转换已禁止(非基本类型(结构体/类/联合)):调用
8312ce86a2fd82c0.Keyword.__new__ 第 0 个实参 %"fef783da4d24330d.Keyword"*
不能隐式转为形参 %"8312ce86a2fd82c0.Keyword"*
根因:`Gen.structs` 的键恒为**短名**(StructGen._generate_structs 以 ClassName 作键,
IR 名才带 sha1 前缀),别名注册只是**浅拷贝**(HandlesImports
`Gen.structs[asname] = Gen.structs[name]`)。Keyword 同时存在于 ast.tokens
(fef783da4d24330d) 与 ast.astaux(8312ce86a2fd82c0):裸名 'Keyword' 先被 .tokens 占用,
别名 'KwNode' 键又只是浅拷贝 ⇒ 构造的 self 按名字取到 tokens 的实例,而 callee
(_find_function('KwNode.__new__'))命中的是 astaux 的。llvmlite 的类型相等按 **IR 名字**
判定(实测同名不同对象 == 为真,见提交说明)⇒ 两份不同名实例必被
_ClassifyPtrImplicitConvert 拒绝。
上一版修复(ba7e117e)不成立:它按"callee 限定类名 + 与 ClassName 同短名"改判,而
ClassName 是别名 'KwNode'、限定类名是 '...Keyword',同短名判据恒假 ⇒ 从未生效。本版删除。
修复:
1) 新增 _CalleeSelfType():self 的 struct 直接取 callee(__new__ → __before_init__ →
__init__)第 0 个形参的 pointee —— 正是 _adjust_args 的比较对象,无歧义;形参上的
实例未具化时按 IR 名换同名已具化实例(_FindStructByIrName;IR 里类型身份就是名字)。
2) _get_struct_type 统一解析序:callee 形参 → sha1 全名键 → 名字键。
3) 合并"sha1 全名键命中"分支:原实现只解析 StructType、**不产出 alloca / 构造调用**,
控制流随后落到函数末尾 `return i32 0` ⇒ 该路径上的跨模块构造会**静默不构造**
(同为类别 a,一并修掉)。
|
2026-09-30 17:00:50 +08:00 |
|
TermiNexus
|
ba7e117ecb
|
fix(HandlesExprCall): 同名类构造消歧——ctor 的 self 实参按 callee 限定类名解析,不再回退有歧义的短名
类别:a(编译器缺陷)
现象:includes/ast/parser.vp:1774 `kw: rawptr[AST] = KwNode(ps.pool, None, val)` 报
FailFastError: 指针隐式转换已禁止(非基本类型(结构体/类/联合)):调用
8312ce86a2fd82c0.Keyword.__new__ 第 0 个实参 %"fef783da4d24330d.Keyword"*
不能隐式转为形参 %"8312ce86a2fd82c0.Keyword"*
根因:Keyword 同时存在于 ast.astaux(8312ce86a2fd82c0) 与 ast.tokens(fef783da4d24330d)。
KwNode 是 `from .astaux import Keyword as KwNode` 的导入别名,_ctor_module_sha1
只从 ModulePath(ast.attr 形态) 解析 ⇒ 裸名/别名调用拿不到 sha1;
_get_struct_type 回退短名 Gen.structs.get('Keyword') ⇒ 撞上 tokens 的同名实例。
修复:从**已解析到的构造函数对象**的 IR 名({sha1}.{Class}.{method})取限定类名,
仅在「同短名 + 已具化」时改判——同短名保证不会把无关类引进来,已具化保证
_allocaEntry 的尺寸正确(opaque 实例算不出大小)。取不到限定名时保持原短名回退,
对无同名冲突的类零变化。
|
2026-09-30 16:38:09 +08:00 |
|
TermiNexus
|
7ee6ebe6b0
|
fix(类型转换): int→i1 目标改为真值归一化 != 0,与 bool(x)/if 条件同判据
类别:a(编译器缺陷)。TPC 侧此前对 i1 目标一律 trunc(取最低位):运行时值 2 →
最低位 0 → false,而同一值在 `if 2:` / `bool(2)`(icmp ne 0)为真 ⇒ 条件上下文与
落存储/强转两处结论相反(静默语义分裂)。
- MemoryOps._CoerceIntToI1(新增,唯一判据源):非 i1 整数 → `icmp ne x, 0`。
- MemoryOps._coerce_value:窄化且目标位宽 == 1 时走 _CoerceIntToI1。
- HandlesAnnAssign._StoreWithCoerce:同上(self.字段 / obj.字段 落存储)。
- HandlesExprCall._HandleTypeCastLlvm:显式强转目标 i1 时同上。
与 TransPyV 侧同批修复(coerce_to_type / _translate_t_type_cast)对齐。
注:TPC 的 `bool` 注解仍是 i8(t.CBool.Size=8),故 `b: bool = 2` 仍按 i8 保位存储
(int(b)=2);本次只覆盖**真 i1 目标**,双端 bool 位宽差异见
SymbolUtils.py:1218-1223 已记录的全局语义分裂。
|
2026-09-30 15:14:31 +08:00 |
|
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
|
0392ccdea0
|
fix(tpc): fail-fast 报文补「属性基址取证事实」,属性读返回 None 不再靠反推
类别:a(编译器缺陷 —— fail-fast 报文缺取证事实,无法一眼定位根因)
现象:HandlesBase._RaiseUnresolvedExpr 与 HandlesExprCall._RequireArgValue 在
「属性读取值失败」时只报 Node 形态(Attribute),报错点与真因相隔数层调用,
需要人工从 Gen.var_struct_class / Gen.structs / Gen.class_members 反推。
改动:
1. HandlesBase 抽出公开方法 _DescribeAttrBase(Gen, Node) -> str(原 _RaiseUnresolvedExpr
内联代码抽出,行为不变),对两类基座给事实:
- Name 基座:var_struct_class / global_struct_class / alloca 类型 / 是否命中
Gen.structs / class_members 字段数与字段名单(前 12)。
- Call(func=BinOp(BitOr)) 强转基座:联合基类名 + 短名是否命中 Gen.structs +
字段数,并显式标注「强转基座本应走 _FailFastAttrCallBase 详细报文,此处仍是本条
⇒ 那条 fail-fast 未触发」,把「另一处缺口」这一事实直接写进报文。
2. _RaiseUnresolvedExpr 改调 _DescribeAttrBase(删除内联重复代码)。
3. HandlesExprCall._RequireArgValue 在实参是 Attribute 时追加同一份基址诊断
(与 HandlesBase 共用,保证两处口径逐字一致)。
不改变任何判定逻辑,仅补取证事实。
|
2026-09-29 17:40:23 +08:00 |
|
TermiNexus
|
b652634356
|
fix(tpc): 裸赋值 RHS 是"联合注解返回"的调用时,从返回注解恢复被指类名
类别:a(编译器缺陷)—— 类型信息被静默丢成通用指针 i8*,后果在数行之后以看不出真因
的报文暴露。
现场(Test/FakeDuckTest/App/main.vp:111/115):
`parts = s1.split(',')` → `p0: str = parts[0]`
报"整数隐式转指针已禁止…出错表达式: 下标表达式 Subscript"。
证据链(三段各有代码/探针依据):
1. `_fakeduck.vp:273` 的 `def split(...) -> list[str]*`:只读探针确认 `list[str]*`
与 `list[str] | t.CPtr` 的 AST **逐字同形**
(`BinOp(BitOr, Subscript(Name(list)), Attribute(t.CPtr))`)⇒ 注解写法没问题。
2. 该联合形态在 LLVM 层映射成**通用指针 i8***(`list[T] | t.CPtr` 的既有约定,
见 HandlesAnnAssign:372-383)。
3. `HandlesAssign` 原有的类名推断整块以 `Value.type.pointee` 是结构体为前提
(:186 的 `isinstance(..., (LiteralStructType, IdentifiedStructType))`)⇒ i8* 直接
整块跳过 ⇒ `var_struct_class['parts']` 从不登记 ⇒ `parts[0]` 不走
`list[str].__getitem__`,退化成通用指针/字节索引 ⇒ 结果类型是整数 i8 ⇒ 赋给
`str` 时触发 int→ptr 拦截。真因位置比报文位置早 4 行。
修复(编译器侧,不要求源码补注解):
- `HandlesExprCall._CallReturnClass(Node, Gen)`:从被调者的 **returns 注解**取回被指
类名。被调者候选键覆盖三种既有形态(`Name` 函数名、`<接收者类>.<方法>`、
FakeDuck 影子类 `_str`/`_bytes`、裸 `<方法>`),取第一个能解析出类名的。
- `HandlesExprCall._ClassFromAnnotation(Ann, Gen)`:剔除 `| t.CPtr` 侧取核类型,
泛型 Subscript 走 `_resolve_generic_slice_type` 构特化名(`list[str]`),并要求该名
能在 `Gen.structs` / `Gen.class_members` 命中(含 sha1 前缀全名的短名归一);
取不到一律返回 None —— **不硬塞名字**。
- `HandlesAssign`:仅当"RHS 是调用 + 值类型是通用指针(pointee 非结构体)+
var_struct_class 尚无该变量"这三个条件同时成立时,才据上恢复登记
`var_struct_class` / `global_struct_class` / `_var_to_heap_ptr`。其余路径逐字不变。
验证:只读探针覆盖 7 种注解形态(`list[str]*` / `list[str] | t.CPtr` / `Foo*` /
`Foo | t.CPtr` / `ast.AST*` …),提取结果全部符合预期(未命中类名时返回 None);
GetDiagnostics 干净。未跑编译器。
遗留(同族,下一轮):上游"联合注解→i8*"这一步丢类名才是真根因;本次是在调用点
恢复。另外 `parts.__len__()` 在类名缺失时可能被 FakeDuck `_str.__len__` 错接,
修完建议跑一次该测试确认 `split len OK`。
|
2026-09-29 17:09:42 +08:00 |
|
TermiNexus
|
783aba1e49
|
fix(tpc): 方法调用/属性调用路径的实参不再静默丢弃(收口"整体错位一格")
类别:a(编译器缺陷)—— 实参求值为空被静默丢弃 ⇒ 后续实参整体前移一格 ⇒ 报出与
真因无关的类型不匹配。
现场(TransPyV/App/lib/core/Gen/Func/FuncGenMixin.vp:1429):
`return self._lambda_scan_body(trans, ie.orelse, param_names, param_count,
cap_names, cap_allocas, cap_tys, cc6)`
→ `_adjust_args` 报"指针类型 i8* 不能隐式转换为整数参数 i32"。
判据(把报文的"逐项"列表与两种假设逐位对照):
形参表(stub declare,与该行源码一致):
self, trans, node=%AST*, param_names=i8*, param_count=i32,
cap_names=i8*, cap_allocas=i8*, cap_tys=i8*, cap_count=i32
实测实参:i8*, i32, i8*, i8*, i8*, i32, i32(9 项)
假设"第 3 个实参(param_names,i8*)被丢弃、末尾由 _fill_default_args 补
cap_count 的零值 i32"⇒ 预测 arg[2..8]=orelse(i8*), param_count(i32),
cap_names(i8*), cap_allocas(i8*), cap_tys(i8*), cc6(i32), 补零(i32)
⇒ **与实测逐位完全一致**。反证:若丢的是末尾的 cc6,预测序列与实测不符。
(`_fill_default_args` 只从**末尾**按形参类型补零:HandlesExprCall.py:202-248)
修复:方法调用路径(_HandleMethodCallLlvm)与属性调用回退路径(_HandleCallLlvm)
共 7 处仍写作 `ArgVal = HandleExprLlvm(arg); if ArgVal: append(ArgVal)` —— 正是
`_RequireArgValue` 文档里点名要收口的旧写法(此前只收口了 4 处类构造)。现全部
改为 `_RequireArgValue(...)`:实参求值为空当场 fail-fast,报文含被调者、实参序号与
源表达式,**不丢弃该实参**。
同族未收口(本次不动,逐条记录):`_ApplyKeywordArgs` 的关键字实参(:337)、
`:595` 的 UserCallArgs、`:1262`、`:1336` 共 4 处仍是旧写法。
验证:GetDiagnostics 干净;未跑编译器。
|
2026-09-29 17:01:14 +08:00 |
|
TermiNexus
|
f4c8c48748
|
fix(tpc): 函数声明创建全部收口到唯一幂等入口,消除 DuplicatedNameError 裸抛
类别 a(编译器缺陷)+ b(机制漏豁免)。报错:翻译 lib\core\Gen\Expr\ExprGenName.vp
失败,报文只有名字 dddc595175f00c66.ExprGenAttr.find_global_in_module
⇒ llvmlite DuplicatedNameError(NameScope.register 对 GlobalValue
deduplicate_name=False,同名 global 再建必抛,__str__ 只回名字)。
根因(已取证,非猜测):
- llvmlite Module 里 `scope`(NameScope,注册/去重)与 `globals`(OrderedDict)
是两套结构;`add_global` 只在构造时写入 ===> 「名字已在 scope._useset、
但 globals 查不到」这一状态一旦出现,任何"先查 globals 再建"的守卫都会失效。
- 该状态由**清理不完整**制造:删旧名时只删"对象真名 existing_func.name/old_name",
而字典键/目标名(func_name / MangledName)仍留在 scope._useset。
别名注册(Gen.functions[短名] = 名为全名的对象)恰好让二者不同名。
- 另有若干创建点只看 Gen.functions、完全不看 module.globals(裸建 ir.Function),
只要 module.globals 已有同名声明就裸抛 DuplicatedNameError。
本次收口(函数声明创建的唯一入口 = BaseGen._CreateOrReuseFuncDecl):
1. BaseGen._CreateOrReuseFuncDecl:新增"名字被非函数 global 占住"分支,把冲突
双方(类型 + repr)报出来,替代原 llvmlite 只给名字的裸抛。
2. 清理不完整处补全为「同时清 真名 + 目标名」:
- HandlesImports.py 模板 declare 装载(clearing func_name 之外还清 existing_func.name)
- HandlesFunctions._replace_function_decl(clearing {old_name, MangledName})
- 其 except 对 FailFastError 改为上抛(不再回退成复用旧声明)
3. 裸建 ir.Function 的创建点改走唯一入口(module.globals 同名则复用、
签名冲突/非函数冲突则 fail-fast):
- HandlesExprCall._HandleStaticMethodCallLlvm({sha1}.Class.Method) ← 本现场形态
- HandlesExprCall._HandleMethodCallLlvm 的 class_sha1 回退分支
- HandlesExprCall._try_declare_c_lib_func / HandlesExprBuiltin._try_declare_c_lib_func
- HandlesAssign 模块级全局赋值处的函数声明
- HandlesImports.__before_init__ 声明(原查 NewFuncName 却建 MangledName)
- HandlesFunctions._EmitFunctionLlvm(补登记 module.globals 已有声明,
使既有的签名修复路径生效,而不是裸建撞名)
行为等价性:上述各点原先"撞名"时必然抛 DuplicatedNameError(即必失败),
收口后要么复用同一符号、要么 fail-fast 报出两侧签名/冲突类型,无静默降级。
|
2026-09-29 13:50:44 +08:00 |
|
TermiNexus
|
9d8aedec4a
|
fix(tpc): 函数声明创建收口到幂等入口 _CreateOrReuseFuncDecl;清理 DDEBUG 探针
类别:a 编译器缺陷(根因修复)+ 调试探针移除。
现场:翻译 CallGenFd.vp 时抛 llvmlite.ir._utils.DuplicatedNameError:
'5d84ea579d83ef73.CallGenFd._translate_fakeduck_call'(llvmlite 的
NameScope 按名字去重,GlobalValue.deduplicate_name=False ⇒ 同名 global
建第二次必抛,且报文只给名字、不给两侧签名)。
根因:BaseGen._get_or_declare_function 建完 ir.Function 后**只加入
module.globals**(llvmlite 自动)而**未登记 Gen.functions**;而
HandlesFunctions._EmitFunctionLlvm 的 need_new 判据只看 Gen.functions
(`MangledName not in Gen.functions`)⇒ 同一名字再建一次 → DuplicatedNameError;
该处 except 又把它吞掉(非 strict 模式只 LogWarning)→ 函数始终没进
Gen.functions → 后续其它创建点(FuncGen._get_or_declare_func /
get_or_declare_c_func,同样只查 self.functions)再建 → 异常从别处逃逸到
Phase2Translator。
修复:
1. BaseGen 新增 _CreateOrReuseFuncDecl(name, func_type) —— 函数声明创建的
唯一幂等入口:module.globals 已有同名函数且**函数类型结构串相同**则复用
(并补登记 Gen.functions;FunctionType 无 __eq__,只能比 str);
类型不同则 fail-fast 报出两侧签名(declare/define 分裂的真因),
绝不静默复用错签名(调用点会按错签名传参)。
2. _get_or_declare_function 改走该入口(顺带补登记 Gen.functions);
FuncGen._get_or_declare_func / get_or_declare_c_func 改走该入口;
HandlesFunctions 定义路径改走该入口,且该处 except 对 FailFastError
直接 re-raise(不再吞)。
3. 清理遗留调试探针(含 sys.exit(1)):BaseGen 三处 [DDEBUG]
(_get_or_declare_function 双点 / _mangle_func_name 前导点与结果双点)、
HandlesExprAsm 两处 [DDEBUG_ASM]、HandlesExprCall 一处
[DDEBUG] _HandleClosureCallLlvm。
|
2026-09-29 13:00:11 +08:00 |
|
TermiNexus
|
fd212b3ff8
|
fix(tpc): 联合强转 (T|t.CPtr)(x) 及其属性访问失败改为 fail-fast(附判定依据)
类别:b 机制漏豁免(把静默 return None 改成响亮失败并带证据)。
现场:TransPyV lib/core/Gen/Expr/ExprGenBase.vp:360 的
v = (ast.Expr*(node)).value 报“赋值表达式 'value'(Attribute 形态)编译期
求值为空”,而同一函数前三条 (ast.Assign/AnnAssign/AugAssign*(node)).value
同款写法正常 ⇒ 无法从报错看出是哪一步丢了类型。
两处静默返回改为 fail-fast(均只对该强转形态生效,其余路径行为不变):
1. HandlesExprCall._HandleTypeUnionCastLlvm:目标类型串解析失败(原为
_vlog().warning + return None)。新增 _DescribeUnionCastFailure 取证:
MergeTypes 返回值/ToString()/异常、_ExtractTypeStrFromUnionBinOp 结果,
以及联合中每个操作数在符号表与类登记表(Gen.structs / _struct_sha1_map /
class_sha1_map)的命中情况 —— 直接指认“基座类名没被当成类”还是
“CPtr 标记侧解析失败”。
2. HandlesExprAttr._handle_attr_call_result:(T|t.CPtr)(x).attr 的 5 个
return None(基座求值为空 / 非指针 / find_struct_by_pointee 未命中 /
结构体不透明 / 成员偏移取不到)改为 _FailFastAttrCallBase,报文含联合
基类名与三家登记表命中、被指类型 elements、class_members 项数与目标成员偏移。
原因:(T|t.CPtr)(x) 只可能来自指针强转(parser 把 (T*)x / (T*)(x) / T*(x)
统一产成该 Call),必须有值产出;静默丢弃会让整条表达式被判为空,把
“类名解析失败 / 结构体不透明 / 成员偏移取不到”三种不同根因混成同一条报文。
|
2026-09-29 12:23:54 +08:00 |
|
TermiNexus
|
53bde9157e
|
fix(tpc): REnum 变体嵌套结构体按需补发 + 模式捕获绑不上即 fail-fast
a 编译器缺陷:导入模块侧 stub 只声明主 REnum(`%"…LLVMType" = type {…}`),**不含**
变体嵌套结构体(`LLVMType_Ptr` 等)——它们由 `_EmitExternalClassDeclLlvm` 的 REnum
分支按主结构体布局就地生成。若本模块从未触发该 REnum 的外部声明发射:
1) match 模式捕获(`case llvmlite.LLVMType.Ptr(pointee_cs):`)绑定静默为空 ⇒ case
body 里引用的绑定名随后报"未定义名称"(现场 VpiReader.vp:1521 `pointee_cs`);
2) REnum 变体构造的载荷实参静默丢弃(只写 tag)—— 静默错码。
修法:
- 新增 BaseHandle._EnsureRenumVariantStruct:成员缺失时按需补发(先试 stub,再按
类 sha1 找到定义模块 .vpi 触发 `_TryLoadClassMembersFromPyi` → 内部即调
`_EmitExternalClassDeclLlvm`)。
- HandlesMatch._HandleRenumMatchLlvm:改用该助手;**模式捕获登记不全即 fail-fast**
(报出变体名、class_members 项数、structs 命中与同前缀键),绝不让绑定名留到
取名时才炸。
- HandlesMatch 非 REnum 兜底分支:MatchClass 含捕获时改为 fail-fast,并列出判据
(IsEnumMember/EnumName/IsRenum/IsStruct/IsEnum),直接暴露"外层 REnum 判定为何
未成立"。
- HandlesExprCall._HandleREnumConstructLlvm:载荷实参存在而嵌套结构体缺失时补齐,
补不上则 fail-fast(拒绝产出"只有 tag 没有载荷"的值)。
|
2026-09-29 11:21:19 +08:00 |
|
TermiNexus
|
833e8c7c33
|
fix(tpc): 识别点号写法的 REnum 变体构造 mod.REnumClass.Variant(...)
a 编译器缺陷(同一语义两种书写的判据不一致):HandlesExprCall 的跨模块 REnum 变体
构造分支只判 `isinstance(Node.func.value, ast.Name)`,即只认裸名写法
`LLVMType.Ptr(x)`;**点号写法** `llvmlite.LLVMType.Struct(fields, fcount, name)`
(Node.func.value 是 Attribute)漏掉,落到下方"模块函数 Struct"路径 ⇒
· 返回类型被当成普通函数返回值(实为 boxed 变体构造指针);
· 实参少一个 pool(arity 也不对)。
现场:ClassGenDef.vp:116 的 `*existing.Ty = llvmlite.LLVMType.Struct(...)`
报"不能把指针类型 %LLVMType* 隐式转为值类型 %LLVMType"。
补齐:新增同口径分支——Node.func.value 为 Attribute 时,按其 attr(REnum 类名)
在符号表(先试 f"{ModulePath}.{attr}" 再试裸名)取 IsRenum 条目,命中
RenumVariants 即走 _HandleREnumConstructLlvm(与裸名分支同一实现)。与
includes/llvmlite/__types.vp:195、__builder.vp:173 的既有用法一致。
|
2026-09-28 23:14:08 +08:00 |
|
TermiNexus
|
b3f72d675b
|
fix(ctx): 方法体编译失败路径也复位「当前方法」上下文,修 self 被按内层特化类解析
现象:编译 ExprGenFstr.translate_joined_str 时 self.Gen 被按 list[cfc4ca8da95a30e1.AST*] 解析 → 属性在类中找不到(连带错误)。
链路:parts.get(pi) 触发泛型特化按需补全(HandlesExprCall._try_complete_generic_specialization)→ 内层 list[...] 方法发射时 _EmitFunctionLlvm 先置 _CurrentCpythonObjectClass = 内层类(HandlesFunctions:1978)→ 方法体编译失败只 re-raise,末尾的类名/var_struct_class 复位被跳过 → 上层调用点**吞掉**该异常继续编译外层方法,于是外层 self.X 全按内层类解析、后续指令也会误插进内层函数的块。
两处修复:① _try_complete_generic_specialization 的 except 里同时复位 Gen.builder/func 与 _CurrentCpythonObjectClass/Gen._current_class_name(该点会吞异常,必须自己收尾);② _EmitFunctionLlvm 的失败路径在 re-raise 前复位 Gen._current_class_name / _CurrentCpythonObjectClass / var_struct_class / global_struct_class(对所有吞异常的调用点都成立)。
|
2026-09-28 16:52:03 +08:00 |
|
TermiNexus
|
809f9d08fa
|
feat(len): len() 对「非 i8 裸指针 / 无 __len__ 的 struct」改为 fail-fast(对齐 TransPyV)
旧实现:非 i8 裸指针(如 []T 形参实为 T*)静默返回常量 0;struct 无 __len__ 时回落 strlen —— 两者都用假长度掩盖错误。
新口径(两侧逐字一致):定长数组/数组指针 → 常量 N;i8*(str/bytes)→ strlen;带 __len__ 的结构体 → 调 __len__;其余一律编译期 TypeError。
新增 _LEN_SUPPORTED_HINT 共享提示语 + _FailFastLenUnsupported 出口(含 行:列 + 源码片段 + 正确做法)。HandlesExprCall.py 为同源死代码副本,一并同步语义未删。
|
2026-09-28 15:53:02 +08:00 |
|
TermiNexus
|
e1a2821bff
|
fix(tpc): 函数声明创建幂等化,消除 DuplicatedNameError
同名声明只在 module.globals、不在 Gen.functions 时,旧代码会再走 ir.Function,而 llvmlite 的 NameScope 按名字去重(GlobalValue.deduplicate_name=False)必抛 DuplicatedNameError。GetOrCreateStubFuncDecl(含 check_existing=False 路径)、GetOrCreateFuncDecl、win32console 内建声明、output-stub 按需载入四处统一先复用 module.globals。真实事故:VarGenMixin.vp 同一模块两处 self.Gen.ExprGen.translate_value(...) 都走 check_existing=False,第二处崩在 llvmlite。
|
2026-09-27 16:18:37 +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
|
2cc816ac13
|
修复了一些错误
|
2026-09-18 20:00:59 +08:00 |
|
TermiNexus
|
6af2dea917
|
修复了一些问题
|
2026-09-17 14:52:37 +08:00 |
|
TermiNexus
|
0721568d41
|
fix(codegen): 消除泛型特化静默兜底并修正 sha1 前缀归一
崩溃根因(已由 IR + 符号化确证):MatchGenMixin._handle_renum_match 的 body_list.get(bi) 被分派到 list[int].get,返回 i32 后 inttoptr 成 AST* 造成指针 32 位截断,运行期读 vtable 崩溃(ASan 坏地址 0xc1158310)。
第 1 步 方法分派:删除「ClassName 不含 [ 时按 Gen.structs 迭代顺序任选特化」的静默兜底,改为按接收者 LLVM 值类型的 pointee 用 find_struct_by_pointee 身份匹配反查唯一特化;反查不到时以「基名匹配且存在目标方法」求唯一候选,候选多于一个即 fail-fast,不再任选。
第 2 步 泛型实参:5 处「解析不出类型实参就补 int/CInt」改为 fail-fast。经核对语言与实现(wiki 类型系统/类章节、_generic_class_templates 的 type_params 无默认值机制、list 模板仅 1 参)确认泛型不存在合法缺省实参,5 处均属未知兜底。
第 3 步 注解赋值(真正的污染写入点):HandlesAnnAssign 中 bnm 与 CN 的比较未归一 sha1 模块前缀(注解侧裸名 list 与带前缀键 CN 恒不等),导致恢复特化名分支不命中、把裸泛型基名写入 var_struct_class,从而被第 1 步的兜底按顺序任选成 list[int]。改为与同函数既有 _cn_short 口径比较,构造仍用带前缀 CN。
|
2026-09-14 16:45:26 +08:00 |
|
TermiNexus
|
355811d64e
|
chore(tpc): 移除属性链/调用分派错误路径的临时诊断打点
- HandlesBase: 删除 _AttrFailDiag 现场诊断(含模块别名链逐跳 dump),恢复精简错误信息
- HandlesExprAttr: 删除 [CHAIN-DBG] stderr 打点与 [attr-diag]/[attr-diag-nested] KeyError 包装
- HandlesExprCall: 删除 Unknown module 异常的 _rc_note 诊断后缀
|
2026-09-12 12:50:35 +08:00 |
|
TermiNexus
|
015fbf17cf
|
fix(tpc): 跨模块模块级变量类登记与 Mod.Var.Field 链解析;并停止跟踪 __pycache__/*.pyc
|
2026-09-12 11:51:42 +08:00 |
|
TermiNexus
|
45e78ad107
|
基线重置,修复了一些 bug
|
2026-09-07 14:46:02 +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
|
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
|
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
|
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
|
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
|
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 |
|
TermiNexus
|
8a0da29461
|
fix(exprcall): 兄弟 Mixin 兜底按调用类是否声明该方法过滤,修复 NoVTable 回归
780cd4a 用 MRO/组合类判断 _is_mixin_parent 不可靠:Combined 定义在 BaseB 之后,BaseB.caller 翻译时组合类未注册、MRO 查询失败 → 兜底静默跳过 → NoVTableCrossMixinTest 的 TPC 编译 fallback 生成不存在的 BaseB.helper(定义在 BaseA)→ ld.lld undefined symbol(回归)。
改为:调用类自身声明了该方法(class_methods 含 MethodName)但 stub 未命中(如 JsonValue.__getitem__ 跨模块 stub 注册问题)→ 不兜底,fail-fast 暴露上游 stub 问题(防误绑 HashTable,1.LOG 根因);调用类未声明(BaseB.helper / MixinC2.mid2)→ 跨 Mixin,全量遍历找定义类。保留 list 特化过滤(3fd875d)。
|
2026-08-21 01:26:19 +08:00 |
|
TermiNexus
|
780cd4a13b
|
fix(exprcall): 兄弟 Mixin 兜底仅对组合类父类启用——防误绑 HashTable 方法
3fd875d 只过滤了 list 特化类名,普通类(HashTable)仍被误绑:JsonValue.__getitem__ 未命中时遍历 class_methods 命中 HashTable.__getitem__,this 前移 sizeof(HashTable)=-48 → Load_project_config root.__getitem__ 读 -1 崩溃(1.LOG 4c1f8f779b98eab9.HashTable._slot_hash)。
加固:兜底前检查 class_name 是否是多继承组合类的父类(存在以它为父类的类,如 Generator 的 44 个 Mixin / Combined(BaseA,BaseB))。普通类方法未命中时不再回退到无关类,走 fail-fast(Undefined method)暴露上游 stub 注册/时序问题。
|
2026-08-20 17:08:14 +08:00 |
|
TermiNexus
|
3fd875daca
|
fix(exprcall): 兄弟 Mixin 兜底过滤泛型特化类名——防误绑定 list 特化函数
与 TPV CallGenCall.vp 086e792 同根因:JsonValue.__getitem__ 在 found_func 未命中时被兜底遍历 class_methods 误绑到 list[ASTptr].__getitem__ 特化函数,this 按 list 布局前移 sizeof(list) → 运行期读 -1 崩溃(Config.vp root.__getitem__)。候选类名含 '[' 时跳过。
|
2026-08-20 11:27:13 +08:00 |
|
TermiNexus
|
bd5d2467ab
|
fix(exprcall): NoVTable 跨 Mixin self. 调用按定义类解析 + this 前移
缺陷(TPV bootstrap 的 undefined symbol: <sha1>.StmtGenDeclMixin.translate_return
同根因):NoVTable 多继承下,BaseB.caller 内 self.helper()(helper 定义在兄弟
Mixin BaseA,经 Combined(BaseA, BaseB) 组合)被 mangle 成 BaseB.helper —— 用
调用者类做前缀,而定义符号是 BaseA.helper -> ld.lld undefined symbol。
修复(HandlesExprCall.py):
1. 调用端 MRO 回退失败后,全局扫描已注册类找方法定义类(兄弟 Mixin 兜底);
2. _adjust_this_for_inherited_method 支持"调用类不含定义类字段"场景:
this 按组合布局前移 sizeof(定义类 struct)(BaseB* -> BaseA*)。
新增 Test/NoVTableCrossMixinTest 回归(caller()==42 通过),TestsOverview 记录。
|
2026-08-20 10:23:47 +08:00 |
|
TermiNexus
|
c02f7dbaf1
|
fix(gentype): _HandleSizeofLlvm 的 CType.POINTER 改 t.CType.POINTER
CType 未导入 HandlesExprCall.py,6ff76f3 引入 NameError。t 模块已导入,
改用 t.CType.POINTER。
|
2026-08-19 22:52:49 +08:00 |
|
TermiNexus
|
6ff76f3cb6
|
fix(gentype): t.CPtr.__sizeof__() 返回 8 修复 list[CPtr] elem_size=0
CPtr 无显式 Size(t.py class CPtr 未设 Size)→ GetClassByName 路径
size_bits=0 → t.CPtr.__sizeof__() 返回 0 → list[t.CPtr](_mbuddy) 单参
构造时 elem_size=0(T.__sizeof__() 分支)→ append 崩溃(ASAN: 读 0xf8
零页,pool.alloc 处)。GetClassByName 路径补 POINTER 判断:HasPosition
(POINTER) 且 size_bytes==0 → 8(指针大小,与 str/bytes 一致)。
|
2026-08-19 22:49:37 +08:00 |
|
TermiNexus
|
2f0d52e736
|
fix(gentype): list[t.CPtr] 特化与 list[对象] elem_size 根本修复
两处根因:
1. list[t.CPtr] 报 Undefined method 'append':
- _resolve_generic_slice_type 对 t.CPtr 返回裸名 'CPtr',type_map['T']='CPtr'
替换进模板(item: CPtr)后 CPtr 不在顶层作用域 → append 声明注册失败
- 改保留带前缀 't.CPtr'(可解析)
- 查找端(SymbolUtils.FindStructNameInAnnotation)与声明端
(DeclarationGenerator)的 CPtr 统一规范化为 'ptr',与特化端
_mangle_generic_class_name 一致(list[CPtr]/list[i8*] vs list[ptr])
- _specialize_generic_class 的 cptr_params/class_type_names 判定改 tn_bare
2. list[对象] elem_size=0(get(0)==get(1) 同槽根因):
- T.__sizeof__() 特化后为 'X | t.CPtr'(BinOp 联合),_HandleSizeofLlvm
对 BinOp 落到 else 返回 0 → list.__elem_size__=0 → 元素全写同槽
- 改含 t.CPtr 的联合类型返回 8(指针大小)
|
2026-08-19 22:44:15 +08:00 |
|
TermiNexus
|
97b714603d
|
fix(HandlesExprCall): this_adjust 字段偏移计算剥离 sha1 前缀
register_reexport 等继承方法调用时 ClassName 带 sha1 前缀(如 e1ea7eaf63a9c3d1.Generator),而 class_members 的 key 是裸类名 → _compute_field_byte_offset 查不到字段 → this_adjust 被跳过 → 继承方法 self 不调整 → 方法内按 ImportsGenMixin 独立布局(0-3)访问 Generator 内存错位 → ReexportSrcs 读到 null 后写 [63] 越界(ASAN 写 0x3f 崩溃)。修复:查 class_members/structs 前剥离前缀(对齐 _EnsureClassParentsLoaded 做法)。
|
2026-08-18 13:32:01 +08:00 |
|
TermiNexus
|
7917be0fa1
|
perf(handles): stub 索引增量重建 + vtable on-demand pyi 缓存类级化,消除 worker 重复解析
- HandlesImports._build_stub_index:以已扫描文件集合替代文件数签名,无新增文件时仅一次集合比较;新增文件只增量解析,消除每编译完一个文件即全量重扫(prof 847 次全量重建 61s)
- HandlesImports._TryLoadStructFromStub:索引命中直接返回,仅在 miss 时才触发增量扫描
- HandlesExprCall._try_register_vtable_ondemand:函数局部 pyi_cache 提升为类级 _vtable_pyi_cache / _vtable_methods_cache,437 次 open+ast.parse 同批 pyi 降为每 pyi 一次(prof 38.5s)
|
2026-08-18 05:27:53 +08:00 |
|
TermiNexus
|
08e7b8d0c0
|
fix(handles): 带前缀类名提取 class_sha1,启用 stub 查找修复 Undefined method
ExprGenAttr 场景:ClassName 带 sha1 前缀(940e5294667daf5a.ExprGenAttr),struct_sha1_map.get(带前缀名)=None → class_sha1 为空 → _HandleMethodCallLlvm 的 stub 查找路径(if not func and class_sha1)被整体跳过 → fail-fast "Undefined method 'get_attribute_ptr'"(尽管 stub.ll 第 24 行存在该 declare)。
- 带前缀类名:class_sha1 直接取前 16 位,FullMethodName 不再拼接(避免双前缀)
- 裸类名:保持原逻辑从 _struct_sha1_map 取 sha1
|
2026-08-17 19:35:24 +08:00 |
|
TermiNexus
|
1f3c83cb6d
|
fix(handles): MRO 查找归一化带 sha1 前缀类名,修复继承方法 Undefined method
TPC 编译 TPV 报 "Undefined method 'find_func_in_module' in class 'c9b44d17cd621a75.CallGenLib'":跨模块 ObjVal 类型反查 Gen.structs 得到带 sha1 前缀的类名,而 class_parents / ModuleSha1Map / _struct_sha1_map 键为裸类名 → _get_mro_chain 查不到父类 → MRO 回退失效 → fail-fast。
- BaseGen._get_mro_chain:查 class_parents 前剥离 "16位hex." 前缀(父类名带前缀时同样处理)
- HandlesExprCall._EnsureClassParentsLoaded:归一化后再查 class_parents / 按需加载父类信息
|
2026-08-17 19:11:48 +08:00 |
|
TermiNexus
|
6fc9e19e24
|
feat(vast): 新增自研 Viper/Python 语法解析器取代标准库 ast
TPC 侧取缔对 Python 标准库 ast 模块的依赖,改用 lib/vast 包:
- Nodes: 与 CPython 3.12 ast 完全同构的 131 个节点类(含抽象基类继承)
- Tokenizer: 词法分析(缩进/字符串/f-string/数字/运算符/软关键字)
- ExprParser: 表达式递归下降解析(优先级/lambda/推导式/f-string/切片)
- Parser: 语句解析(def/class/if/for/try/with/match/import/注解)
- Utils/Unparser: walk/dump/unparse/copy_location/literal_eval 等辅助
- 软关键字 fn/fun/func/function 并入解析器, 废除 ExpandSoftKeywords 预处理
- lib/_bootstrap 将 lib 目录加入 sys.path, import vast as ast 零修改替换
- 52 个文件 import ast 替换为 import vast as ast; 94 文件差分测试 0 失败
|
2026-08-17 09:36:38 +08:00 |
|
TermiNexus
|
fd3254cdd4
|
fix(TPC): 模块名与类名同名时 X.func() 按模块函数解析
import lib.core.X as X 且模块内有同名 class X 时,X.func() 此前被
is_class_name 判定拦截走 _HandleStaticMethodCallLlvm,用模块函数签名
生成带类前缀的 {sha1}.X.func 声明,而 define 是 {sha1}.func,导致
链接 undefined symbol(CompilerFactory.get_perm_pool)。现加模块别名
优先规则:SymbolTable 命中 IsModuleAlias 时跳过类静态方法路径,让位
模块函数调用;类构造 X.X(args) 仍走 struct 路径。同时移除
_HandleExternalCallLlvm 中误加的 else: return None 截断。
includes/llvmlite/__types.vp:DeepCopyType 各层分配源改由调用方传入
pool 参数(传 perm_pool 即持久),includes 层不依赖 App 工厂。
|
2026-08-14 04:02:22 +08:00 |
|
TermiNexus
|
2f0b741d55
|
fix(gen): TPC 治本——struct opaque 具化、多返回值 fail-fast、with MRO 修复
1. HandlesExprCall: vtable 分派前 _EnsureReceiverStructConcrete 主动具化 struct
body(stub + class_members 双路径),消除元数据已注册、本体仍 opaque 的
撕裂状态,失败即 fail-fast 暴露上游 stub 加载时序问题;
2. HandlesImports: stub 加载后仍 opaque 时不保留成功缓存(可重试),
避免 opaque 状态被固化导致 vtable 分派 GEP 崩溃;
3. HandlesAssign: 跨模块多返回值 CReturnTypes 恢复(LiteralStructType 回退)
+ 解析失败 fail-fast,不再静默跳过致目标变量未初始化触发堆损坏;
4. HandlesWith: MRO 继承方法解析跳过无函数体的 stub declare(Phase1 继承
包装声明),bitcast 目标改用函数签名参数类型避免 opaque 占位对象。
|
2026-08-13 07:51:27 +08:00 |
|
TermiNexus
|
d687216772
|
fix(TPC): 继承链 vtable 状态追溯 + 默认参数检查信息缺失保护
- _resolve_class_flags 沿 class_parent 链追溯 vtable 状态:Stmt/ExprNode 空中间基类(@t.CVTable 无方法)跨模块未注册 class_vtable,子类 IsCVTable 误判为 False → __before_init__ base=0 不写 vtable → 实例 vtable=null → 虚调用段错误。改为沿链查找任一祖先有 vtable 即继承。
- 函数调用严格参数检查:默认参数信息缺失(跨模块 stub 加载/并行编译时序未同步)时跳过检查,避免 fatal_error 误报缺少必需参数。
|
2026-08-10 23:01:43 +08:00 |
|