修正了种子编译器的错误
This commit is contained in:
1 parent
135aa05485
commit
ca7c2120b8
1185 files changed
+12056
-2673
No files matched your search
@@ -327,6 +327,52 @@ class ExprCallHandle(BaseHandle):
|
||||
if ArgVal:
|
||||
args.append(ArgVal)
|
||||
return Gen.builder.call(fn_ptr, args, name=f"call_{FuncName}")
|
||||
# 处理 t.CPtr (i8*) 函数指针调用
|
||||
# 当函数被赋值给 t.CPtr 变量时,原始函数类型退化为 i8*
|
||||
# 检查是否是闭包变量(通过 _closure_var_types 追踪)
|
||||
if isinstance(closure_ptr.type, ir.PointerType) and isinstance(closure_ptr.type.pointee, ir.IntType) and closure_ptr.type.pointee.width == 8:
|
||||
ClosureInfo: tuple[ir.Type, list[ir.Type]] | None = Gen._closure_var_types.get(FuncName)
|
||||
if ClosureInfo is not None:
|
||||
# 闭包结构体解包:{i8* env, i8* fn} -> 加载 env 和 fn,构造正确函数签名
|
||||
FnRetType: ir.Type = ClosureInfo[0]
|
||||
NonlocalArgTypes: list[ir.Type] = ClosureInfo[1]
|
||||
I8PtrType: ir.PointerType = ir.IntType(8).as_pointer()
|
||||
ClosureStructType: ir.LiteralStructType = ir.LiteralStructType([I8PtrType, I8PtrType])
|
||||
ClosureStructPtr: ir.Value = Gen.builder.bitcast(closure_ptr, ir.PointerType(ClosureStructType), name=f"cast_closure_{FuncName}")
|
||||
# 加载 env(field 0)和 fn(field 1)
|
||||
EnvGep: ir.Value = Gen.builder.gep(ClosureStructPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name=f"env_gep_{FuncName}")
|
||||
EnvVal: ir.Value = Gen._load(EnvGep, name=f"env_{FuncName}")
|
||||
FnGep: ir.Value = Gen.builder.gep(ClosureStructPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 1)], name=f"fn_gep_{FuncName}")
|
||||
FnVal: ir.Value = Gen._load(FnGep, name=f"fn_{FuncName}")
|
||||
# 收集用户调用参数
|
||||
UserArgTypes: list[ir.Type] = []
|
||||
UserCallArgs: list[ir.Value] = []
|
||||
for arg in Node.args:
|
||||
ArgVal = self.HandleExprLlvm(arg)
|
||||
if ArgVal:
|
||||
UserCallArgs.append(ArgVal)
|
||||
UserArgTypes.append(ArgVal.type)
|
||||
# 构造完整函数类型:[nonlocal_types..., user_arg_types...]
|
||||
FullArgTypes: list[ir.Type] = list(NonlocalArgTypes) + UserArgTypes
|
||||
FullFnType: ir.FunctionType = ir.FunctionType(FnRetType, FullArgTypes)
|
||||
FullFnPtr: ir.Value = Gen.builder.bitcast(FnVal, ir.PointerType(FullFnType), name=f"cast_fn_{FuncName}")
|
||||
# 调用参数:env 对应 nonlocal 参数,bitcast 到正确类型
|
||||
CallArgs: list[ir.Value] = []
|
||||
if NonlocalArgTypes:
|
||||
CallArgs.append(Gen.builder.bitcast(EnvVal, NonlocalArgTypes[0], name=f"cast_env_{FuncName}"))
|
||||
CallArgs.extend(UserCallArgs)
|
||||
return Gen.builder.call(FullFnPtr, CallArgs, name=f"call_{FuncName}")
|
||||
# 普通函数指针调用(无闭包):从调用参数构造函数类型,默认返回 i32
|
||||
cptr_arg_types: list[ir.Type] = []
|
||||
cptr_call_args: list[ir.Value] = []
|
||||
for arg in Node.args:
|
||||
ArgVal = self.HandleExprLlvm(arg)
|
||||
if ArgVal:
|
||||
cptr_call_args.append(ArgVal)
|
||||
cptr_arg_types.append(ArgVal.type)
|
||||
cptr_fn_type = ir.FunctionType(ir.IntType(32), cptr_arg_types)
|
||||
cptr_fn_ptr = Gen.builder.bitcast(closure_ptr, ir.PointerType(cptr_fn_type), name=f"cast_fn_{FuncName}")
|
||||
return Gen.builder.call(cptr_fn_ptr, cptr_call_args, name=f"call_{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):
|
||||
@@ -352,11 +398,16 @@ class ExprCallHandle(BaseHandle):
|
||||
raise Exception(f"Undefined function: '{FuncName}'")
|
||||
if isinstance(Node.func, ast.Subscript):
|
||||
# Handle list[int](mb) syntax — generic class constructor with explicit type args
|
||||
# Handle xxx[T](x) syntax — generic function call with explicit type args
|
||||
sub: ast.Subscript = Node.func
|
||||
if isinstance(sub.value, ast.Name):
|
||||
ClassName: str = sub.value.id
|
||||
if hasattr(self.Trans.ClassHandler, '_generic_class_templates') and ClassName in self.Trans.ClassHandler._generic_class_templates:
|
||||
return self._HandleGenericClassNewLlvm(Node, ClassName, explicit_slice=sub.slice)
|
||||
FuncName: str = sub.value.id
|
||||
# 优先检查泛型类模板
|
||||
if hasattr(self.Trans.ClassHandler, '_generic_class_templates') and FuncName in self.Trans.ClassHandler._generic_class_templates:
|
||||
return self._HandleGenericClassNewLlvm(Node, FuncName, explicit_slice=sub.slice)
|
||||
# 检查泛型函数模板(如 xxx[T](x))
|
||||
if hasattr(self.Trans.FunctionHandler, '_generic_templates') and FuncName in self.Trans.FunctionHandler._generic_templates:
|
||||
return self._HandleGenericCallExplicitLlvm(Node, FuncName, explicit_slice=sub.slice)
|
||||
if isinstance(Node.func, ast.Attribute):
|
||||
if Node.func.attr in ('update', 'final', 'transform'):
|
||||
pass
|
||||
@@ -489,6 +540,42 @@ class ExprCallHandle(BaseHandle):
|
||||
if (is_instance_var or _is_chained_instance) and not is_class_name:
|
||||
return self._HandleMethodCallLlvm(Node)
|
||||
FuncAttr = Node.func.attr
|
||||
# c 模块的特殊语法设施(Addr/Deref/DerefAs/Set/Load/Asm 等)必须优先处理,
|
||||
# 即使它们在 Gen.structs 中(c.py 的类会被声明为结构体但不应被实例化)。
|
||||
# c.py 是语法部分,不应被编译,其中的类是编译器语法设施。
|
||||
# 必须在 Gen.structs 检查之前处理,否则 c.Deref/c.DerefAs 会被
|
||||
# _HandleClassNewLlvm 当成普通类实例化(根因:HandlesExprCall.py:497)。
|
||||
if ModulePath == 'c':
|
||||
if FuncAttr == 'Asm':
|
||||
return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node)
|
||||
elif FuncAttr == 'Addr':
|
||||
return self.Trans.CSpecialCallHandle._HandleCAddrLlvm(Node)
|
||||
elif FuncAttr == 'Set':
|
||||
return self.Trans.CSpecialCallHandle._HandleCSetLlvm(Node)
|
||||
elif FuncAttr == 'Load':
|
||||
return self.Trans.CSpecialCallHandle._HandleCLoadLlvm(Node)
|
||||
elif FuncAttr == 'Deref':
|
||||
return self.Trans.CSpecialCallHandle._HandleCDerefLlvm(Node)
|
||||
elif FuncAttr == 'DerefAs':
|
||||
return self._HandleCDerefAsLlvm(Node)
|
||||
elif FuncAttr == 'PtrToInt':
|
||||
return self.Trans.CSpecialCallHandle._HandleCPtrToIntLlvm(Node)
|
||||
elif FuncAttr in ('CIf', 'CElif'):
|
||||
return self.Trans.CSpecialCallHandle._HandleCIfLlvm(Node)
|
||||
elif FuncAttr == 'CError':
|
||||
msg = "compile-time error"
|
||||
if Node.args:
|
||||
arg = Node.args[0]
|
||||
if isinstance(arg, ast.Constant) and isinstance(arg.value, str):
|
||||
msg = arg.value
|
||||
lineno = getattr(Node, 'lineno', 0)
|
||||
raise Exception(f"#error: {msg} (line {lineno})")
|
||||
elif FuncAttr in ('AsmInp', 'AsmOut'):
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
elif FuncAttr == 'LLVMIR':
|
||||
return self._HandleLLVMIRLlvm(Node)
|
||||
elif FuncAttr in ('LInp', 'LOut'):
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
if FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr, module_sha1=_ctor_module_sha1)
|
||||
if result is not None:
|
||||
@@ -572,40 +659,6 @@ class ExprCallHandle(BaseHandle):
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr, module_sha1=_ctor_module_sha1)
|
||||
if result is not None:
|
||||
return result
|
||||
# c 模块的特殊语法设施(Addr/Deref/DerefAs/Set/Load/Asm 等)必须优先处理,
|
||||
# 即使它们在 Gen.structs 中(c.py 的类会被声明为结构体但不应被实例化)。
|
||||
# c.py 是语法部分,不应被编译,其中的类是编译器语法设施。
|
||||
if ModulePath == 'c':
|
||||
if FuncAttr == 'Asm':
|
||||
return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node)
|
||||
elif FuncAttr == 'Addr':
|
||||
return self.Trans.CSpecialCallHandle._HandleCAddrLlvm(Node)
|
||||
elif FuncAttr == 'Set':
|
||||
return self.Trans.CSpecialCallHandle._HandleCSetLlvm(Node)
|
||||
elif FuncAttr == 'Load':
|
||||
return self.Trans.CSpecialCallHandle._HandleCLoadLlvm(Node)
|
||||
elif FuncAttr == 'Deref':
|
||||
return self.Trans.CSpecialCallHandle._HandleCDerefLlvm(Node)
|
||||
elif FuncAttr == 'DerefAs':
|
||||
return self._HandleCDerefAsLlvm(Node)
|
||||
elif FuncAttr == 'PtrToInt':
|
||||
return self.Trans.CSpecialCallHandle._HandleCPtrToIntLlvm(Node)
|
||||
elif FuncAttr in ('CIf', 'CElif'):
|
||||
return self.Trans.CSpecialCallHandle._HandleCIfLlvm(Node)
|
||||
elif FuncAttr == 'CError':
|
||||
msg = "compile-time error"
|
||||
if Node.args:
|
||||
arg = Node.args[0]
|
||||
if isinstance(arg, ast.Constant) and isinstance(arg.value, str):
|
||||
msg = arg.value
|
||||
lineno = getattr(Node, 'lineno', 0)
|
||||
raise Exception(f"#error: {msg} (line {lineno})")
|
||||
elif FuncAttr in ('AsmInp', 'AsmOut'):
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
elif FuncAttr == 'LLVMIR':
|
||||
return self._HandleLLVMIRLlvm(Node)
|
||||
elif FuncAttr in ('LInp', 'LOut'):
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
if FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr, module_sha1=_ctor_module_sha1)
|
||||
if result is not None:
|
||||
@@ -1037,21 +1090,55 @@ class ExprCallHandle(BaseHandle):
|
||||
|
||||
icmp_match = re.match(r'icmp\s+(\w+)\s+(\w+)\s+%__OP(\d+)__,\s*%__OP(\d+)__', template)
|
||||
if icmp_match:
|
||||
pred = icmp_match.group(1)
|
||||
pred: str = icmp_match.group(1)
|
||||
op1 = resolve_op(int(icmp_match.group(3)))
|
||||
op2 = resolve_op(int(icmp_match.group(4)))
|
||||
if op1 and op2:
|
||||
result = Gen.builder.icmp_signed(pred, op1, op2, name="llvmir_result")
|
||||
return self._StoreLLVMIROutputs(Gen, result, output_targets)
|
||||
# LLVM IR 谓词(eq/ne/sgt/sge/slt/sle/ugt/uge/ult/ule)映射到 llvmlite
|
||||
# llvmlite 的 icmp_signed/icmp_unsigned 只接受 '=='/'!='/'<'/'<='/'>'/>='
|
||||
_ICMP_PRED_MAP: dict[str, tuple[str, str]] = {
|
||||
'eq': ('==', 'signed'), 'ne': ('!=', 'signed'),
|
||||
'sgt': ('>', 'signed'), 'sge': ('>=', 'signed'),
|
||||
'slt': ('<', 'signed'), 'sle': ('<=', 'signed'),
|
||||
'ugt': ('>', 'unsigned'), 'uge': ('>=', 'unsigned'),
|
||||
'ult': ('<', 'unsigned'), 'ule': ('<=', 'unsigned'),
|
||||
}
|
||||
pred_info: tuple[str, str] | None = _ICMP_PRED_MAP.get(pred)
|
||||
if pred_info:
|
||||
llvmlite_pred: str
|
||||
cmp_kind: str
|
||||
llvmlite_pred, cmp_kind = pred_info
|
||||
icmp_method: Any = Gen.builder.icmp_signed if cmp_kind == 'signed' else Gen.builder.icmp_unsigned
|
||||
result = icmp_method(llvmlite_pred, op1, op2, name="llvmir_result")
|
||||
return self._StoreLLVMIROutputs(Gen, result, output_targets)
|
||||
|
||||
fcmp_match = re.match(r'fcmp\s+(\w+(?:\s+fast)?)\s+(\w+)\s+%__OP(\d+)__,\s*%__OP(\d+)__', template)
|
||||
fcmp_match = re.match(r'fcmp\s+([\w\s]+?)\s+(\w+)\s+%__OP(\d+)__,\s*%__OP(\d+)__', template)
|
||||
if fcmp_match:
|
||||
pred = fcmp_match.group(1)
|
||||
pred_raw: str = fcmp_match.group(1).strip()
|
||||
# 分离 fast 修饰符(可能是 "oeq fast" 或 "fast oeq")
|
||||
is_fast: bool = 'fast' in pred_raw
|
||||
pred: str = pred_raw.replace('fast', '').strip()
|
||||
op1 = resolve_op(int(fcmp_match.group(3)))
|
||||
op2 = resolve_op(int(fcmp_match.group(4)))
|
||||
if op1 and op2:
|
||||
result = Gen.builder.fcmp_ordered(pred, op1, op2, name="llvmir_result")
|
||||
return self._StoreLLVMIROutputs(Gen, result, output_targets)
|
||||
# LLVM IR fcmp 谓词(oeq/ogt/olt/ord/uno/ueq 等)映射到 llvmlite
|
||||
_FCMP_PRED_MAP: dict[str, tuple[str, str]] = {
|
||||
'oeq': ('==', 'ordered'), 'ogt': ('>', 'ordered'),
|
||||
'oge': ('>=', 'ordered'), 'olt': ('<', 'ordered'),
|
||||
'ole': ('<=', 'ordered'), 'one': ('!=', 'ordered'),
|
||||
'ord': ('ord', 'ordered'), 'uno': ('uno', 'unordered'),
|
||||
'ueq': ('==', 'unordered'), 'ugt': ('>', 'unordered'),
|
||||
'uge': ('>=', 'unordered'), 'ult': ('<', 'unordered'),
|
||||
'ule': ('<=', 'unordered'), 'une': ('!=', 'unordered'),
|
||||
}
|
||||
fcmp_info: tuple[str, str] | None = _FCMP_PRED_MAP.get(pred)
|
||||
if fcmp_info:
|
||||
llvmlite_pred: str
|
||||
cmp_kind: str
|
||||
llvmlite_pred, cmp_kind = fcmp_info
|
||||
fcmp_method: Any = Gen.builder.fcmp_ordered if cmp_kind == 'ordered' else Gen.builder.fcmp_unordered
|
||||
result = fcmp_method(llvmlite_pred, op1, op2, name="llvmir_result")
|
||||
return self._StoreLLVMIROutputs(Gen, result, output_targets)
|
||||
|
||||
for op_name, method_name in binop_map.items():
|
||||
pattern = re.compile(
|
||||
@@ -3547,6 +3634,10 @@ class ExprCallHandle(BaseHandle):
|
||||
|
||||
def _HandleClassNewLlvm(self, Node: ast.Call, ClassName: str, module_sha1: str | None = None) -> ir.Value:
|
||||
Gen: LlvmGeneratorMixin = self.Trans.LlvmGen
|
||||
# DEBUG: 追踪 Asm 类的构造
|
||||
if ClassName == 'Asm':
|
||||
import sys as _dbg_sys
|
||||
print(f"[DEBUG_CLASSNEW] _HandleClassNewLlvm called for Asm, module_sha1={module_sha1}", file=_dbg_sys.stderr)
|
||||
# 跨模块类型引用:优先用 {module_sha1}.{ClassName} 查找 struct
|
||||
_struct_full_key: str | None = f"{module_sha1}.{ClassName}" if module_sha1 else None
|
||||
|
||||
@@ -3562,6 +3653,9 @@ class ExprCallHandle(BaseHandle):
|
||||
InitFuncName = f'{ClassName}.__init__'
|
||||
NewMethodFuncName = f'{ClassName}.__new__'
|
||||
has_new_method = Gen._find_function(NewMethodFuncName) is not None
|
||||
if ClassName == 'Asm':
|
||||
import sys as _dbg_sys
|
||||
print(f"[DEBUG_CLASSNEW] Asm: has_before_init={Gen._has_function(NewFuncName)}, has_new={has_new_method}, struct_in_gen={ClassName in Gen.structs}", file=_dbg_sys.stderr)
|
||||
if Gen._has_function(NewFuncName):
|
||||
NewFunc = Gen._get_function(NewFuncName)
|
||||
StructType = _get_struct_type(ClassName)
|
||||
@@ -3873,6 +3967,59 @@ class ExprCallHandle(BaseHandle):
|
||||
return ElemPtr
|
||||
return None
|
||||
|
||||
def _HandleGenericCallExplicitLlvm(self, Node: ast.Call, FuncName: str, explicit_slice: ast.AST) -> ir.Value | None:
|
||||
"""处理泛型函数手动传类型参数的调用 xxx[T](x)。
|
||||
|
||||
与自动推导的 _HandleGenericCallLlvm 不同,这里从 explicit_slice
|
||||
提取类型参数,而不是从参数值推导。
|
||||
"""
|
||||
Gen: LlvmGeneratorMixin = self.Trans.LlvmGen
|
||||
template: dict = self.Trans.FunctionHandler._generic_templates[FuncName]
|
||||
type_param_names: list[str] = template['type_params']
|
||||
# 从 slice 提取类型参数
|
||||
type_args: list[str] = []
|
||||
slice_nodes: list[ast.AST] = []
|
||||
if isinstance(explicit_slice, ast.Tuple):
|
||||
slice_nodes = list(explicit_slice.elts)
|
||||
else:
|
||||
slice_nodes = [explicit_slice]
|
||||
for sn in slice_nodes:
|
||||
result = self._resolve_generic_slice_type(sn)
|
||||
if result is not None:
|
||||
type_args.append(result[0])
|
||||
# 补齐缺少的类型参数
|
||||
while len(type_args) < len(type_param_names):
|
||||
type_args.append('int')
|
||||
type_args = type_args[:len(type_param_names)]
|
||||
# 特化
|
||||
spec_name = self.Trans.FunctionHandler._specialize_generic_function(FuncName, type_args, Gen)
|
||||
if spec_name is None:
|
||||
return None
|
||||
mangled_spec = Gen._mangle_func_name(spec_name)
|
||||
func = None
|
||||
if mangled_spec in Gen.functions:
|
||||
func = Gen.functions[mangled_spec]
|
||||
elif spec_name in Gen.functions:
|
||||
func = Gen.functions[spec_name]
|
||||
else:
|
||||
for fname, fobj in Gen.functions.items():
|
||||
if spec_name in fname or fname.endswith(spec_name):
|
||||
func = fobj
|
||||
break
|
||||
if func is None:
|
||||
return None
|
||||
# 处理调用参数
|
||||
CallArgs: list[ir.Value] = []
|
||||
for arg_node in Node.args:
|
||||
arg_val = self.HandleExprLlvm(arg_node)
|
||||
if arg_val:
|
||||
CallArgs.append(arg_val)
|
||||
if not CallArgs:
|
||||
CallArgs = [ir.Constant(ir.IntType(32), 0) for _ in func.args]
|
||||
CallArgs = Gen._apply_auto_addr(spec_name, CallArgs)
|
||||
adjusted = Gen._adjust_args(CallArgs, func)
|
||||
return Gen.builder.call(func, adjusted, name=f"call_{spec_name}")
|
||||
|
||||
def _HandleGenericCallLlvm(self, Node: ast.Call, FuncName: str) -> ir.Value | None:
|
||||
Gen: LlvmGeneratorMixin = self.Trans.LlvmGen
|
||||
template: dict = self.Trans.FunctionHandler._generic_templates[FuncName]
|
||||
|
||||
Reference in new issue
Block a user