To: vim_dev@googlegroups.com Subject: Patch 8.2.2223 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 ! 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 ! 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 -- Bram@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 ///