重置上传,新增了多个标准库,开始 TransPyV 自举实验
This commit is contained in:
@@ -248,7 +248,15 @@ class StructGenMixin:
|
||||
if is_packed:
|
||||
self.structs[ClassName].packed = True
|
||||
continue
|
||||
mangled_name: str = self._mangle_name(ClassName)
|
||||
# 修复跨模块类型定义冲突:如果类是从其他模块导入的(已在 class_sha1_map 注册),
|
||||
# 必须使用导入的 source_sha1 作为前缀,而非本地模块的 sha1。
|
||||
# 否则会创建缺少基类字段(如 GSListNode.Next)的本地类型定义,
|
||||
# 导致字段索引错位 → 访问违规崩溃。
|
||||
_imported_sha1: str = self.class_sha1_map.get(ClassName, '')
|
||||
if _imported_sha1:
|
||||
mangled_name: str = f"{_imported_sha1}.{ClassName}"
|
||||
else:
|
||||
mangled_name: str = self._mangle_name(ClassName)
|
||||
struct_type: ir.IdentifiedStructType = ir.IdentifiedStructType(self.module, mangled_name, packed=is_packed)
|
||||
self.structs[ClassName] = struct_type
|
||||
|
||||
@@ -361,7 +369,18 @@ class StructGenMixin:
|
||||
_vtable_first_ok: bool = True
|
||||
if _has_vtable_precheck and len(existing_st.elements) > 0:
|
||||
_vtable_first_ok = isinstance(existing_st.elements[0], ir.PointerType)
|
||||
if len(existing_st.elements) >= _expected_count_pre and _vtable_first_ok:
|
||||
# 检测 T* 占位类型(未特化的泛型类型参数)。
|
||||
# 当 struct 包含 T* 字段时(如 BasicBlock 继承 GSListNode[BasicBlock] 但 stub 未特化),
|
||||
# 说明 stub 使用了未特化的基类,需清除重新生成。
|
||||
_has_t_placeholder_pre: bool = False
|
||||
for _elem_pre in existing_st.elements:
|
||||
if isinstance(_elem_pre, ir.PointerType) and isinstance(_elem_pre.pointee, ir.IdentifiedStructType):
|
||||
_pname_pre: str = _elem_pre.pointee.name
|
||||
_short_pre: str = _pname_pre.rsplit('.', 1)[-1] if '.' in _pname_pre else _pname_pre
|
||||
if _short_pre == 'T':
|
||||
_has_t_placeholder_pre = True
|
||||
break
|
||||
if len(existing_st.elements) >= _expected_count_pre and _vtable_first_ok and not _has_t_placeholder_pre:
|
||||
if ClassName in self.class_packed and not existing_st.packed:
|
||||
existing_st.packed = True
|
||||
continue
|
||||
@@ -438,7 +457,12 @@ class StructGenMixin:
|
||||
# 由 _TryLoadStructFromStub 设置完整 body。
|
||||
member_types = []
|
||||
else:
|
||||
member_types = [ir.IntType(8)]
|
||||
# 无 vtable 且 class_members 为空:常见于 register_method 早期
|
||||
# 调用 _generate_structs(此时 class_members[ClassName]=[] 但尚未
|
||||
# 填充实际字段)。保持 opaque,避免 set_body(*[i8]) 永久损坏 struct
|
||||
# (llvmlite 的 set_body 只能调用一次)。后续 _generate_structs 调用
|
||||
# 会从 class_members 或 stub 设置正确 body。
|
||||
member_types = []
|
||||
|
||||
# 获取之前创建的 struct 并设置成员
|
||||
struct_type: ir.IdentifiedStructType = self.structs[ClassName]
|
||||
@@ -454,10 +478,26 @@ class StructGenMixin:
|
||||
import_handler: Any = self._import_handler_ref
|
||||
if import_handler is not None and ClassName not in self._classes_in_progress:
|
||||
try:
|
||||
import_handler._TryLoadStructFromStub(ClassName, self)
|
||||
# 传入 source_sha1 确保从正确的 stub 文件加载完整定义
|
||||
_src_sha1: str = self.class_sha1_map.get(ClassName, '')
|
||||
import_handler._TryLoadStructFromStub(ClassName, self, source_sha1=_src_sha1 or None)
|
||||
except Exception:
|
||||
pass
|
||||
struct_type = self.structs.get(ClassName, struct_type)
|
||||
# 检测 stub body 中的 T* 占位类型(未特化的泛型类型参数)。
|
||||
# 若 stub 使用了未特化的基类(如 GSListNode 而非 GSListNode[BasicBlock]),
|
||||
# 清除 _elements 让 set_body 用正确的 class_members 重新设置。
|
||||
if struct_type.elements is not None and member_types:
|
||||
_has_t_placeholder_post: bool = False
|
||||
for _elem_post in struct_type.elements:
|
||||
if isinstance(_elem_post, ir.PointerType) and isinstance(_elem_post.pointee, ir.IdentifiedStructType):
|
||||
_pname_post: str = _elem_post.pointee.name
|
||||
_short_post: str = _pname_post.rsplit('.', 1)[-1] if '.' in _pname_post else _pname_post
|
||||
if _short_post == 'T':
|
||||
_has_t_placeholder_post = True
|
||||
break
|
||||
if _has_t_placeholder_post:
|
||||
struct_type._elements = None
|
||||
if struct_type.elements is None:
|
||||
# 防御性检查:member_types 为空时不调用 set_body。
|
||||
# set_body(*[]) 会设置 elements=() 使 is_opaque=False,
|
||||
@@ -485,18 +525,20 @@ class StructGenMixin:
|
||||
# _shared_class_vtable 和 _shared_cross_module_vtable,导致 class_vtable 与
|
||||
# _cross_module_vtable_classes 内容相同,无法用以区分本模块类与跨模块类。
|
||||
# _generate_structs 会为所有 class_methods 的类创建空 struct type,导致 self.structs
|
||||
# 也包含所有类。唯一可靠的过滤条件是 self.functions:_EmitClassLlvm 在本函数之前
|
||||
# 调用(LlvmGenerator.py L178-182),本模块定义的类方法已加入 self.functions;
|
||||
# import 声明的跨模块类方法也在 self.functions 中。若 self.functions 中没有任何
|
||||
# 以 "{ClassName}." 开头的键,说明本模块既未定义也未导入该类的方法,虚表会保持
|
||||
# 全 null,虚表分派时调用 null 指针引发段错误。此时应跳过虚表创建,让链接器
|
||||
# 从定义该类的模块解析虚表符号。
|
||||
# 也包含所有类。过滤条件是 self.functions:只考虑本模块定义的函数(define,有函数体),
|
||||
# 跳过跨模块的 declare(无函数体)。跨模块类的 declare 通过 HandlesImports 加入
|
||||
# self.functions(短名如 "MemManager.alloc"),但其 is_declaration=True。
|
||||
# 若只存在 declare 而无 define,说明本模块未定义该类,虚表应由定义模块创建。
|
||||
# vtable linkage='internal',跨模块调用通过对象的 vtable 指针(首字段)完成分派,
|
||||
# 不依赖本模块的 vtable 全局变量。
|
||||
has_local_method: bool = False
|
||||
prefix: str = f"{ClassName}."
|
||||
for func_name in self.functions:
|
||||
for func_name, func_obj in self.functions.items():
|
||||
if func_name.startswith(prefix):
|
||||
has_local_method = True
|
||||
break
|
||||
# 跳过跨模块的 declare(无函数体),只考虑本模块定义的函数
|
||||
if not getattr(func_obj, 'is_declaration', False):
|
||||
has_local_method = True
|
||||
break
|
||||
if not has_local_method:
|
||||
continue
|
||||
VtableType: ir.ArrayType = ir.ArrayType(ir.PointerType(ir.IntType(8)), len(methods))
|
||||
|
||||
Reference in New Issue
Block a user