feat(cdef): define 常量带类型注册——按声明类型物化(DWORD(-11) → i32 位型)
方案 C:CDefine 不再只存无类型 int,而是把**声明整数类型**(位宽 + 符号性)一并登记,使用点按该类型物化,而不是按数值大小猜 i32/i64。链路:① SymbolUtils 新增 DefineIntSignednessOf / DefineDeclIntTypeFromAnnotation(由 T | t.CDefine 注解经符号表 typedef 链解析宽度与符号性)/ DefineDeclTypeValue(按声明类型把值归一成 (位宽, 位型值));② 同模块注册(LlvmGenerator._register_cdefine_constant)与跨模块提取(Phase2Translator._ExtractCDefineConstantsFromPyi,含 _shared_all_decl_types 的 pickle 传递)分别写 Gen._define_decl_types / translator._define_decl_types;③ 物化处(HandlesExpr 裸名两处、HandlesExprAttr._make_define_constant,及 from-import 注册)优先按声明类型出常量。这样 win32file 的 STD_*_HANDLE(DWORD(-10/-11/-12))解析为 i32 位型 0xFFFFFFF5 等,与 GetStdHandle(ULONG) 使用点一致。
This commit is contained in:
1 parent
e1a0fbf9c0
commit
d5b4e9a8b9
6 files changed
+198
-20
No files matched your search
@@ -9,7 +9,7 @@ import llvmlite.ir as ir
|
||||
from lib.core.Handles.HandlesBase import BaseHandle
|
||||
from lib.constants.config import mode as _config_mode
|
||||
from lib.includes.t import CTypeRegistry as _CR
|
||||
from lib.core.SymbolUtils import RequireDefineUseWidthAt, RequireIntLiteralStorable, RequireNameDefined
|
||||
from lib.core.SymbolUtils import RequireDefineUseWidthAt, RequireIntLiteralStorable, RequireNameDefined, DefineDeclTypeValue
|
||||
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
@@ -455,6 +455,12 @@ class ExprHandle(BaseHandle):
|
||||
RequireDefineUseWidthAt(Gen, self.Trans, Node, _cdefine_val,
|
||||
int(_use_ty.width), VarName, _use_ctx)
|
||||
return ir.Constant(_use_ty, val & ((1 << _use_ty.width) - 1))
|
||||
# 带类型注册:无使用处宽度提示时,按 define 的**声明类型**物化
|
||||
# (`define X: DWORD = -11` → i32 位型 0xFFFFFFF5,而不是按值大小猜 i64)。
|
||||
_dtv: tuple[int, int] | None = DefineDeclTypeValue(
|
||||
getattr(Gen, '_define_decl_types', None) or getattr(self.Trans, '_define_decl_types', None), VarName, val)
|
||||
if _dtv is not None:
|
||||
return ir.Constant(ir.IntType(_dtv[0]), _dtv[1])
|
||||
if VarName in Gen.var_signedness and Gen.var_signedness[VarName]:
|
||||
if val < -(1 << 31) or val > 0xFFFFFFFF:
|
||||
return ir.Constant(ir.IntType(64), val & 0xFFFFFFFFFFFFFFFF)
|
||||
@@ -493,6 +499,11 @@ class ExprHandle(BaseHandle):
|
||||
RequireDefineUseWidthAt(Gen, self.Trans, Node, val,
|
||||
int(_use_ty2.width), VarName, _use_ctx2)
|
||||
return ir.Constant(_use_ty2, val & ((1 << _use_ty2.width) - 1))
|
||||
# 带类型注册:同本模块路径——按声明类型物化(见上)。
|
||||
_dtv2: tuple[int, int] | None = DefineDeclTypeValue(
|
||||
getattr(Gen, '_define_decl_types', None) or getattr(self.Trans, '_define_decl_types', None), VarName, val)
|
||||
if _dtv2 is not None:
|
||||
return ir.Constant(ir.IntType(_dtv2[0]), _dtv2[1])
|
||||
if val < -(1 << 31) or val > 0xFFFFFFFF:
|
||||
return ir.Constant(ir.IntType(64), val & 0xFFFFFFFFFFFFFFFF)
|
||||
return ir.Constant(ir.IntType(32), val & 0xFFFFFFFF)
|
||||
|
||||
@@ -5,6 +5,7 @@ if TYPE_CHECKING:
|
||||
from lib.core.LlvmCodeGenerator import LlvmCodeGenerator
|
||||
from lib.core.Handles.HandlesBase import BaseHandle, FuncMeta
|
||||
from lib.core.VLogger import get_logger as _vlog
|
||||
from lib.core.SymbolUtils import DefineDeclTypeValue
|
||||
import vast as ast
|
||||
import llvmlite.ir as ir
|
||||
|
||||
@@ -388,8 +389,18 @@ class ExprAttrHandle(BaseHandle):
|
||||
return self._gep_and_Load_member(Gen, CastedObj, offset, Node.attr, lookup_CN, spec_st)
|
||||
return None
|
||||
|
||||
def _make_define_constant(self, Gen: LlvmCodeGenerator, val: int | float | str) -> ir.Value | None:
|
||||
"""将 CDefine 值转为 LLVM 常量"""
|
||||
def _make_define_constant(self, Gen: LlvmCodeGenerator, val: int | float | str, Name: str | None = None) -> ir.Value | None:
|
||||
"""将 CDefine 值转为 LLVM 常量。
|
||||
|
||||
带类型注册优先:若该 define 登记了**声明整数类型**(`Gen._define_decl_types`),
|
||||
按该类型的位宽与符号性物化(u32 `DWORD(-11)` → `i32 0xFFFFFFF5`),而不是按
|
||||
数值大小猜 i32/i64(后者会把 `4294967285` 误判成 i64,与 i32/ULONG 使用点不符)。
|
||||
"""
|
||||
if isinstance(val, int) and not isinstance(val, bool):
|
||||
_dt: tuple[int, int] | None = DefineDeclTypeValue(
|
||||
getattr(Gen, '_define_decl_types', None) or getattr(self.Trans, '_define_decl_types', None), Name, val)
|
||||
if _dt is not None:
|
||||
return ir.Constant(ir.IntType(_dt[0]), _dt[1])
|
||||
if isinstance(val, int):
|
||||
if abs(val) > 2147483647:
|
||||
return ir.Constant(ir.IntType(64), val)
|
||||
@@ -419,12 +430,12 @@ class ExprAttrHandle(BaseHandle):
|
||||
for lookup_key in PossibleKeys:
|
||||
SymInfo: Any = self.Trans.SymbolTable.lookup(lookup_key)
|
||||
if SymInfo and SymInfo.IsDefine and SymInfo.DefineValue is not None:
|
||||
return self._make_define_constant(Gen, SymInfo.DefineValue)
|
||||
return self._make_define_constant(Gen, SymInfo.DefineValue, AttrName)
|
||||
# 也检查 _define_constants(LlvmGenerator 预扫描阶段填充)
|
||||
define_constants: Any = getattr(Gen, '_define_constants', {})
|
||||
for key in (f"{VarName}.{AttrName}", AttrName):
|
||||
if key in define_constants:
|
||||
return self._make_define_constant(Gen, define_constants[key])
|
||||
return self._make_define_constant(Gen, define_constants[key], AttrName)
|
||||
# 回退:_all_define_constants(Phase2Translator 从所有 .pyi 预提取的跨模块 CDefine,
|
||||
# 与 _HandleNameLlvm 的裸名回退同源)。**模块属性访问**(`win32file.STD_OUTPUT_HANDLE`)
|
||||
# 此前只查 SymbolTable/_define_constants → 未命中就落到 _lookup_module_global 生成
|
||||
@@ -436,7 +447,7 @@ class ExprAttrHandle(BaseHandle):
|
||||
all_dc: dict[str, Any] = getattr(Gen, '_all_define_constants', None) or getattr(self.Trans, '_all_define_constants', None) or {}
|
||||
for key2 in (f"{VarName}.{AttrName}", AttrName):
|
||||
if key2 in all_dc:
|
||||
return self._make_define_constant(Gen, all_dc[key2])
|
||||
return self._make_define_constant(Gen, all_dc[key2], AttrName)
|
||||
return None
|
||||
|
||||
def _NormalizeModuleGlobalValue(self, Gen: LlvmCodeGenerator, Val: Any, AttrName: str) -> Any:
|
||||
@@ -688,7 +699,7 @@ class ExprAttrHandle(BaseHandle):
|
||||
for _cdefine_key in (AttrName, f"{VarName}.{AttrName}"):
|
||||
_sym: Any = self.Trans.SymbolTable.lookup(_cdefine_key)
|
||||
if _sym and _sym.IsDefine and _sym.DefineValue is not None:
|
||||
_const_val: Any = self._make_define_constant(Gen, _sym.DefineValue)
|
||||
_const_val: Any = self._make_define_constant(Gen, _sym.DefineValue, AttrName)
|
||||
if _const_val is not None:
|
||||
return _const_val
|
||||
|
||||
|
||||
@@ -521,6 +521,13 @@ class ImportHandle(BaseHandle):
|
||||
all_dc: dict = getattr(Gen, '_all_define_constants', None) or getattr(self.Trans, '_all_define_constants', None) or {}
|
||||
if name in all_dc:
|
||||
define_constants[name] = all_dc[name]
|
||||
# 带类型注册:把跨模块 define 的**声明整数类型**一并带入本模块,
|
||||
# 供使用点按声明类型(如 DWORD=u32)物化,而不是按值大小猜 i32/i64。
|
||||
all_dt: dict = getattr(Gen, '_define_decl_types', None) or getattr(self.Trans, '_define_decl_types', None) or {}
|
||||
if name in all_dt:
|
||||
_dt_map: dict = vars(Gen).setdefault('_define_decl_types', {})
|
||||
if name not in _dt_map:
|
||||
_dt_map[name] = all_dt[name]
|
||||
continue
|
||||
if not hasattr(self.Trans, '_t_c_imported_names'):
|
||||
self.Trans._t_c_imported_names = {}
|
||||
|
||||
Reference in new issue
Block a user