Some simple information syncing
This commit is contained in:
@@ -20,6 +20,9 @@ from typing import Any, Callable, Optional, TYPE_CHECKING
|
||||
import llvmlite.ir as ir
|
||||
|
||||
from lib.core.Handles.HandlesBase import CTypeInfo
|
||||
# 治本修复:导入 t 模块和 CType 基类,用于类型构造调用求值(如 t.CUnsignedLong(-11))
|
||||
from lib.includes import t as _t_module
|
||||
from lib.includes.t import CType as _CType_base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from lib.core.LlvmCodeGenerator import LlvmCodeGenerator
|
||||
@@ -36,7 +39,7 @@ class ConstEvaluator:
|
||||
def eval_with_symtab(node: ast.AST, symtab: Any) -> Optional[Any]:
|
||||
"""求值常量表达式,支持从 SymbolTable 查找 define 值。
|
||||
|
||||
支持: Constant, BinOp, UnaryOp, Name(define), Attribute(define)
|
||||
支持: Constant, BinOp, UnaryOp, Name(define), Attribute(define), Call(类型构造)
|
||||
"""
|
||||
if isinstance(node, ast.Constant):
|
||||
return node.value
|
||||
@@ -52,8 +55,68 @@ class ConstEvaluator:
|
||||
if size_val is not None:
|
||||
return size_val
|
||||
return ConstEvaluator._eval_attribute_define(node, symtab)
|
||||
# 治本修复:支持 t.CUnsignedLong(-11) 等类型构造调用
|
||||
if isinstance(node, ast.Call):
|
||||
return ConstEvaluator._eval_ctype_ctor_call(node, symtab)
|
||||
return ConstEvaluator._eval_arith(node, lambda n: ConstEvaluator.eval_with_symtab(n, symtab))
|
||||
|
||||
@staticmethod
|
||||
def _eval_ctype_ctor_call(node: ast.Call, symtab: Any) -> Optional[Any]:
|
||||
"""求值类型构造调用,如 t.CUnsignedLong(-11)、CInt(42)。
|
||||
|
||||
在无 ctx(EvalContext)的场景下,通过 symtab 和 t 模块直接求值。
|
||||
按类型的 Size 和 IsSigned 应用位掩码。
|
||||
"""
|
||||
func: ast.expr = node.func
|
||||
func_name: str | None = None
|
||||
module_name: str | None = None
|
||||
if isinstance(func, ast.Attribute):
|
||||
if isinstance(func.value, ast.Name):
|
||||
module_name = func.value.id
|
||||
func_name = func.attr
|
||||
elif isinstance(func, ast.Name):
|
||||
func_name = func.id
|
||||
|
||||
ctype_cls: Any = None
|
||||
if module_name == 't' and func_name:
|
||||
ctype_cls = getattr(_t_module, func_name, None)
|
||||
elif func_name and not module_name:
|
||||
ctype_cls = getattr(_t_module, func_name, None)
|
||||
if ctype_cls is None and symtab:
|
||||
t_type_syms = getattr(symtab, '_t_type_symbols', {})
|
||||
cls_candidate = t_type_syms.get(func_name)
|
||||
if cls_candidate is not None:
|
||||
ctype_cls = cls_candidate
|
||||
|
||||
if ctype_cls is None or not (isinstance(ctype_cls, type) and issubclass(ctype_cls, _CType_base)):
|
||||
return None
|
||||
if not node.args:
|
||||
return None
|
||||
|
||||
arg_val: Any = ConstEvaluator.eval_with_symtab(node.args[0], symtab)
|
||||
if arg_val is None:
|
||||
return None
|
||||
|
||||
size: int | None = None
|
||||
is_signed: bool | None = None
|
||||
try:
|
||||
tmp_inst = ctype_cls()
|
||||
size = getattr(tmp_inst, 'Size', None)
|
||||
is_signed = getattr(tmp_inst, 'IsSigned', None)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if isinstance(arg_val, int) and size and size > 0:
|
||||
mask: int = (1 << size) - 1
|
||||
if is_signed:
|
||||
masked: int = arg_val & mask
|
||||
if masked >= (1 << (size - 1)):
|
||||
masked -= (1 << size)
|
||||
return masked
|
||||
else:
|
||||
return arg_val & mask
|
||||
return arg_val
|
||||
|
||||
# ==================================================================
|
||||
# Level 3: + Gen._define_constants / _all_define_constants / 平台宏
|
||||
# ==================================================================
|
||||
@@ -147,7 +210,7 @@ class ConstEvaluator:
|
||||
|
||||
@staticmethod
|
||||
def _eval_compile_time_call(node: ast.Call, ctx: 'EvalContext') -> Optional[Any]:
|
||||
"""处理编译时函数调用,如 ctraits.isptr(x)"""
|
||||
"""处理编译时函数调用,如 ctraits.isptr(x)、t.CUnsignedLong(-11)"""
|
||||
func: ast.expr = node.func
|
||||
func_name: str | None = None
|
||||
module_name: str | None = None
|
||||
@@ -200,6 +263,60 @@ class ConstEvaluator:
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
# 治本修复:支持 t.CUnsignedLong(-11) 等类型构造调用
|
||||
# 当 t.CUnsignedLong(value) / CUnsignedInt(value) / CInt(value) 等被用作常量表达式时,
|
||||
# 求值参数并返回(按类型的无符号/有符号语义应用位掩码)。
|
||||
# 这修复了 stdint.py 中 INFINITE = t.CUnsignedLong(-1) 等常量无法被求值的问题。
|
||||
is_ctype_ctor: bool = False
|
||||
ctype_cls: Any = None
|
||||
if module_name == 't' and func_name:
|
||||
ctype_cls = getattr(_t_module, func_name, None)
|
||||
if ctype_cls is not None and isinstance(ctype_cls, type) and issubclass(ctype_cls, _CType_base):
|
||||
is_ctype_ctor = True
|
||||
elif func_name and not module_name:
|
||||
# from t import CUnsignedLong 形式
|
||||
ctype_cls = getattr(_t_module, func_name, None)
|
||||
if ctype_cls is not None and isinstance(ctype_cls, type) and issubclass(ctype_cls, _CType_base):
|
||||
is_ctype_ctor = True
|
||||
# 也检查 _t_type_symbols(符号表中的 t 模块类型符号)
|
||||
if not is_ctype_ctor and ctx.symtab:
|
||||
t_type_syms = getattr(ctx.symtab, '_t_type_symbols', {})
|
||||
cls_candidate = t_type_syms.get(func_name)
|
||||
if cls_candidate is not None and isinstance(cls_candidate, type) and issubclass(cls_candidate, _CType_base):
|
||||
ctype_cls = cls_candidate
|
||||
is_ctype_ctor = True
|
||||
|
||||
if is_ctype_ctor and node.args:
|
||||
try:
|
||||
arg_node: ast.expr = node.args[0]
|
||||
arg_val: Any = ConstEvaluator.eval_full(arg_node, ctx)
|
||||
if arg_val is None:
|
||||
return None
|
||||
# 按类型的 Size 和 IsSigned 应用位掩码
|
||||
size: int | None = getattr(ctype_cls, '_Size', None)
|
||||
is_signed: bool | None = getattr(ctype_cls, '_IsSigned', None)
|
||||
# 尝试创建临时实例获取 Size/IsSigned
|
||||
try:
|
||||
tmp_inst = ctype_cls()
|
||||
size = getattr(tmp_inst, 'Size', size)
|
||||
is_signed = getattr(tmp_inst, 'IsSigned', is_signed)
|
||||
except Exception:
|
||||
pass
|
||||
if isinstance(arg_val, int) and size and size > 0:
|
||||
mask: int = (1 << size) - 1
|
||||
if is_signed:
|
||||
# 有符号类型:解释为补码
|
||||
masked: int = arg_val & mask
|
||||
if masked >= (1 << (size - 1)):
|
||||
masked -= (1 << size)
|
||||
return masked
|
||||
else:
|
||||
# 无符号类型:直接掩码
|
||||
return arg_val & mask
|
||||
return arg_val
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user