Patch 8.2.2223

3 views
Skip to first unread message

Bram Moolenaar

unread,
Dec 26, 2020, 11:43:55 AM12/26/20
to vim...@googlegroups.com

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 -- Br...@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 ///
Reply all
Reply to author
Forward
0 new messages