Patch 8.2.2162
Problem:    Vim9: Cannot load or store autoload variables.
Solution:   Add ISN_LOADAUTO and ISN_STOREAUTO. (closes #7485)
Files:      src/vim9compile.c, src/vim9.h, src/vim9execute.c, src/dict.c,
            src/eval.c, src/evalvars.c, src/proto/evalvars.pro,
            src/testdir/test_vim9_disassemble.vim,
            src/testdir/test_vim9_script.vim


*** ../vim-8.2.2161/src/vim9compile.c   2020-12-18 19:49:52.349571840 +0100
--- src/vim9compile.c   2020-12-19 15:38:42.981882699 +0100
***************
*** 2535,2541 ****
                case 's': res = compile_load_scriptvar(cctx, name,
                                                            NULL, NULL, error);
                          break;
!               case 'g': isn_type = ISN_LOADG; break;
                case 'w': isn_type = ISN_LOADW; break;
                case 't': isn_type = ISN_LOADT; break;
                case 'b': isn_type = ISN_LOADB; break;
--- 2535,2551 ----
                case 's': res = compile_load_scriptvar(cctx, name,
                                                            NULL, NULL, error);
                          break;
!               case 'g': if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
!                             isn_type = ISN_LOADG;
!                         else
!                         {
!                             isn_type = ISN_LOADAUTO;
!                             vim_free(name);
!                             name = vim_strnsave(*arg, end - *arg);
!                             if (name == NULL)
!                                 return FAIL;
!                         }
!                         break;
                case 'w': isn_type = ISN_LOADW; break;
                case 't': isn_type = ISN_LOADT; break;
                case 'b': isn_type = ISN_LOADB; break;
***************
*** 2738,2744 ****
      if (compile_arguments(arg, cctx, &argcount) == FAIL)
        goto theend;
  
!     is_autoload = vim_strchr(name, '#') != NULL;
      if (ASCII_ISLOWER(*name) && name[1] != ':' && !is_autoload)
      {
        int         idx;
--- 2748,2754 ----
      if (compile_arguments(arg, cctx, &argcount) == FAIL)
        goto theend;
  
!     is_autoload = vim_strchr(name, AUTOLOAD_CHAR) != NULL;
      if (ASCII_ISLOWER(*name) && name[1] != ':' && !is_autoload)
      {
        int         idx;
***************
*** 4986,4992 ****
            generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
            break;
        case dest_global:
!           generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
            break;
        case dest_buffer:
            generate_LOAD(cctx, ISN_LOADB, 0, name + 2, type);
--- 4996,5005 ----
            generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
            break;
        case dest_global:
!           if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
!               generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
!           else
!               generate_LOAD(cctx, ISN_LOADAUTO, 0, name, type);
            break;
        case dest_buffer:
            generate_LOAD(cctx, ISN_LOADB, 0, name + 2, type);
***************
*** 5198,5204 ****
                                                                    opt_flags);
        case dest_global:
            // include g: with the name, easier to execute that way
!           return generate_STORE(cctx, ISN_STOREG, 0, name);
        case dest_buffer:
            // include b: with the name, easier to execute that way
            return generate_STORE(cctx, ISN_STOREB, 0, name);
--- 5211,5218 ----
                                                                    opt_flags);
        case dest_global:
            // include g: with the name, easier to execute that way
!           return generate_STORE(cctx, vim_strchr(name, AUTOLOAD_CHAR) == NULL
!                                       ? ISN_STOREG : ISN_STOREAUTO, 0, name);
        case dest_buffer:
            // include b: with the name, easier to execute that way
            return generate_STORE(cctx, ISN_STOREB, 0, name);
***************
*** 8007,8012 ****
--- 8021,8027 ----
      {
        case ISN_DEF:
        case ISN_EXEC:
+       case ISN_LOADAUTO:
        case ISN_LOADB:
        case ISN_LOADENV:
        case ISN_LOADG:
***************
*** 8017,8022 ****
--- 8032,8038 ----
        case ISN_PUSHFUNC:
        case ISN_PUSHS:
        case ISN_RANGE:
+       case ISN_STOREAUTO:
        case ISN_STOREB:
        case ISN_STOREENV:
        case ISN_STOREG:
*** ../vim-8.2.2161/src/vim9.h  2020-12-18 19:49:52.349571840 +0100
--- src/vim9.h  2020-12-19 14:26:30.450999685 +0100
***************
*** 24,29 ****
--- 24,30 ----
      ISN_LOAD,     // push local variable isn_arg.number
      ISN_LOADV,            // push v: variable isn_arg.number
      ISN_LOADG,            // push g: variable isn_arg.string
+     ISN_LOADAUTO,   // push g: autoload variable isn_arg.string
      ISN_LOADB,            // push b: variable isn_arg.string
      ISN_LOADW,            // push w: variable isn_arg.string
      ISN_LOADT,            // push t: variable isn_arg.string
***************
*** 41,46 ****
--- 42,48 ----
      ISN_STORE,            // pop into local variable isn_arg.number
      ISN_STOREV,           // pop into v: variable isn_arg.number
      ISN_STOREG,           // pop into global variable isn_arg.string
+     ISN_STOREAUTO,  // pop into global autoload variable isn_arg.string
      ISN_STOREB,           // pop into buffer-local variable isn_arg.string
      ISN_STOREW,           // pop into window-local variable isn_arg.string
      ISN_STORET,           // pop into tab-local variable isn_arg.string
*** ../vim-8.2.2161/src/vim9execute.c   2020-12-18 19:49:52.349571840 +0100
--- src/vim9execute.c   2020-12-19 16:01:10.224915769 +0100
***************
*** 1391,1396 ****
--- 1391,1411 ----
                }
                break;
  
+           // load autoload variable
+           case ISN_LOADAUTO:
+               {
+                   char_u *name = iptr->isn_arg.string;
+ 
+                   if (GA_GROW(&ectx.ec_stack, 1) == FAIL)
+                       goto failed;
+                   SOURCING_LNUM = iptr->isn_lnum;
+                   if (eval_variable(name, STRLEN(name),
+                                 STACK_TV_BOT(0), NULL, TRUE, FALSE) == FAIL)
+                       goto on_error;
+                   ++ectx.ec_stack.ga_len;
+               }
+               break;
+ 
            // load g:/b:/w:/t: namespace
            case ISN_LOADGDICT:
            case ISN_LOADBDICT:
***************
*** 1611,1616 ****
--- 1626,1639 ----
                }
                break;
  
