修正了 TPC 的一些错误,包括 Test 维护后 TPV 无法重新编译或重编译后越界的部分问题

This commit is contained in:
2026-07-20 11:12:30 +08:00
parent ab73420b4f
commit a277ded8d4
476 changed files with 4000 additions and 3439 deletions

View File

@@ -220,6 +220,11 @@ class ClassHandle(BaseHandle):
Gen.global_vars = saved_global_vars
self.Trans.VarScopes = saved_var_scopes
Gen._generic_class_specializations[spec_key] = (spec_name, declare_only)
# 缓存 type_args/type_names供后续 declare_only=False 完整特化补发方法体使用
# (如 _HandleMethodCallLlvm 中发现方法未定义时触发)
if not hasattr(Gen, '_generic_class_spec_type_info'):
Gen._generic_class_spec_type_info = {}
Gen._generic_class_spec_type_info[spec_key] = (list(type_args), list(type_names) if type_names else None)
if not hasattr(self.Trans, '_generic_class_specializations'):
self.Trans._generic_class_specializations = {}
self.Trans._generic_class_specializations[spec_key] = spec_name
@@ -535,33 +540,50 @@ class ClassHandle(BaseHandle):
if pm_name in parent_defaults:
Gen.class_member_defaults[ClassName][pm_name] = parent_defaults[pm_name]
Gen.class_members[ClassName] = inherited + Gen.class_members[ClassName]
if ParentClass in Gen.class_methods:
parent_methods: list = list(Gen.class_methods[ParentClass])
# 构建子类有方法映射(方法短名 -> 方法全名)
child_method_map: dict[str, str] = {}
for m in Gen.class_methods[ClassName]:
method_name: str = m.split('.')[-1] if '.' in m else m
child_method_map[method_name] = m
# 父类方法在前(保证 vtable 布局一致性,子类多态分派索引正确),
# 子类新增方法在后。子类覆盖的方法放在父类方法的位置(用子类实现)。
new_methods: list = []
covered_names: set[str] = set()
for pm in parent_methods:
method_name: str = pm.split('.')[-1] if '.' in pm else pm
if method_name in child_method_map:
# 子类覆盖了父类方法 — 用子类的实现,放在父类的位置
new_methods.append(child_method_map[method_name])
covered_names.add(method_name)
else:
# 父类独有方法 — 子类未覆盖,注册子类包装器
child_method: str = f"{ClassName}.{method_name}"
new_methods.append(child_method)
Gen.register_method(ClassName, child_method)
# 添加子类新增方法(不在父类中的)
for m in Gen.class_methods[ClassName]:
method_name: str = m.split('.')[-1] if '.' in m else m
if method_name not in covered_names:
new_methods.append(m)
if ParentClass in Gen.class_methods:
parent_methods: list = list(Gen.class_methods[ParentClass])
# 从 Node.body 收集子类有方法(此时 Gen.class_methods[ClassName] 可能为空,
# 因为自有方法在 L660-676 才注册。若直接用 Gen.class_methods[ClassName]
# child_method_map 会为空,所有父类方法被当作"未覆盖"添加为包装器,
# 然后 register_method 又把它们追加到 Gen.class_methods[ClassName]
# L566 循环再次添加 → 产生重复条目vtable 布局与导入模块不一致)
child_method_map: dict[str, str] = {}
child_self_methods_snapshot: list[str] = []
for _item in Node.body:
if isinstance(_item, ast.FunctionDef):
_mname: str = _item.name
if _mname in ('__new__', '__init__', '__before_init__'):
continue
_item_meta: FuncMeta = self.Trans.FunctionHandler._ExtractFuncMeta(_item.decorator_list)
if FuncMeta.PROPERTY_SETTER in _item_meta:
_full: str = f"{ClassName}.{_mname}$set"
elif FuncMeta.PROPERTY_DELETER in _item_meta:
_full = f"{ClassName}.{_mname}$del"
else:
_full = f"{ClassName}.{_mname}"
_short: str = _mname
child_method_map[_short] = _full
child_self_methods_snapshot.append(_full)
# 父类方法在前(保证 vtable 布局一致性,子类多态分派索引正确),
# 子类新增方法在后。子类覆盖的方法放在父类方法的位置(用子类实现)。
new_methods: list = []
covered_names: set[str] = set()
for pm in parent_methods:
method_name: str = pm.split('.')[-1] if '.' in pm else pm
if method_name in child_method_map:
# 子类覆盖了父类方法 — 用子类的实现,放在父类的位置
new_methods.append(child_method_map[method_name])
covered_names.add(method_name)
else:
# 父类独有方法 — 子类未覆盖,注册子类包装器
child_method: str = f"{ClassName}.{method_name}"
new_methods.append(child_method)
Gen.register_method(ClassName, child_method)
# 添加子类新增方法(不在父类中的)— 使用快照避免 register_method 污染
for m in child_self_methods_snapshot:
method_name: str = m.split('.')[-1] if '.' in m else m
if method_name not in covered_names:
new_methods.append(m)
Gen.class_methods[ClassName] = new_methods
# 提取首个裸字符串字面量作为结构体 __doc__ docstring
if (Node.body and isinstance(Node.body[0], ast.Expr)
@@ -609,6 +631,19 @@ class ClassHandle(BaseHandle):
if ClassName not in Gen.class_member_element_class:
Gen.class_member_element_class[ClassName] = {}
Gen.class_member_element_class[ClassName][VarName] = element_class
# 泛型特化结构体指针字段(如 GSList[BasicBlock] | t.CPtr
# 记录特化名,供后续 _try_access_opaque_generic_member 在所有候选特化版本
# 都有目标字段(如 Head/Tail/Count时选择正确特化版本。
# 现有 i8* 分支不覆盖结构体指针字段,这里补充。
elif (isinstance(MemberType, ir.PointerType)
and isinstance(MemberType.pointee, ir.IdentifiedStructType)
and isinstance(item.annotation, ast.BinOp)
and isinstance(item.annotation.op, ast.BitOr)):
spec_in_anno: str | None = FindStructNameInAnnotation(item.annotation, Gen.structs)
if spec_in_anno and '[' in spec_in_anno:
if ClassName not in Gen.class_member_element_class:
Gen.class_member_element_class[ClassName] = {}
Gen.class_member_element_class[ClassName][VarName] = spec_in_anno
if hasattr(TypeInfo.BaseType, 'IsSigned'):
Gen.class_member_signeds[ClassName][VarName] = TypeInfo.BaseType.IsSigned
else: