From 58cfe2346ec2e83009b9bdd88626e06d6c91cd45 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sun, 4 Oct 2026 20:09:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpv):=20=5F=5Fnew=5F=5F=20=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E6=8C=89=E8=A2=AB=E8=B0=83=E6=96=B9=E7=AD=BE=E5=90=8D?= =?UTF-8?q?=E6=88=AA=E6=8E=89=E5=A4=9A=E4=BD=99=E5=B0=BE=E5=8F=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mlir-opt 报: error: 'llvm.call' op incorrect number of operands (8) for callee (expecting: 7) %245 = llvm.call @a959d1abdb31a471.FunctionDef.__new__(%35, %239, %240, %241, %242, %243, %is_async, %244) : (...) -> !llvm.ptr 定义/声明侧(ast/stmts.vp vpi 核实): FunctionDef.__new__(self, pool, name, args, decorator_list, returns, is_async) = 7 个形参(非-self 6) FunctionDef.__init__(..., is_async, type_params = None) = 8 个形参(非-self 7,多出的 type_params 有默认值) 根因:构造器路径把 ctor 实参**全量**转发给 __new__,而 __new__ 的签名比 __init__ 短(无 type_params)⇒ 调用点传了 7 个非-self 实参,声明只收 6 个。 (临时探针实测:mdf_param_count=6 正确、封参逻辑未触发,extra_count=7 才是不匹配源。) 修复:_call_method_on_ptr 中对 method_name == "__new__" 且已找到 declare 时,按被调方 非-self 形参数截掉多余**尾参**(这些尾参 __new__ 本就不接收,语义上由 __init__ 消费;__new__ 只负责分配存储)。探针已删除。 验证:python ./TransPyC/Projectrans.py --project ./TransPyV/project.vpj --clean --rebuild-includes --clear-cache 重编通过; ./TransPyV/output/TransPyV.exe --project ./Test/SlotsBugTest/project.json PhaseB 编译完成 → PhaseC 产出 SlotsBugTest.exe → TransPyV 完成。 --- App/lib/core/Gen/Call/CallGenCall.vp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/App/lib/core/Gen/Call/CallGenCall.vp b/App/lib/core/Gen/Call/CallGenCall.vp index d468148..e621d63 100644 --- a/App/lib/core/Gen/Call/CallGenCall.vp +++ b/App/lib/core/Gen/Call/CallGenCall.vp @@ -385,6 +385,22 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): self.Gen.TypeGenErr.fatal_error(node, err_cm4) self.Gen.TypeGenErr.fatal_error(node, "方法返回类型无法确定") + # __new__ 的签名可能**短于** __init__:ctor 路径把 ctor 实参**全量**转发给 + # __new__,会多传尾参 ⇒ call 实参数 > declare 形参数 + # (mlir-opt: "llvm.call op incorrect number of operands (8) for callee + # (expecting: 7)";现场 ast.FunctionDef.__new__ 无 type_params,而 + # __init__ 有 `type_params = None`,调用点仍按 ctor 全量传 7 个)。 + # 按被调方(declare/vpi 解析出的)非-self 形参数**截掉尾参**:这些尾参 + # __new__ 本就不接收,语义上由 __init__ 消费(__new__ 只负责分配存储)。 + if string.strcmp(method_name, "__new__") == 0 and found_func is not None: + nn_pc: int = 0 + nn_pn: mlirlite.Param* = mlirlite.function_get_param_head(found_func) + while nn_pn is not None: + nn_pc += 1 + nn_pn = mlirlite.param_get_next(nn_pn) + if nn_pc > 1 and extra_count > nn_pc - 1: + extra_count = nn_pc - 1 + # 构建参数链表: self_ptr → extra_args... mlirlite.value_set_next(self_ptr, None) head: mlirlite.Value* = self_ptr