fix(HandlesImports): 跨模块 class_members 展平同步按继承源去重

81ad712 只同步了 HandlesClassDef(运行时) 与 DeclarationGenerator(stub struct),遗漏并行 worker 跨模块重建路径 _EmitExternalClassDeclLlvm:仍用旧拼接+按字段名过滤算法,菱形继承下与 stub struct 布局不一致,worker 中 this_adjust 算不出偏移,继承方法 self 不调整,运行时错位崩溃(register_reexport 写 0x3f)。改为递归按继承源去重,与 HandlesClassDef._FlattenInherited 一致。
This commit is contained in:
TermiNexus committed 2026-08-18 13:44:22 +08:00
1 parent 97b714603d
commit b021c5b527
1 file changed
+58 -12
+58 -12
View File
@@ -14,7 +14,7 @@ from lib.core.VLogger import get_logger as _vlog
from lib.constants.config import mode as _config_mode from lib.constants.config import mode as _config_mode
from lib.includes import t from lib.includes import t
from lib.includes.t import CTypeRegistry from lib.includes.t import CTypeRegistry
from lib.core.SymbolUtils import ParseListAnnotation, ExtractTypeNameFromBinOp, AnnotationContainsName from lib.core.SymbolUtils import ParseListAnnotation, ExtractTypeNameFromBinOp, AnnotationContainsName, FindStructNameInAnnotation
class ImportHandle(BaseHandle): class ImportHandle(BaseHandle):
@@ -1738,6 +1738,28 @@ class ImportHandle(BaseHandle):
Gen.class_members[ClassName].append((VarName, MemberType)) Gen.class_members[ClassName].append((VarName, MemberType))
_existing_member_names.add(VarName) _existing_member_names.add(VarName)
Gen.class_member_bitfields[ClassName][VarName] = 0 Gen.class_member_bitfields[ClassName][VarName] = 0
# 与 HandlesClassDef 对齐:联合类型字段(如 `list[str] | t.CPtr`)
# 记录泛型特化名到 class_member_element_class。否则跨模块 import
# 的类(如 TypeGenBase.CTypedefNames)缺此记录,_HandleLenLlvm
# 无法识别字段为 list → len() 误编译为 strlen → stdint 崩溃。
if isinstance(MemberType, ir.PointerType) and isinstance(MemberType.pointee, ir.IntType) and MemberType.pointee.width == 8:
if isinstance(item.annotation, ast.BinOp) and isinstance(item.annotation.op, ast.BitOr):
element_class: str | None = FindStructNameInAnnotation(item.annotation, Gen.structs)
if not element_class and TypeInfo.IsStruct and TypeInfo.Name and TypeInfo.Name in Gen.structs:
element_class = TypeInfo.Name
if element_class:
if ClassName not in Gen.class_member_element_class:
Gen.class_member_element_class[ClassName] = {}
Gen.class_member_element_class[ClassName][VarName] = element_class
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 TypeInfo.ByteOrder: if TypeInfo.ByteOrder:
Gen.class_member_byteorders[ClassName][VarName] = TypeInfo.ByteOrder Gen.class_member_byteorders[ClassName][VarName] = TypeInfo.ByteOrder
else: else:
@@ -1926,17 +1948,41 @@ class ImportHandle(BaseHandle):
# 加载失败,回滚到旧占位条目(有总比没有好) # 加载失败,回滚到旧占位条目(有总比没有好)
Gen.class_members[_ParentClass] = _old_parent_members Gen.class_members[_ParentClass] = _old_parent_members
if _ParentClass in Gen.class_members: if _ParentClass in Gen.class_members:
_parent_members: list = list(Gen.class_members[_ParentClass]) # 按继承源去重(与 HandlesClassDef._FlattenInherited 一致,2026-08-18):
_parent_defaults: dict = dict(Gen.class_member_defaults.get(_ParentClass, {})) # 菱形继承(Generator 同时继承 ClassGenMixin/ClassGenEnum/.../ClassGenBase,
# 跨父类不去重(与 HandlesClassDef 展平、DeclarationGenerator stub 一致): # 而它们都继承 ClassGenBase)若直接拼接会重复展平 → 与 DeclarationGenerator
# 多继承展平必须保留每个父类全部字段(含重名如多个 Mixin 的 TempDir), # stub struct 布局不一致 → 并行 worker 里 this_adjust 算不出偏移 → 继承
# 否则 Mixin 方法体 this_adjust + 块内局部索引寻址与全量布局错位。 # 方法 self 不调整 → 运行时错位崩溃(register_reexport 写 0x3f)。
for _pm_name, _pm_type in _parent_members: # 递归每类只处理一次,每类只贡献非祖先字段。
if _pm_name == '__vtable__': _seen_flat_cls: set[str] = set()
continue def _FlattenExt(cls_name: str) -> None:
_all_inherited.append((_pm_name, _pm_type)) if cls_name in _seen_flat_cls:
if _pm_name in _parent_defaults: return
Gen.class_member_defaults[ClassName][_pm_name] = _parent_defaults[_pm_name] _seen_flat_cls.add(cls_name)
for _gp in Gen.class_parents.get(cls_name, []) or []:
_FlattenExt(_gp)
_anc_flat: set[str] = set()
_stk: list[str] = [cls_name]
_vis: set[str] = set()
while _stk:
_c = _stk.pop()
for _gp2 in Gen.class_parents.get(_c, []) or []:
if _gp2 in _vis:
continue
_vis.add(_gp2)
_stk.append(_gp2)
for _mn2, _mt2 in Gen.class_members.get(_gp2, []) or []:
_anc_flat.add(_mn2)
for _mn3, _mt3 in Gen.class_members.get(cls_name, []) or []:
if _mn3 == '__vtable__':
continue
if _mn3 in _anc_flat:
continue
_all_inherited.append((_mn3, _mt3))
_pd3: dict = dict(Gen.class_member_defaults.get(cls_name, {}))
if _mn3 in _pd3:
Gen.class_member_defaults[ClassName][_mn3] = _pd3[_mn3]
_FlattenExt(_ParentClass)
if _all_inherited: if _all_inherited:
# 防重复注册(2026-08-10):_EmitExternalClassDeclLlvm 可能被多个模块 # 防重复注册(2026-08-10):_EmitExternalClassDeclLlvm 可能被多个模块
# 加载路径重复调用(_LoadModuleDeclarationsFromFile / _LoadDeclarationsFromStubLlvm # 加载路径重复调用(_LoadModuleDeclarationsFromFile / _LoadDeclarationsFromStubLlvm