修正了一些错误
This commit is contained in:
@@ -7,6 +7,13 @@ from lib.core.Handles.HandlesBase import BaseHandle, FuncMeta
|
||||
import ast
|
||||
import llvmlite.ir as ir
|
||||
|
||||
# [CDF-LOAD] 模块加载标记:用于确认修复后的代码被实际加载
|
||||
try:
|
||||
with open('d:/Users/TermiNexus/Desktop/TransPyC/_attr_debug.log', 'a', encoding='utf-8') as _f:
|
||||
_f.write('[CDF-LOAD] HandlesExprAttr.py loaded (with CDefine fix)\n')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
class ExprAttrHandle(BaseHandle):
|
||||
|
||||
@@ -174,25 +181,44 @@ class ExprAttrHandle(BaseHandle):
|
||||
return None
|
||||
|
||||
def _lookup_cdefine(self, Gen: LlvmCodeGenerator, VarName: str, AttrName: str) -> ir.Value | None:
|
||||
"""在符号表和模块中查找 CDefine 常量值"""
|
||||
imported_modules: Any = getattr(self.Trans, '_ImportedModules', None)
|
||||
if not imported_modules:
|
||||
return None
|
||||
"""在符号表和模块中查找 CDefine 常量值
|
||||
|
||||
注意:不再强制依赖 _ImportedModules。即使该集合为空(例如自举编译
|
||||
阶段尚未填充),也始终检查符号表与 Gen._define_constants,确保
|
||||
ast.CONST_INT 这类 CDefine 常量能够被解析为立即数而非全局变量引用。
|
||||
"""
|
||||
PossibleKeys: list[str] = [f"{VarName}.{AttrName}", AttrName]
|
||||
for mod_name in imported_modules:
|
||||
if mod_name.endswith(f".{VarName}") or mod_name == VarName:
|
||||
key: str = f"{mod_name}.{AttrName}"
|
||||
if key not in PossibleKeys:
|
||||
PossibleKeys.append(key)
|
||||
imported_modules: Any = getattr(self.Trans, '_ImportedModules', None)
|
||||
if imported_modules:
|
||||
for mod_name in imported_modules:
|
||||
if mod_name.endswith(f".{VarName}") or mod_name == VarName:
|
||||
key: str = f"{mod_name}.{AttrName}"
|
||||
if key not in PossibleKeys:
|
||||
PossibleKeys.append(key)
|
||||
# 始终遍历符号表(不依赖 imported_modules 是否为空)
|
||||
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)
|
||||
# 也检查 _define_constants
|
||||
# 也检查 _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])
|
||||
# [CDF-DBG] CDefine 查找失败时的诊断输出
|
||||
if AttrName in ('CONST_INT', 'CONST_FLOAT', 'CONST_STR', 'CONST_BOOL', 'CONST_NONE'):
|
||||
_dbg_keys: list[str] = []
|
||||
for _k in PossibleKeys:
|
||||
_si: Any = self.Trans.SymbolTable.lookup(_k)
|
||||
_dbg_keys.append(f"{_k}=>si={_si is not None},isdef={getattr(_si, 'IsDefine', None)},dv={getattr(_si, 'DefineValue', None)}")
|
||||
_dc_keys: list[str] = [f"{k}=>{define_constants.get(k, '<miss>')}" for k in (f"{VarName}.{AttrName}", AttrName)]
|
||||
try:
|
||||
with open('d:/Users/TermiNexus/Desktop/TransPyC/_attr_debug.log', 'a', encoding='utf-8') as _f:
|
||||
_f.write(f"[CDF-DBG] miss VarName={VarName} AttrName={AttrName} imported_modules={imported_modules}\n")
|
||||
_f.write(f"[CDF-DBG] sym_keys={_dbg_keys}\n")
|
||||
_f.write(f"[CDF-DBG] dc_keys={_dc_keys}\n")
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
def _lookup_module_global(self, Gen: LlvmCodeGenerator, VarName: str, AttrName: str) -> ir.Value | None:
|
||||
@@ -394,6 +420,18 @@ class ExprAttrHandle(BaseHandle):
|
||||
Gen: LlvmCodeGenerator = self.Trans.LlvmGen
|
||||
AttrName: str = Node.attr
|
||||
|
||||
# [HAN-DBG] 入口诊断:标记 CONST_* 属性访问
|
||||
if AttrName in ('CONST_INT', 'CONST_FLOAT', 'CONST_STR', 'CONST_BOOL', 'CONST_NONE'):
|
||||
_in_globals: bool = AttrName in Gen.module.globals
|
||||
_gv_type: Any = None
|
||||
if _in_globals:
|
||||
_gv_type = str(Gen.module.globals[AttrName].type)
|
||||
try:
|
||||
with open('d:/Users/TermiNexus/Desktop/TransPyC/_attr_debug.log', 'a', encoding='utf-8') as _f:
|
||||
_f.write(f"[HAN-DBG] enter VarName={VarName} AttrName={AttrName} in_globals={_in_globals} gv_type={_gv_type}\n")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# __doc__ 魔法字符串:函数/结构体的 docstring
|
||||
if AttrName == '__doc__':
|
||||
doc_ptr: ir.Value | None = Gen._get_doc_ptr(VarName)
|
||||
@@ -410,9 +448,26 @@ class ExprAttrHandle(BaseHandle):
|
||||
if result is not None:
|
||||
return result
|
||||
|
||||
# 冗余回退:直接以短名/全名查符号表的 CDefine 条目
|
||||
# 覆盖 _ImportedModules 未填充但符号表已注册 CDefine 的场景
|
||||
# (例如自举编译期 ast.CONST_INT 在 LlvmGenerator 预扫描阶段
|
||||
# 已注册到 SymbolTable,但 _ImportedModules 仍为空)。
|
||||
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)
|
||||
if _const_val is not None:
|
||||
return _const_val
|
||||
|
||||
# 尝试 import 模块全局变量
|
||||
result = self._lookup_module_global(Gen, VarName, AttrName)
|
||||
if result is not None:
|
||||
if AttrName in ('CONST_INT', 'CONST_FLOAT', 'CONST_STR', 'CONST_BOOL', 'CONST_NONE'):
|
||||
try:
|
||||
with open('d:/Users/TermiNexus/Desktop/TransPyC/_attr_debug.log', 'a', encoding='utf-8') as _f:
|
||||
_f.write(f"[HAN-DBG] module_global HIT VarName={VarName} AttrName={AttrName} result_type={result.type}\n")
|
||||
except Exception:
|
||||
pass
|
||||
return result
|
||||
|
||||
# FakeDuck: 检查是否有影子结构体 a__meta__ (str 变量的 per-instance 字段存储)
|
||||
@@ -433,6 +488,12 @@ class ExprAttrHandle(BaseHandle):
|
||||
# 尝试 attr 直接作为全局变量(仅当 VarName 不是结构体变量时)
|
||||
if not ClassName and AttrName in Gen.module.globals:
|
||||
gv: Any = Gen.module.globals[AttrName]
|
||||
if AttrName in ('CONST_INT', 'CONST_FLOAT', 'CONST_STR', 'CONST_BOOL', 'CONST_NONE'):
|
||||
try:
|
||||
with open('d:/Users/TermiNexus/Desktop/TransPyC/_attr_debug.log', 'a', encoding='utf-8') as _f:
|
||||
_f.write(f"[HAN-DBG] FALLBACK_TO_GLOBAL VarName={VarName} AttrName={AttrName} gv_type={gv.type}\n")
|
||||
except Exception:
|
||||
pass
|
||||
if AttrName in Gen.variables and Gen.variables[AttrName] is None:
|
||||
str_gv_name: str = AttrName + '_str'
|
||||
if str_gv_name in Gen.module.globals:
|
||||
@@ -838,6 +899,20 @@ class ExprAttrHandle(BaseHandle):
|
||||
def _HandleAttributeLlvm(self, Node: ast.Attribute) -> ir.Value | None:
|
||||
Gen: LlvmCodeGenerator = self.Trans.LlvmGen
|
||||
|
||||
# [ATTR-DBG] 入口诊断:标记 CONST_* 属性访问的派发路径
|
||||
if Node.attr in ('CONST_INT', 'CONST_FLOAT', 'CONST_STR', 'CONST_BOOL', 'CONST_NONE'):
|
||||
_val_kind: str = type(Node.value).__name__
|
||||
_val_id: str = ''
|
||||
if isinstance(Node.value, ast.Name):
|
||||
_val_id = Node.value.id
|
||||
elif isinstance(Node.value, ast.Attribute):
|
||||
_val_id = f"<Attribute attr={Node.value.attr}>"
|
||||
try:
|
||||
with open('d:/Users/TermiNexus/Desktop/TransPyC/_attr_debug.log', 'a', encoding='utf-8') as _f:
|
||||
_f.write(f"[ATTR-DBG] dispatch Node.attr={Node.attr} value_kind={_val_kind} value_id={_val_id}\n")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if isinstance(Node.value, ast.Name):
|
||||
VarName: str = Node.value.id
|
||||
# 处理 t/c import 的别名重定向
|
||||
@@ -846,6 +921,12 @@ class ExprAttrHandle(BaseHandle):
|
||||
src_module: str
|
||||
src_name: str
|
||||
src_module, src_name = t_c_imported[VarName]
|
||||
if Node.attr in ('CONST_INT', 'CONST_FLOAT', 'CONST_STR', 'CONST_BOOL', 'CONST_NONE'):
|
||||
try:
|
||||
with open('d:/Users/TermiNexus/Desktop/TransPyC/_attr_debug.log', 'a', encoding='utf-8') as _f:
|
||||
_f.write(f"[ATTR-DBG] REDIRECT VarName={VarName} -> src_module={src_module} src_name={src_name}\n")
|
||||
except Exception:
|
||||
pass
|
||||
virtual_attr: ast.Attribute = ast.Attribute(
|
||||
value=ast.Name(id=src_module, ctx=ast.Load()),
|
||||
attr=src_name, ctx=ast.Load()
|
||||
@@ -1388,10 +1469,13 @@ class ExprAttrHandle(BaseHandle):
|
||||
return parts
|
||||
|
||||
def _try_resolve_nested_cdefine(self, Node: ast.Attribute) -> ir.Value | None:
|
||||
"""尝试解析嵌套属性路径上的 CDefine 常量
|
||||
|
||||
注意:不再强制依赖 _ImportedModules。即使该集合为空(如自举编译
|
||||
早期阶段),也始终构建属性路径并检查符号表,确保 ast.CONST_INT
|
||||
这类跨模块 CDefine 常量可被解析为立即数。
|
||||
"""
|
||||
Gen: LlvmCodeGenerator = self.Trans.LlvmGen
|
||||
imported_modules: Any = getattr(self.Trans, '_ImportedModules', None)
|
||||
if not imported_modules:
|
||||
return None
|
||||
parts: list[str] = self._build_attr_path(Node)
|
||||
if len(parts) < 2:
|
||||
return None
|
||||
@@ -1400,6 +1484,7 @@ class ExprAttrHandle(BaseHandle):
|
||||
possible_keys: list[str] = [attr_name]
|
||||
full_path: str = '.'.join(parts)
|
||||
possible_keys.append(full_path)
|
||||
imported_modules: Any = getattr(self.Trans, '_ImportedModules', None)
|
||||
if module_parts:
|
||||
ModulePath: str = '.'.join(module_parts)
|
||||
resolved_first: str = self.Trans.SymbolTable.resolve_alias(module_parts[0])
|
||||
@@ -1407,15 +1492,16 @@ class ExprAttrHandle(BaseHandle):
|
||||
resolved_parts: list[str] = [resolved_first] + module_parts[1:]
|
||||
resolved_path: str = '.'.join(resolved_parts)
|
||||
possible_keys.append(f"{resolved_path}.{attr_name}")
|
||||
for mod_name in imported_modules:
|
||||
if mod_name.endswith('.' + ModulePath) or mod_name == ModulePath:
|
||||
key: str = f"{mod_name}.{attr_name}"
|
||||
if key not in possible_keys:
|
||||
possible_keys.append(key)
|
||||
if module_parts and (mod_name.endswith('.' + module_parts[-1]) or mod_name == module_parts[-1]):
|
||||
key = f"{mod_name}.{attr_name}"
|
||||
if key not in possible_keys:
|
||||
possible_keys.append(key)
|
||||
if imported_modules:
|
||||
for mod_name in imported_modules:
|
||||
if mod_name.endswith('.' + ModulePath) or mod_name == ModulePath:
|
||||
key: str = f"{mod_name}.{attr_name}"
|
||||
if key not in possible_keys:
|
||||
possible_keys.append(key)
|
||||
if module_parts and (mod_name.endswith('.' + module_parts[-1]) or mod_name == module_parts[-1]):
|
||||
key = f"{mod_name}.{attr_name}"
|
||||
if key not in possible_keys:
|
||||
possible_keys.append(key)
|
||||
for lookup_key in possible_keys:
|
||||
SymInfo: Any = self.Trans.SymbolTable.lookup(lookup_key)
|
||||
if SymInfo and SymInfo.IsDefine and SymInfo.DefineValue is not None:
|
||||
@@ -1426,6 +1512,17 @@ class ExprAttrHandle(BaseHandle):
|
||||
return ir.Constant(ir.IntType(32), val)
|
||||
elif isinstance(val, float):
|
||||
return ir.Constant(ir.FloatType(), val)
|
||||
# 回退:检查 Gen._define_constants(LlvmGenerator 预扫描阶段填充)
|
||||
define_constants: Any = getattr(Gen, '_define_constants', {})
|
||||
for key in (attr_name, full_path):
|
||||
if key in define_constants:
|
||||
val: Any = define_constants[key]
|
||||
if isinstance(val, int):
|
||||
if val > 0x7FFFFFFF or val < -0x80000000:
|
||||
return ir.Constant(ir.IntType(64), val & 0xFFFFFFFFFFFFFFFF)
|
||||
return ir.Constant(ir.IntType(32), val)
|
||||
elif isinstance(val, float):
|
||||
return ir.Constant(ir.FloatType(), val)
|
||||
return None
|
||||
|
||||
def _try_resolve_cross_module_enum(self, module_alias: str, enum_class_name: str, member_name: str) -> ir.Value | None:
|
||||
|
||||
Reference in New Issue
Block a user