From a90afb9a590c92d537faeb16f9ccd282fc78aeff Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 15 Jul 2020 22:38:56 +0200 Subject: [PATCH] patch 8.2.1224: Vim9: arguments from partial are not used Problem: Vim9: arguments from partial are not used. Solution: Put the partial arguments on the stack. (closes #6460) --- src/testdir/test_vim9_func.vim | 18 ++++++++++++++++++ src/version.c | 2 ++ src/vim9execute.c | 22 ++++++++++++++++++++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 3e90a02b80..d201181fae 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -1055,5 +1055,23 @@ def Test_closure_in_map() delete('XclosureDir', 'rf') enddef +def Test_partial_call() + let Xsetlist = function('setloclist', [0]) + Xsetlist([], ' ', {'title': 'test'}) + assert_equal({'title': 'test'}, getloclist(0, {'title': 1})) + + Xsetlist = function('setloclist', [0, [], ' ']) + Xsetlist({'title': 'test'}) + assert_equal({'title': 'test'}, getloclist(0, {'title': 1})) + + Xsetlist = function('setqflist') + Xsetlist([], ' ', {'title': 'test'}) + assert_equal({'title': 'test'}, getqflist({'title': 1})) + + Xsetlist = function('setqflist', [[], ' ']) + Xsetlist({'title': 'test'}) + assert_equal({'title': 'test'}, getqflist({'title': 1})) +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/version.c b/src/version.c index 92cbe501d3..2a915fb61d 100644 --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1224, /**/ 1223, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index eb900c876f..a0d7f630bc 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -575,14 +575,32 @@ call_by_name(char_u *name, int argcount, ectx_T *ectx, isn_T *iptr) } static int -call_partial(typval_T *tv, int argcount, ectx_T *ectx) +call_partial(typval_T *tv, int argcount_arg, ectx_T *ectx) { + int argcount = argcount_arg; char_u *name = NULL; int called_emsg_before = called_emsg; if (tv->v_type == VAR_PARTIAL) { - partial_T *pt = tv->vval.v_partial; + partial_T *pt = tv->vval.v_partial; + int i; + + if (pt->pt_argc > 0) + { + // Make space for arguments from the partial, shift the "argcount" + // arguments up. + if (ga_grow(&ectx->ec_stack, pt->pt_argc) == FAIL) + return FAIL; + for (i = 1; i <= argcount; ++i) + *STACK_TV_BOT(-i + pt->pt_argc) = *STACK_TV_BOT(-i); + ectx->ec_stack.ga_len += pt->pt_argc; + argcount += pt->pt_argc; + + // copy the arguments from the partial onto the stack + for (i = 0; i < pt->pt_argc; ++i) + copy_tv(&pt->pt_argv[i], STACK_TV_BOT(-argcount + i)); + } if (pt->pt_func != NULL) {