feat(tpv): App 与 TPVAppBK 新代版本对齐(rowptr 配套实现全套)
把 TransPyV/App 覆盖为 TPVAppBK 内容(39 文件):6 参注册式 _BuildReachableSha1Set 全套(StubMergerBuild/Store/Collect/__init__/IncludesScanner/Phase1Scan 等)、CallGen 与 TypeGenResolve 等新代实现。配套根 includes 为 rowptr 工作区(另有 includes_rowptr_bk 备份)。
This commit is contained in:
1 parent
c35246f426
commit
6b368b46a7
39 files changed
+2813
-505
No files matched your search
@@ -340,6 +340,113 @@ class ClassGenBase:
|
||||
if nm.id is not None and string.strcmp(nm.id, deco_name) == 0:
|
||||
return 1
|
||||
return 0
|
||||
def _tattr_name(self, node: ast.AST | t.CPtr, attr_name: str) -> int:
|
||||
"""从 t.attr.<name> / t.attr.<name>(args) 节点提取最外层属性名并比较。
|
||||
|
||||
Call(t.attr.aligned(16))→ 递归取 func;Attribute(t.attr.packed)→ 取 attr。
|
||||
"""
|
||||
if node is None:
|
||||
return 0
|
||||
if node.kind() == ast.ASTKind.Call:
|
||||
cl2: ast.Call | t.CPtr = (ast.Call | t.CPtr)(node)
|
||||
if cl2.func is None:
|
||||
return 0
|
||||
return self._tattr_name(cl2.func, attr_name)
|
||||
if node.kind() == ast.ASTKind.Attribute:
|
||||
at2: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
|
||||
if at2.attr is None:
|
||||
return 0
|
||||
return 1 if string.strcmp(at2.attr, attr_name) == 0 else 0
|
||||
return 0
|
||||
def _class_has_tattr(self, decorator_list: list[ast.AST | t.CPtr] | t.CPtr,
|
||||
attr_name: str) -> int:
|
||||
"""检查装饰器列表是否含 t.attr.<attr_name>(@c.Attribute(t.attr.xxx) 或 @t.attr.xxx)。
|
||||
|
||||
覆盖 packed/aligned/naked/section 等所有 t.attr 属性(B5)。
|
||||
"""
|
||||
if decorator_list is None:
|
||||
return 0
|
||||
dn: t.CSizeT = len(decorator_list)
|
||||
if dn == 0:
|
||||
return 0
|
||||
for di in range(dn):
|
||||
deco: ast.AST | t.CPtr = decorator_list.get(di)
|
||||
if deco is None:
|
||||
continue
|
||||
k: int = deco.kind()
|
||||
if k == ast.ASTKind.Call:
|
||||
cl: ast.Call | t.CPtr = (ast.Call | t.CPtr)(deco)
|
||||
# @c.Attribute(t.attr.xxx) 形式:func 是 Attribute(c, "Attribute")
|
||||
if cl.func is None or cl.func.kind() != ast.ASTKind.Attribute:
|
||||
continue
|
||||
at0: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cl.func)
|
||||
if at0.attr is None or string.strcmp(at0.attr, "Attribute") != 0:
|
||||
continue
|
||||
if cl.args is None:
|
||||
continue
|
||||
an: t.CSizeT = len(cl.args)
|
||||
for ai in range(an):
|
||||
ag: ast.AST | t.CPtr = cl.args.get(ai)
|
||||
if ag is not None and self._tattr_name(ag, attr_name) != 0:
|
||||
return 1
|
||||
else:
|
||||
# @t.attr.xxx 直接形式
|
||||
if self._tattr_name(deco, attr_name) != 0:
|
||||
return 1
|
||||
return 0
|
||||
def _tattr_aligned_int(self, node: ast.AST | t.CPtr) -> int:
|
||||
"""t.attr.aligned(N) → N(整数参数),非 aligned 或无参返回 0"""
|
||||
if node is None:
|
||||
return 0
|
||||
if node.kind() == ast.ASTKind.Call:
|
||||
cl2: ast.Call | t.CPtr = (ast.Call | t.CPtr)(node)
|
||||
if cl2.func is None or cl2.func.kind() != ast.ASTKind.Attribute:
|
||||
return 0
|
||||
at2: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cl2.func)
|
||||
if at2.attr is None or string.strcmp(at2.attr, "aligned") != 0:
|
||||
return 0
|
||||
if cl2.args is None or len(cl2.args) == 0:
|
||||
return 0
|
||||
a0: ast.AST | t.CPtr = cl2.args.get(0)
|
||||
if a0 is None or a0.kind() != ast.ASTKind.Constant:
|
||||
return 0
|
||||
cn: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(a0)
|
||||
if cn.const_kind != ast.CONST_INT:
|
||||
return 0
|
||||
return int(cn.int_val)
|
||||
return 0
|
||||
def _class_aligned_value(self, decorator_list: list[ast.AST | t.CPtr] | t.CPtr) -> int:
|
||||
"""取 @c.Attribute(t.attr.aligned(N)) 的对齐字节数,无 aligned 返回 0"""
|
||||
if decorator_list is None:
|
||||
return 0
|
||||
dn: t.CSizeT = len(decorator_list)
|
||||
if dn == 0:
|
||||
return 0
|
||||
for di in range(dn):
|
||||
deco: ast.AST | t.CPtr = decorator_list.get(di)
|
||||
if deco is None:
|
||||
continue
|
||||
if deco.kind() == ast.ASTKind.Call:
|
||||
cl: ast.Call | t.CPtr = (ast.Call | t.CPtr)(deco)
|
||||
if cl.func is None or cl.func.kind() != ast.ASTKind.Attribute:
|
||||
continue
|
||||
at0: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cl.func)
|
||||
if at0.attr is None or string.strcmp(at0.attr, "Attribute") != 0:
|
||||
continue
|
||||
if cl.args is None:
|
||||
continue
|
||||
an: t.CSizeT = len(cl.args)
|
||||
for ai in range(an):
|
||||
ag: ast.AST | t.CPtr = cl.args.get(ai)
|
||||
if ag is not None:
|
||||
av: int = self._tattr_aligned_int(ag)
|
||||
if av > 0:
|
||||
return av
|
||||
else:
|
||||
av2: int = self._tattr_aligned_int(deco)
|
||||
if av2 > 0:
|
||||
return av2
|
||||
return 0
|
||||
def _extract_func_meta(self, decorator_list: list[ast.AST | t.CPtr] | t.CPtr) -> int:
|
||||
"""从装饰器列表提取元数据位掩码,返回 0=无装饰器元数据"""
|
||||
meta: int = 0
|
||||
|
||||
@@ -5,6 +5,7 @@ import ast
|
||||
import llvmlite
|
||||
import memhub
|
||||
import string
|
||||
import stdio
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Gen.Translator as HT
|
||||
@@ -120,6 +121,18 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
on_copy))
|
||||
# Phase B: 将已存在的命名结构体注册到当前模块(输出类型定义行)
|
||||
llvmlite.module_add_named_type(trans.Module, pool, existing.Ty)
|
||||
# B5:existing 路径(Phase B 已注册类)同样需设置 packed/aligned——
|
||||
# Phase A 注册时虽已设置,但 Phase B 重新 add_named_type 后节点
|
||||
# IsPacked=0,打印输出 `{...}`(idt_entry packed 未生效根因)。
|
||||
if self.Gen.ClassGenBase._class_has_tattr(cd.decorator_list, "packed") != 0:
|
||||
llvmlite.module_set_named_type_packed(trans.Module, pool, existing.Ty, 1)
|
||||
# StructTable 每 Phase 可能重建(existing 是 Phase B 新 entry),
|
||||
# 必须补设 IsPacked——否则跨模块 stub 注入(ensure_struct_def
|
||||
# _in_module)按 entry.IsPacked 判定 packed 时读 0 → stub 非 packed。
|
||||
existing.IsPacked = 1
|
||||
align_ex: int = self.Gen.ClassGenBase._class_aligned_value(cd.decorator_list)
|
||||
if align_ex > 0 and existing.Align == 0:
|
||||
existing.Align = align_ex
|
||||
# Phase A-pre(declare_only=1)多遍扫描时,类已注册但不应翻译方法体
|
||||
# Phase B(declare_only=0)时全量翻译方法体
|
||||
if trans._declare_only == 1:
|
||||
@@ -228,6 +241,15 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# L422-426 / FuncGenMixin L482-483),不致命,本遍文件不写盘。
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:父类未注册即 pending(用后移除)
|
||||
dbg_p: str = trans.ModuleSha1 if trans.ModuleSha1 is not None else "?"
|
||||
stdio.printf("[DEPDBG] pending(class_parent): mod=%s cls=%s parent=%s\n",
|
||||
dbg_p, class_name, pname if pname is not None else "none")
|
||||
# 持久化(用后移除):供 Phase2 收敛失败最终诊断按调用方过滤
|
||||
if trans.ModuleSha1 is not None:
|
||||
self.Gen.CallGenBase._AppendPhaseAPending(
|
||||
trans.ModuleSha1, "class_parent", class_name,
|
||||
"-", "-", pname if pname is not None else "-")
|
||||
return 0
|
||||
pfc: int = parent_entry.FieldCount
|
||||
for pfi in range(pfc):
|
||||
@@ -345,7 +367,29 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# 供 translate_attribute 做后续 bitcast。
|
||||
is_generic_sub: int = 0
|
||||
if aa.annotation is not None and aa.annotation.kind() == ast.ASTKind.Subscript:
|
||||
is_generic_sub = 1
|
||||
# t.CArray[elem, N](含裸 CArray[elem, N])是定长值数组,
|
||||
# 非泛型堆对象——元素类型未就绪时若回退 Ptr(i8) 会注册成退化
|
||||
# 字段布局,Phase B 复用该 entry 后 GEP 元素成 i8,字段访问/
|
||||
# 赋值全部失效(zhuff_tree.codes: t.CArray[zhuff_code, 288]
|
||||
# 在 1a 因 zhuff_code 未注册(code: UINT 查表失败,类注册整体
|
||||
# 中止)退化为 Ptr(i8) 并注册,1b 复用退化 entry →
|
||||
# self.codes[i].bits 字段查找失败 → pending(attr_read/write) →
|
||||
# "if 条件表达式翻译失败"根因)。仅真正的泛型类(list[T]/
|
||||
# Vector[T] 等堆对象)未特化才回退 Ptr(i8)(AnnotClassName
|
||||
# 携带 mangled name 供后续 bitcast 恢复)。
|
||||
sub_g: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(aa.annotation)
|
||||
is_carray_sub_g: int = 0
|
||||
if sub_g is not None and sub_g.value is not None:
|
||||
if sub_g.value.kind() == ast.ASTKind.Attribute:
|
||||
svg_at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(sub_g.value)
|
||||
if svg_at.attr is not None and string.strcmp(svg_at.attr, "CArray") == 0:
|
||||
is_carray_sub_g = 1
|
||||
elif sub_g.value.kind() == ast.ASTKind.Name:
|
||||
svg_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(sub_g.value)
|
||||
if svg_nm.id is not None and (string.strcmp(svg_nm.id, "CArray") == 0 or string.strcmp(svg_nm.id, "rawarray") == 0):
|
||||
is_carray_sub_g = 1
|
||||
if is_carray_sub_g == 0:
|
||||
is_generic_sub = 1
|
||||
if is_generic_sub != 0:
|
||||
# 泛型未特化:回退为 Ptr(i8),依赖 AnnotClassName 做后续类型恢复
|
||||
field_ty = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
@@ -362,6 +406,15 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# 翻译: <file>,请检查依赖模块是否已编译/注册"),不静默掩盖。
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
# [DEPDBG] 临时诊断:字段注解类型未注册即 pending(用后移除)
|
||||
dbg_f: str = trans.ModuleSha1 if trans.ModuleSha1 is not None else "?"
|
||||
stdio.printf("[DEPDBG] pending(class_field_ty): mod=%s cls=%s field=%s\n",
|
||||
dbg_f, class_name, tgt.id if tgt.id is not None else "none")
|
||||
# 持久化(用后移除):供 Phase2 收敛失败最终诊断按调用方过滤
|
||||
if trans.ModuleSha1 is not None:
|
||||
self.Gen.CallGenBase._AppendPhaseAPending(
|
||||
trans.ModuleSha1, "class_field_ty", class_name,
|
||||
tgt.id if tgt.id is not None else "-", "-", "-")
|
||||
return 0
|
||||
# 旧行为:fast-fail NameError(已移除——Phase A 依赖未就绪时
|
||||
# 误报真实错误,中断多遍收敛;真实错误交给收敛检查兜底)
|
||||
@@ -482,6 +535,14 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# 注册命名结构体到模块(输出 %"name" = type { ... } 定义行)
|
||||
llvmlite.module_add_named_type(trans.Module, pool, struct_ty)
|
||||
|
||||
# B5:@c.Attribute(t.attr.packed) 打包结构体 → 类型定义输出 <{...}>
|
||||
# (LLVM packed struct,无字段填充,GEP 按 packed 布局计算偏移)。
|
||||
# idt/gdt/elf/fat32 等二进制格式结构体依赖它读写硬件/磁盘布局。
|
||||
is_packed_cd: int = self.Gen.ClassGenBase._class_has_tattr(
|
||||
cd.decorator_list, "packed")
|
||||
if is_packed_cd != 0:
|
||||
llvmlite.module_set_named_type_packed(trans.Module, pool, struct_ty, 1)
|
||||
|
||||
# 扫描字段类型,为跨模块结构体引用添加 opaque 声明
|
||||
# 例如 list[int].__pool__ 引用 memhub.MemManager,需要在当前模块添加 %"sha1.MemManager" = type opaque
|
||||
for fi in range(field_count):
|
||||
@@ -500,6 +561,15 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
VLogger.error(f"failed to register {class_name}", "CLASS")
|
||||
return 0
|
||||
|
||||
# B5:记录 packed 标记到 StructEntry(供 __sizeof__/字段布局等派生查询)
|
||||
if is_packed_cd != 0:
|
||||
entry.IsPacked = 1
|
||||
# B5:记录 aligned 对齐值(@c.Attribute(t.attr.aligned(N)),如 fpu_context 16 对齐),
|
||||
# 供全局变量/局部 alloca 生成时施加对齐。
|
||||
align_cd: int = self.Gen.ClassGenBase._class_aligned_value(cd.decorator_list)
|
||||
if align_cd > 0:
|
||||
entry.Align = align_cd
|
||||
|
||||
# 标记 VTable 状态(直接用 entry,规避跨模块同名 find_struct 找错)
|
||||
if has_vtable == 1:
|
||||
entry.HasVTable = 1
|
||||
|
||||
@@ -5,6 +5,7 @@ import ast
|
||||
import llvmlite
|
||||
import memhub
|
||||
import string
|
||||
import stdio
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Gen.Translator as HT
|
||||
@@ -618,6 +619,12 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
oop_has_vt_pre = oop_entry.HasVTable
|
||||
if oop_has_vt_pre == 1:
|
||||
self._collect_vtable_methods(trans, cd, class_name)
|
||||
# [PF-DBG] vtable 方法收集后 pending 检测(用后移除)
|
||||
if trans is not None and trans._deps_pending != 0 and trans._pf_dbg_pend_flagged == 0:
|
||||
trans._pf_dbg_pend_flagged = 1
|
||||
stdio.printf("[PF-DBG] pending-after-vtcollect: cls=%s sha1=%s\n",
|
||||
class_name, trans.ModuleSha1 if trans.ModuleSha1 is not None else "?")
|
||||
stdio.fflush(None)
|
||||
for ci in range(cn):
|
||||
stmt: ast.AST | t.CPtr = children.get(ci)
|
||||
if stmt is None:
|
||||
@@ -626,6 +633,19 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
fd: ast.FunctionDef | t.CPtr = (ast.FunctionDef | t.CPtr)(stmt)
|
||||
if fd is not None and fd.name is not None:
|
||||
self._translate_method(trans, fd, struct_ty, class_name)
|
||||
# [PF-DBG] 单个方法翻译后 pending 检测(用后移除)
|
||||
if trans is not None and trans._deps_pending != 0 and trans._pf_dbg_pend_flagged == 0:
|
||||
trans._pf_dbg_pend_flagged = 1
|
||||
stdio.printf("[PF-DBG] pending-after-method: cls=%s method=%s sha1=%s\n",
|
||||
class_name, fd.name,
|
||||
trans.ModuleSha1 if trans.ModuleSha1 is not None else "?")
|
||||
stdio.fflush(None)
|
||||
# [PF-DBG] 方法翻译后 pending 检测(用后移除)
|
||||
if trans is not None and trans._deps_pending != 0 and trans._pf_dbg_pend_flagged == 0:
|
||||
trans._pf_dbg_pend_flagged = 1
|
||||
stdio.printf("[PF-DBG] pending-after-methods: cls=%s sha1=%s\n",
|
||||
class_name, trans.ModuleSha1 if trans.ModuleSha1 is not None else "?")
|
||||
stdio.fflush(None)
|
||||
|
||||
# 如果有虚表,先生成 VTable 全局变量(设置 VTableMethodCount)
|
||||
# 必须在 __before_init__ 之前,否则 __before_init__ 读不到 VTableMethodCount
|
||||
@@ -635,9 +655,21 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
has_vt_flag = oop_entry.HasVTable
|
||||
if has_vt_flag == 1:
|
||||
self._generate_vtable(trans, cd, class_name)
|
||||
# [PF-DBG] vtable 生成后 pending 检测(用后移除)
|
||||
if trans is not None and trans._deps_pending != 0 and trans._pf_dbg_pend_flagged == 0:
|
||||
trans._pf_dbg_pend_flagged = 1
|
||||
stdio.printf("[PF-DBG] pending-after-vtable: cls=%s sha1=%s\n",
|
||||
class_name, trans.ModuleSha1 if trans.ModuleSha1 is not None else "?")
|
||||
stdio.fflush(None)
|
||||
|
||||
# 生成 __before_init__ 函数(零值填充 + 默认值赋值 + vtable 指针设置)
|
||||
self._generate_before_init(trans, struct_ty, class_name)
|
||||
# [PF-DBG] before_init 生成后 pending 检测(用后移除)
|
||||
if trans is not None and trans._deps_pending != 0 and trans._pf_dbg_pend_flagged == 0:
|
||||
trans._pf_dbg_pend_flagged = 1
|
||||
stdio.printf("[PF-DBG] pending-after-before_init: cls=%s sha1=%s\n",
|
||||
class_name, trans.ModuleSha1 if trans.ModuleSha1 is not None else "?")
|
||||
stdio.fflush(None)
|
||||
|
||||
return 0
|
||||
# ============================================================
|
||||
|
||||
Reference in new issue
Block a user