diff --git a/lib/core/Handles/HandlesAssign.py b/lib/core/Handles/HandlesAssign.py index eba063d..79e554b 100644 --- a/lib/core/Handles/HandlesAssign.py +++ b/lib/core/Handles/HandlesAssign.py @@ -6,6 +6,7 @@ import vast as ast import sys import llvmlite.ir as ir from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta +from lib.core.Handles.HandlesSpecialCall import EmitRawCopyLlvm from lib.core.VLogger import get_logger as _vlog from lib.core.ConstEvaluator import ConstEvaluator, EvalContext from lib.constants.config import mode as _config_mode @@ -599,7 +600,7 @@ class AssignHandle(BaseHandle): f"解引用赋值右侧 '*' 的操作数必须是指针类型(类型推断退化," f"实际 {SrcPtr.type}){Gen._get_node_info()}" ) - if self.Trans.CSpecialCallHandle.EmitRawCopyLlvm(Ptr, SrcPtr, Gen): + if EmitRawCopyLlvm(Ptr, SrcPtr, Gen): return DerefValue: ir.Value | None = self.HandleExprLlvm(Node.value) if DerefValue is None: diff --git a/lib/core/Handles/HandlesExprBuiltin.py b/lib/core/Handles/HandlesExprBuiltin.py index 63f0d0b..2bdfe70 100644 --- a/lib/core/Handles/HandlesExprBuiltin.py +++ b/lib/core/Handles/HandlesExprBuiltin.py @@ -45,16 +45,6 @@ class ExprBuiltinHandle(BaseHandle): return None FuncName: str = Node.func.id - # Two-arg scalar alias form (int(v, CPtr) / char / bool / float / double) - # is a pointer wrap, not a scalar cast: route it to the same exit as the - # attribute form CInt(v, CPtr). Ignoring the CPtr mark would degrade - # it to a bare trunc, e.g. includes/argparse.vp get_bool() reading a - # pointer's low 32 bits instead of the stored value. - if (len(Node.args) >= 2 and FuncName in ('int', 'char', 'bool', 'float', 'double') - and self.Trans.ExprCallHandle._IsCPtrMark(Node.args[1])): - PtrCastAttr: str = 'C' + FuncName[0].upper() + FuncName[1:] - return self.Trans.TSpecialCallHandle._HandleTPtrCastLlvm(Node, PtrCastAttr) - if FuncName == 'print': return self._HandlePrintLlvm(Node) elif FuncName == 'len': diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index 318781f..53af848 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -3253,9 +3253,6 @@ class ExprCallHandle(BaseHandle): if FuncMeta.CLASS_METHOD in SymInfo.MetaList: return self._HandleStaticMethodCallLlvm(Node, ClassName, MethodName) if isinstance(Node.func.value, ast.Name) : - result = self.Trans.TSpecialCallHandle._HandleTSpecialCallLlvm(Node) - if result is not None: - return result ctype_cls = CTypeRegistry.GetClassByName(MethodName) if ctype_cls is not None: try: diff --git a/lib/core/Handles/HandlesSpecialCall.py b/lib/core/Handles/HandlesSpecialCall.py index f197e80..48c0592 100644 --- a/lib/core/Handles/HandlesSpecialCall.py +++ b/lib/core/Handles/HandlesSpecialCall.py @@ -1,175 +1,28 @@ -from __future__ import annotations -from typing import TYPE_CHECKING -import vast as ast -import llvmlite.ir as ir -if TYPE_CHECKING: - from lib.core.translator import Translator - from lib.core.Translator.LlvmGenerator import LlvmGeneratorMixin -from lib.core.Handles.HandlesBase import BaseHandle -from lib.core.TypeSystem import CTypeRegistry -from lib.core.VLogger import get_logger as _vlog -from lib.constants.config import mode as _config_mode - - -class CSpecialCallHandle(BaseHandle): - def EmitRawCopyLlvm(self, DstPtr: ir.Value, SrcPtr: ir.Value, Gen: LlvmGeneratorMixin, - NamePrefix: str = "rawcopy") -> bool: - """Emit `*dst = *src` as a raw byte copy (Load semantics); False if unusable. - - The width comes from the destination pointee and the source pointer is - bitcast to it, so this reinterprets memory instead of converting values - (e.g. `*&bits = *&dbl` must keep the IEEE bits, not fptosi). - """ - if not isinstance(DstPtr.type, ir.PointerType) or not isinstance(SrcPtr.type, ir.PointerType): - return False - Pointee: ir.Type = DstPtr.type.pointee - if isinstance(Pointee, ir.VoidType): - return False - TargetPtrTy: ir.PointerType = ir.PointerType(Pointee) - SrcCast: ir.Value = SrcPtr if SrcPtr.type == TargetPtrTy else Gen.builder.bitcast(SrcPtr, TargetPtrTy, name=f"{NamePrefix}_src_cast") - Loaded: ir.Value | None = Gen._load(SrcCast, name=f"{NamePrefix}_loaded") - if Loaded is None: - return False - DstCast: ir.Value = DstPtr if DstPtr.type == TargetPtrTy else Gen.builder.bitcast(DstPtr, TargetPtrTy, name=f"{NamePrefix}_dst_cast") - Gen._store(Loaded, DstCast) - return True - - def _ResolveTAttrToCName(attr: str) -> str | None: - ctype_cls: type | None = CTypeRegistry.GetClassByName(attr) - if ctype_cls is not None: - try: - inst = ctype_cls() - cname = type(inst).__name__ - if cname: - return cname - except Exception as _e: - if _config_mode == "strict": - raise - _vlog().warning(f"处理函数调用失败: {_e}", "Exception") - return None - - def _HandleTSpecialCallLlvm(self, Node: ast.Call) -> ir.Value | None: - Gen: LlvmGeneratorMixin = self.Trans.LlvmGen - if not Node.args: - return None - attr: str = Node.func.attr - - if attr == 'CType': - return self._HandleCTypeLlvm(Node) - - target_type: str | None = self._ResolveTAttrToCName(attr) - if target_type is not None: - IsPtr_cast = False - if len(Node.args) >= 2: - second_arg = Node.args[1] - if isinstance(second_arg, ast.Name) and second_arg.id == 'CPtr': - IsPtr_cast = True - if IsPtr_cast: - return self._HandleTPtrCastLlvm(Node, attr) - if target_type == 'void': - target_type = 'void *' - return self.Trans.ExprCallHandle._HandleTypeCastLlvm(Node.args[0], target_type) - return None - - def _HandleCTypeLlvm(self, Node: ast.Call) -> ir.Value | None: - Gen: LlvmGeneratorMixin = self.Trans.LlvmGen - arg_val: ir.Value | None = self.HandleExprLlvm(Node.args[0]) - if not arg_val: - return None - target_type_str: str = 'unsigned long long' - if len(Node.args) >= 2: - type_parts: list[str] = [] - ptr_count: int = 0 - for i in range(1, len(Node.args)): - type_arg = Node.args[i] - if isinstance(type_arg, ast.Name): - type_attr = type_arg.id - _PREFIX_MAP: dict[str, str] = { - 'CUnsigned': 'unsigned', 'CSigned': 'signed', - 'CConst': 'const', 'CVolatile': 'volatile', - } - if type_attr in _PREFIX_MAP: - type_parts.append(_PREFIX_MAP[type_attr]) - elif type_attr in ('CPtr', 'CArrayPtr'): - ptr_count += 1 - else: - resolved = self._ResolveTAttrToCName(type_attr) - if resolved is not None: - type_parts.append(resolved) - if type_parts: - target_type_str = ' '.join(type_parts) - if ptr_count > 0: - target_type_str += ' ' + '*' * ptr_count - if isinstance(arg_val.type, ir.PointerType): - int_val = Gen.builder.ptrtoint(arg_val, ir.IntType(64), name="ptr_to_int") - return int_val - return self.Trans.ExprCallHandle._HandleTypeCastLlvm(Node.args[0], target_type_str) - - def _HandleTPtrCastLlvm(self, Node: ast.Call, attr: str) -> ir.Value | None: - Gen: LlvmGeneratorMixin = self.Trans.LlvmGen - if attr in ('CChar', 'CUnsignedChar'): - first_arg = Node.args[0] - if isinstance(first_arg, ast.Call) and isinstance(first_arg.func, ast.Name) and first_arg.func.id == 'CInt' and first_arg.args: - inner_val = self.HandleExprLlvm(first_arg.args[0]) - if isinstance(inner_val.type, ir.PointerType): - return Gen.builder.bitcast(inner_val, ir.PointerType(ir.IntType(8)), name=f"c{attr.lower()}_ptr_from_cint") - expr_val = self.HandleExprLlvm(Node.args[0]) - if isinstance(expr_val.type, ir.IntType) and expr_val.type.width == 8: - var = Gen._alloca(ir.ArrayType(ir.IntType(8), 2), name=f"c{attr.lower()}_ptr") - zero = ir.Constant(ir.IntType(32), 0) - char_ptr = Gen.builder.gep(var, [zero, zero], name="char_ptr") - Gen._store(expr_val, char_ptr) - null_char = ir.Constant(ir.IntType(8), 0) - null_ptr = Gen.builder.gep(var, [zero, ir.Constant(ir.IntType(32), 1)], name="null_ptr") - Gen._store(null_char, null_ptr) - return char_ptr - elif isinstance(expr_val.type, ir.PointerType): - if isinstance(expr_val.type.pointee, ir.PointerType): - Loaded_ptr = Gen._load(expr_val, name="load_ptr") - if isinstance(Loaded_ptr.type, ir.PointerType) and isinstance(Loaded_ptr.type.pointee, ir.IntType) and Loaded_ptr.type.pointee.width == 8: - return Loaded_ptr - if isinstance(expr_val.type.pointee, ir.IntType) and expr_val.type.pointee.width == 8: - return expr_val - return Gen.builder.bitcast(expr_val, ir.PointerType(ir.IntType(8)), name="cast_to_char_ptr") - elif isinstance(expr_val.type, ir.IntType): - if expr_val.type.width == 32: - expr_val = Gen.builder.zext(expr_val, ir.IntType(64), name="zext_to_64") - return Gen.builder.inttoptr(expr_val, ir.PointerType(ir.IntType(8)), name=f"inttoptr_c{attr.lower()}") - return Gen.emit_constant(0, 'int') - elif attr == 'CVoid': - return self.Trans.ExprCallHandle._HandleTypeCastLlvm(Node.args[0], 'void *') - elif attr == 'CInt': - expr_val = self.HandleExprLlvm(Node.args[0]) - if expr_val: - if isinstance(expr_val.type, ir.IntType): - if expr_val.type.width < 64: - expr_val = Gen.builder.zext(expr_val, ir.IntType(64), name="zext_to_64") - return Gen.builder.inttoptr(expr_val, ir.PointerType(ir.IntType(32)), name="cint_ptr") - return Gen.builder.bitcast(expr_val, ir.PointerType(ir.IntType(32)), name="cint_ptr") - else: - ctype_cls = CTypeRegistry.GetClassByName(attr) - if ctype_cls is not None: - llvm_str = CTypeRegistry.CTypeToLLVM(ctype_cls) - target_type = Gen._type_str_to_llvm(llvm_str) - if target_type: - # 基础类型 (int/float) → 加一层指针 → T* - if isinstance(target_type, (ir.IntType, ir.FloatType, ir.DoubleType)): - target_ptr_type = ir.PointerType(target_type) - expr_val = self.HandleExprLlvm(Node.args[0]) - if expr_val: - if isinstance(expr_val.type, ir.IntType): - if expr_val.type.width < 64: - expr_val = Gen.builder.zext(expr_val, ir.IntType(64), name="zext_to_64") - return Gen.builder.inttoptr(expr_val, target_ptr_type, name=f"{attr.lower()}_ptr") - return Gen.builder.bitcast(expr_val, target_ptr_type, name=f"{attr.lower()}_ptr") - # 指针类型 (如 CPtr → i8*) → 再加一层指针 → i8** - elif isinstance(target_type, ir.PointerType): - target_ptr_type = ir.PointerType(target_type) - expr_val = self.HandleExprLlvm(Node.args[0]) - if expr_val: - if isinstance(expr_val.type, ir.IntType): - if expr_val.type.width < 64: - expr_val = Gen.builder.zext(expr_val, ir.IntType(64), name="zext_to_64") - return Gen.builder.inttoptr(expr_val, target_ptr_type, name=f"{attr.lower()}_ptr") - return Gen.builder.bitcast(expr_val, target_ptr_type, name=f"{attr.lower()}_ptr") - return None +from __future__ import annotations +from typing import TYPE_CHECKING +import llvmlite.ir as ir +if TYPE_CHECKING: + from lib.core.Translator.LlvmGenerator import LlvmGeneratorMixin + + +def EmitRawCopyLlvm(DstPtr: ir.Value, SrcPtr: ir.Value, Gen: LlvmGeneratorMixin, + NamePrefix: str = "rawcopy") -> bool: + """Emit `*dst = *src` as a raw byte copy (Load semantics); False if unusable. + + The width comes from the destination pointee and the source pointer is + bitcast to it, so this reinterprets memory instead of converting values + (e.g. `*&bits = *&dbl` must keep the IEEE bits, not fptosi). + """ + if not isinstance(DstPtr.type, ir.PointerType) or not isinstance(SrcPtr.type, ir.PointerType): + return False + Pointee: ir.Type = DstPtr.type.pointee + if isinstance(Pointee, ir.VoidType): + return False + TargetPtrTy: ir.PointerType = ir.PointerType(Pointee) + SrcCast: ir.Value = SrcPtr if SrcPtr.type == TargetPtrTy else Gen.builder.bitcast(SrcPtr, TargetPtrTy, name=f"{NamePrefix}_src_cast") + Loaded: ir.Value | None = Gen._load(SrcCast, name=f"{NamePrefix}_loaded") + if Loaded is None: + return False + DstCast: ir.Value = DstPtr if DstPtr.type == TargetPtrTy else Gen.builder.bitcast(DstPtr, TargetPtrTy, name=f"{NamePrefix}_dst_cast") + Gen._store(Loaded, DstCast) + return True diff --git a/lib/core/Handles/__init__.py b/lib/core/Handles/__init__.py index 528d660..9c3acad 100644 --- a/lib/core/Handles/__init__.py +++ b/lib/core/Handles/__init__.py @@ -16,7 +16,6 @@ from .HandlesExprAsm import ExprAsmHandle from .HandlesExprFormat import ExprFormatHandle from .HandlesExprLambda import ExprLambdaHandle from .HandlesExprCall import ExprCallHandle -from .HandlesSpecialCall import CSpecialCallHandle, TSpecialCallHandle from .HandlesBody import BodyHandle from .HandlesReturn import ReturnHandle from .HandlesAssign import AssignHandle diff --git a/lib/core/Translator/BaseTranslator.py b/lib/core/Translator/BaseTranslator.py index 9d35f52..d866b39 100644 --- a/lib/core/Translator/BaseTranslator.py +++ b/lib/core/Translator/BaseTranslator.py @@ -16,7 +16,6 @@ from lib.core.Handles import ( WithHandle, TryHandle, AssertHandle, RaiseHandle, MatchHandle, ExprUtils, ExprOpsHandle, ExprAttrHandle, ExprBuiltinHandle, ExprAsmHandle, ExprFormatHandle, ExprLambdaHandle, ExprCallHandle, - CSpecialCallHandle, TSpecialCallHandle, ClassHandle, FunctionHandle, ImportHandle, @@ -107,8 +106,6 @@ class BaseTranslatorMixin: self.ExprFormatHandle = ExprFormatHandle(self) self.ExprLambdaHandle = ExprLambdaHandle(self) self.ExprCallHandle = ExprCallHandle(self) - self.CSpecialCallHandle = CSpecialCallHandle(self) - self.TSpecialCallHandle = TSpecialCallHandle(self) self.ClassHandler = ClassHandle(self) self.FunctionHandler = FunctionHandle(self) self.ImportHandler = ImportHandle(self)