# HG changeset patch # User Bram Moolenaar # Date 1642510805 -3600 # Node ID 6c177a9b436e55caca448bdd9b12e8430fc28de4 # Parent 93806718f8051cd55f1dad2057296a1dad688cf3 patch 8.2.4131: Vim9: calling function in autoload import does not work Commit: https://github.com/vim/vim/commit/cbbc48f64b9cfd88720dc94b0578a3726f725178 Author: Bram Moolenaar Date: Tue Jan 18 12:58:28 2022 +0000 patch 8.2.4131: Vim9: calling function in autoload import does not work Problem: Vim9: calling function in autoload import does not work in a :def function. Solution: When a variable is not found and a PCALL follows use a funcref. (closes #9550) diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim --- a/src/testdir/test_vim9_import.vim +++ b/src/testdir/test_vim9_import.vim @@ -1264,6 +1264,10 @@ def Test_vim9script_autoload_call() var lines =<< trim END vim9script autoload + export def RetArg(arg: string): string + return arg + enddef + export def Getother() g:result = 'other' enddef @@ -1273,6 +1277,13 @@ def Test_vim9script_autoload_call() lines =<< trim END vim9script import autoload 'another.vim' + + # compile this before 'another.vim' is loaded + def CallAnother() + assert_equal('foo', 'foo'->another.RetArg()) + enddef + CallAnother() + call another.Getother() assert_equal('other', g:result) END diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4131, +/**/ 4130, /**/ 4129, diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2200,10 +2200,12 @@ exec_instructions(ectx_T *ectx) case ISN_LOADW: case ISN_LOADT: { - dictitem_T *di = NULL; - hashtab_T *ht = NULL; - char namespace; - + dictitem_T *di = NULL; + hashtab_T *ht = NULL; + char namespace; + + if (GA_GROW_FAILS(&ectx->ec_stack, 1)) + goto theend; switch (iptr->isn_type) { case ISN_LOADG: @@ -2227,14 +2229,38 @@ exec_instructions(ectx_T *ectx) } di = find_var_in_ht(ht, 0, iptr->isn_arg.string, TRUE); - if (di == NULL && ht == get_globvar_ht()) + if (di == NULL && ht == get_globvar_ht() + && vim_strchr(iptr->isn_arg.string, + AUTOLOAD_CHAR) != NULL) { - // may need to load autoload script + // Global variable has an autoload name, may still need + // to load the script. if (script_autoload(iptr->isn_arg.string, FALSE)) di = find_var_in_ht(ht, 0, iptr->isn_arg.string, TRUE); if (did_emsg) goto on_error; + if (di == NULL) + { + isn_T *next = &ectx->ec_instr[ectx->ec_iidx]; + + // When compiling "script.Func()" when "script" is + // an autoload import then this results in + // "LOADG script#Func" because we don't know if it + // is a funcref variable or a function name. In + // that case a PCALL follows, push the function + // name instead. + if (next->isn_type == ISN_PCALL) + { + tv = STACK_TV_BOT(0); + tv->v_type = VAR_FUNC; + tv->v_lock = 0; + tv->vval.v_string = + vim_strsave(iptr->isn_arg.string); + ++ectx->ec_stack.ga_len; + break; + } + } } if (di == NULL) @@ -2246,8 +2272,6 @@ exec_instructions(ectx_T *ectx) } else { - if (GA_GROW_FAILS(&ectx->ec_stack, 1)) - goto theend; copy_tv(&di->di_tv, STACK_TV_BOT(0)); ++ectx->ec_stack.ga_len; }