refactor(handles): 删除 CSpecialCallHandle/TSpecialCallHandle
EmitRawCopyLlvm 改为模块级函数;删除 c./t. 语法糖处理类及 BaseTranslator 实例化,全仓零引用。
This commit is contained in:
1 parent
d15ae02f3e
commit
2e80424d67
6 files changed
+30
-193
No files matched your search
@@ -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:
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user