+           // store an autoload variable
+           case ISN_STOREAUTO:
+               SOURCING_LNUM = iptr->isn_lnum;
+               set_var(iptr->isn_arg.string, STACK_TV_BOT(-1), TRUE);
+               clear_tv(STACK_TV_BOT(-1));
+               --ectx.ec_stack.ga_len;
+               break;
+ 
            // store number in local variable
            case ISN_STORENR:
                tv = STACK_TV_VAR(iptr->isn_arg.storenr.stnr_idx);
***************
*** 3286,3291 ****
--- 3309,3317 ----
                                 iptr->isn_arg.loadstore.ls_name, si->sn_name);
                }
                break;
+           case ISN_LOADAUTO:
+               smsg("%4d LOADAUTO %s", current, iptr->isn_arg.string);
+               break;
            case ISN_LOADG:
                smsg("%4d LOADG g:%s", current, iptr->isn_arg.string);
                break;
***************
*** 3337,3342 ****
--- 3363,3371 ----
                smsg("%4d STOREV v:%s", current,
                                       get_vim_var_name(iptr->isn_arg.number));
                break;
+           case ISN_STOREAUTO:
+               smsg("%4d STOREAUTO %s", current, iptr->isn_arg.string);
+               break;
            case ISN_STOREG:
                smsg("%4d STOREG %s", current, iptr->isn_arg.string);
                break;
*** ../vim-8.2.2161/src/dict.c  2020-12-15 21:41:53.141431375 +0100
--- src/dict.c  2020-12-19 16:17:34.510365354 +0100
***************
*** 1073,1079 ****
                        && HI2DI(hi2)->di_tv.v_type == VAR_FUNC
                        && var_wrong_func_name(hi2->hi_key, di1 == NULL))
                    break;
!               if (!valid_varname(hi2->hi_key))
                    break;
            }
            if (di1 == NULL)
--- 1073,1079 ----
                        && HI2DI(hi2)->di_tv.v_type == VAR_FUNC
                        && var_wrong_func_name(hi2->hi_key, di1 == NULL))
                    break;
