基本稳定
This commit is contained in:
1 parent
0a10b20dde
commit
a39b5da0f8
27 files changed
+392
-962
No files matched your search
@@ -1442,6 +1442,11 @@ class AssignHandle(BaseHandle):
|
||||
VarType: ir.Type = Gen._ctype_to_llvm(TypeInfo)
|
||||
if isinstance(VarType, ir.VoidType):
|
||||
VarType = ir.IntType(32)
|
||||
# 记录模块级注解类型:供函数内 global 变量的 += (HandlesAugAssign)参考,
|
||||
# 避免用 RHS 字面量类型(i32)误建 i32 全局导致 i64/i32 类型不匹配。
|
||||
if not hasattr(Gen, '_module_ann_types'):
|
||||
Gen._module_ann_types = {}
|
||||
Gen._module_ann_types[VarName] = VarType
|
||||
if VarName in Gen.variables or VarName in Gen.module.globals:
|
||||
# 时序修复:第一遍创建全局时类未处理(SymbolTable 无枚举成员),
|
||||
# initializer 回退为 0。第二遍类已处理,尝试用解析出的枚举值更新 initializer。
|
||||
|
||||
@@ -19,8 +19,27 @@ class AugAssignHandle(BaseHandle):
|
||||
ast.Div: '__truediv__', ast.FloorDiv: '__floordiv__', ast.Mod: '__mod__', ast.Pow: '__pow__',
|
||||
}
|
||||
|
||||
def _resolve_global_var_type(self, Gen: "Translator.LlvmGen", VarName: str, fallback: ir.Type) -> ir.Type:
|
||||
"""解析 global 变量的 LLVM 类型:优先用模块级 AnnAssign 的注解类型。
|
||||
|
||||
问题场景:函数内 `_g_alloc_count += 1`(global 声明),模块级注解为
|
||||
`_g_alloc_count: t.CSizeT`(i64)。若不查模块级注解类型,此处会用 RHS 字面量
|
||||
类型(i32)自动建 i32 全局,与模块内其他读取/写入(i64)类型不匹配,
|
||||
产生 "Operands must be the same type, got (i64, i32)" 类错误。
|
||||
模块级 AnnAssign 已通过 _EmitGlobalAnnAssignLlvm 创建 LLVM 全局,
|
||||
但注解无初始值(如 `_g_alloc_max: t.CSizeT = 0`)时 initializer 为空、
|
||||
Gen.module.globals 中无该符号,故需在此兜底解析注解类型。
|
||||
"""
|
||||
module_ann: dict = getattr(Gen, '_module_ann_types', None)
|
||||
if module_ann and VarName in module_ann:
|
||||
ann_type: ir.Type = module_ann[VarName]
|
||||
if ann_type is not None:
|
||||
return ann_type
|
||||
if isinstance(fallback, ir.IntType):
|
||||
return fallback
|
||||
return ir.IntType(64)
|
||||
|
||||
def _is_aug_unsigned(self, Node: ast.AugAssign, OldVal: ir.Value | None, Value: ir.Value) -> bool:
|
||||
"""判断增量赋值操作是否应使用无符号指令"""
|
||||
Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
|
||||
if isinstance(Node.target, ast.Name):
|
||||
if Gen._check_node_unsigned(Node.target):
|
||||
@@ -92,7 +111,7 @@ class AugAssignHandle(BaseHandle):
|
||||
# (注解无初始值的全局变量),此处自动创建零初始化全局变量
|
||||
GVar: ir.GlobalVariable
|
||||
if VarName not in Gen.module.globals:
|
||||
_gv_type: ir.Type = Value.type if isinstance(Value.type, ir.IntType) else ir.IntType(64)
|
||||
_gv_type: ir.Type = self._resolve_global_var_type(Gen, VarName, Value.type)
|
||||
GVar = ir.GlobalVariable(Gen.module, _gv_type, name=VarName)
|
||||
GVar.initializer = ir.Constant(_gv_type, 0)
|
||||
else:
|
||||
|
||||
@@ -631,8 +631,12 @@ class ClassHandle(BaseHandle):
|
||||
child_method: str = f"{ClassName}.{method_name}"
|
||||
new_methods.append(child_method)
|
||||
Gen.register_method(ClassName, child_method)
|
||||
covered_names.add(method_name)
|
||||
# 添加子类新增方法(不在父类中的)
|
||||
for m in Gen.class_methods[ClassName]:
|
||||
# 用快照遍历:register_method 会原地修改 class_methods,
|
||||
# 若遍历活列表会把父类独有方法(已由 register_method 追加)再次追加,
|
||||
# 导致 vtable 槽数与跨模块调用方推断不一致(如 MemBuddy 36 槽 vs 28 槽)。
|
||||
for m in list(Gen.class_methods[ClassName]):
|
||||
method_name: str = m.split('.')[-1] if '.' in m else m
|
||||
if method_name not in covered_names:
|
||||
new_methods.append(m)
|
||||
|
||||
@@ -7,16 +7,8 @@ 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):
|
||||
|
||||
# ========== 辅助方法 ==========
|
||||
|
||||
def _apply_bswap_on_Load(self, val: ir.Value, ClassName: str, AttrName: str) -> ir.Value:
|
||||
@@ -205,20 +197,6 @@ class ExprAttrHandle(BaseHandle):
|
||||
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:
|
||||
@@ -420,18 +398,6 @@ 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)
|
||||
@@ -462,12 +428,6 @@ class ExprAttrHandle(BaseHandle):
|
||||
# 尝试 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 字段存储)
|
||||
@@ -488,12 +448,6 @@ 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:
|
||||
@@ -899,20 +853,6 @@ 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 的别名重定向
|
||||
@@ -921,12 +861,6 @@ 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()
|
||||
|
||||
@@ -1726,14 +1726,16 @@ class FunctionHandle(BaseHandle):
|
||||
triple = getattr(Gen, 'module_triple', '') or getattr(Gen.module, 'triple', '')
|
||||
is_windows = 'windows' in triple if triple else False
|
||||
ptr_size = getattr(Gen, 'ptr_size', 8)
|
||||
# va_list 大小取决于 ABI:Windows x64 = 1个指针,Linux x64 = __va_list_tag[1](24字节)
|
||||
# 32位平台:Windows = 4字节指针,Linux = 12字节
|
||||
# va_list 大小取决于 ABI:Windows x64 = __va_list_tag(24字节),Linux x64 = __va_list_tag[1](24字节)
|
||||
# 注意:x86_64-pc-windows-gnu 的 llvm.va_start 写的是 24 字节的 struct __va_list_tag
|
||||
# ({i32 gp_offset, i32 fp_offset, i8* overflow_arg_area, i8* reg_save_area}),
|
||||
# 若只分配 8 字节会向调用者栈帧越界写 16 字节,导致随机栈破坏(历史崩溃根因)。
|
||||
if ptr_size == 4:
|
||||
va_list_size = 4 if is_windows else 12
|
||||
va_list_align = 4
|
||||
else:
|
||||
va_list_size = 8 if is_windows else 24
|
||||
va_list_align = 8 if is_windows else 16
|
||||
va_list_size = 24
|
||||
va_list_align = 16
|
||||
va_list_type = ir.ArrayType(ir.IntType(8), va_list_size)
|
||||
va_list_alloc = Gen._allocaEntry(va_list_type, name=f"{vararg_name}_va_list", align=va_list_align)
|
||||
va_list_ptr = Gen.builder.bitcast(va_list_alloc, ir.IntType(8).as_pointer(), name=f"{vararg_name}_va_list_i8ptr")
|
||||
|
||||
Reference in new issue
Block a user