# 类型定义模块 from __future__ import annotations import sys import types from typing import Any, ClassVar, Optional, TypeVar, Generic, TypeAlias, Callable from lib.constants.config import mode as _ConfigMode from lib.core.VLogger import get_logger as _vlog # ============================================================================= # 类型映射常量 # ============================================================================= # 标记基类注册表(由 @_marker_base 装饰器自动注册,或手动添加) _MARKER_BASES: set[str] = set() def _marker_base(cls: type) -> type: """将类名注册为标记基类,供 HandlesClassDef 检测使用""" _MARKER_BASES.add(cls.__name__) return cls # 平台相关类型的默认 Size(可由 configure_platform 修改) _LONG_SIZE = 64 _UNSIGNED_LONG_SIZE = 64 _WCHAR_T_SIZE = 32 _SIZE_T_SIZE = 64 _INTPTR_T_SIZE = 64 _UINTPTR_T_SIZE = 64 _PTRDIFF_T_SIZE = 64 def configure_platform(triple: Optional[str] = None) -> None: """根据目标三元组配置平台相关类型的大小 Args: triple: LLVM 目标三元组字符串,如 'x86_64-pc-windows-gnu' """ global _LONG_SIZE, _UNSIGNED_LONG_SIZE, _WCHAR_T_SIZE global _SIZE_T_SIZE, _INTPTR_T_SIZE, _UINTPTR_T_SIZE, _PTRDIFF_T_SIZE if not triple: return triple_lower: str = triple.lower() is_windows: bool = any(k in triple_lower for k in ('windows', 'win32', 'mingw', 'msvc', 'cygwin')) is_32bit: bool = any(k in triple_lower for k in ('i386', 'i686')) if is_windows: _LONG_SIZE = 32 # Windows LLP64: long = 32 位 _UNSIGNED_LONG_SIZE = 32 _WCHAR_T_SIZE = 16 # Windows: wchar_t = 16 位 if is_32bit: _SIZE_T_SIZE = 32 _INTPTR_T_SIZE = 32 _UINTPTR_T_SIZE = 32 _PTRDIFF_T_SIZE = 32 # ============================================================================= # CType 基类 # ============================================================================= class CType: """C 类型基类""" PREFIX: ClassVar[str] = 'prefix' BASE: ClassVar[str] = 'base' POINTER: ClassVar[str] = 'ptr' ARRAY: ClassVar[str] = 'array' NAMED: ClassVar[str] = 'named' STORAGE_CLASS: ClassVar[str] = 'storage_class' TYPE_QUALIFIER: ClassVar[str] = 'type_qualifier' position: ClassVar[frozenset[str]] = frozenset({BASE}) # 类属性,支持联合类型如 BASE | SPECIAL def __init__(self, value: Any = None, *types: Any) -> None: self.value: Any = value self.types: tuple[Any, ...] = types self.Name: str = '' self.IsBasicType: bool = False self.IsPointer: bool = False self.IsSigned: Optional[bool] = None self.Size: Optional[int] = None def GetPositions(self) -> frozenset[str]: """获取 position 的 frozenset 形式""" return self.position @classmethod def HasPosition(cls, pos: str) -> bool: """检查是否包含指定的位置""" return pos in cls.position @classmethod def IsNamed(cls) -> bool: """检查是否是命名类型(struct/union/enum/typedef 等)""" return cls.NAMED in cls.position @classmethod def IsStorageClass(cls) -> bool: """检查是否是存储类修饰符""" return cls.STORAGE_CLASS in cls.position @classmethod def IsTypeQualifier(cls) -> bool: """检查是否是类型限定符""" return cls.TYPE_QUALIFIER in cls.position @classmethod def IsBasicType(cls) -> bool: """检查是否是基本类型""" return cls.BASE in cls.position @classmethod def IsPrefix(cls) -> bool: """检查是否是前缀类型""" return cls.PREFIX in cls.position def rfind(self, s: str) -> None: """注解""" pass def get_position(self) -> frozenset[str]: """获取类型在声明中的位置""" return self.position def __merge__(self, types: Any) -> Any: return types def __or__(self, other: Any) -> list[Any]: return [self, other] def __set_default__(self, **kwargs: Any) -> CTypeDefault: """设置默认值/初始值,用于 static/global 变量的初始化 Args: **kwargs: 成员名称和值的键值对 Returns: 包含默认值信息的 CTypeDefault 对象 """ return CTypeDefault(self, **kwargs) def GetFullType(self, VarName: str = '', ArraySizeStr: str = '') -> str: """获取完整的类型声明字符串 Args: VarName: 变量名 ArraySizeStr: 数组大小字符串 Returns: 完整的类型声明字符串 """ ptr_str: str = '*' if self.IsPointer else '' if VarName: return f'{self.Name}{ptr_str} {VarName}{ArraySizeStr}' return f'{self.Name}{ptr_str}' def __repr__(self) -> str: ptr_str: str = '*' if self.IsPointer else '' return f'CType({self.Name}{ptr_str}, IsBasicType={self.IsBasicType})' class CChar(CType): def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = 8 class CInt(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = 32 class CShort(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = 16 class CLong(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = _LONG_SIZE class CLongLong(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = 64 class CFloat(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: Optional[bool] = None self.Size: int = 32 class CDouble(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: Optional[bool] = None self.Size: int = 64 class CFloat8T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: Optional[bool] = None self.Size: int = 8 class CFloat16T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: Optional[bool] = None self.Size: int = 16 class CFloat32T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: Optional[bool] = None self.Size: int = 32 class CFloat64T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: Optional[bool] = None self.Size: int = 64 class CFloat128T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: Optional[bool] = None self.Size: int = 128 class CVoid(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: Optional[bool] = None self.Size: int = 0 class CUnsigned(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 32 class CUnsignedChar(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 8 class CUnsignedInt(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 32 class CUnsignedShort(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 16 class CUnsignedLong(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = _UNSIGNED_LONG_SIZE class CUnsignedLongLong(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 64 class CSignedChar(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = 8 @_marker_base class CStruct(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE, CType.NAMED}) def __init__(self, value: Any = None, name: Optional[str] = None) -> None: self.name: Optional[str] = name super().__init__(value) @_marker_base class CUnion(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE, CType.NAMED}) def __init__(self, value: Any = None) -> None: super().__init__(value) @_marker_base class CEnum(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE, CType.NAMED}) def __init__(self, value: Any = None) -> None: super().__init__(value) Enum = CEnum @_marker_base class REnum(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE, CType.NAMED}) tag: int = 0 # 无用,只是个标记 def __init__(self, value: Any = None) -> None: super().__init__(value) ''' class Object(CType): """Python 对象类型,用于支持类方法外联函数""" position = frozenset({CType.BASE, CType.NAMED}) def __init__(self, value=None): super().__init__(value) def __call__(self, cls): return cls ''' def Object() -> None: pass def CVTable() -> None: pass def NoVTable() -> None: """标记类为非多态继承基类:被子类继承时字段直接展平嵌入,不生成 vtable,避免 vtable 开销。 区别于 @t.CVTable(启用多态 vtable)。对应 C++ 的非多态继承(struct A : B {} 无 virtual)。""" pass def TLS() -> None: """标记函数为 TLS 初始化函数,首次调用时执行,后续调用跳过。 编译器自动生成全局标志变量和一次性执行检查代码。 """ pass # Object 和 CVTable 是普通函数,Exception 是 Python 内建类型,Enum 是 CEnum 的别名 # 这些名称无法通过 @_marker_base 装饰器自动注册,需手动添加到 _MARKER_BASES # TLS 是函数装饰器标记,由编译器在函数处理阶段识别 _MARKER_BASES.update({'Object', 'CVTable', 'Exception', 'Enum'}) CTypedef: TypeAlias = TypeAlias class _CTypedef(CType): position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.NAMED}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CAuto(CType): position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CRegister(CType): position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CStatic(CType): position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CExtern(CType): position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CConst(CType): position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.TYPE_QUALIFIER}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CInline(CType): position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CExport(CType): position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CVolatile(CType): position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.TYPE_QUALIFIER}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CSizeT(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = _SIZE_T_SIZE class CInt8T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = 8 class CInt16T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = 16 class CInt32T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = 32 class CInt64T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = 64 class CUInt8T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 8 class CUInt16T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 16 class CUInt32T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 32 class CUInt64T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 64 class CIntPtrT(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = _INTPTR_T_SIZE class CUIntPtrT(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = _UINTPTR_T_SIZE class CPtrDiffT(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = _PTRDIFF_T_SIZE class CWCharT(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = True self.Size: int = _WCHAR_T_SIZE class CChar8T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 8 class CChar16T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 16 class CChar32T(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 32 class CBool(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) self.IsSigned: bool = False self.Size: int = 8 T = TypeVar("T") class CPtr(CType, Generic[T]): position: ClassVar[frozenset[str]] = frozenset({CType.POINTER}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CNeedPtr(CPtr): """函数签名注解:自动取地址(仅对非指针值)。 用作参数类型时,编译器在调用处自动将非指针值取地址为指针。 若参数已经是指针,则不做操作。""" position: ClassVar[frozenset[str]] = frozenset({CType.POINTER}) auto_addr_mode: ClassVar[str] = 'need' def __init__(self, value: Any = None) -> None: super().__init__(value) class CAutoPtr(CPtr): """函数签名注解:无条件取地址。 用作参数类型时,编译器在调用处无条件将值取地址为指针, 即使值本身已经是指针也会再取一层地址。""" position: ClassVar[frozenset[str]] = frozenset({CType.POINTER}) auto_addr_mode: ClassVar[str] = 'always' def __init__(self, value: Any = None) -> None: super().__init__(value) class CTypeDefault(CType): """用于存储 C 类型默认值/初始化的包装类 当使用 t.CStatic.__set_default__(open=mouse_open, ...) 时创建 """ def __init__(self, BaseType: Any, **kwargs: Any) -> None: super().__init__() self.BaseType: Any = BaseType self.defaults: dict[str, Any] = kwargs self.position: frozenset[str] = BaseType.position if hasattr(BaseType, 'position') else CType.BASE def __repr__(self) -> str: return f'CTypeDefault({self.BaseType}, {self.defaults})' class CArrayPtr(CType): position: ClassVar[frozenset[str]] = frozenset({CType.POINTER}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CArray(CType): """栈上固定数组类型注解。 用法: names: t.CArray[VOIDPTR, 32] # void*[32] data: t.CArray[t.CInt, 64] # int[64] 第一个参数为元素类型,第二个参数为数组大小(整数或常量名)。""" position: ClassVar[frozenset[str]] = frozenset({CType.ARRAY}) def __init__(self, value: Any = None) -> None: super().__init__(value) def __class_getitem__(cls, item: Any) -> type: return cls class CDefine(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) class CPass(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: super().__init__(value) class State(CType): """状态标记,用于仅声明不定义,等价于 CExport | CExtern""" position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) @staticmethod def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: """处理 t.State() 调用""" return ['t.State'] class Postdefinition: def __init__(self, c: Any) -> None: pass class Bit: def __init__(self, i: Any) -> None: pass class BigEndian(CType): """大端序(Big-Endian)字节序标记类 用于标记结构体成员应使用大端序存储。 在小端序平台(如x86)上读取时,会自动进行字节交换。 用法示例: class MyStruct: a: t.CInt | t.BigEndian # 大端序存储的整数 """ IsSigned: ClassVar[bool] = True Size: ClassVar[int] = 32 Align: ClassVar[int] = 32 class LittleEndian(CType): """小端序(Little-Endian)字节序标记类 用于标记结构体成员应使用小端序存储。 在小端序平台(如x86)上读取时,不需要进行字节交换。 用法示例: class MyStruct: b: t.CInt | t.LittleEndian # 小端序存储的整数 """ IsSigned: ClassVar[bool] = True Size: ClassVar[int] = 32 Align: ClassVar[int] = 32 class ASM_DESCR: """内嵌 ASM 破坏描述符类 定义了所有可能的破坏描述符和约束字符,用于 GCC 内嵌汇编 """ # 操作数修饰符 MODIFIER_OUTPUT = '=' # 输出操作数 MODIFIER_READWRITE = '+' # 读写操作数 MODIFIER_INPUT = '' # 输入操作数(默认) MODIFIER_GLOBAL = '&' # 全局操作数 # 寄存器约束(32位命名) REG_ANY = 'r' # 任何通用寄存器 REG_EAX = 'a' # EAX/RAX 寄存器 REG_EBX = 'b' # EBX/RBX 寄存器 REG_ECX = 'c' # ECX/RCX 寄存器 REG_EDX = 'd' # EDX/RDX 寄存器 REG_ESI = 'S' # ESI/RSI 寄存器 REG_EDI = 'D' # EDI/RDI 寄存器 REG_STACK = 'q' # 任何通用寄存器(EAX, EBX, ECX, EDX) REG_FLOAT = 'f' # 浮点寄存器 REG_MMX = 'y' # MMX 寄存器 REG_XMM = 'x' # XMM 寄存器 # 寄存器约束(64位命名,GCC约束字符与32位相同) REG_RAX = 'a' # RAX 寄存器 REG_RBX = 'b' # RBX 寄存器 REG_RCX = 'c' # RCX 寄存器 REG_RDX = 'd' # RDX 寄存器 REG_RSI = 'S' # RSI 寄存器 REG_RDI = 'D' # RDI 寄存器 REG_R8 = 'r' # R8 寄存器(需通过r约束+显式指定) REG_R9 = 'r' # R9 寄存器 REG_R10 = 'r' # R10 寄存器 REG_R11 = 'r' # R11 寄存器 REG_R12 = 'r' # R12 寄存器 REG_R13 = 'r' # R13 寄存器 REG_R14 = 'r' # R14 寄存器 REG_R15 = 'r' # R15 寄存器 REG_RBP = 'r' # RBP 寄存器 REG_RSP = 'r' # RSP 寄存器 # 内存约束 MEMORY = 'm' # 内存操作数 # 立即数约束 IMMEDIATE = 'i' # 立即数 IMMEDIATE_CONST = 'n' # 常量立即数 # 综合约束 ANY = 'g' # 任何通用寄存器、内存或立即数 MEMORY_OR_REG = 'o' # 内存或寄存器 # 破坏描述符(clobber list) CLOBBER_EAX = 'eax' # 破坏 EAX/RAX 寄存器 CLOBBER_EBX = 'ebx' # 破坏 EBX/RBX 寄存器 CLOBBER_ECX = 'ecx' # 破坏 ECX/RCX 寄存器 CLOBBER_EDX = 'edx' # 破坏 EDX/RDX 寄存器 CLOBBER_ESI = 'esi' # 破坏 ESI/RSI 寄存器 CLOBBER_EDI = 'edi' # 破坏 EDI/RDI 寄存器 CLOBBER_EBP = 'ebp' # 破坏 EBP/RBP 寄存器 CLOBBER_ESP = 'esp' # 破坏 ESP/RSP 寄存器 CLOBBER_AL = 'al' # 破坏 AL 寄存器(EAX/RAX 低8位) CLOBBER_AH = 'ah' # 破坏 AH 寄存器(EAX/RAX 高8位) CLOBBER_BL = 'bl' # 破坏 BL 寄存器(EBX/RBX 低8位) CLOBBER_BH = 'bh' # 破坏 BH 寄存器(EBX/RBX 高8位) CLOBBER_CL = 'cl' # 破坏 CL 寄存器(ECX/RCX 低8位) CLOBBER_CH = 'ch' # 破坏 CH 寄存器(ECX/RCX 高8位) CLOBBER_DL = 'dl' # 破坏 DL 寄存器(EDX/RDX 低8位) CLOBBER_DH = 'dh' # 破坏 DH 寄存器(EDX/RDX 高8位) CLOBBER_CC = 'cc' # 破坏条件代码寄存器(标志寄存器) CLOBBER_MEMORY = 'memory' # 破坏内存(表示汇编代码修改了内存) # 16 位寄存器破坏描述符 CLOBBER_AX = 'ax' # 破坏 AX 寄存器 CLOBBER_BX = 'bx' # 破坏 BX 寄存器 CLOBBER_CX = 'cx' # 破坏 CX 寄存器 CLOBBER_DX = 'dx' # 破坏 DX 寄存器 CLOBBER_SI = 'si' # 破坏 SI 寄存器 CLOBBER_DI = 'di' # 破坏 DI 寄存器 CLOBBER_BP = 'bp' # 破坏 BP 寄存器 # 64位寄存器破坏描述符 CLOBBER_RAX = 'rax' # 破坏 RAX 寄存器 CLOBBER_RBX = 'rbx' # 破坏 RBX 寄存器 CLOBBER_RCX = 'rcx' # 破坏 RCX 寄存器 CLOBBER_RDX = 'rdx' # 破坏 RDX 寄存器 CLOBBER_RSI = 'rsi' # 破坏 RSI 寄存器 CLOBBER_RDI = 'rdi' # 破坏 RDI 寄存器 CLOBBER_RBP = 'rbp' # 破坏 RBP 寄存器 CLOBBER_RSP = 'rsp' # 破坏 RSP 寄存器 CLOBBER_R8 = 'r8' # 破坏 R8 寄存器 CLOBBER_R9 = 'r9' # 破坏 R9 寄存器 CLOBBER_R10 = 'r10' # 破坏 R10 寄存器 CLOBBER_R11 = 'r11' # 破坏 R11 寄存器 CLOBBER_R12 = 'r12' # 破坏 R12 寄存器 CLOBBER_R13 = 'r13' # 破坏 R13 寄存器 CLOBBER_R14 = 'r14' # 破坏 R14 寄存器 CLOBBER_R15 = 'r15' # 破坏 R15 寄存器 # 预定义的组合约束(32位命名) OUTPUT_REG = '=r' # 输出操作数,使用任何通用寄存器 OUTPUT_MEM = '=m' # 输出操作数,使用内存 OUTPUT_EAX = '=a' # 输出操作数,使用 EAX/RAX 寄存器 OUTPUT_EBX = '=b' # 输出操作数,使用 EBX/RBX 寄存器 OUTPUT_ECX = '=c' # 输出操作数,使用 ECX/RCX 寄存器 OUTPUT_EDX = '=d' # 输出操作数,使用 EDX/RDX 寄存器 OUTPUT_ESI = '=S' # 输出操作数,使用 ESI/RSI 寄存器 OUTPUT_EDI = '=D' # 输出操作数,使用 EDI/RDI 寄存器 # 预定义的组合约束(64位命名) OUTPUT_RAX = '=a' # 输出操作数,使用 RAX 寄存器 OUTPUT_RBX = '=b' # 输出操作数,使用 RBX 寄存器 OUTPUT_RCX = '=c' # 输出操作数,使用 RCX 寄存器 OUTPUT_RDX = '=d' # 输出操作数,使用 RDX 寄存器 OUTPUT_RSI = '=S' # 输出操作数,使用 RSI 寄存器 OUTPUT_RDI = '=D' # 输出操作数,使用 RDI 寄存器 INPUT_REG = 'r' # 输入操作数,使用任何通用寄存器 INPUT_MEM = 'm' # 输入操作数,使用内存 INPUT_EAX = 'a' # 输入操作数,使用 EAX/RAX 寄存器 INPUT_EBX = 'b' # 输入操作数,使用 EBX/RBX 寄存器 INPUT_ECX = 'c' # 输入操作数,使用 ECX/RCX 寄存器 INPUT_EDX = 'd' # 输入操作数,使用 EDX/RDX 寄存器 INPUT_ESI = 'S' # 输入操作数,使用 ESI/RSI 寄存器 INPUT_EDI = 'D' # 输入操作数,使用 EDI/RDI 寄存器 INPUT_IMM = 'i' # 输入操作数,使用立即数 INPUT_ANY = 'g' # 输入操作数,使用任何通用寄存器、内存或立即数 # 输入约束(64位命名) INPUT_RAX = 'a' # 输入操作数,使用 RAX 寄存器 INPUT_RBX = 'b' # 输入操作数,使用 RBX 寄存器 INPUT_RCX = 'c' # 输入操作数,使用 RCX 寄存器 INPUT_RDX = 'd' # 输入操作数,使用 RDX 寄存器 INPUT_RSI = 'S' # 输入操作数,使用 RSI 寄存器 INPUT_RDI = 'D' # 输入操作数,使用 RDI 寄存器 # 所有单独约束字符列表 ALL_CONSTRAINTS = [ # 操作数修饰符 MODIFIER_OUTPUT, MODIFIER_READWRITE, MODIFIER_INPUT, MODIFIER_GLOBAL, # 寄存器约束 REG_ANY, REG_EAX, REG_EBX, REG_ECX, REG_EDX, REG_ESI, REG_EDI, REG_STACK, REG_FLOAT, REG_MMX, REG_XMM, # 内存约束 MEMORY, # 立即数约束 IMMEDIATE, IMMEDIATE_CONST, # 综合约束 ANY, MEMORY_OR_REG ] # 所有破坏描述符列表 ALL_CLOBBERS = [ CLOBBER_EAX, CLOBBER_EBX, CLOBBER_ECX, CLOBBER_EDX, CLOBBER_ESI, CLOBBER_EDI, CLOBBER_EBP, CLOBBER_ESP, CLOBBER_CC, CLOBBER_MEMORY, CLOBBER_RAX, CLOBBER_RBX, CLOBBER_RCX, CLOBBER_RDX, CLOBBER_RSI, CLOBBER_RDI, CLOBBER_RBP, CLOBBER_RSP, CLOBBER_R8, CLOBBER_R9, CLOBBER_R10, CLOBBER_R11, CLOBBER_R12, CLOBBER_R13, CLOBBER_R14, CLOBBER_R15 ] # 所有描述符列表 ALL = ALL_CONSTRAINTS + ALL_CLOBBERS # 定义 ASM_LIST,包含所有可能的汇编约束字符 ASM_LIST: list[str] = ASM_DESCR.ALL class attr: """C 语言 __attribute__ 属性操作类型""" @staticmethod def noreturn() -> str: return "noreturn" @staticmethod def format(printf: Any, arg1: Any, arg2: Any) -> str: return f"format({printf}, {arg1}, {arg2})" @staticmethod def section(name: str) -> str: return f'section("{name}")' @staticmethod def aligned(bytes: int) -> str: return f"aligned({bytes})" @staticmethod def packed() -> str: return "packed" @staticmethod def unused() -> str: return "unused" @staticmethod def used() -> str: return "used" @staticmethod def weak() -> str: return "weak" @staticmethod def alias(name: str) -> str: return f'alias("{name}")' @staticmethod def visibility(type: str) -> str: return f'visibility("{type}")' @staticmethod def constructor() -> str: return "constructor" @staticmethod def destructor() -> str: return "destructor" @staticmethod def always_inline() -> str: return "always_inline" @staticmethod def noinline() -> str: return "noinline" @staticmethod def pure() -> str: return "pure" @staticmethod def const() -> str: return "const" @staticmethod def malloc() -> str: return "malloc" @staticmethod def alloc_size(n: int) -> str: return f"alloc_size({n})" @staticmethod def warn_unused_result() -> str: return "warn_unused_result" @staticmethod def deprecated(msg: Optional[str] = None) -> str: if msg: return f'deprecated("{msg}")' return "deprecated" @staticmethod def fallthrough() -> str: return "fallthrough" @staticmethod def likely() -> str: return "likely" @staticmethod def unlikely() -> str: return "unlikely" @staticmethod def hot() -> str: return "hot" @staticmethod def cold() -> str: return "cold" @staticmethod def interrupt() -> str: return "interrupt" @staticmethod def naked() -> str: return "naked" @staticmethod def sentinel(n: int = 0) -> str: return f"sentinel({n})" @staticmethod def nonnull(*args: Any) -> str: if args: return f"nonnull({', '.join(map(str, args))})" return "nonnull" @staticmethod def returns_nonnull() -> str: return "returns_nonnull" @staticmethod def access(mode: Any, *args: Any) -> str: return f"access({mode}, {', '.join(map(str, args))})" @staticmethod def cleanup(func: str) -> str: return f'cleanup({func})' @staticmethod def transparent_union() -> str: return "transparent_union" @staticmethod def mode(mode_name: str) -> str: return f"mode({mode_name})" @staticmethod def vector_size(bytes: int) -> str: return f"vector_size({bytes})" @staticmethod def target(string: str) -> str: return f'target("{string}")' @staticmethod def optimize(level: str) -> str: return f'optimize("{level}")' @staticmethod def no_instrument_function() -> str: return "no_instrument_function" @staticmethod def no_sanitize(type: str) -> str: return f"no_sanitize({type})" @staticmethod def no_stack_protector() -> str: return "no_stack_protector" @staticmethod def stack_protector() -> str: return "stack_protector" @staticmethod def error(msg: str) -> str: return f'error("{msg}")' @staticmethod def warning(msg: str) -> str: return f'warning("{msg}")' class llvm: """LLVM 函数属性描述符 用于在返回类型注解中指定 LLVM 函数属性。 例如: def foo() -> t.CInt | t.attr.llvm.nobuiltin | t.attr.llvm.nounwind: """ # 以下空类仅作为类型注解占位符使用,由 HandlesFunctions._GetAttrLLVMName # 从 AST 直接提取属性名(node.attr),不依赖 CName 属性。 class nobuiltin: pass class nounwind: pass class noredzone: pass class willreturn: pass class mustprogress: pass class optnone: pass class noinline: pass class alwaysinline: pass class readnone: pass class readonly: pass class writeonly: pass class inaccessiblememonly: pass class inaccessiblemem_or_argmemonly: pass class CTypeRegistry: """基于 CType 元属性的类型注册表,替代手动映射表 利用 CType 子类的 position/IsSigned/Size 元属性自动推导: - LLVM IR 类型字符串 (如 'i32', 'double', 'i8*') - C 类型名称 (如 'int', 'unsigned char', 'long long') - Python CType 类引用 (如 t.CInt32T) """ _name_to_class: ClassVar[Optional[dict[str, type]]] = None @classmethod def _build(cls) -> None: if cls._name_to_class is not None: return mod: Optional[types.ModuleType] = sys.modules.get(__name__) if mod is None: return cls._name_to_class = {} for name, obj in vars(mod).items(): if not isinstance(obj, type) or not issubclass(obj, CType) or obj is CType: continue if obj in (CTypeDefault, BigEndian, LittleEndian): continue try: inst: Any = obj() except Exception: continue pos: frozenset[str] = getattr(obj, 'position', frozenset()) if CType.PREFIX in pos and CType.BASE not in pos: continue if CType.POINTER in pos and CType.BASE not in pos: cls._name_to_class[name] = obj continue # 注册基本类型(有 Size)和命名基本类型(CStruct/CUnion/CEnum/REnum)。 # 不再依赖 CName 属性,依据 position/Size 推断。 if getattr(inst, 'Size', None) is not None or CType.NAMED in pos: cls._name_to_class[name] = obj @classmethod def GetClassByName(cls, name: str) -> Optional[type]: """根据 Python 类名获取 CType 类 (如 'CInt32T' -> t.CInt32T)""" cls._build() return cls._name_to_class.get(name) @staticmethod def CTypeToLLVM(ctype_class: Optional[type]) -> str: """从 CType 类的元属性推导 LLVM IR 类型字符串 规则: - position 含 POINTER 且不含 BASE → 'i8*' - position 含 PREFIX 且不含 BASE → '' (修饰符,无LLVM类型) - Size == 0 且 IsSigned is None → 'void' - IsSigned is None 且 Size > 0 → 浮点: half/float/double/fp128 - IsSigned is True/False 且 Size > 0 → 整数: i{Size} """ if ctype_class is None: return 'i8*' pos: frozenset[str] = getattr(ctype_class, 'position', frozenset()) if CType.POINTER in pos and CType.BASE not in pos: return 'i8*' if CType.PREFIX in pos and CType.BASE not in pos: return '' try: inst: Any = ctype_class() except Exception: return 'i8*' size: Optional[int] = getattr(inst, 'Size', None) is_signed: Optional[bool] = getattr(inst, 'IsSigned', None) if size is None or size == 0: if is_signed is None: return 'void' return 'i8*' if is_signed is None: float_map: dict[int, str] = {8: 'half', 16: 'half', 32: 'float', 64: 'double', 128: 'fp128'} return float_map.get(size, f'f{size}') return f'i{size}' _llvm_to_ctype_cache: ClassVar[Optional[dict[str, type]]] = None @classmethod def LLVMToCType(cls, llvm_str: str) -> Optional[type]: if cls._llvm_to_ctype_cache is None: cls._build() cls._llvm_to_ctype_cache = {} for name, ctype_cls in cls._name_to_class.items(): pos: frozenset[str] = getattr(ctype_cls, 'position', frozenset()) if CType.PREFIX in pos and CType.BASE not in pos: continue llvm_key: str = cls.CTypeToLLVM(ctype_cls) if llvm_key and llvm_key not in cls._llvm_to_ctype_cache: cls._llvm_to_ctype_cache[llvm_key] = ctype_cls return cls._llvm_to_ctype_cache.get(llvm_str) @classmethod def NameToLLVM(cls, name: str) -> Optional[str]: """根据 Python 类型名推导 LLVM IR 类型 (如 'CFloat64T' -> 'double') 修饰符类型 (CConst, CStatic 等) 返回空字符串。 指针类型 (CPtr) 返回 'i8*'。 未知类型返回 None。 """ cls._build() mod: Optional[types.ModuleType] = sys.modules.get(__name__) if mod and hasattr(mod, name): obj: Any = getattr(mod, name) if isinstance(obj, type) and issubclass(obj, CType): return cls.CTypeToLLVM(obj) return None @classmethod def ResolveName(cls, name: str) -> Optional[tuple[type, int]]: """解析类型名到 (CType类, 指针层级) 支持的格式: - Python 类名: 'CInt32T' -> (t.CInt32T, 0) - C 基本类型名/Python 内置名: 'int' -> (t.CInt, 0), 'bool' -> (t.CBool, 0) 注意:stdint.h 类型名(int8_t/uint8_t/size_t/intptr_t 等)和 Win32 大写别名(INT8/UINT8/BYTE/DWORD/FLOAT8 等)由 stdint.py 通过 t.CTypedef 提供,用户 `from stdint import *` 后即可使用。 指针必须使用 t.CPtr[T] 显式表达(如 t.CPtr[t.CInt]), 本方法不再做 PTR 后缀的隐式类型推断,以避免违反类型自由原则。 """ cls._build() direct: Optional[type] = cls._name_to_class.get(name) if direct is not None: pos: frozenset[str] = getattr(direct, 'position', frozenset()) ptr_level: int = 1 if CType.POINTER in pos and CType.BASE not in pos else 0 return (direct, ptr_level) # C 基本类型名 / Python 内置类型名 → Python 类名硬编码表。 # 仅保留语言内置名称;stdint.h 类型名由 stdint.py 的 typedef 提供。 _CNAME_ALIAS: dict[str, str] = { # Python 内置类型名 'bool': 'CBool', 'int': 'CInt', 'float': 'CFloat', # C 基本类型名 'char': 'CChar', 'short': 'CShort', 'long': 'CLong', 'long long': 'CLongLong', 'double': 'CDouble', 'void': 'CVoid', 'unsigned': 'CUnsigned', 'signed': 'CInt', 'signed int': 'CInt', 'signed char': 'CSignedChar', 'unsigned char': 'CUnsignedChar', 'unsigned int': 'CUnsignedInt', 'unsigned short': 'CUnsignedShort', 'unsigned long': 'CUnsignedLong', 'unsigned long long': 'CUnsignedLongLong', } cname_alias: Optional[str] = _CNAME_ALIAS.get(name) if cname_alias is not None: alias_cls: Optional[type] = cls._name_to_class.get(cname_alias) if alias_cls is not None: return (alias_cls, 0) return None