!               if (!valid_varname(hi2->hi_key, TRUE))
                    break;
            }
            if (di1 == NULL)
*** ../vim-8.2.2161/src/eval.c  2020-12-18 19:49:52.337571884 +0100
--- src/eval.c  2020-12-19 16:17:41.446343651 +0100
***************
*** 1049,1055 ****
                wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
                               && rettv->v_type == VAR_FUNC
                               && var_wrong_func_name(key, lp->ll_di == NULL))
!                       || !valid_varname(key);
                if (len != -1)
                    key[len] = prevval;
                if (wrong)
--- 1049,1055 ----
                wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
                               && rettv->v_type == VAR_FUNC
                               && var_wrong_func_name(key, lp->ll_di == NULL))
!                       || !valid_varname(key, TRUE);
                if (len != -1)
                    key[len] = prevval;
                if (wrong)
*** ../vim-8.2.2161/src/evalvars.c      2020-12-18 15:37:57.248171925 +0100
--- src/evalvars.c      2020-12-19 16:22:34.353408599 +0100
***************
*** 3195,3202 ****
            goto failed;
        }
  
!       // Make sure the variable name is valid.
!       if (!valid_varname(varname))
            goto failed;
  
        di = alloc(sizeof(dictitem_T) + STRLEN(varname));
--- 3195,3204 ----
            goto failed;
        }
  
!       // Make sure the variable name is valid.  In Vim9 script an autoload
!       // variable must be prefixed with "g:".
!       if (!valid_varname(varname, !vim9script
!                                              || STRNCMP(name, "g:", 2) == 0))
            goto failed;
  
        di = alloc(sizeof(dictitem_T) + STRLEN(varname));
***************
*** 3349,3365 ****
  }
  
  /*
!  * Check if a variable name is valid.
   * Return FALSE and give an error if not.
   */
      int
! valid_varname(char_u *varname)
  {
      char_u *p;
  
      for (p = varname; *p != NUL; ++p)
        if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
!                                                  && *p != AUTOLOAD_CHAR)
        {
            semsg(_(e_illvar), varname);
            return FALSE;
--- 3351,3367 ----
  }
  
  /*
!  * Check if a variable name is valid.  When "autoload" is true "#" is allowed.
   * Return FALSE and give an error if not.
   */
      int
