Patch 8.2.2223
Problem:    Vim9: Reloading marks a :def function as deleted.
Solution:   Clear the function contents but keep the index.
Files:      runtime/doc/vim9.txt, src/vim9compile.c, src/userfunc.c,
            src/testdir/test_vim9_script.vim


*** ../vim-8.2.2222/runtime/doc/vim9.txt        2020-12-26 15:39:24.615550807 
+0100
--- runtime/doc/vim9.txt        2020-12-26 17:42:04.372668240 +0100
***************
*** 219,241 ****
        def g:SomeFunc()
        ....
  
- There is one gotcha: If a compiled function is replaced and it is called from
- another compiled function that is not replaced, it will try to call the
- function from before it was replaced, which no longer exists.  This doesn't
- work: >
-       vimscript noclear
- 
-       def ReplaceMe()
-         echo 'function redefined every time'
-       enddef
- 
-       if exists('s:loaded') | finish | endif
-       var s:loaded = true
- 
-       def NotReplaced()
-         ReplaceMe()  # Error if ReplaceMe() was redefined
-       enddef
- 
  
  Variable declarations with :var, :final and :const ~
                                                *vim9-declaration* *:var*
--- 219,224 ----
*** ../vim-8.2.2222/src/vim9compile.c   2020-12-25 21:56:53.412944936 +0100
--- src/vim9compile.c   2020-12-26 17:16:06.833043658 +0100
***************
*** 145,151 ****
      int               ctx_has_cmdmod;     // ISN_CMDMOD was generated
  };
  
! static void delete_def_function_contents(dfunc_T *dfunc);
  
  /*
   * Lookup variable "name" in the local scope and return it in "lvar".
--- 145,151 ----
      int               ctx_has_cmdmod;     // ISN_CMDMOD was generated
  };
  
! static void delete_def_function_contents(dfunc_T *dfunc, int mark_deleted);
  
  /*
   * Lookup variable "name" in the local scope and return it in "lvar".
***************
*** 7498,7509 ****
      int               new_def_function = FALSE;
  
      // When using a function that was compiled before: Free old instructions.
!     // Otherwise add a new entry in "def_functions".
      if (ufunc->uf_dfunc_idx > 0)
      {
        dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
                                                         + ufunc->uf_dfunc_idx;
!       delete_def_function_contents(dfunc);
      }
      else
      {
--- 7498,7509 ----
      int               new_def_function = FALSE;
  
      // When using a function that was compiled before: Free old instructions.
!     // The index is reused.  Otherwise add a new entry in "def_functions".
      if (ufunc->uf_dfunc_idx > 0)
      {
        dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
                                                         + ufunc->uf_dfunc_idx;
!       delete_def_function_contents(dfunc, FALSE);
      }
      else
      {
***************
*** 8344,8350 ****
   * Free all instructions for "dfunc" except df_name.
   */
      static void
