diff --git a/App/lib/core/Gen/Call/CallGenLeafKit.vp b/App/lib/core/Gen/Call/CallGenLeafKit.vp index a005a9f..a009942 100644 --- a/App/lib/core/Gen/Call/CallGenLeafKit.vp +++ b/App/lib/core/Gen/Call/CallGenLeafKit.vp @@ -117,6 +117,23 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # ============================================================ def _emit_eh_guarded_call(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, func: mlirlite.Function*, call_name: str, head: mlirlite.Value*, count: int, ret_ty: mlirlite.LLVMType*, is_variadic: int) -> mlirlite.Value*: """Call a function with try-except EH detection; returns the call result (positioned at ok block)""" + # Argument-count check (fail-fast at the front end instead of leaking to the LLVM verifier). + # Callee params include the injected EH out-params (%__eh_msg_out__/__eh_code_out__), which the + # caller does not pass explicitly (they are appended later in this function), so subtract them. + if func is not None and is_variadic == 0: + n_declared: int = 0 + p_chk: mlirlite.Param* = mlirlite.function_get_param_head(func) + while p_chk is not None: + n_declared += 1 + p_chk = mlirlite.param_get_next(p_chk) + if self._func_has_eh_params(func) == 1: n_declared = n_declared - 2 + if n_declared >= 0 and count != n_declared: + fname_chk: str = mlirlite.function_get_name(func) + if fname_chk is None: fname_chk = call_name + self.Gen.TypeGenErr.fatal_error( + None, + f"Argument count mismatch calling '{fname_chk}': the callee declares {n_declared} parameter(s) but the call passes {count} argument(s)", + "TypeError") if trans is None or self._func_has_eh_params(func) == 0: return mlirlite.build_call(builder, call_name, head, count, ret_ty, is_variadic) # ---- 1. determine output pointers ---- i8_ty_g: mlirlite.LLVMType* = mlirlite.Int8(pool)