! valid_varname(char_u *varname, int autoload)
  {
      char_u *p;
  
      for (p = varname; *p != NUL; ++p)
        if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
!                                        && !(autoload && *p == AUTOLOAD_CHAR))
        {
            semsg(_(e_illvar), varname);
            return FALSE;
*** ../vim-8.2.2161/src/proto/evalvars.pro      2020-12-12 14:33:37.096920916 
+0100
--- src/proto/evalvars.pro      2020-12-19 16:20:48.425750518 +0100
***************
*** 75,81 ****
  int var_check_fixed(int flags, char_u *name, int use_gettext);
  int var_wrong_func_name(char_u *name, int new_var);
  int value_check_lock(int lock, char_u *name, int use_gettext);
! int valid_varname(char_u *varname);
  void reset_v_option_vars(void);
  void assert_error(garray_T *gap);
  int var_exists(char_u *var);
--- 75,81 ----
  int var_check_fixed(int flags, char_u *name, int use_gettext);
  int var_wrong_func_name(char_u *name, int new_var);
  int value_check_lock(int lock, char_u *name, int use_gettext);
! int valid_varname(char_u *varname, int autoload);
  void reset_v_option_vars(void);
  void assert_error(garray_T *gap);
  int var_exists(char_u *var);
*** ../vim-8.2.2161/src/testdir/test_vim9_disassemble.vim       2020-12-13 
14:19:22.131979168 +0100
--- src/testdir/test_vim9_disassemble.vim       2020-12-19 15:48:11.699601520 
+0100
***************
*** 23,28 ****
--- 23,29 ----
    echo s:scriptvar
    echo g:globalvar
    echo get(g:, "global")
+   echo g:auto#var
    echo b:buffervar
    echo get(b:, "buffer")
    echo w:windowvar
***************
*** 68,75 ****
          'echo get(g:, "global")\_s*' ..
          '\d\+ LOAD g:\_s*' ..
          '\d\+ PUSHS "global"\_s*' ..
!         '\d\+ BCALL get(argc 2).*' ..
!         ' LOADB b:buffervar.*' ..
          'echo get(b:, "buffer")\_s*' ..
          '\d\+ LOAD b:\_s*' ..
          '\d\+ PUSHS "buffer"\_s*' ..
--- 69,82 ----
          'echo get(g:, "global")\_s*' ..
          '\d\+ LOAD g:\_s*' ..
          '\d\+ PUSHS "global"\_s*' ..
!         '\d\+ BCALL get(argc 2)\_s*' ..
!         '\d\+ ECHO 1\_s*' ..
!         'echo g:auto#var\_s*' ..
!         '\d\+ LOADAUTO g:auto#var\_s*' ..
!         '\d\+ ECHO 1\_s*' ..
!         'echo b:buffervar\_s*' ..
!         '\d\+ LOADB b:buffervar\_s*' ..
!         '\d\+ ECHO 1\_s*' ..
          'echo get(b:, "buffer")\_s*' ..
          '\d\+ LOAD b:\_s*' ..
          '\d\+ PUSHS "buffer"\_s*' ..
***************
*** 197,202 ****
--- 204,210 ----
    v:char = 'abc'
    s:scriptvar = 'sv'
    g:globalvar = 'gv'
+   g:auto#var = 'av'
    b:buffervar = 'bv'
    w:windowvar = 'wv'
    t:tabpagevar = 'tv'
***************
*** 220,225 ****
--- 228,235 ----
          ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
          'g:globalvar = ''gv''.*' ..
          ' STOREG g:globalvar.*' ..
+         'g:auto#var = ''av''.*' ..
+         ' STOREAUTO g:auto#var.*' ..
          'b:buffervar = ''bv''.*' ..
          ' STOREB b:buffervar.*' ..
          'w:windowvar = ''wv''.*' ..
*** ../vim-8.2.2161/src/testdir/test_vim9_script.vim    2020-12-14 
18:31:24.062840347 +0100
--- src/testdir/test_vim9_script.vim    2020-12-19 16:27:46.256385358 +0100
***************
*** 2779,2788 ****
    quit
  enddef
  
! " test using a vim9script that is auto-loaded from an autocmd
  def Test_vim9_autoload()
    var lines =<< trim END
       vim9script
       def foo#test()
           echomsg getreg('"')
       enddef
--- 2779,2812 ----
    quit
  enddef
  
! " test using an auto-loaded function and variable
  def Test_vim9_autoload()
    var lines =<< trim END
       vim9script
+      def some#gettest(): string
+        return 'test'
+      enddef
+      g:some#name = 'name'
+   END
+ 
+   mkdir('Xdir/autoload', 'p')
+   writefile(lines, 'Xdir/autoload/some.vim')
+   var save_rtp = &rtp
+   exe 'set rtp^=' .. getcwd() .. '/Xdir'
+ 
+   assert_equal('test', g:some#gettest())
+   assert_equal('name', g:some#name)
+   g:some#other = 'other'
+   assert_equal('other', g:some#other)
+ 
+   delete('Xdir', 'rf')
+   &rtp = save_rtp
+ enddef
+ 
+ " test using a vim9script that is auto-loaded from an autocmd
+ def Test_vim9_aucmd_autoload()
+   var lines =<< trim END
+      vim9script
       def foo#test()
           echomsg getreg('"')
       enddef
***************
*** 2842,2847 ****
--- 2866,2877 ----
    delete('Xdidit')
    delete('Xscript')
    delete('Xruntime', 'rf')
+ 
+   lines =<< trim END
+     vim9script
+     var foo#bar = 'asdf'
+   END
+   CheckScriptFailure(lines, 'E461: Illegal variable name: foo#bar', 2)
  enddef
  
  def Test_script_var_in_autocmd()
*** ../vim-8.2.2161/src/version.c       2020-12-19 13:32:01.960764077 +0100
--- src/version.c       2020-12-19 16:29:38.512012925 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2162,
  /**/

-- 
If you had to identify, in one word, the reason why the
human race has not achieved, and never will achieve, its
full potential, that word would be "meetings."

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202012191531.0BJFVNcZ1591362%40masaka.moolenaar.net.

Raspunde prin e-mail lui