Patch 9.0.0398
Problem: Members of funccall_T are inconsistently named.
Solution: Use the "fc_" prefix for all members.
Files: src/structs.h, src/profiler.c, src/userfunc.c, src/vim9execute.c,
src/evalvars.c
*** ../vim-9.0.0397/src/structs.h 2022-09-06 18:31:09.074310277 +0100
--- src/structs.h 2022-09-06 18:53:35.296180233 +0100
***************
*** 1735,1774 ****
*/
struct funccall_S
{
! ufunc_T *func; // function being called
! int linenr; // next line to be executed
! int returned; // ":return" used
struct // fixed variables for arguments
{
dictitem_T var; // variable (without room for name)
char_u room[VAR_SHORT_LEN]; // room for the name
! } fixvar[FIXVAR_CNT];
! dict_T l_vars; // l: local function variables
! dictitem_T l_vars_var; // variable for l: scope
! dict_T l_avars; // a: argument variables
! dictitem_T l_avars_var; // variable for a: scope
! list_T l_varlist; // list for a:000
! listitem_T l_listitems[MAX_FUNC_ARGS]; // listitems for a:000
! typval_T *rettv; // return value
! linenr_T breakpoint; // next line with breakpoint or zero
! int dbg_tick; // debug_tick when breakpoint was set
! int level; // top nesting level of executed
function
garray_T fc_defer; // functions to be called on return
ectx_T *fc_ectx; // execution context for :def function, NULL
// otherwise
#ifdef FEAT_PROFILE
! proftime_T prof_child; // time spent in a child
#endif
! funccall_T *caller; // calling function or NULL; or next
funccal in
// list pointed to by previous_funccal.
// for closure
int fc_refcount; // number of user functions that
reference this
// funccal
int fc_copyID; // for garbage collection
! garray_T fc_funcs; // list of ufunc_T* which keep a reference to
// "func"
};
--- 1735,1774 ----
*/
struct funccall_S
{
! ufunc_T *fc_func; // function being called
! int fc_linenr; // next line to be executed
! int fc_returned; // ":return" used
struct // fixed variables for arguments
{
dictitem_T var; // variable (without room for name)
char_u room[VAR_SHORT_LEN]; // room for the name
! } fc_fixvar[FIXVAR_CNT];
! dict_T fc_l_vars; // l: local function variables
! dictitem_T fc_l_vars_var; // variable for l: scope
! dict_T fc_l_avars; // a: argument variables
! dictitem_T fc_l_avars_var; // variable for a: scope
! list_T fc_l_varlist; // list for a:000
! listitem_T fc_l_listitems[MAX_FUNC_ARGS]; // listitems for a:000
! typval_T *fc_rettv; // return value
! linenr_T fc_breakpoint; // next line with breakpoint or zero
! int fc_dbg_tick; // debug_tick when breakpoint was set
! int fc_level; // top nesting level of executed
function
garray_T fc_defer; // functions to be called on return
ectx_T *fc_ectx; // execution context for :def function, NULL
// otherwise
#ifdef FEAT_PROFILE
! proftime_T fc_prof_child; // time spent in a child
#endif
! funccall_T *fc_caller; // calling function or NULL; or next
funccal in
// list pointed to by previous_funccal.
// for closure
int fc_refcount; // number of user functions that
reference this
// funccal
int fc_copyID; // for garbage collection
! garray_T fc_ufuncs; // list of ufunc_T* which keep a reference to
// "func"
};
*** ../vim-9.0.0397/src/profiler.c 2022-05-28 13:38:55.000000000 +0100
--- src/profiler.c 2022-09-06 18:46:14.653046563 +0100
***************
*** 718,725 ****
{
funccall_T *fc = get_current_funccal();
! if (fc != NULL && fc->func->uf_profiling)
! profile_start(&fc->prof_child);
script_prof_save(tm);
}
--- 718,725 ----
{
funccall_T *fc = get_current_funccal();
! if (fc != NULL && fc->fc_func->uf_profiling)
! profile_start(&fc->fc_prof_child);
script_prof_save(tm);
}
***************
*** 733,744 ****
{
funccall_T *fc = get_current_funccal();
! if (fc != NULL && fc->func->uf_profiling)
{
! profile_end(&fc->prof_child);
! profile_sub_wait(tm, &fc->prof_child); // don't count waiting time
! profile_add(&fc->func->uf_tm_children, &fc->prof_child);
! profile_add(&fc->func->uf_tml_children, &fc->prof_child);
}
script_prof_restore(tm);
}
--- 733,744 ----
{
funccall_T *fc = get_current_funccal();
! if (fc != NULL && fc->fc_func->uf_profiling)
{
! profile_end(&fc->fc_prof_child);
! profile_sub_wait(tm, &fc->fc_prof_child); // don't count waiting time
! profile_add(&fc->fc_func->uf_tm_children, &fc->fc_prof_child);
! profile_add(&fc->fc_func->uf_tml_children, &fc->fc_prof_child);
}
script_prof_restore(tm);
}
***************
*** 753,759 ****
func_line_start(void *cookie, long lnum)
{
funccall_T *fcp = (funccall_T *)cookie;
! ufunc_T *fp = fcp->func;
if (fp->uf_profiling && lnum >= 1 && lnum <= fp->uf_lines.ga_len)
{
--- 753,759 ----
func_line_start(void *cookie, long lnum)
{
funccall_T *fcp = (funccall_T *)cookie;
! ufunc_T *fp = fcp->fc_func;
if (fp->uf_profiling && lnum >= 1 && lnum <= fp->uf_lines.ga_len)
{
***************
*** 775,781 ****
func_line_exec(void *cookie)
{
funccall_T *fcp = (funccall_T *)cookie;
! ufunc_T *fp = fcp->func;
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
fp->uf_tml_execed = TRUE;
--- 775,781 ----
func_line_exec(void *cookie)
{
funccall_T *fcp = (funccall_T *)cookie;
! ufunc_T *fp = fcp->fc_func;
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
fp->uf_tml_execed = TRUE;
***************
*** 788,794 ****
func_line_end(void *cookie)
{
funccall_T *fcp = (funccall_T *)cookie;
! ufunc_T *fp = fcp->func;
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
{
--- 788,794 ----
func_line_end(void *cookie)
{
funccall_T *fcp = (funccall_T *)cookie;
! ufunc_T *fp = fcp->fc_func;
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
{
*** ../vim-9.0.0397/src/userfunc.c 2022-09-06 18:31:09.070310282 +0100
--- src/userfunc.c 2022-09-06 18:54:28.732071228 +0100
***************
*** 499,508 ****
fp->uf_scoped = current_funccal;
current_funccal->fc_refcount++;
! if (ga_grow(¤t_funccal->fc_funcs, 1) == FAIL)
return FAIL;
! ((ufunc_T **)current_funccal->fc_funcs.ga_data)
! [current_funccal->fc_funcs.ga_len++] = fp;
return OK;
}
--- 499,508 ----
fp->uf_scoped = current_funccal;
current_funccal->fc_refcount++;
! if (ga_grow(¤t_funccal->fc_ufuncs, 1) == FAIL)
return FAIL;
! ((ufunc_T **)current_funccal->fc_ufuncs.ga_data)
! [current_funccal->fc_ufuncs.ga_len++] = fp;
return OK;
}
***************
*** 2141,2149 ****
{
int i;
! for (i = 0; i < fc->fc_funcs.ga_len; ++i)
{
! ufunc_T *fp = ((ufunc_T **)(fc->fc_funcs.ga_data))[i];
// When garbage collecting a funccall_T may be freed before the
// function that references it, clear its uf_scoped field.
--- 2141,2149 ----
{
int i;
! for (i = 0; i < fc->fc_ufuncs.ga_len; ++i)
{
! ufunc_T *fp = ((ufunc_T **)(fc->fc_ufuncs.ga_data))[i];
// When garbage collecting a funccall_T may be freed before the
// function that references it, clear its uf_scoped field.
***************
*** 2152,2160 ****
if (fp != NULL && fp->uf_scoped == fc)
fp->uf_scoped = NULL;
}
! ga_clear(&fc->fc_funcs);
! func_ptr_unref(fc->func);
vim_free(fc);
}
--- 2152,2160 ----
if (fp != NULL && fp->uf_scoped == fc)
fp->uf_scoped = NULL;
}
! ga_clear(&fc->fc_ufuncs);
! func_ptr_unref(fc->fc_func);
vim_free(fc);
}
***************
*** 2169,2181 ****
listitem_T *li;
// Free all l: variables.
! vars_clear(&fc->l_vars.dv_hashtab);
// Free all a: variables.
! vars_clear(&fc->l_avars.dv_hashtab);
// Free the a:000 variables.
! FOR_ALL_LIST_ITEMS(&fc->l_varlist, li)
clear_tv(&li->li_tv);
free_funccal(fc);
--- 2169,2181 ----
listitem_T *li;
// Free all l: variables.
! vars_clear(&fc->fc_l_vars.dv_hashtab);
// Free all a: variables.
! vars_clear(&fc->fc_l_avars.dv_hashtab);
// Free the a:000 variables.
! FOR_ALL_LIST_ITEMS(&fc->fc_l_varlist, li)
clear_tv(&li->li_tv);
free_funccal(fc);
***************
*** 2191,2209 ****
int may_free_fc = fc->fc_refcount <= 0;
int free_fc = TRUE;
! current_funccal = fc->caller;
// Free all l: variables if not referred.
! if (may_free_fc && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT)
! vars_clear(&fc->l_vars.dv_hashtab);
else
free_fc = FALSE;
// If the a:000 list and the l: and a: dicts are not referenced and
// there is no closure using it, we can free the funccall_T and what's
// in it.
! if (may_free_fc && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
! vars_clear_ext(&fc->l_avars.dv_hashtab, FALSE);
else
{
int todo;
--- 2191,2209 ----
int may_free_fc = fc->fc_refcount <= 0;
int free_fc = TRUE;
! current_funccal = fc->fc_caller;
// Free all l: variables if not referred.
! if (may_free_fc && fc->fc_l_vars.dv_refcount == DO_NOT_FREE_CNT)
! vars_clear(&fc->fc_l_vars.dv_hashtab);
else
free_fc = FALSE;
// If the a:000 list and the l: and a: dicts are not referenced and
// there is no closure using it, we can free the funccall_T and what's
// in it.
! if (may_free_fc && fc->fc_l_avars.dv_refcount == DO_NOT_FREE_CNT)
! vars_clear_ext(&fc->fc_l_avars.dv_hashtab, FALSE);
else
{
int todo;
***************
*** 2213,2220 ****
free_fc = FALSE;
// Make a copy of the a: variables, since we didn't do that above.
! todo = (int)fc->l_avars.dv_hashtab.ht_used;
! for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
{
if (!HASHITEM_EMPTY(hi))
{
--- 2213,2220 ----
free_fc = FALSE;
// Make a copy of the a: variables, since we didn't do that above.
! todo = (int)fc->fc_l_avars.dv_hashtab.ht_used;
! for (hi = fc->fc_l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
{
if (!HASHITEM_EMPTY(hi))
{
***************
*** 2225,2232 ****
}
}
! if (may_free_fc && fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT)
! fc->l_varlist.lv_first = NULL;
else
{
listitem_T *li;
--- 2225,2232 ----
}
}
! if (may_free_fc && fc->fc_l_varlist.lv_refcount == DO_NOT_FREE_CNT)
! fc->fc_l_varlist.lv_first = NULL;
else
{
listitem_T *li;
***************
*** 2234,2240 ****
free_fc = FALSE;
// Make a copy of the a:000 items, since we didn't do that above.
! FOR_ALL_LIST_ITEMS(&fc->l_varlist, li)
copy_tv(&li->li_tv, &li->li_tv);
}
--- 2234,2240 ----
free_fc = FALSE;
// Make a copy of the a:000 items, since we didn't do that above.
! FOR_ALL_LIST_ITEMS(&fc->fc_l_varlist, li)
copy_tv(&li->li_tv, &li->li_tv);
}
***************
*** 2247,2253 ****
// "fc" is still in use. This can happen when returning "a:000",
// assigning "l:" to a global variable or defining a closure.
// Link "fc" in the list for garbage collection later.
! fc->caller = previous_funccal;
previous_funccal = fc;
if (want_garbage_collect)
--- 2247,2253 ----
// "fc" is still in use. This can happen when returning "a:000",
// assigning "l:" to a global variable or defining a closure.
// Link "fc" in the list for garbage collection later.
! fc->fc_caller = previous_funccal;
previous_funccal = fc;
if (want_garbage_collect)
***************
*** 2305,2325 ****
return;
if (--fc->fc_refcount <= 0 && (force || (
! fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
! && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
! && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)))
! for (pfc = &previous_funccal; *pfc != NULL; pfc = &(*pfc)->caller)
{
if (fc == *pfc)
{
! *pfc = fc->caller;
free_funccal_contents(fc);
return;
}
}
! for (i = 0; i < fc->fc_funcs.ga_len; ++i)
! if (((ufunc_T **)(fc->fc_funcs.ga_data))[i] == fp)
! ((ufunc_T **)(fc->fc_funcs.ga_data))[i] = NULL;
}
/*
--- 2305,2325 ----
return;
if (--fc->fc_refcount <= 0 && (force || (
! fc->fc_l_varlist.lv_refcount == DO_NOT_FREE_CNT
! && fc->fc_l_vars.dv_refcount == DO_NOT_FREE_CNT
! && fc->fc_l_avars.dv_refcount == DO_NOT_FREE_CNT)))
! for (pfc = &previous_funccal; *pfc != NULL; pfc = &(*pfc)->fc_caller)
{
if (fc == *pfc)
{
! *pfc = fc->fc_caller;
free_funccal_contents(fc);
return;
}
}
! for (i = 0; i < fc->fc_ufuncs.ga_len; ++i)
! if (((ufunc_T **)(fc->fc_ufuncs.ga_data))[i] == fp)
! ((ufunc_T **)(fc->fc_ufuncs.ga_data))[i] = NULL;
}
/*
***************
*** 2599,2605 ****
int save_did_emsg;
int default_arg_err = FALSE;
dictitem_T *v;
! int fixvar_idx = 0; // index in fixvar[]
int i;
int ai;
int islambda = FALSE;
--- 2599,2605 ----
int save_did_emsg;
int default_arg_err = FALSE;
dictitem_T *v;
! int fixvar_idx = 0; // index in fc_fixvar[]
int i;
int ai;
int islambda = FALSE;
***************
*** 2629,2650 ****
fc = ALLOC_CLEAR_ONE(funccall_T);
if (fc == NULL)
return;
! fc->caller = current_funccal;
current_funccal = fc;
! fc->func = fp;
! fc->rettv = rettv;
! fc->level = ex_nesting_level;
// Check if this function has a breakpoint.
! fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
! fc->dbg_tick = debug_tick;
// Set up fields for closure.
! ga_init2(&fc->fc_funcs, sizeof(ufunc_T *), 1);
func_ptr_ref(fp);
if (fp->uf_def_status != UF_NOT_COMPILED)
{
#ifdef FEAT_PROFILE
! ufunc_T *caller = fc->caller == NULL ? NULL : fc->caller->func;
#endif
// Execute the function, possibly compiling it first.
#ifdef FEAT_PROFILE
--- 2629,2650 ----
fc = ALLOC_CLEAR_ONE(funccall_T);
if (fc == NULL)
return;
! fc->fc_caller = current_funccal;
current_funccal = fc;
! fc->fc_func = fp;
! fc->fc_rettv = rettv;
! fc->fc_level = ex_nesting_level;
// Check if this function has a breakpoint.
! fc->fc_breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
! fc->fc_dbg_tick = debug_tick;
// Set up fields for closure.
! ga_init2(&fc->fc_ufuncs, sizeof(ufunc_T *), 1);
func_ptr_ref(fp);
if (fp->uf_def_status != UF_NOT_COMPILED)
{
#ifdef FEAT_PROFILE
! ufunc_T *caller = fc->fc_caller == NULL ? NULL : fc->fc_caller->fc_func;
#endif
// Execute the function, possibly compiling it first.
#ifdef FEAT_PROFILE
***************
*** 2660,2666 ****
|| (caller != NULL && caller->uf_profiling)))
profile_may_end_func(&profile_info, fp, caller);
#endif
! current_funccal = fc->caller;
free_funccal(fc);
sticky_cmdmod_flags = save_sticky_cmdmod_flags;
return;
--- 2660,2666 ----
|| (caller != NULL && caller->uf_profiling)))
profile_may_end_func(&profile_info, fp, caller);
#endif
! current_funccal = fc->fc_caller;
free_funccal(fc);
sticky_cmdmod_flags = save_sticky_cmdmod_flags;
return;
***************
*** 2669,2691 ****
islambda = fp->uf_flags & FC_LAMBDA;
/*
! * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
* with names up to VAR_SHORT_LEN long. This avoids having to alloc/free
* each argument variable and saves a lot of time.
*/
/*
* Init l: variables.
*/
! init_var_dict(&fc->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE);
if (selfdict != NULL)
{
// Set l:self to "selfdict". Use "name" to avoid a warning from
// some compiler that checks the destination size.
! v = &fc->fixvar[fixvar_idx++].var;
name = v->di_key;
STRCPY(name, "self");
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
! hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v));
v->di_tv.v_type = VAR_DICT;
v->di_tv.v_lock = 0;
v->di_tv.vval.v_dict = selfdict;
--- 2669,2691 ----
islambda = fp->uf_flags & FC_LAMBDA;
/*
! * Note about using fc->fc_fixvar[]: This is an array of FIXVAR_CNT
variables
* with names up to VAR_SHORT_LEN long. This avoids having to alloc/free
* each argument variable and saves a lot of time.
*/
/*
* Init l: variables.
*/
! init_var_dict(&fc->fc_l_vars, &fc->fc_l_vars_var, VAR_DEF_SCOPE);
if (selfdict != NULL)
{
// Set l:self to "selfdict". Use "name" to avoid a warning from
// some compiler that checks the destination size.
! v = &fc->fc_fixvar[fixvar_idx++].var;
name = v->di_key;
STRCPY(name, "self");
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
! hash_add(&fc->fc_l_vars.dv_hashtab, DI2HIKEY(v));
v->di_tv.v_type = VAR_DICT;
v->di_tv.v_lock = 0;
v->di_tv.vval.v_dict = selfdict;
***************
*** 2697,2724 ****
* Set a:0 to "argcount" less number of named arguments, if >= 0.
* Set a:000 to a list with room for the "..." arguments.
*/
! init_var_dict(&fc->l_avars, &fc->l_avars_var, VAR_SCOPE);
if ((fp->uf_flags & FC_NOARGS) == 0)
! add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0",
(varnumber_T)(argcount >= fp->uf_args.ga_len
? argcount - fp->uf_args.ga_len : 0));
! fc->l_avars.dv_lock = VAR_FIXED;
if ((fp->uf_flags & FC_NOARGS) == 0)
{
// Use "name" to avoid a warning from some compiler that checks the
// destination size.
! v = &fc->fixvar[fixvar_idx++].var;
name = v->di_key;
STRCPY(name, "000");
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
! hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
v->di_tv.v_type = VAR_LIST;
v->di_tv.v_lock = VAR_FIXED;
! v->di_tv.vval.v_list = &fc->l_varlist;
}
! CLEAR_FIELD(fc->l_varlist);
! fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT;
! fc->l_varlist.lv_lock = VAR_FIXED;
/*
* Set a:firstline to "firstline" and a:lastline to "lastline".
--- 2697,2724 ----
* Set a:0 to "argcount" less number of named arguments, if >= 0.
* Set a:000 to a list with room for the "..." arguments.
*/
! init_var_dict(&fc->fc_l_avars, &fc->fc_l_avars_var, VAR_SCOPE);
if ((fp->uf_flags & FC_NOARGS) == 0)
! add_nr_var(&fc->fc_l_avars, &fc->fc_fixvar[fixvar_idx++].var, "0",
(varnumber_T)(argcount >= fp->uf_args.ga_len
? argcount - fp->uf_args.ga_len : 0));
! fc->fc_l_avars.dv_lock = VAR_FIXED;
if ((fp->uf_flags & FC_NOARGS) == 0)
{
// Use "name" to avoid a warning from some compiler that checks the
// destination size.
! v = &fc->fc_fixvar[fixvar_idx++].var;
name = v->di_key;
STRCPY(name, "000");
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
! hash_add(&fc->fc_l_avars.dv_hashtab, DI2HIKEY(v));
v->di_tv.v_type = VAR_LIST;
v->di_tv.v_lock = VAR_FIXED;
! v->di_tv.vval.v_list = &fc->fc_l_varlist;
}
! CLEAR_FIELD(fc->fc_l_varlist);
! fc->fc_l_varlist.lv_refcount = DO_NOT_FREE_CNT;
! fc->fc_l_varlist.lv_lock = VAR_FIXED;
/*
* Set a:firstline to "firstline" and a:lastline to "lastline".
***************
*** 2728,2737 ****
*/
if ((fp->uf_flags & FC_NOARGS) == 0)
{
! add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline",
! (varnumber_T)funcexe->fe_firstline);
! add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline",
! (varnumber_T)funcexe->fe_lastline);
}
for (i = 0; i < argcount || i < fp->uf_args.ga_len; ++i)
{
--- 2728,2737 ----
*/
if ((fp->uf_flags & FC_NOARGS) == 0)
{
! add_nr_var(&fc->fc_l_avars, &fc->fc_fixvar[fixvar_idx++].var,
! "firstline", (varnumber_T)funcexe->fe_firstline);
! add_nr_var(&fc->fc_l_avars, &fc->fc_fixvar[fixvar_idx++].var,
! "lastline", (varnumber_T)funcexe->fe_lastline);
}
for (i = 0; i < argcount || i < fp->uf_args.ga_len; ++i)
{
***************
*** 2779,2785 ****
}
if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN)
{
! v = &fc->fixvar[fixvar_idx++].var;
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
STRCPY(v->di_key, name);
}
--- 2779,2785 ----
}
if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN)
{
! v = &fc->fc_fixvar[fixvar_idx++].var;
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
STRCPY(v->di_key, name);
}
***************
*** 2805,2822 ****
// Named arguments should be accessed without the "a:" prefix in
// lambda expressions. Add to the l: dict.
copy_tv(&v->di_tv, &v->di_tv);
! hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v));
}
else
! hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
if (ai >= 0 && ai < MAX_FUNC_ARGS)
{
! listitem_T *li = &fc->l_listitems[ai];
li->li_tv = argvars[i];
li->li_tv.v_lock = VAR_FIXED;
! list_append(&fc->l_varlist, li);
}
}
--- 2805,2822 ----
// Named arguments should be accessed without the "a:" prefix in
// lambda expressions. Add to the l: dict.
copy_tv(&v->di_tv, &v->di_tv);
! hash_add(&fc->fc_l_vars.dv_hashtab, DI2HIKEY(v));
}
else
! hash_add(&fc->fc_l_avars.dv_hashtab, DI2HIKEY(v));
if (ai >= 0 && ai < MAX_FUNC_ARGS)
{
! listitem_T *li = &fc->fc_l_listitems[ai];
li->li_tv = argvars[i];
li->li_tv.v_lock = VAR_FIXED;
! list_append(&fc->fc_l_varlist, li);
}
}
***************
*** 2879,2885 ****
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
profile_may_start_func(&profile_info, fp,
! fc->caller == NULL ? NULL : fc->caller->func);
#endif
// "legacy" does not apply to commands in the function
--- 2879,2885 ----
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
profile_may_start_func(&profile_info, fp,
! fc->fc_caller == NULL ? NULL : fc->fc_caller->fc_func);
#endif
// "legacy" does not apply to commands in the function
***************
*** 2923,2929 ****
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
{
! ufunc_T *caller = fc->caller == NULL ? NULL : fc->caller->func;
if (fp->uf_profiling || (caller != NULL && caller->uf_profiling))
profile_may_end_func(&profile_info, fp, caller);
--- 2923,2929 ----
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
{
! ufunc_T *caller = fc->fc_caller == NULL ? NULL : fc->fc_caller->fc_func;
if (fp->uf_profiling || (caller != NULL && caller->uf_profiling))
profile_may_end_func(&profile_info, fp, caller);
***************
*** 2938,2946 ****
if (aborting())
smsg(_("%s aborted"), SOURCING_NAME);
! else if (fc->rettv->v_type == VAR_NUMBER)
smsg(_("%s returning #%ld"), SOURCING_NAME,
! (long)fc->rettv->vval.v_number);
else
{
char_u buf[MSG_BUF_LEN];
--- 2938,2946 ----
if (aborting())
smsg(_("%s aborted"), SOURCING_NAME);
! else if (fc->fc_rettv->v_type == VAR_NUMBER)
smsg(_("%s returning #%ld"), SOURCING_NAME,
! (long)fc->fc_rettv->vval.v_number);
else
{
char_u buf[MSG_BUF_LEN];
***************
*** 2952,2958 ****
// have some idea how it starts and ends. smsg() would always
// truncate it at the end. Don't want errors such as E724 here.
++emsg_off;
! s = tv2string(fc->rettv, &tofree, numbuf2, 0);
--emsg_off;
if (s != NULL)
{
--- 2952,2958 ----
// have some idea how it starts and ends. smsg() would always
// truncate it at the end. Don't want errors such as E724 here.
++emsg_off;
! s = tv2string(fc->fc_rettv, &tofree, numbuf2, 0);
--emsg_off;
if (s != NULL)
{
***************
*** 3188,3194 ****
// Clean up the current_funccal chain and the funccal stack.
while (current_funccal != NULL)
{
! clear_tv(current_funccal->rettv);
cleanup_function_call(current_funccal);
if (current_funccal == NULL && funccal_stack != NULL)
restore_funccal();
--- 3188,3194 ----
// Clean up the current_funccal chain and the funccal stack.
while (current_funccal != NULL)
{
! clear_tv(current_funccal->fc_rettv);
cleanup_function_call(current_funccal);
if (current_funccal == NULL && funccal_stack != NULL)
restore_funccal();
***************
*** 5418,5426 ****
static int
can_free_funccal(funccall_T *fc, int copyID)
{
! return (fc->l_varlist.lv_copyID != copyID
! && fc->l_vars.dv_copyID != copyID
! && fc->l_avars.dv_copyID != copyID
&& fc->fc_copyID != copyID);
}
--- 5418,5426 ----
static int
can_free_funccal(funccall_T *fc, int copyID)
{
! return (fc->fc_l_varlist.lv_copyID != copyID
! && fc->fc_l_vars.dv_copyID != copyID
! && fc->fc_l_avars.dv_copyID != copyID
&& fc->fc_copyID != copyID);
}
***************
*** 5696,5702 ****
{
funccall_T *funccal;
! for (funccal = current_funccal; funccal != NULL; funccal =
funccal->caller)
if (funccal->fc_ectx != NULL)
{
// :def function
--- 5696,5703 ----
{
funccall_T *funccal;
! for (funccal = current_funccal; funccal != NULL;
! funccal = funccal->fc_caller)
if (funccal->fc_ectx != NULL)
{
// :def function
***************
*** 5849,5855 ****
if (reanimate)
// Undo the return.
! current_funccal->returned = FALSE;
/*
* Cleanup (and inactivate) conditionals, but stop when a try conditional
--- 5850,5856 ----
if (reanimate)
// Undo the return.
! current_funccal->fc_returned = FALSE;
/*
* Cleanup (and inactivate) conditionals, but stop when a try conditional
***************
*** 5872,5878 ****
// When undoing a return in order to make it pending, get the stored
// return rettv.
if (reanimate)
! rettv = current_funccal->rettv;
if (rettv != NULL)
{
--- 5873,5879 ----
// When undoing a return in order to make it pending, get the stored
// return rettv.
if (reanimate)
! rettv = current_funccal->fc_rettv;
if (rettv != NULL)
{
***************
*** 5890,5912 ****
// The pending return value could be overwritten by a ":return"
// without argument in a finally clause; reset the default
// return value.
! current_funccal->rettv->v_type = VAR_NUMBER;
! current_funccal->rettv->vval.v_number = 0;
}
}
report_make_pending(CSTP_RETURN, rettv);
}
else
{
! current_funccal->returned = TRUE;
// If the return is carried out now, store the return value. For
// a return immediately after reanimation, the value is already
// there.
if (!reanimate && rettv != NULL)
{
! clear_tv(current_funccal->rettv);
! *current_funccal->rettv = *(typval_T *)rettv;
if (!is_cmd)
vim_free(rettv);
}
--- 5891,5913 ----
// The pending return value could be overwritten by a ":return"
// without argument in a finally clause; reset the default
// return value.
! current_funccal->fc_rettv->v_type = VAR_NUMBER;
! current_funccal->fc_rettv->vval.v_number = 0;
}
}
report_make_pending(CSTP_RETURN, rettv);
}
else
{
! current_funccal->fc_returned = TRUE;
// If the return is carried out now, store the return value. For
// a return immediately after reanimation, the value is already
// there.
if (!reanimate && rettv != NULL)
{
! clear_tv(current_funccal->fc_rettv);
! *current_funccal->fc_rettv = *(typval_T *)rettv;
if (!is_cmd)
vim_free(rettv);
}
***************
*** 5961,5976 ****
getline_opt_T options UNUSED)
{
funccall_T *fcp = (funccall_T *)cookie;
! ufunc_T *fp = fcp->func;
char_u *retval;
garray_T *gap; // growarray with function lines
// If breakpoints have been added/deleted need to check for it.
! if (fcp->dbg_tick != debug_tick)
{
! fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
SOURCING_LNUM);
! fcp->dbg_tick = debug_tick;
}
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
--- 5962,5977 ----
getline_opt_T options UNUSED)
{
funccall_T *fcp = (funccall_T *)cookie;
! ufunc_T *fp = fcp->fc_func;
char_u *retval;
garray_T *gap; // growarray with function lines
// If breakpoints have been added/deleted need to check for it.
! if (fcp->fc_dbg_tick != debug_tick)
{
! fcp->fc_breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
SOURCING_LNUM);
! fcp->fc_dbg_tick = debug_tick;
}
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
***************
*** 5979,5998 ****
gap = &fp->uf_lines;
if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
! || fcp->returned)
retval = NULL;
else
{
// Skip NULL lines (continuation lines).
! while (fcp->linenr < gap->ga_len
! && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL)
! ++fcp->linenr;
! if (fcp->linenr >= gap->ga_len)
retval = NULL;
else
{
! retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
! SOURCING_LNUM = fcp->linenr;
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
func_line_start(cookie, SOURCING_LNUM);
--- 5980,5999 ----
gap = &fp->uf_lines;
if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
! || fcp->fc_returned)
retval = NULL;
else
{
// Skip NULL lines (continuation lines).
! while (fcp->fc_linenr < gap->ga_len
! && ((char_u **)(gap->ga_data))[fcp->fc_linenr] == NULL)
! ++fcp->fc_linenr;
! if (fcp->fc_linenr >= gap->ga_len)
retval = NULL;
else
{
! retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->fc_linenr++]);
! SOURCING_LNUM = fcp->fc_linenr;
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
func_line_start(cookie, SOURCING_LNUM);
***************
*** 6001,6013 ****
}
// Did we encounter a breakpoint?
! if (fcp->breakpoint != 0 && fcp->breakpoint <= SOURCING_LNUM)
{
dbg_breakpoint(fp->uf_name, SOURCING_LNUM);
// Find next breakpoint.
! fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
SOURCING_LNUM);
! fcp->dbg_tick = debug_tick;
}
return retval;
--- 6002,6014 ----
}
// Did we encounter a breakpoint?
! if (fcp->fc_breakpoint != 0 && fcp->fc_breakpoint <= SOURCING_LNUM)
{
dbg_breakpoint(fp->uf_name, SOURCING_LNUM);
// Find next breakpoint.
! fcp->fc_breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
SOURCING_LNUM);
! fcp->fc_dbg_tick = debug_tick;
}
return retval;
***************
*** 6024,6031 ****
// Ignore the "abort" flag if the abortion behavior has been changed due
to
// an error inside a try conditional.
! return (((fcp->func->uf_flags & FC_ABORT) && did_emsg &&
!aborted_in_try())
! || fcp->returned);
}
/*
--- 6025,6033 ----
// Ignore the "abort" flag if the abortion behavior has been changed due
to
// an error inside a try conditional.
! return (((fcp->fc_func->uf_flags & FC_ABORT)
! && did_emsg && !aborted_in_try())
! || fcp->fc_returned);
}
/*
***************
*** 6035,6041 ****
func_has_abort(
void *cookie)
{
! return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT;
}
--- 6037,6043 ----
func_has_abort(
void *cookie)
{
! return ((funccall_T *)cookie)->fc_func->uf_flags & FC_ABORT;
}
***************
*** 6143,6149 ****
char_u *
func_name(void *cookie)
{
! return ((funccall_T *)cookie)->func->uf_name;
}
/*
--- 6145,6151 ----
char_u *
func_name(void *cookie)
{
! return ((funccall_T *)cookie)->fc_func->uf_name;
}
/*
***************
*** 6152,6158 ****
linenr_T *
func_breakpoint(void *cookie)
{
! return &((funccall_T *)cookie)->breakpoint;
}
/*
--- 6154,6160 ----
linenr_T *
func_breakpoint(void *cookie)
{
! return &((funccall_T *)cookie)->fc_breakpoint;
}
/*
***************
*** 6161,6167 ****
int *
func_dbg_tick(void *cookie)
{
! return &((funccall_T *)cookie)->dbg_tick;
}
/*
--- 6163,6169 ----
int *
func_dbg_tick(void *cookie)
{
! return &((funccall_T *)cookie)->fc_dbg_tick;
}
/*
***************
*** 6170,6176 ****
int
func_level(void *cookie)
{
! return ((funccall_T *)cookie)->level;
}
/*
--- 6172,6178 ----
int
func_level(void *cookie)
{
! return ((funccall_T *)cookie)->fc_level;
}
/*
***************
*** 6179,6185 ****
int
current_func_returned(void)
{
! return current_funccal->returned;
}
int
--- 6181,6187 ----
int
current_func_returned(void)
{
! return current_funccal->fc_returned;
}
int
***************
*** 6194,6206 ****
if (can_free_funccal(*pfc, copyID))
{
fc = *pfc;
! *pfc = fc->caller;
free_funccal_contents(fc);
did_free = TRUE;
did_free_funccal = TRUE;
}
else
! pfc = &(*pfc)->caller;
}
if (did_free_funccal)
// When a funccal was freed some more items might be garbage
--- 6196,6208 ----
if (can_free_funccal(*pfc, copyID))
{
fc = *pfc;
! *pfc = fc->fc_caller;
free_funccal_contents(fc);
did_free = TRUE;
did_free_funccal = TRUE;
}
else
! pfc = &(*pfc)->fc_caller;
}
if (did_free_funccal)
// When a funccal was freed some more items might be garbage
***************
*** 6225,6231 ****
{
for (i = 0; i < debug_backtrace_level; i++)
{
! temp_funccal = funccal->caller;
if (temp_funccal)
funccal = temp_funccal;
else
--- 6227,6233 ----
{
for (i = 0; i < debug_backtrace_level; i++)
{
! temp_funccal = funccal->fc_caller;
if (temp_funccal)
funccal = temp_funccal;
else
***************
*** 6243,6251 ****
hashtab_T *
get_funccal_local_ht()
{
! if (current_funccal == NULL || current_funccal->l_vars.dv_refcount == 0)
return NULL;
! return &get_funccal()->l_vars.dv_hashtab;
}
/*
--- 6245,6253 ----
hashtab_T *
get_funccal_local_ht()
{
! if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount ==
0)
return NULL;
! return &get_funccal()->fc_l_vars.dv_hashtab;
}
/*
***************
*** 6255,6263 ****
dictitem_T *
get_funccal_local_var()
{
! if (current_funccal == NULL || current_funccal->l_vars.dv_refcount == 0)
return NULL;
! return &get_funccal()->l_vars_var;
}
/*
--- 6257,6265 ----
dictitem_T *
get_funccal_local_var()
{
! if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount ==
0)
return NULL;
! return &get_funccal()->fc_l_vars_var;
}
/*
***************
*** 6267,6275 ****
hashtab_T *
get_funccal_args_ht()
{
! if (current_funccal == NULL || current_funccal->l_vars.dv_refcount == 0)
return NULL;
! return &get_funccal()->l_avars.dv_hashtab;
}
/*
--- 6269,6277 ----
hashtab_T *
get_funccal_args_ht()
{
! if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount ==
0)
return NULL;
! return &get_funccal()->fc_l_avars.dv_hashtab;
}
/*
***************
*** 6279,6287 ****
dictitem_T *
get_funccal_args_var()
{
! if (current_funccal == NULL || current_funccal->l_vars.dv_refcount == 0)
return NULL;
! return &get_funccal()->l_avars_var;
}
/*
--- 6281,6289 ----
dictitem_T *
get_funccal_args_var()
{
! if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount ==
0)
return NULL;
! return &get_funccal()->fc_l_avars_var;
}
/*
***************
*** 6290,6297 ****
void
list_func_vars(int *first)
{
! if (current_funccal != NULL && current_funccal->l_vars.dv_refcount > 0)
! list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab,
"l:", FALSE, first);
}
--- 6292,6299 ----
void
list_func_vars(int *first)
{
! if (current_funccal != NULL && current_funccal->fc_l_vars.dv_refcount > 0)
! list_hashtable_vars(¤t_funccal->fc_l_vars.dv_hashtab,
"l:", FALSE, first);
}
***************
*** 6304,6311 ****
get_current_funccal_dict(hashtab_T *ht)
{
if (current_funccal != NULL
! && ht == ¤t_funccal->l_vars.dv_hashtab)
! return ¤t_funccal->l_vars;
return NULL;
}
--- 6306,6313 ----
get_current_funccal_dict(hashtab_T *ht)
{
if (current_funccal != NULL
! && ht == ¤t_funccal->fc_l_vars.dv_hashtab)
! return ¤t_funccal->fc_l_vars;
return NULL;
}
***************
*** 6320,6330 ****
hashitem_T *hi = NULL;
char_u *varname;
! if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL)
return NULL;
// Search in parent scope, which can be referenced from a lambda.
! current_funccal = current_funccal->func->uf_scoped;
while (current_funccal != NULL)
{
ht = find_var_ht(name, &varname);
--- 6322,6332 ----
hashitem_T *hi = NULL;
char_u *varname;
! if (current_funccal == NULL || current_funccal->fc_func->uf_scoped ==
NULL)
return NULL;
// Search in parent scope, which can be referenced from a lambda.
! current_funccal = current_funccal->fc_func->uf_scoped;
while (current_funccal != NULL)
{
ht = find_var_ht(name, &varname);
***************
*** 6337,6345 ****
break;
}
}
! if (current_funccal == current_funccal->func->uf_scoped)
break;
! current_funccal = current_funccal->func->uf_scoped;
}
current_funccal = old_current_funccal;
--- 6339,6347 ----
break;
}
}
! if (current_funccal == current_funccal->fc_func->uf_scoped)
break;
! current_funccal = current_funccal->fc_func->uf_scoped;
}
current_funccal = old_current_funccal;
***************
*** 6357,6367 ****
hashtab_T *ht;
char_u *varname;
! if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL)
return NULL;
// Search in parent scope which is possible to reference from lambda
! current_funccal = current_funccal->func->uf_scoped;
while (current_funccal)
{
ht = find_var_ht(name, &varname);
--- 6359,6369 ----
hashtab_T *ht;
char_u *varname;
! if (current_funccal == NULL || current_funccal->fc_func->uf_scoped ==
NULL)
return NULL;
// Search in parent scope which is possible to reference from lambda
! current_funccal = current_funccal->fc_func->uf_scoped;
while (current_funccal)
{
ht = find_var_ht(name, &varname);
***************
*** 6371,6379 ****
if (v != NULL)
break;
}
! if (current_funccal == current_funccal->func->uf_scoped)
break;
! current_funccal = current_funccal->func->uf_scoped;
}
current_funccal = old_current_funccal;
--- 6373,6381 ----
if (v != NULL)
break;
}
! if (current_funccal == current_funccal->fc_func->uf_scoped)
break;
! current_funccal = current_funccal->fc_func->uf_scoped;
}
current_funccal = old_current_funccal;
***************
*** 6388,6399 ****
{
funccall_T *fc;
! for (fc = previous_funccal; fc != NULL; fc = fc->caller)
{
fc->fc_copyID = copyID + 1;
! if (set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL)
! || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL)
! || set_ref_in_list_items(&fc->l_varlist, copyID + 1, NULL))
return TRUE;
}
return FALSE;
--- 6390,6401 ----
{
funccall_T *fc;
! for (fc = previous_funccal; fc != NULL; fc = fc->fc_caller)
{
fc->fc_copyID = copyID + 1;
! if (set_ref_in_ht(&fc->fc_l_vars.dv_hashtab, copyID + 1, NULL)
! || set_ref_in_ht(&fc->fc_l_avars.dv_hashtab, copyID + 1, NULL)
! || set_ref_in_list_items(&fc->fc_l_varlist, copyID + 1, NULL))
return TRUE;
}
return FALSE;
***************
*** 6405,6414 ****
if (fc->fc_copyID != copyID)
{
fc->fc_copyID = copyID;
! if (set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL)
! || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL)
! || set_ref_in_list_items(&fc->l_varlist, copyID, NULL)
! || set_ref_in_func(NULL, fc->func, copyID))
return TRUE;
}
return FALSE;
--- 6407,6416 ----
if (fc->fc_copyID != copyID)
{
fc->fc_copyID = copyID;
! if (set_ref_in_ht(&fc->fc_l_vars.dv_hashtab, copyID, NULL)
! || set_ref_in_ht(&fc->fc_l_avars.dv_hashtab, copyID, NULL)
! || set_ref_in_list_items(&fc->fc_l_varlist, copyID, NULL)
! || set_ref_in_func(NULL, fc->fc_func, copyID))
return TRUE;
}
return FALSE;
***************
*** 6423,6435 ****
funccall_T *fc;
funccal_entry_T *entry;
! for (fc = current_funccal; fc != NULL; fc = fc->caller)
if (set_ref_in_funccal(fc, copyID))
return TRUE;
// Also go through the funccal_stack.
for (entry = funccal_stack; entry != NULL; entry = entry->next)
! for (fc = entry->top_funccal; fc != NULL; fc = fc->caller)
if (set_ref_in_funccal(fc, copyID))
return TRUE;
return FALSE;
--- 6425,6437 ----
funccall_T *fc;
funccal_entry_T *entry;
! for (fc = current_funccal; fc != NULL; fc = fc->fc_caller)
if (set_ref_in_funccal(fc, copyID))
return TRUE;
// Also go through the funccal_stack.
for (entry = funccal_stack; entry != NULL; entry = entry->next)
! for (fc = entry->top_funccal; fc != NULL; fc = fc->fc_caller)
if (set_ref_in_funccal(fc, copyID))
return TRUE;
return FALSE;
***************
*** 6500,6506 ****
}
if (fp != NULL)
{
! for (fc = fp->uf_scoped; fc != NULL; fc = fc->func->uf_scoped)
abort = abort || set_ref_in_funccal(fc, copyID);
}
--- 6502,6508 ----
}
if (fp != NULL)
{
! for (fc = fp->uf_scoped; fc != NULL; fc = fc->fc_func->uf_scoped)
abort = abort || set_ref_in_funccal(fc, copyID);
}
*** ../vim-9.0.0397/src/vim9execute.c 2022-09-06 18:31:09.070310282 +0100
--- src/vim9execute.c 2022-09-06 18:39:30.633746431 +0100
***************
*** 5080,5091 ****
case ISN_PROF_END:
{
#ifdef FEAT_PROFILE
! funccall_T cookie;
! ufunc_T *cur_ufunc =
(((dfunc_T *)def_functions.ga_data)
+ ectx->ec_dfunc_idx)->df_ufunc;
! cookie.func = cur_ufunc;
if (iptr->isn_type == ISN_PROF_START)
{
func_line_start(&cookie, iptr->isn_lnum);
--- 5080,5091 ----
case ISN_PROF_END:
{
#ifdef FEAT_PROFILE
! funccall_T cookie;
! ufunc_T *cur_ufunc =
(((dfunc_T *)def_functions.ga_data)
+ ectx->ec_dfunc_idx)->df_ufunc;
! cookie.fc_func = cur_ufunc;
if (iptr->isn_type == ISN_PROF_START)
{
func_line_start(&cookie, iptr->isn_lnum);
*** ../vim-9.0.0397/src/evalvars.c 2022-09-03 10:52:18.395075356 +0100
--- src/evalvars.c 2022-09-06 18:51:55.628381740 +0100
***************
*** 3391,3397 ****
if (*name == 'v') // v: variable
return &vimvarht;
if (get_current_funccal() != NULL
! && get_current_funccal()->func->uf_def_status == UF_NOT_COMPILED)
{
// a: and l: are only used in functions defined with ":function"
if (*name == 'a') // a: function argument
--- 3391,3398 ----
if (*name == 'v') // v: variable
return &vimvarht;
if (get_current_funccal() != NULL
! && get_current_funccal()->fc_func->uf_def_status
! == UF_NOT_COMPILED)
{
// a: and l: are only used in functions defined with ":function"
if (*name == 'a') // a: function argument
*** ../vim-9.0.0397/src/version.c 2022-09-06 18:31:09.074310277 +0100
--- src/version.c 2022-09-06 18:56:08.119866967 +0100
***************
*** 705,706 ****
--- 705,708 ----
{ /* Add new patch number below this line */
+ /**/
+ 398,
/**/
--
hundred-and-one symptoms of being an internet addict:
18. Your wife drapes a blond wig over your monitor to remind you of what she
looks like.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ 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/20220906175822.289371C0CE4%40moolenaar.net.