comparison src/vim9execute.c @ 30138:6575d0bf6061 v9.0.0405

patch 9.0.0405: arguments in a partial not used by a :def function Commit: https://github.com/vim/vim/commit/c9c967da09d9faf5ba989c943352274fea365841 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Sep 7 16:48:46 2022 +0100 patch 9.0.0405: arguments in a partial not used by a :def function Problem: Arguments in a partial not used by a :def function. Solution: Put the partial arguments on the stack.
author Bram Moolenaar <Bram@vim.org>
date Wed, 07 Sep 2022 18:00:04 +0200
parents 01408b56f093
children 9f8b1f584395
comparison
equal deleted inserted replaced
30137:a207126c5111 30138:6575d0bf6061
5270 int 5270 int
5271 call_def_function( 5271 call_def_function(
5272 ufunc_T *ufunc, 5272 ufunc_T *ufunc,
5273 int argc_arg, // nr of arguments 5273 int argc_arg, // nr of arguments
5274 typval_T *argv, // arguments 5274 typval_T *argv, // arguments
5275 int flags, // DEF_ flags
5275 partial_T *partial, // optional partial for context 5276 partial_T *partial, // optional partial for context
5276 funccall_T *funccal, 5277 funccall_T *funccal,
5277 typval_T *rettv) // return value 5278 typval_T *rettv) // return value
5278 { 5279 {
5279 ectx_T ectx; // execution context 5280 ectx_T ectx; // execution context
5280 int argc = argc_arg; 5281 int argc = argc_arg;
5282 int partial_argc = partial == NULL
5283 || (flags & DEF_USE_PT_ARGV) == 0
5284 ? 0 : partial->pt_argc;
5285 int total_argc = argc + partial_argc;
5281 typval_T *tv; 5286 typval_T *tv;
5282 int idx; 5287 int idx;
5283 int ret = FAIL; 5288 int ret = FAIL;
5284 int defcount = ufunc->uf_args.ga_len - argc; 5289 int defcount = ufunc->uf_args.ga_len - total_argc;
5285 sctx_T save_current_sctx = current_sctx; 5290 sctx_T save_current_sctx = current_sctx;
5286 int did_emsg_before = did_emsg_cumul + did_emsg; 5291 int did_emsg_before = did_emsg_cumul + did_emsg;
5287 int save_suppress_errthrow = suppress_errthrow; 5292 int save_suppress_errthrow = suppress_errthrow;
5288 msglist_T **saved_msg_list = NULL; 5293 msglist_T **saved_msg_list = NULL;
5289 msglist_T *private_msg_list = NULL; 5294 msglist_T *private_msg_list = NULL;
5343 ga_init2(&ectx.ec_trystack, sizeof(trycmd_T), 10); 5348 ga_init2(&ectx.ec_trystack, sizeof(trycmd_T), 10);
5344 ga_init2(&ectx.ec_funcrefs, sizeof(partial_T *), 10); 5349 ga_init2(&ectx.ec_funcrefs, sizeof(partial_T *), 10);
5345 ectx.ec_did_emsg_before = did_emsg_before; 5350 ectx.ec_did_emsg_before = did_emsg_before;
5346 ++ex_nesting_level; 5351 ++ex_nesting_level;
5347 5352
5348 idx = argc - ufunc->uf_args.ga_len; 5353 idx = total_argc - ufunc->uf_args.ga_len;
5349 if (idx > 0 && ufunc->uf_va_name == NULL) 5354 if (idx > 0 && ufunc->uf_va_name == NULL)
5350 { 5355 {
5351 semsg(NGETTEXT(e_one_argument_too_many, e_nr_arguments_too_many, 5356 semsg(NGETTEXT(e_one_argument_too_many, e_nr_arguments_too_many,
5352 idx), idx); 5357 idx), idx);
5353 goto failed_early; 5358 goto failed_early;
5354 } 5359 }
5355 idx = argc - ufunc->uf_args.ga_len + ufunc->uf_def_args.ga_len; 5360 idx = total_argc - ufunc->uf_args.ga_len + ufunc->uf_def_args.ga_len;
5356 if (idx < 0) 5361 if (idx < 0)
5357 { 5362 {
5358 semsg(NGETTEXT(e_one_argument_too_few, e_nr_arguments_too_few, 5363 semsg(NGETTEXT(e_one_argument_too_few, e_nr_arguments_too_few,
5359 -idx), -idx); 5364 -idx), -idx);
5360 goto failed_early; 5365 goto failed_early;
5361 } 5366 }
5362 5367
5363 // Put arguments on the stack, but no more than what the function expects. 5368 // Put values from the partial and arguments on the stack, but no more than
5364 // A lambda can be called with more arguments than it uses. 5369 // what the function expects. A lambda can be called with more arguments
5365 for (idx = 0; idx < argc 5370 // than it uses.
5371 for (idx = 0; idx < total_argc
5366 && (ufunc->uf_va_name != NULL || idx < ufunc->uf_args.ga_len); 5372 && (ufunc->uf_va_name != NULL || idx < ufunc->uf_args.ga_len);
5367 ++idx) 5373 ++idx)
5368 { 5374 {
5375 int argv_idx = idx - partial_argc;
5376
5377 tv = idx < partial_argc ? partial->pt_argv + idx : argv + argv_idx;
5369 if (idx >= ufunc->uf_args.ga_len - ufunc->uf_def_args.ga_len 5378 if (idx >= ufunc->uf_args.ga_len - ufunc->uf_def_args.ga_len
5370 && argv[idx].v_type == VAR_SPECIAL 5379 && tv->v_type == VAR_SPECIAL
5371 && argv[idx].vval.v_number == VVAL_NONE) 5380 && tv->vval.v_number == VVAL_NONE)
5372 { 5381 {
5373 // Use the default value. 5382 // Use the default value.
5374 STACK_TV_BOT(0)->v_type = VAR_UNKNOWN; 5383 STACK_TV_BOT(0)->v_type = VAR_UNKNOWN;
5375 } 5384 }
5376 else 5385 else
5377 { 5386 {
5378 if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len 5387 if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len
5379 && check_typval_arg_type( 5388 && check_typval_arg_type(
5380 ufunc->uf_arg_types[idx], &argv[idx], 5389 ufunc->uf_arg_types[idx], tv,
5381 NULL, idx + 1) == FAIL) 5390 NULL, argv_idx + 1) == FAIL)
5382 goto failed_early; 5391 goto failed_early;
5383 copy_tv(&argv[idx], STACK_TV_BOT(0)); 5392 copy_tv(tv, STACK_TV_BOT(0));
5384 } 5393 }
5385 ++ectx.ec_stack.ga_len; 5394 ++ectx.ec_stack.ga_len;
5386 } 5395 }
5387 5396
5388 // Turn varargs into a list. Empty list if no args. 5397 // Turn varargs into a list. Empty list if no args.