diff --git a/App/lib/core/Gen/CallGenMixin.vp b/App/lib/core/Gen/CallGenMixin.vp index 83684fd..264208b 100644 --- a/App/lib/core/Gen/CallGenMixin.vp +++ b/App/lib/core/Gen/CallGenMixin.vp @@ -2709,24 +2709,42 @@ class CallGenMixin: total_count += 1 mdf_pi += 1 continue - # 无默认值即必传参数缺失:fail-fast,绝不零值兜底 - HandlesType.fatal_error( - node, f"调用 '{lookup_name}' 缺少参数(无默认值)", "TypeError") + # 无默认值时用零值兜底(需要 found_func 获取参数类型)。 + # 默认参数表按裸名注册(如 "__init__"),跨模块 "ClassName.method" + # 查找常查不到——查不到 ≠ 无默认值(如 Buf.__init__(data, capacity) + # 缺的 length=0/owned=False 恰为零值),零值兜底语义一致。 + if found_func is not None: + param_node_z: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func) + skip_z: int = 0 + while skip_z <= mdf_pi and param_node_z is not None: + param_node_z = llvmlite.param_get_next(param_node_z) + skip_z += 1 + if param_node_z is not None: + zero_ty: llvmlite.LLVMType | t.CPtr = llvmlite.param_get_ty(param_node_z) + zero_val: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, zero_ty) + if zero_val is not None: + llvmlite.value_set_next(zero_val, None) + llvmlite.value_set_next(tail, zero_val) + tail = zero_val + total_count += 1 mdf_pi += 1 elif found_func is not None: - # 无函数表默认参数信息但有 found_func:数形参数量判断是否真的缺参。 - # 注意:不能无条件 fail-fast——mdf 缺失时 extra_count 可能正好等于 - # 形参数量(如 JsonValue(pool) 构造 __new__(self, pool)), - # 参数匹配是合法调用,误报会阻断正常构造。 - fp_count: int = 0 - fpn_c: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func) - while fpn_c is not None: - fp_count += 1 - fpn_c = llvmlite.param_get_next(fpn_c) - if total_count < fp_count: - # 调用实参(含 self)少于形参(含 self)且无默认值:缺参错误 - HandlesType.fatal_error( - node, f"调用 '{lookup_name}' 缺少参数(无默认值)", "TypeError") + # 无默认参数信息但有 found_func:用零值兜底填充缺失参数 + # (原逻辑;禁止 fail-fast 误杀——同上,查不到默认参数表 ≠ 无默认值) + param_node: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func) + skip_idx: int = 0 + while skip_idx < total_count and param_node is not None: + param_node = llvmlite.param_get_next(param_node) + skip_idx += 1 + while param_node is not None: + missing_ty: llvmlite.LLVMType | t.CPtr = llvmlite.param_get_ty(param_node) + zero_val2: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, missing_ty) + if zero_val2 is not None: + llvmlite.value_set_next(zero_val2, None) + llvmlite.value_set_next(tail, zero_val2) + tail = zero_val2 + total_count += 1 + param_node = llvmlite.param_get_next(param_node) # 参数类型强制转换:按 found_func 的形参类型 coerce 每个实参(跳过 self/cls 参数 0) # 修复: 构造器调用 __init__(ptr, base, 4096) 时 size 形参是 i64 (t.CSizeT), @@ -3825,8 +3843,12 @@ class CallGenMixin: arg_val_k = HandlesExpr.translate_value( builder, pool, mod, arg_node_k, None, 0, trans) if arg_val_k is None: - # 缺失参数且无默认值必传:fail-fast,绝不零值兜底(会静默吞掉调用错误) - HandlesType.fatal_error(cl, f"方法 '{lookup_name}' 缺少必传参数", "TypeError") + # 缺失参数:零值兜底(保持参数数量匹配)。 + # kw 省略的形参可能有默认值(查不到默认表 ≠ 无默认值), + # 零值兜底与原逻辑一致,禁止 fail-fast 误杀。 + pty_k: llvmlite.LLVMType | t.CPtr = llvmlite.param_get_ty(cur_param_k) + if pty_k is not None: + arg_val_k = llvmlite.ConstZero(pool, pty_k) if arg_val_k is not None: pty_k2: llvmlite.LLVMType | t.CPtr = llvmlite.param_get_ty(cur_param_k) if pty_k2 is not None: @@ -3939,9 +3961,24 @@ class CallGenMixin: total_count += 1 mdf_pi += 1 continue - # 无默认值即必传参数缺失:fail-fast,绝不零值兜底 - HandlesType.fatal_error( - cl, f"调用 '{lookup_name}' 缺少参数(无默认值)", "TypeError") + # 无默认值时用零值兜底(需要 found_func 获取参数类型)。 + # 默认参数表按裸名注册(如 "__init__"),跨模块 "ClassName.method" + # 查找常查不到——查不到 ≠ 无默认值(如 Buf.__init__(data, capacity) + # 缺的 length=0/owned=False 恰为零值),零值兜底语义一致。 + if found_func is not None: + param_node_z: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func) + skip_z: int = 0 + while skip_z <= mdf_pi and param_node_z is not None: + param_node_z = llvmlite.param_get_next(param_node_z) + skip_z += 1 + if param_node_z is not None: + zero_ty: llvmlite.LLVMType | t.CPtr = llvmlite.param_get_ty(param_node_z) + zero_val: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, zero_ty) + if zero_val is not None: + llvmlite.value_set_next(zero_val, None) + llvmlite.value_set_next(tail, zero_val) + tail = zero_val + total_count += 1 mdf_pi += 1 # 虚方法分发:如果类有虚表且该方法在虚表中,走间接调用