可用的回归测试通过的标准版本
This commit is contained in:
@@ -48,9 +48,9 @@ class ExprCallHandle(BaseHandle):
|
||||
elif arg.name == '__eh_code_out__' and eh_code_ptr is None:
|
||||
eh_code_ptr = arg
|
||||
if eh_msg_ptr is None:
|
||||
eh_msg_ptr = Gen._alloca_entry(ir.PointerType(ir.IntType(8)), name="eh_msg_out_null")
|
||||
eh_msg_ptr = Gen._allocaEntry(ir.PointerType(ir.IntType(8)), name="eh_msg_out_null")
|
||||
if eh_code_ptr is None:
|
||||
eh_code_ptr = Gen._alloca_entry(ir.IntType(32), name="eh_code_out_null")
|
||||
eh_code_ptr = Gen._allocaEntry(ir.IntType(32), name="eh_code_out_null")
|
||||
Gen._store(ir.Constant(ir.PointerType(ir.IntType(8)), None), eh_msg_ptr)
|
||||
Gen._store(ir.Constant(ir.IntType(32), 0), eh_code_ptr)
|
||||
CallArgs.append(eh_msg_ptr)
|
||||
@@ -83,7 +83,7 @@ class ExprCallHandle(BaseHandle):
|
||||
elif arg.name == '__eh_code_out__' and eh_code_ptr is None:
|
||||
eh_code_ptr = arg
|
||||
if eh_msg_ptr is not None:
|
||||
eh_msg_val = Gen._load(eh_msg_ptr, name=f"load_eh_msg_{func_name}")
|
||||
eh_msg_val = Gen._load(eh_msg_ptr, name=f"Load_eh_msg_{func_name}")
|
||||
null_ptr = ir.Constant(ir.PointerType(ir.IntType(8)), None)
|
||||
is_error = Gen.builder.icmp_signed('!=', eh_msg_val, null_ptr, name=f"check_eh_msg_{func_name}")
|
||||
OkBB = Gen.func.append_basic_block(name=f"ok_after_{func_name}")
|
||||
@@ -114,7 +114,7 @@ class ExprCallHandle(BaseHandle):
|
||||
ExceptBB, _, exception_code, _ = Gen.eh_except_block_stack[-1]
|
||||
if ExceptBB is not None:
|
||||
if has_eh_code_out and eh_code_ptr is not None:
|
||||
eh_code_val = Gen._load(eh_code_ptr, name=f"load_eh_code_{func_name}")
|
||||
eh_code_val = Gen._load(eh_code_ptr, name=f"Load_eh_code_{func_name}")
|
||||
Gen._store(eh_code_val, exception_code)
|
||||
else:
|
||||
Gen._store(ir.Constant(ir.IntType(32), 1), exception_code)
|
||||
@@ -199,8 +199,8 @@ class ExprCallHandle(BaseHandle):
|
||||
|
||||
def _HandleCallLlvm(self, Node):
|
||||
Gen = self.Trans.LlvmGen
|
||||
func_attr = None
|
||||
module_path = None
|
||||
FuncAttr = None
|
||||
ModulePath = None
|
||||
if isinstance(Node.func, ast.Name):
|
||||
FuncName = Node.func.id
|
||||
if hasattr(self.Trans.FunctionHandler, '_generic_templates') and FuncName in self.Trans.FunctionHandler._generic_templates:
|
||||
@@ -231,9 +231,9 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(Val.type, ir.IntType):
|
||||
if Val.type.width == 1:
|
||||
return Val
|
||||
return Gen.builder.icmp_signed('!=', Val, Gen._zero_const(Val.type), name="bool_result")
|
||||
return Gen.builder.icmp_signed('!=', Val, Gen._ZeroConst(Val.type), name="bool_result")
|
||||
elif isinstance(Val.type, ir.PointerType):
|
||||
return Gen.builder.icmp_signed('!=', Val, Gen._zero_const(Val.type), name="bool_result")
|
||||
return Gen.builder.icmp_signed('!=', Val, Gen._ZeroConst(Val.type), name="bool_result")
|
||||
return Val
|
||||
return ir.Constant(ir.IntType(1), 0)
|
||||
elif FuncName == 'int':
|
||||
@@ -355,7 +355,7 @@ class ExprCallHandle(BaseHandle):
|
||||
return self._HandleCallLlvm(virtual_node)
|
||||
# 检查是否是闭包变量(lambda 赋值给变量后调用)
|
||||
if FuncName in Gen.variables and Gen.variables[FuncName] is not None:
|
||||
closure_ptr = Gen._load(Gen.variables[FuncName], name=f"load_closure_{FuncName}")
|
||||
closure_ptr = Gen._load(Gen.variables[FuncName], name=f"Load_closure_{FuncName}")
|
||||
if isinstance(closure_ptr.type, ir.PointerType) and isinstance(closure_ptr.type.pointee, ir.LiteralStructType):
|
||||
st = closure_ptr.type.pointee
|
||||
if len(st.elements) == 2 and isinstance(st.elements[1], ir.PointerType) and isinstance(st.elements[1].pointee, ir.FunctionType):
|
||||
@@ -428,30 +428,30 @@ class ExprCallHandle(BaseHandle):
|
||||
type_name = Node.func.value.attr
|
||||
SizeofNode = ast.Name(id=type_name, ctx=ast.Load())
|
||||
return self._HandleSizeofLlvm(SizeofNode)
|
||||
module_path = self._get_module_path(Node.func.value)
|
||||
if module_path:
|
||||
aliases = getattr(self.Trans, '_import_aliases', {})
|
||||
first_part = module_path.split('.')[0]
|
||||
ModulePath = self._get_ModulePath(Node.func.value)
|
||||
if ModulePath:
|
||||
aliases = getattr(self.Trans, '_ImportAliases', {})
|
||||
first_part = ModulePath.split('.')[0]
|
||||
if first_part in aliases:
|
||||
module_path = aliases[first_part] + module_path[len(first_part):]
|
||||
is_instance_var = isinstance(Node.func.value, ast.Name) and Node.func.value.id in Gen.var_struct_class and Node.func.value.id not in Gen.module_sha1_map
|
||||
ModulePath = aliases[first_part] + ModulePath[len(first_part):]
|
||||
is_instance_var = isinstance(Node.func.value, ast.Name) and Node.func.value.id in Gen.var_struct_class and Node.func.value.id not in Gen.ModuleSha1Map
|
||||
is_class_name = isinstance(Node.func.value, ast.Name) and (Node.func.value.id in Gen.structs or (Node.func.value.id in self.Trans.SymbolTable and getattr(self.Trans.SymbolTable[Node.func.value.id], 'IsStruct', False)))
|
||||
if is_instance_var and not is_class_name:
|
||||
return self._HandleMethodCallLlvm(Node)
|
||||
func_attr = Node.func.attr
|
||||
if func_attr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, func_attr)
|
||||
FuncAttr = Node.func.attr
|
||||
if FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr)
|
||||
if result is not None:
|
||||
return result
|
||||
if hasattr(self.Trans.ClassHandler, '_generic_class_templates') and func_attr in self.Trans.ClassHandler._generic_class_templates:
|
||||
return self._HandleGenericClassNewLlvm(Node, func_attr)
|
||||
if func_attr in self.Trans.SymbolTable:
|
||||
SymInfo = self.Trans.SymbolTable[func_attr]
|
||||
if hasattr(self.Trans.ClassHandler, '_generic_class_templates') and FuncAttr in self.Trans.ClassHandler._generic_class_templates:
|
||||
return self._HandleGenericClassNewLlvm(Node, FuncAttr)
|
||||
if FuncAttr in self.Trans.SymbolTable:
|
||||
SymInfo = self.Trans.SymbolTable[FuncAttr]
|
||||
if SymInfo.IsStruct:
|
||||
if func_attr not in Gen.structs:
|
||||
self._ensure_struct_declared(func_attr)
|
||||
if func_attr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, func_attr)
|
||||
if FuncAttr not in Gen.structs:
|
||||
self._ensure_struct_declared(FuncAttr)
|
||||
if FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr)
|
||||
if result is not None:
|
||||
return result
|
||||
if getattr(SymInfo, 'IsEnumMember', False) and getattr(SymInfo, 'EnumName', None):
|
||||
@@ -459,58 +459,58 @@ class ExprCallHandle(BaseHandle):
|
||||
if EnumName in self.Trans.SymbolTable:
|
||||
EnumInfo = self.Trans.SymbolTable[EnumName]
|
||||
if getattr(EnumInfo, 'IsRenum', False):
|
||||
result = self._HandleREnumConstructLlvm(Node, EnumName, func_attr, SymInfo.value)
|
||||
result = self._HandleREnumConstructLlvm(Node, EnumName, FuncAttr, SymInfo.value)
|
||||
if result is not None:
|
||||
return result
|
||||
FullAttrKey = f"{module_path}.{func_attr}"
|
||||
FullAttrKey = f"{ModulePath}.{FuncAttr}"
|
||||
if FullAttrKey in self.Trans.SymbolTable:
|
||||
SymInfo = self.Trans.SymbolTable[FullAttrKey]
|
||||
if SymInfo.IsStruct:
|
||||
if func_attr not in Gen.structs:
|
||||
self._ensure_struct_declared(func_attr)
|
||||
if func_attr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, func_attr)
|
||||
if FuncAttr not in Gen.structs:
|
||||
self._ensure_struct_declared(FuncAttr)
|
||||
if FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr)
|
||||
if result is not None:
|
||||
return result
|
||||
if is_class_name:
|
||||
ClassName = Node.func.value.id
|
||||
result = self._HandleStaticMethodCallLlvm(Node, ClassName, func_attr)
|
||||
result = self._HandleStaticMethodCallLlvm(Node, ClassName, FuncAttr)
|
||||
if result is not None:
|
||||
return result
|
||||
FullAttrKey = f"{module_path}.{func_attr}"
|
||||
FullAttrKey = f"{ModulePath}.{FuncAttr}"
|
||||
if FullAttrKey in self.Trans.SymbolTable:
|
||||
SymInfo = self.Trans.SymbolTable[FullAttrKey]
|
||||
if getattr(SymInfo, 'IsTypedef', False):
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
if getattr(SymInfo, 'IsStruct', False):
|
||||
if func_attr not in Gen.structs:
|
||||
self._ensure_struct_declared(func_attr)
|
||||
if func_attr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, func_attr)
|
||||
if FuncAttr not in Gen.structs:
|
||||
self._ensure_struct_declared(FuncAttr)
|
||||
if FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr)
|
||||
if result is not None:
|
||||
return result
|
||||
if func_attr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, func_attr)
|
||||
if FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr)
|
||||
if result is not None:
|
||||
return result
|
||||
if module_path == 'c':
|
||||
if func_attr == 'Asm':
|
||||
if ModulePath == 'c':
|
||||
if FuncAttr == 'Asm':
|
||||
return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node)
|
||||
elif func_attr == 'Addr':
|
||||
elif FuncAttr == 'Addr':
|
||||
return self.Trans.CSpecialCallHandle._HandleCAddrLlvm(Node)
|
||||
elif func_attr == 'Set':
|
||||
elif FuncAttr == 'Set':
|
||||
return self.Trans.CSpecialCallHandle._HandleCSetLlvm(Node)
|
||||
elif func_attr == 'Load':
|
||||
elif FuncAttr == 'Load':
|
||||
return self.Trans.CSpecialCallHandle._HandleCLoadLlvm(Node)
|
||||
elif func_attr == 'Deref':
|
||||
elif FuncAttr == 'Deref':
|
||||
return self.Trans.CSpecialCallHandle._HandleCDerefLlvm(Node)
|
||||
elif func_attr == 'DerefAs':
|
||||
elif FuncAttr == 'DerefAs':
|
||||
return self._HandleCDerefAsLlvm(Node)
|
||||
elif func_attr == 'PtrToInt':
|
||||
elif FuncAttr == 'PtrToInt':
|
||||
return self.Trans.CSpecialCallHandle._HandleCPtrToIntLlvm(Node)
|
||||
elif func_attr in ('CIf', 'CElif'):
|
||||
elif FuncAttr in ('CIf', 'CElif'):
|
||||
return self.Trans.CSpecialCallHandle._HandleCIfLlvm(Node)
|
||||
elif func_attr == 'CError':
|
||||
elif FuncAttr == 'CError':
|
||||
msg = "compile-time error"
|
||||
if Node.args:
|
||||
arg = Node.args[0]
|
||||
@@ -520,52 +520,119 @@ class ExprCallHandle(BaseHandle):
|
||||
msg = arg.s
|
||||
lineno = getattr(Node, 'lineno', 0)
|
||||
raise Exception(f"#error: {msg} (line {lineno})")
|
||||
elif func_attr in ('AsmInp', 'AsmOut'):
|
||||
elif FuncAttr in ('AsmInp', 'AsmOut'):
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
elif func_attr == 'LLVMIR':
|
||||
elif FuncAttr == 'LLVMIR':
|
||||
return self._HandleLLVMIRLlvm(Node)
|
||||
elif func_attr in ('LInp', 'LOut'):
|
||||
elif FuncAttr in ('LInp', 'LOut'):
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
if module_path == 't':
|
||||
method_result_t = self._HandleMethodCallLlvm(Node)
|
||||
if method_result_t is not None:
|
||||
return method_result_t
|
||||
raise Exception(f"Undefined method: 't.{func_attr}'")
|
||||
if ModulePath == 't':
|
||||
MethodResult_t = self._HandleMethodCallLlvm(Node)
|
||||
if MethodResult_t is not None:
|
||||
return MethodResult_t
|
||||
raise Exception(f"Undefined method: 't.{FuncAttr}'")
|
||||
if isinstance(Node.func.value, ast.Attribute):
|
||||
inner_attr = Node.func.value.attr
|
||||
if inner_attr in Gen.structs or (inner_attr in self.Trans.SymbolTable and getattr(self.Trans.SymbolTable[inner_attr], 'IsStruct', False)):
|
||||
static_result = self._HandleStaticMethodCallLlvm(Node, inner_attr, func_attr)
|
||||
static_result = self._HandleStaticMethodCallLlvm(Node, inner_attr, FuncAttr)
|
||||
if static_result is not None:
|
||||
return static_result
|
||||
method_result_attr = self._HandleMethodCallLlvm(Node)
|
||||
is_zero_attr = isinstance(method_result_attr, ir.Constant) and isinstance(method_result_attr.type, ir.IntType) and method_result_attr.constant == 0
|
||||
if method_result_attr is not None and not is_zero_attr:
|
||||
return method_result_attr
|
||||
result = self._HandleExternalCallLlvm(Node, func_attr, module_path)
|
||||
MethodResult_attr = self._HandleMethodCallLlvm(Node)
|
||||
is_zero_attr = isinstance(MethodResult_attr, ir.Constant) and isinstance(MethodResult_attr.type, ir.IntType) and MethodResult_attr.constant == 0
|
||||
if MethodResult_attr is not None and not is_zero_attr:
|
||||
return MethodResult_attr
|
||||
result = self._HandleExternalCallLlvm(Node, FuncAttr, ModulePath)
|
||||
if result is not None:
|
||||
return result
|
||||
method_result = self._HandleMethodCallLlvm(Node)
|
||||
is_zero_result = isinstance(method_result, ir.Constant) and isinstance(method_result.type, ir.IntType) and method_result.constant == 0
|
||||
if is_zero_result and func_attr is not None:
|
||||
mangled_name = Gen._mangle_func_name(func_attr, module_path if module_path and module_path != 't' else None)
|
||||
MethodResult = self._HandleMethodCallLlvm(Node)
|
||||
IsZeroResult = isinstance(MethodResult, ir.Constant) and isinstance(MethodResult.type, ir.IntType) and MethodResult.constant == 0
|
||||
if IsZeroResult and FuncAttr is not None:
|
||||
mangled_name = Gen._mangle_func_name(FuncAttr, ModulePath if ModulePath and ModulePath != 't' else None)
|
||||
if Gen._has_function(mangled_name):
|
||||
CallArgs = []
|
||||
for arg in Node.args:
|
||||
ArgVal = self.HandleExprLlvm(arg)
|
||||
if ArgVal:
|
||||
CallArgs.append(ArgVal)
|
||||
return Gen.builder.call(Gen._get_function(mangled_name), CallArgs, name=f"call_{func_attr}")
|
||||
if method_result is None or is_zero_result:
|
||||
imported = getattr(self.Trans, '_imported_modules', set())
|
||||
aliases = getattr(self.Trans, '_import_aliases', {})
|
||||
is_known = module_path in imported or module_path in aliases
|
||||
if module_path and is_known:
|
||||
raise Exception(f"Undefined symbol: '{module_path}.{func_attr}'")
|
||||
if module_path and module_path not in {'t', 'c'} and not is_known:
|
||||
raise Exception(f"Unknown module: '{module_path}' (undefined symbol: '{module_path}.{func_attr}')")
|
||||
if not module_path and func_attr:
|
||||
raise Exception(f"Undefined method: '{func_attr}'")
|
||||
return method_result if method_result is not None else ir.Constant(ir.IntType(32), 0)
|
||||
return Gen.builder.call(Gen._get_function(mangled_name), CallArgs, name=f"call_{FuncAttr}")
|
||||
if MethodResult is None or IsZeroResult:
|
||||
imported = getattr(self.Trans, '_ImportedModules', set())
|
||||
aliases = getattr(self.Trans, '_ImportAliases', {})
|
||||
ModuleSha1Map = getattr(Gen, 'ModuleSha1Map', {})
|
||||
IsKnown = (ModulePath in imported or ModulePath in aliases or
|
||||
ModulePath in ModuleSha1Map)
|
||||
if not IsKnown and ModulePath and '.' in ModulePath:
|
||||
LastPart = ModulePath.split('.')[-1]
|
||||
IsKnown = (LastPart in imported or LastPart in aliases or
|
||||
LastPart in ModuleSha1Map)
|
||||
# 最后尝试: 用 FuncAttr 直接查找 Gen.functions(_find_function 会遍历 SHA1 前缀)
|
||||
if FuncAttr and ModulePath and ModulePath not in {'t', 'c'}:
|
||||
# 优先检查 FuncAttr 是否为 struct/类构造器
|
||||
if FuncAttr not in Gen.structs:
|
||||
self._ensure_struct_declared(FuncAttr)
|
||||
if FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr)
|
||||
if result is not None:
|
||||
return result
|
||||
# 检查 FullAttrKey 是否为 struct(如 hashlib.md5)
|
||||
if ModulePath:
|
||||
FullAttrKey = f"{ModulePath}.{FuncAttr}"
|
||||
if FullAttrKey in self.Trans.SymbolTable:
|
||||
FullSymInfo = self.Trans.SymbolTable[FullAttrKey]
|
||||
if getattr(FullSymInfo, 'IsStruct', False) or getattr(FullSymInfo, 'IsCpythonObject', False):
|
||||
if FuncAttr not in Gen.structs:
|
||||
self._ensure_struct_declared(FuncAttr)
|
||||
if FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr)
|
||||
if result is not None:
|
||||
return result
|
||||
fallback_func = Gen._find_function(FuncAttr)
|
||||
if fallback_func is not None:
|
||||
CallArgs = []
|
||||
for arg in Node.args:
|
||||
ArgVal = self.HandleExprLlvm(arg)
|
||||
if ArgVal:
|
||||
CallArgs.append(ArgVal)
|
||||
self._append_eh_msg_out_arg(CallArgs, fallback_func, Gen)
|
||||
result = Gen.builder.call(fallback_func, CallArgs, name=f"call_{FuncAttr}")
|
||||
return self._check_eh_return(result, FuncAttr, Gen, called_func=fallback_func)
|
||||
# 尝试从 stub 按需加载函数声明
|
||||
if ModulePath in ModuleSha1Map:
|
||||
sha1 = ModuleSha1Map[ModulePath]
|
||||
stub_mangled = f"{sha1}.{FuncAttr}"
|
||||
try:
|
||||
stub_func_type = self.Trans.ImportHandler._LookupStubFuncType(stub_mangled, Gen)
|
||||
except Exception:
|
||||
stub_func_type = None
|
||||
if not stub_func_type:
|
||||
try:
|
||||
stub_func_type = self.Trans.ImportHandler._LookupStubFuncType(FuncAttr, Gen)
|
||||
except Exception:
|
||||
stub_func_type = None
|
||||
if stub_func_type:
|
||||
decl_name = stub_mangled if stub_mangled in getattr(self.Trans.ImportHandler, '_stub_func_cache', {}) else FuncAttr
|
||||
if decl_name not in Gen.functions:
|
||||
func_decl = ir.Function(Gen.module, stub_func_type, name=decl_name)
|
||||
Gen.functions[decl_name] = func_decl
|
||||
if decl_name != FuncAttr and FuncAttr not in Gen.functions:
|
||||
Gen.functions[FuncAttr] = func_decl
|
||||
else:
|
||||
func_decl = Gen.functions[decl_name]
|
||||
CallArgs = []
|
||||
for arg in Node.args:
|
||||
ArgVal = self.HandleExprLlvm(arg)
|
||||
if ArgVal:
|
||||
CallArgs.append(ArgVal)
|
||||
self._append_eh_msg_out_arg(CallArgs, func_decl, Gen)
|
||||
result = Gen.builder.call(func_decl, CallArgs, name=f"call_{FuncAttr}")
|
||||
return self._check_eh_return(result, FuncAttr, Gen, called_func=func_decl)
|
||||
if ModulePath and IsKnown:
|
||||
raise Exception(f"Undefined symbol: '{ModulePath}.{FuncAttr}'")
|
||||
if ModulePath and ModulePath not in {'t', 'c'} and not IsKnown:
|
||||
raise Exception(f"Unknown module: '{ModulePath}' (undefined symbol: '{ModulePath}.{FuncAttr}')")
|
||||
if not ModulePath and FuncAttr:
|
||||
raise Exception(f"Undefined method: '{FuncAttr}'")
|
||||
return MethodResult if MethodResult is not None else ir.Constant(ir.IntType(32), 0)
|
||||
if isinstance(Node.func, ast.BinOp) and isinstance(Node.func.op, ast.BitOr):
|
||||
return self._HandleTypeUnionCastLlvm(Node)
|
||||
raise Exception(f"Unsupported call expression")
|
||||
@@ -771,7 +838,7 @@ class ExprCallHandle(BaseHandle):
|
||||
ast.copy_location(new_node, Node)
|
||||
return new_node
|
||||
|
||||
def _get_module_path(self, node):
|
||||
def _get_ModulePath(self, node):
|
||||
parts = []
|
||||
while isinstance(node, ast.Attribute):
|
||||
parts.append(node.attr)
|
||||
@@ -936,9 +1003,9 @@ class ExprCallHandle(BaseHandle):
|
||||
result = method(src_val, dest_type, name="llvmir_result")
|
||||
return self._StoreLLVMIROutputs(Gen, result, output_targets)
|
||||
|
||||
load_match = re.match(r'load\s+(\w+),\s*(\w+)\s+%__OP(\d+)__', template)
|
||||
if load_match:
|
||||
ptr_val = resolve_op(int(load_match.group(3)))
|
||||
Load_match = re.match(r'Load\s+(\w+),\s*(\w+)\s+%__OP(\d+)__', template)
|
||||
if Load_match:
|
||||
ptr_val = resolve_op(int(Load_match.group(3)))
|
||||
if ptr_val:
|
||||
result = Gen.builder.load(ptr_val, name="llvmir_result")
|
||||
return self._StoreLLVMIROutputs(Gen, result, output_targets)
|
||||
@@ -1095,8 +1162,8 @@ class ExprCallHandle(BaseHandle):
|
||||
expected_type = self._ParseLLVMType(Gen, expected_type_str.rstrip('*'))
|
||||
if not expected_type:
|
||||
return val
|
||||
is_ptr = expected_type_str.endswith('*')
|
||||
if is_ptr:
|
||||
IsPtr = expected_type_str.endswith('*')
|
||||
if IsPtr:
|
||||
expected_ptr_type = ir.PointerType(expected_type)
|
||||
if isinstance(val.type, ir.PointerType) and val.type != expected_ptr_type:
|
||||
try:
|
||||
@@ -1124,31 +1191,32 @@ class ExprCallHandle(BaseHandle):
|
||||
return Gen.builder.inttoptr(val, expected_type)
|
||||
return val
|
||||
|
||||
def _HandleExternalCallLlvm(self, Node, func_name, module_path):
|
||||
def _HandleExternalCallLlvm(self, Node, func_name, ModulePath):
|
||||
Gen = self.Trans.LlvmGen
|
||||
|
||||
# 解析 import 别名: 如 window -> vpsdk.window
|
||||
if module_path and module_path not in ('c', 't'):
|
||||
import_aliases = getattr(self.Trans, '_import_aliases', {})
|
||||
if module_path in import_aliases:
|
||||
module_path = import_aliases[module_path]
|
||||
if ModulePath and ModulePath not in ('c', 't'):
|
||||
import_aliases = getattr(self.Trans, '_ImportAliases', {})
|
||||
if ModulePath in import_aliases:
|
||||
ModulePath = import_aliases[ModulePath]
|
||||
|
||||
is_user_module = (module_path and module_path not in ('c', 't') and
|
||||
(module_path in Gen.module_sha1_map or
|
||||
module_path in getattr(self.Trans, '_imported_modules', set()) or
|
||||
module_path in getattr(self.Trans, '_import_aliases', {})))
|
||||
if module_path and module_path not in ('c', 't') and not is_user_module:
|
||||
is_user_module = (module_path in Gen.module_sha1_map or
|
||||
module_path.split('.')[-1] in Gen.module_sha1_map)
|
||||
if is_user_module and module_path not in Gen.module_sha1_map:
|
||||
module_path = module_path.split('.')[-1]
|
||||
is_user_module = (ModulePath and ModulePath not in ('c', 't') and
|
||||
(ModulePath in Gen.ModuleSha1Map or
|
||||
ModulePath in getattr(self.Trans, '_ImportedModules', set()) or
|
||||
ModulePath in getattr(self.Trans, '_ImportAliases', {})))
|
||||
if ModulePath and ModulePath not in ('c', 't') and not is_user_module:
|
||||
is_user_module = (ModulePath in Gen.ModuleSha1Map or
|
||||
ModulePath.split('.')[-1] in Gen.ModuleSha1Map or
|
||||
ModulePath.split('.')[-1] in getattr(self.Trans, '_ImportedModules', set()))
|
||||
if is_user_module and ModulePath not in Gen.ModuleSha1Map and ModulePath not in getattr(self.Trans, '_ImportedModules', set()):
|
||||
ModulePath = ModulePath.split('.')[-1]
|
||||
|
||||
if module_path and module_path not in ('c', 't') and not is_user_module:
|
||||
if ModulePath and ModulePath not in ('c', 't') and not is_user_module:
|
||||
return None
|
||||
|
||||
if is_user_module:
|
||||
mangled_name = Gen._mangle_func_name(func_name, module_path)
|
||||
sym_key = f'{module_path}.{func_name}'
|
||||
mangled_name = Gen._mangle_func_name(func_name, ModulePath)
|
||||
sym_key = f'{ModulePath}.{func_name}'
|
||||
sym_info = self.Trans.SymbolTable.get(sym_key) or self.Trans.SymbolTable.get(func_name)
|
||||
is_inline = sym_info and (getattr(sym_info, 'IsInline', False) or isinstance(getattr(sym_info, 'Storage', None), t.CInline))
|
||||
if is_inline and getattr(sym_info, 'InlineBody', None):
|
||||
@@ -1166,11 +1234,11 @@ class ExprCallHandle(BaseHandle):
|
||||
kw_provided.add(exact_param_names.index(kw.arg))
|
||||
for i in range(len(exact_param_names)):
|
||||
if i >= provided and i not in kw_provided:
|
||||
raise Exception(f"调用 {module_path}.{func_name}() 缺少必需参数 '{exact_param_names[i]}',该参数没有默认值")
|
||||
elif module_path in Gen.module_sha1_map and len(Node.args) == 0:
|
||||
raise Exception(f"调用 {ModulePath}.{func_name}() 缺少必需参数 '{exact_param_names[i]}',该参数没有默认值")
|
||||
elif ModulePath in Gen.ModuleSha1Map and len(Node.args) == 0:
|
||||
func = Gen.functions.get(mangled_name)
|
||||
if func and len(func.function_type.args) > 0:
|
||||
raise Exception(f"调用 {module_path}.{func_name}() 缺少必需参数,函数需要 {len(func.function_type.args)} 个参数但未传入任何参数")
|
||||
raise Exception(f"调用 {ModulePath}.{func_name}() 缺少必需参数,函数需要 {len(func.function_type.args)} 个参数但未传入任何参数")
|
||||
if Gen._has_function(mangled_name):
|
||||
return self._HandleClosureCallLlvm(Node, mangled_name)
|
||||
try:
|
||||
@@ -1195,7 +1263,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if decl_name != func_name and func_name not in Gen.functions:
|
||||
Gen.functions[func_name] = func_decl
|
||||
return self._HandleClosureCallLlvm(Node, decl_name)
|
||||
sym_key = f'{module_path}.{func_name}'
|
||||
sym_key = f'{ModulePath}.{func_name}'
|
||||
sym_info = self.Trans.SymbolTable.get(sym_key)
|
||||
if not sym_info:
|
||||
sym_info = self.Trans.SymbolTable.get(func_name)
|
||||
@@ -1234,9 +1302,13 @@ class ExprCallHandle(BaseHandle):
|
||||
if replaced and replaced != existing:
|
||||
Gen.functions[mangled_name] = replaced
|
||||
return self._HandleClosureCallLlvm(Node, mangled_name)
|
||||
# 回退: 直接用 func_name 查找(_find_function 会遍历 SHA1 前缀)
|
||||
fallback_func = Gen._find_function(func_name)
|
||||
if fallback_func is not None:
|
||||
return self._HandleClosureCallLlvm(Node, func_name)
|
||||
return None
|
||||
|
||||
if module_path == 'c':
|
||||
if ModulePath == 'c':
|
||||
if func_name == 'Asm':
|
||||
return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node)
|
||||
elif func_name == 'Addr':
|
||||
@@ -1276,7 +1348,7 @@ class ExprCallHandle(BaseHandle):
|
||||
'GetConsoleOutputCP': (ir.IntType(32), []),
|
||||
'GetConsoleCP': (ir.IntType(32), []),
|
||||
}
|
||||
if module_path and 'win32console' in module_path and func_name in win32_apis:
|
||||
if ModulePath and 'win32console' in ModulePath and func_name in win32_apis:
|
||||
ret_type, param_types = win32_apis[func_name]
|
||||
if func_name not in Gen.functions:
|
||||
func_type = ir.FunctionType(ret_type, param_types)
|
||||
@@ -1304,7 +1376,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if func_name in self._C_LIB_FUNCS:
|
||||
return self._HandleClosureCallLlvm(Node, func_name)
|
||||
|
||||
mangled_name = Gen._mangle_func_name(func_name, module_path)
|
||||
mangled_name = Gen._mangle_func_name(func_name, ModulePath)
|
||||
try:
|
||||
stub_func_type = self.Trans.ImportHandler._LookupStubFuncType(mangled_name, Gen)
|
||||
except Exception:
|
||||
@@ -1322,7 +1394,7 @@ class ExprCallHandle(BaseHandle):
|
||||
Gen.functions[func_name] = func_decl
|
||||
return self._HandleClosureCallLlvm(Node, decl_name)
|
||||
|
||||
sym_key = f'{module_path}.{func_name}' if module_path else func_name
|
||||
sym_key = f'{ModulePath}.{func_name}' if ModulePath else func_name
|
||||
sym_info = self.Trans.SymbolTable.get(sym_key)
|
||||
if not sym_info:
|
||||
sym_info = self.Trans.SymbolTable.get(func_name)
|
||||
@@ -1347,7 +1419,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(lp, ir.VoidType):
|
||||
lp = ir.IntType(8).as_pointer()
|
||||
llvm_param_types.append(lp)
|
||||
mangled_name = Gen._mangle_func_name(func_name, module_path)
|
||||
mangled_name = Gen._mangle_func_name(func_name, ModulePath)
|
||||
if mangled_name not in Gen.functions:
|
||||
func_type = ir.FunctionType(ret_type, llvm_param_types, var_arg=sym_is_variadic)
|
||||
func_decl = ir.Function(Gen.module, func_type, name=mangled_name)
|
||||
@@ -1372,18 +1444,22 @@ class ExprCallHandle(BaseHandle):
|
||||
type_info = None
|
||||
try:
|
||||
type_info = getattr(self.Trans, 'TypeMergeHandler', None) and self.Trans.TypeMergeHandler.MergeTypes(Node.func)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as _e:
|
||||
from lib.core.VLogger import get_logger as _vlog
|
||||
from lib.constants.config import mode as _config_mode
|
||||
if _config_mode == "strict":
|
||||
raise
|
||||
_vlog().warning(f"解析类型失败: {_e}", "Exception")
|
||||
if not isinstance(type_info, CTypeInfo):
|
||||
return None
|
||||
target_type_str = type_info.ToString()
|
||||
is_ptr = type_info.IsPtr
|
||||
if is_ptr and target_type_str and '*' not in target_type_str:
|
||||
IsPtr = type_info.IsPtr
|
||||
if IsPtr and target_type_str and '*' not in target_type_str:
|
||||
target_type_str += ' *'
|
||||
if not target_type_str:
|
||||
return None
|
||||
if type_info.IsPtr and not is_ptr:
|
||||
is_ptr = True
|
||||
if type_info.IsPtr and not IsPtr:
|
||||
IsPtr = True
|
||||
if '*' not in target_type_str:
|
||||
target_type_str += ' *'
|
||||
if isinstance(type_info.Storage, t.CExport) or isinstance(type_info.Storage, t.CExtern):
|
||||
@@ -1408,8 +1484,8 @@ class ExprCallHandle(BaseHandle):
|
||||
dst_is_float = isinstance(target_type, (ir.FloatType, ir.DoubleType))
|
||||
src_is_int = isinstance(val.type, ir.IntType)
|
||||
dst_is_int = isinstance(target_type, ir.IntType)
|
||||
src_is_ptr = isinstance(val.type, ir.PointerType)
|
||||
dst_is_ptr = isinstance(target_type, ir.PointerType)
|
||||
src_IsPtr = isinstance(val.type, ir.PointerType)
|
||||
dst_IsPtr = isinstance(target_type, ir.PointerType)
|
||||
if src_is_int and dst_is_float:
|
||||
is_unsigned = Gen._check_node_unsigned(expr_node)
|
||||
if is_unsigned:
|
||||
@@ -1442,17 +1518,17 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(val.type, ir.DoubleType) and isinstance(target_type, ir.FloatType):
|
||||
return Gen.builder.fptrunc(val, target_type, name="fptrunc_cast")
|
||||
return val
|
||||
if src_is_ptr and dst_is_int:
|
||||
if src_IsPtr and dst_is_int:
|
||||
if target_type.width < 64:
|
||||
ptr_to_i64 = Gen.builder.ptrtoint(val, ir.IntType(64), name="ptr2i64")
|
||||
return Gen.builder.trunc(ptr_to_i64, target_type, name="ptr2int_cast")
|
||||
return Gen.builder.ptrtoint(val, target_type, name="ptr2int_cast")
|
||||
if src_is_int and dst_is_ptr:
|
||||
if src_is_int and dst_IsPtr:
|
||||
return Gen.builder.inttoptr(val, target_type, name="int2ptr_cast")
|
||||
if src_is_ptr and dst_is_ptr:
|
||||
if src_IsPtr and dst_IsPtr:
|
||||
if isinstance(val.type.pointee, ir.PointerType) and isinstance(target_type.pointee, ir.IntType):
|
||||
loaded = Gen._load(val, name="load_ptr")
|
||||
return loaded
|
||||
Loaded = Gen._load(val, name="load_ptr")
|
||||
return Loaded
|
||||
return Gen.builder.bitcast(val, target_type, name="ptrcast")
|
||||
try:
|
||||
return Gen.builder.bitcast(val, target_type, name="cast")
|
||||
@@ -1464,7 +1540,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if RenumName not in Gen.structs:
|
||||
return None
|
||||
RenumType = Gen.structs[RenumName]
|
||||
result = Gen._alloca_entry(RenumType, name=f"{RenumName}_{VariantName}")
|
||||
result = Gen._allocaEntry(RenumType, name=f"{RenumName}_{VariantName}")
|
||||
tag_ptr = Gen.builder.gep(result, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name="renum_tag_ptr")
|
||||
Gen._store(ir.Constant(ir.IntType(32), TagValue), tag_ptr)
|
||||
NestedStructName = f"{RenumName}_{VariantName}"
|
||||
@@ -1473,10 +1549,10 @@ class ExprCallHandle(BaseHandle):
|
||||
NestedStructPtrType = ir.PointerType(NestedStructType)
|
||||
variant_ptr = Gen.builder.bitcast(result, NestedStructPtrType, name=f"cast_{NestedStructName}")
|
||||
members = Gen.class_members.get(NestedStructName, [])
|
||||
payload_members = [(n, t) for n, t in members if n != '__tag']
|
||||
payLoad_members = [(n, t) for n, t in members if n != '__tag']
|
||||
for i, arg in enumerate(Node.args):
|
||||
if i < len(payload_members):
|
||||
member_name, member_type = payload_members[i]
|
||||
if i < len(payLoad_members):
|
||||
member_name, member_type = payLoad_members[i]
|
||||
ArgVal = self.HandleExprLlvm(arg)
|
||||
if ArgVal:
|
||||
Coerced = Gen._coerce_value(ArgVal, member_type)
|
||||
@@ -1543,7 +1619,7 @@ class ExprCallHandle(BaseHandle):
|
||||
old_var_scopes = list(self.Trans.VarScopes)
|
||||
for param_name, val in saved_vars.items():
|
||||
if val is not None:
|
||||
alloca = Gen._alloca_entry(val.type, name=f"inline_arg_{param_name}")
|
||||
alloca = Gen._allocaEntry(val.type, name=f"inline_arg_{param_name}")
|
||||
Gen._store(val, alloca)
|
||||
self.Trans.VarScopes.append((param_name, alloca))
|
||||
self.Trans.BodyHandler.HandleBodyLlvm(inline_body)
|
||||
@@ -1679,7 +1755,7 @@ class ExprCallHandle(BaseHandle):
|
||||
CallArgs.append(Gen.variables[var_name])
|
||||
elif var_name in Gen._reg_values:
|
||||
OldVal = Gen._reg_values[var_name]
|
||||
var = Gen._alloca_entry(OldVal.type, name=var_name)
|
||||
var = Gen._allocaEntry(OldVal.type, name=var_name)
|
||||
Gen._store(OldVal, var)
|
||||
Gen.variables[var_name] = var
|
||||
del Gen._reg_values[var_name]
|
||||
@@ -1762,7 +1838,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if target_bits is None:
|
||||
target_bits = 0
|
||||
is_float = getattr(ctype_inst, 'IsSigned', False) is None and target_bits > 0 if ctype_inst else False
|
||||
is_ptr_cast = len(Node.args) >= 2 and (
|
||||
IsPtr_cast = len(Node.args) >= 2 and (
|
||||
(isinstance(Node.args[1], ast.Attribute) and Node.args[1].attr == 'CPtr' and isinstance(Node.args[1].value, ast.Name) and Node.args[1].value.id == 't') or
|
||||
(isinstance(Node.args[1], ast.Name) and Node.args[1].id == 'CPtr')
|
||||
)
|
||||
@@ -1771,10 +1847,10 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(ArgNode, ast.Subscript):
|
||||
SubscriptPtr = self._HandleSubscriptPtrLlvm(ArgNode)
|
||||
if SubscriptPtr:
|
||||
if MethodName == 'CPtr' or is_ptr_cast:
|
||||
if MethodName == 'CPtr' or IsPtr_cast:
|
||||
return SubscriptPtr
|
||||
if isinstance(SubscriptPtr.type, ir.PointerType):
|
||||
val = Gen._load(SubscriptPtr, name="load_subscript_val")
|
||||
val = Gen._load(SubscriptPtr, name="Load_subscript_val")
|
||||
else:
|
||||
val = SubscriptPtr
|
||||
if target_bits > 0 and isinstance(val.type, ir.IntType) and not is_float:
|
||||
@@ -1784,7 +1860,7 @@ class ExprCallHandle(BaseHandle):
|
||||
val = Gen.builder.trunc(val, ir.IntType(target_bits), name="trunc_cast")
|
||||
return val
|
||||
val = self.HandleExprLlvm(ArgNode)
|
||||
if is_ptr_cast:
|
||||
if IsPtr_cast:
|
||||
if target_bits > 0 and not is_float:
|
||||
target_ptr_type = ir.PointerType(ir.IntType(target_bits))
|
||||
elif is_float and target_bits == 32:
|
||||
@@ -1839,9 +1915,9 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(ArgVal, ir.Constant) and isinstance(ArgVal.type, ir.IntType):
|
||||
return ir.Constant(ir.IntType(1), 1 if ArgVal.constant != 0 else 0)
|
||||
if isinstance(ArgVal.type, ir.IntType):
|
||||
return Gen.builder.icmp_signed('!=', ArgVal, Gen._zero_const(ArgVal.type), name="cif_cond")
|
||||
return Gen.builder.icmp_signed('!=', ArgVal, Gen._ZeroConst(ArgVal.type), name="cif_cond")
|
||||
if isinstance(ArgVal.type, ir.PointerType):
|
||||
return Gen.builder.icmp_signed('!=', ArgVal, Gen._zero_const(ArgVal.type), name="cif_cond")
|
||||
return Gen.builder.icmp_signed('!=', ArgVal, Gen._ZeroConst(ArgVal.type), name="cif_cond")
|
||||
return ir.Constant(ir.IntType(1), 0)
|
||||
elif MethodName in ('CIfdef', 'CIfndef'):
|
||||
return ir.Constant(ir.IntType(1), 1)
|
||||
@@ -1858,8 +1934,12 @@ class ExprCallHandle(BaseHandle):
|
||||
val = self.HandleExprLlvm(arg)
|
||||
if isinstance(val, str):
|
||||
msg = val
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as _e:
|
||||
from lib.core.VLogger import get_logger as _vlog
|
||||
from lib.constants.config import mode as _config_mode
|
||||
if _config_mode == "strict":
|
||||
raise
|
||||
_vlog().warning(f"处理函数调用失败: {_e}", "Exception")
|
||||
lineno = getattr(Node, 'lineno', 0)
|
||||
raise Exception(f"#error: {msg} (line {lineno})")
|
||||
elif MethodName in ('CElse', 'CEndif', 'CPragma', 'CUndef'):
|
||||
@@ -1877,21 +1957,21 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(var_ptr.type, ir.PointerType) and isinstance(var_ptr.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType)):
|
||||
ObjVal = var_ptr
|
||||
else:
|
||||
tmp = Gen._alloca_entry(ObjVal.type, name="chain_method_tmp")
|
||||
tmp = Gen._allocaEntry(ObjVal.type, name="chain_method_tmp")
|
||||
Gen._store(ObjVal, tmp)
|
||||
ObjVal = tmp
|
||||
else:
|
||||
tmp = Gen._alloca_entry(ObjVal.type, name="chain_method_tmp")
|
||||
tmp = Gen._allocaEntry(ObjVal.type, name="chain_method_tmp")
|
||||
Gen._store(ObjVal, tmp)
|
||||
ObjVal = tmp
|
||||
else:
|
||||
tmp = Gen._alloca_entry(ObjVal.type, name="chain_method_tmp")
|
||||
tmp = Gen._allocaEntry(ObjVal.type, name="chain_method_tmp")
|
||||
Gen._store(ObjVal, tmp)
|
||||
ObjVal = tmp
|
||||
if isinstance(Node.func.value, ast.Name):
|
||||
ModuleName = Node.func.value.id
|
||||
aliases = getattr(self.Trans, '_import_aliases', {})
|
||||
imported = getattr(self.Trans, '_imported_modules', set())
|
||||
aliases = getattr(self.Trans, '_ImportAliases', {})
|
||||
imported = getattr(self.Trans, '_ImportedModules', set())
|
||||
actual_module = aliases.get(ModuleName, ModuleName)
|
||||
if ModuleName in imported or actual_module in imported:
|
||||
mangled_name = Gen._mangle_func_name(MethodName, actual_module)
|
||||
@@ -2001,7 +2081,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if not stub_func_type:
|
||||
stub_func_type = self.Trans.ImportHandler._LookupStubFuncType(MethodName, Gen)
|
||||
if not stub_func_type and mangled_name != MethodName:
|
||||
for sha1 in getattr(Gen, 'module_sha1_map', {}).values():
|
||||
for sha1 in getattr(Gen, 'ModuleSha1Map', {}).values():
|
||||
alt_name = f"{sha1}.{MethodName}"
|
||||
stub_func_type = self.Trans.ImportHandler._LookupStubFuncType(alt_name, Gen)
|
||||
if stub_func_type:
|
||||
@@ -2250,7 +2330,7 @@ class ExprCallHandle(BaseHandle):
|
||||
val = Gen.builder.zext(val, ir.IntType(32), name="zext_bool_print")
|
||||
elif val.type.width == 8:
|
||||
if self._is_char_type(arg):
|
||||
char_var = Gen._alloca_entry(ir.IntType(8), name="print_char_buf")
|
||||
char_var = Gen._allocaEntry(ir.IntType(8), name="print_char_buf")
|
||||
Gen.builder.store(val, char_var)
|
||||
fmt_parts.append('%c')
|
||||
fmt_args.append(char_var)
|
||||
@@ -2314,7 +2394,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if ClassName in Gen.structs:
|
||||
obj_val = Gen.builder.bitcast(obj_val, ir.PointerType(Gen.structs[ClassName]), name=f"cast_{ClassName}")
|
||||
str_val = Gen.builder.call(Gen._get_function(f'{ClassName}.__str__'), [obj_val], name=f"call_{ClassName}.__str__")
|
||||
Gen._register_temp_ptr(str_val)
|
||||
Gen._RegisterTempPtr(str_val)
|
||||
Gen._emit_printf([str_val], unsigned_flags=[False], sep=None, end=None)
|
||||
elif isinstance(arg, ast.Name) and arg.id in Gen.var_struct_class:
|
||||
ClassName = Gen.var_struct_class[arg.id]
|
||||
@@ -2325,7 +2405,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(obj_val.type, ir.PointerType) and not isinstance(obj_val.type.pointee, type(Gen.structs[ClassName])):
|
||||
obj_val = Gen.builder.bitcast(obj_val, ir.PointerType(Gen.structs[ClassName]), name=f"cast_{ClassName}")
|
||||
str_val = Gen.builder.call(str_func, [obj_val], name=f"call_{ClassName}.__str__")
|
||||
Gen._register_temp_ptr(str_val)
|
||||
Gen._RegisterTempPtr(str_val)
|
||||
Gen._emit_printf([str_val], unsigned_flags=[False], sep=None, end=None)
|
||||
else:
|
||||
val = self.HandleExprLlvm(arg)
|
||||
@@ -2340,7 +2420,7 @@ class ExprCallHandle(BaseHandle):
|
||||
pointee = val.type.pointee
|
||||
if not self._is_char_pointer(val):
|
||||
try:
|
||||
val = Gen._load(val, name="print_load")
|
||||
val = Gen._load(val, name="print_Load")
|
||||
except Exception as _e:
|
||||
if __import__('lib.constants.config', fromlist=['mode']).mode == "strict":
|
||||
self.Trans.LogWarning(f"异常被忽略: {_e}")
|
||||
@@ -2431,7 +2511,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(pointee, (ir.IdentifiedStructType, ir.LiteralStructType)):
|
||||
for CN, ST in Gen.structs.items():
|
||||
if pointee == ST:
|
||||
result = self.Trans.ExprUtils._try_operator_overload(CN, '__len__', val, Gen)
|
||||
result = self.Trans.ExprUtils._try_operator_overLoad(CN, '__len__', val, Gen)
|
||||
if result is not None:
|
||||
return result
|
||||
break
|
||||
@@ -2479,8 +2559,12 @@ class ExprCallHandle(BaseHandle):
|
||||
size_bits = getattr(ctype_inst, 'Size', 0) or 0
|
||||
size_bytes = size_bits // 8
|
||||
return ir.Constant(ir.IntType(64), size_bytes)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as _e:
|
||||
from lib.core.VLogger import get_logger as _vlog
|
||||
from lib.constants.config import mode as _config_mode
|
||||
if _config_mode == "strict":
|
||||
raise
|
||||
_vlog().warning(f"解析类型失败: {_e}", "Exception")
|
||||
resolved = CTypeRegistry.ResolveName(type_name)
|
||||
if resolved:
|
||||
ctype_cls, ptr_level = resolved
|
||||
@@ -2491,8 +2575,12 @@ class ExprCallHandle(BaseHandle):
|
||||
if ptr_level > 0:
|
||||
size_bytes = 8
|
||||
return ir.Constant(ir.IntType(64), size_bytes)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as _e:
|
||||
from lib.core.VLogger import get_logger as _vlog
|
||||
from lib.constants.config import mode as _config_mode
|
||||
if _config_mode == "strict":
|
||||
raise
|
||||
_vlog().warning(f"解析类型失败: {_e}", "Exception")
|
||||
return ir.Constant(ir.IntType(64), 0)
|
||||
|
||||
struct_type = Gen.structs[type_name]
|
||||
@@ -2516,7 +2604,7 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(pointee, (ir.IdentifiedStructType, ir.LiteralStructType)):
|
||||
for CN, ST in Gen.structs.items():
|
||||
if pointee == ST:
|
||||
result = self.Trans.ExprUtils._try_operator_overload(CN, '__abs__', val, Gen)
|
||||
result = self.Trans.ExprUtils._try_operator_overLoad(CN, '__abs__', val, Gen)
|
||||
if result is not None:
|
||||
return result
|
||||
break
|
||||
@@ -2562,12 +2650,12 @@ class ExprCallHandle(BaseHandle):
|
||||
if TypeInfo.IsEnum:
|
||||
enum_type_name = arg_name
|
||||
elif isinstance(arg, ast.Attribute):
|
||||
last_part = None
|
||||
LastPart = None
|
||||
enum_class_name = None
|
||||
if isinstance(arg.value, ast.Name):
|
||||
last_part = arg.attr
|
||||
if last_part in self.Trans.SymbolTable:
|
||||
AttrInfo = self.Trans.SymbolTable[last_part]
|
||||
LastPart = arg.attr
|
||||
if LastPart in self.Trans.SymbolTable:
|
||||
AttrInfo = self.Trans.SymbolTable[LastPart]
|
||||
if AttrInfo.IsEnumMember and AttrInfo.EnumName:
|
||||
enum_type_name = AttrInfo.EnumName
|
||||
elif isinstance(arg.value, ast.Attribute):
|
||||
@@ -2576,9 +2664,9 @@ class ExprCallHandle(BaseHandle):
|
||||
parts = attr_path.split('.')
|
||||
if len(parts) >= 2:
|
||||
enum_class_name = parts[-2]
|
||||
last_part = parts[-1]
|
||||
qualified_name_dot = f"{enum_class_name}.{last_part}"
|
||||
qualified_name_under = f"{enum_class_name}_{last_part}"
|
||||
LastPart = parts[-1]
|
||||
qualified_name_dot = f"{enum_class_name}.{LastPart}"
|
||||
qualified_name_under = f"{enum_class_name}_{LastPart}"
|
||||
enum_member_found = None
|
||||
for qname in (qualified_name_dot, qualified_name_under):
|
||||
if qname in self.Trans.SymbolTable:
|
||||
@@ -2588,7 +2676,7 @@ class ExprCallHandle(BaseHandle):
|
||||
break
|
||||
if not enum_member_found:
|
||||
for key in self.Trans.SymbolTable:
|
||||
if key == last_part:
|
||||
if key == LastPart:
|
||||
info = self.Trans.SymbolTable[key]
|
||||
if info.IsEnumMember and info.EnumName == enum_class_name:
|
||||
enum_member_found = info
|
||||
@@ -2921,7 +3009,7 @@ class ExprCallHandle(BaseHandle):
|
||||
NewFunc = Gen._get_function(NewFuncName)
|
||||
StructType = Gen.structs.get(ClassName)
|
||||
if StructType:
|
||||
result = Gen._alloca_entry(StructType, name=f"{ClassName}_alloca")
|
||||
result = Gen._allocaEntry(StructType, name=f"{ClassName}_alloca")
|
||||
else:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
Gen.builder.call(NewFunc, [result], name=f"before_init_{ClassName}")
|
||||
@@ -2983,7 +3071,7 @@ class ExprCallHandle(BaseHandle):
|
||||
StructType = StructType.pointee
|
||||
is_opaque = isinstance(StructType, ir.IdentifiedStructType) and (StructType.elements is None or len(StructType.elements) == 0)
|
||||
if is_opaque:
|
||||
result = Gen._alloca_entry(StructType, name=f"{ClassName}_alloca")
|
||||
result = Gen._allocaEntry(StructType, name=f"{ClassName}_alloca")
|
||||
Gen.builder.store(ir.Constant(StructType, None), result)
|
||||
InitFunc = Gen.functions.get(InitFuncName)
|
||||
if not InitFunc:
|
||||
@@ -3006,7 +3094,7 @@ class ExprCallHandle(BaseHandle):
|
||||
adjusted_init = Gen._adjust_args(InitArgs, InitFunc)
|
||||
Gen.builder.call(InitFunc, adjusted_init, name=f"init_{ClassName}")
|
||||
return result
|
||||
result = Gen._alloca_entry(StructType, name=f"{ClassName}_alloca")
|
||||
result = Gen._allocaEntry(StructType, name=f"{ClassName}_alloca")
|
||||
# Call __new__ method if it exists (may replace self with heap pointer)
|
||||
if has_new_method:
|
||||
NewMethodFunc = Gen._find_function(NewMethodFuncName)
|
||||
@@ -3196,7 +3284,7 @@ class ExprCallHandle(BaseHandle):
|
||||
return ptr
|
||||
return None
|
||||
if isinstance(ValueVal.type, ir.PointerType) and isinstance(ValueVal.type.pointee, ir.PointerType):
|
||||
LoadedValueVal = Gen._load(ValueVal, name="load_subscript")
|
||||
LoadedValueVal = Gen._load(ValueVal, name="Load_subscript")
|
||||
if isinstance(LoadedValueVal.type, ir.PointerType):
|
||||
ElemPtr = Gen.builder.gep(LoadedValueVal, [IndexVal], name="subscript")
|
||||
return ElemPtr
|
||||
@@ -3232,7 +3320,7 @@ class ExprCallHandle(BaseHandle):
|
||||
IndexVal = Gen.builder.trunc(IndexVal, ir.IntType(32), name="trunc_arr_index")
|
||||
ElemPtr = Gen.builder.gep(VarPtr, [zero, IndexVal], name="subscript")
|
||||
return ElemPtr
|
||||
arr_alloc = Gen._alloca_entry(ValueVal.type, name="arr_subscript_tmp")
|
||||
arr_alloc = Gen._allocaEntry(ValueVal.type, name="arr_subscript_tmp")
|
||||
Gen._store(ValueVal, arr_alloc)
|
||||
ElemPtr = Gen.builder.gep(arr_alloc, [zero, IndexVal], name="subscript")
|
||||
return ElemPtr
|
||||
|
||||
Reference in New Issue
Block a user