! delete_def_function_contents(dfunc_T *dfunc)
  {
      int idx;
  
--- 8344,8350 ----
   * Free all instructions for "dfunc" except df_name.
   */
      static void
! delete_def_function_contents(dfunc_T *dfunc, int mark_deleted)
  {
      int idx;
  
***************
*** 8355,8363 ****
        for (idx = 0; idx < dfunc->df_instr_count; ++idx)
            delete_instr(dfunc->df_instr + idx);
        VIM_CLEAR(dfunc->df_instr);
      }
  
!     dfunc->df_deleted = TRUE;
  }
  
  /*
--- 8355,8367 ----
        for (idx = 0; idx < dfunc->df_instr_count; ++idx)
            delete_instr(dfunc->df_instr + idx);
        VIM_CLEAR(dfunc->df_instr);
+       dfunc->df_instr = NULL;
      }
  
!     if (mark_deleted)
!       dfunc->df_deleted = TRUE;
!     if (dfunc->df_ufunc != NULL)
!       dfunc->df_ufunc->uf_def_status = UF_NOT_COMPILED;
  }
  
  /*
***************
*** 8374,8380 ****
                                                         + ufunc->uf_dfunc_idx;
  
        if (--dfunc->df_refcount <= 0)
!           delete_def_function_contents(dfunc);
        ufunc->uf_def_status = UF_NOT_COMPILED;
        ufunc->uf_dfunc_idx = 0;
        if (dfunc->df_ufunc == ufunc)
--- 8378,8384 ----
                                                         + ufunc->uf_dfunc_idx;
  
        if (--dfunc->df_refcount <= 0)
!           delete_def_function_contents(dfunc, TRUE);
        ufunc->uf_def_status = UF_NOT_COMPILED;
        ufunc->uf_dfunc_idx = 0;
        if (dfunc->df_ufunc == ufunc)
***************
*** 8410,8416 ****
      {
        dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + idx;
  
!       delete_def_function_contents(dfunc);
        vim_free(dfunc->df_name);
      }
  
--- 8414,8420 ----
      {
        dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + idx;
  
!       delete_def_function_contents(dfunc, TRUE);
        vim_free(dfunc->df_name);
      }
  
*** ../vim-8.2.2222/src/userfunc.c      2020-12-25 22:30:13.072086418 +0100
--- src/userfunc.c      2020-12-26 17:35:33.489581892 +0100
***************
*** 3628,3634 ****
                fp->uf_profiling = FALSE;
                fp->uf_prof_initialized = FALSE;
  #endif
!               unlink_def_function(fp);
            }
        }
      }
--- 3628,3634 ----
                fp->uf_profiling = FALSE;
                fp->uf_prof_initialized = FALSE;
  #endif
!               fp->uf_def_status = UF_NOT_COMPILED;
            }
        }
      }
***************
*** 3694,3701 ****
        fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
        if (fp == NULL)
            goto erret;
-       fp->uf_def_status = eap->cmdidx == CMD_def ? UF_TO_BE_COMPILED
-                                                            : UF_NOT_COMPILED;
  
        if (fudi.fd_dict != NULL)
        {
--- 3694,3699 ----
*** ../vim-8.2.2222/src/testdir/test_vim9_script.vim    2020-12-26 
15:39:24.619550795 +0100
--- src/testdir/test_vim9_script.vim    2020-12-26 17:39:54.484991655 +0100
***************
*** 1174,1183 ****
      var s:notReloaded = 'yes'
      s:reloaded = 'first'
      def g:Values(): list<string>
!       return [s:reloaded, s:notReloaded, Once()]
!     enddef
!     def g:CallAgain(): string
!       return Again()
      enddef
  
      def Once(): string
--- 1174,1180 ----
      var s:notReloaded = 'yes'
      s:reloaded = 'first'
      def g:Values(): list<string>
!       return [s:reloaded, s:notReloaded, Again(), Once()]
      enddef
  
      def Once(): string
***************
*** 1188,1207 ****
    g:loadCount = 0
    source XReloaded
    assert_equal(1, g:loadCount)
!   assert_equal(['first', 'yes', 'once'], g:Values())
!   assert_equal('again', g:CallAgain())
    source XReloaded
    assert_equal(2, g:loadCount)
!   assert_equal(['init', 'yes', 'once'], g:Values())
!   assert_fails('call g:CallAgain()', 'E933:')
    source XReloaded
    assert_equal(3, g:loadCount)
!   assert_equal(['init', 'yes', 'once'], g:Values())
!   assert_fails('call g:CallAgain()', 'E933:')
  
    delete('Xreloaded')
    delfunc g:Values
-   delfunc g:CallAgain
    unlet g:loadCount
  enddef
  
--- 1185,1200 ----
    g:loadCount = 0
    source XReloaded
    assert_equal(1, g:loadCount)
!   assert_equal(['first', 'yes', 'again', 'once'], g:Values())
    source XReloaded
    assert_equal(2, g:loadCount)
!   assert_equal(['init', 'yes', 'again', 'once'], g:Values())
    source XReloaded
    assert_equal(3, g:loadCount)
!   assert_equal(['init', 'yes', 'again', 'once'], g:Values())
  
    delete('Xreloaded')
    delfunc g:Values
    unlet g:loadCount
  enddef
  
*** ../vim-8.2.2222/src/version.c       2020-12-26 15:39:24.619550795 +0100
--- src/version.c       2020-12-26 16:56:57.956354567 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2223,
  /**/

-- 
The startling truth finally became apparent, and it was this: Numbers
written on restaurant checks within the confines of restaurants do not follow
the same mathematical laws as numbers written on any other pieces of paper in
any other parts of the Universe.  This single statement took the scientific
world by storm.  So many mathematical conferences got held in such good
restaurants that many of the finest minds of a generation died of obesity and
heart failure, and the science of mathematics was put back by years.
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202012261643.0BQGhiU23889786%40masaka.moolenaar.net.

Raspunde prin e-mail lui