forked from aniani/vim
patch 9.0.0398: members of funccall_T are inconsistently named
Problem: Members of funccall_T are inconsistently named. Solution: Use the "fc_" prefix for all members.
This commit is contained in:
parent
58779858fb
commit
ca16c60f33
@ -3391,7 +3391,8 @@ find_var_ht(char_u *name, char_u **varname)
|
||||
if (*name == 'v') // v: variable
|
||||
return &vimvarht;
|
||||
if (get_current_funccal() != NULL
|
||||
&& get_current_funccal()->func->uf_def_status == UF_NOT_COMPILED)
|
||||
&& 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
|
||||
|
@ -718,8 +718,8 @@ prof_child_enter(
|
||||
{
|
||||
funccall_T *fc = get_current_funccal();
|
||||
|
||||
if (fc != NULL && fc->func->uf_profiling)
|
||||
profile_start(&fc->prof_child);
|
||||
if (fc != NULL && fc->fc_func->uf_profiling)
|
||||
profile_start(&fc->fc_prof_child);
|
||||
script_prof_save(tm);
|
||||
}
|
||||
|
||||
@ -733,12 +733,12 @@ prof_child_exit(
|
||||
{
|
||||
funccall_T *fc = get_current_funccal();
|
||||
|
||||
if (fc != NULL && fc->func->uf_profiling)
|
||||
if (fc != NULL && fc->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);
|
||||
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,7 +753,7 @@ prof_child_exit(
|
||||
func_line_start(void *cookie, long lnum)
|
||||
{
|
||||
funccall_T *fcp = (funccall_T *)cookie;
|
||||
ufunc_T *fp = fcp->func;
|
||||
ufunc_T *fp = fcp->fc_func;
|
||||
|
||||
if (fp->uf_profiling && lnum >= 1 && lnum <= fp->uf_lines.ga_len)
|
||||
{
|
||||
@ -775,7 +775,7 @@ func_line_start(void *cookie, long lnum)
|
||||
func_line_exec(void *cookie)
|
||||
{
|
||||
funccall_T *fcp = (funccall_T *)cookie;
|
||||
ufunc_T *fp = fcp->func;
|
||||
ufunc_T *fp = fcp->fc_func;
|
||||
|
||||
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
|
||||
fp->uf_tml_execed = TRUE;
|
||||
@ -788,7 +788,7 @@ func_line_exec(void *cookie)
|
||||
func_line_end(void *cookie)
|
||||
{
|
||||
funccall_T *fcp = (funccall_T *)cookie;
|
||||
ufunc_T *fp = fcp->func;
|
||||
ufunc_T *fp = fcp->fc_func;
|
||||
|
||||
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
|
||||
{
|
||||
|
@ -1735,40 +1735,40 @@ typedef struct
|
||||
*/
|
||||
struct funccall_S
|
||||
{
|
||||
ufunc_T *func; // function being called
|
||||
int linenr; // next line to be executed
|
||||
int returned; // ":return" used
|
||||
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
|
||||
} 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
|
||||
} 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 prof_child; // time spent in a child
|
||||
proftime_T fc_prof_child; // time spent in a child
|
||||
#endif
|
||||
funccall_T *caller; // calling function or NULL; or next funccal in
|
||||
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_funcs; // list of ufunc_T* which keep a reference to
|
||||
garray_T fc_ufuncs; // list of ufunc_T* which keep a reference to
|
||||
// "func"
|
||||
};
|
||||
|
||||
|
270
src/userfunc.c
270
src/userfunc.c
@ -499,10 +499,10 @@ register_closure(ufunc_T *fp)
|
||||
fp->uf_scoped = current_funccal;
|
||||
current_funccal->fc_refcount++;
|
||||
|
||||
if (ga_grow(¤t_funccal->fc_funcs, 1) == FAIL)
|
||||
if (ga_grow(¤t_funccal->fc_ufuncs, 1) == FAIL)
|
||||
return FAIL;
|
||||
((ufunc_T **)current_funccal->fc_funcs.ga_data)
|
||||
[current_funccal->fc_funcs.ga_len++] = fp;
|
||||
((ufunc_T **)current_funccal->fc_ufuncs.ga_data)
|
||||
[current_funccal->fc_ufuncs.ga_len++] = fp;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -2141,9 +2141,9 @@ free_funccal(funccall_T *fc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fc->fc_funcs.ga_len; ++i)
|
||||
for (i = 0; i < fc->fc_ufuncs.ga_len; ++i)
|
||||
{
|
||||
ufunc_T *fp = ((ufunc_T **)(fc->fc_funcs.ga_data))[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,9 +2152,9 @@ free_funccal(funccall_T *fc)
|
||||
if (fp != NULL && fp->uf_scoped == fc)
|
||||
fp->uf_scoped = NULL;
|
||||
}
|
||||
ga_clear(&fc->fc_funcs);
|
||||
ga_clear(&fc->fc_ufuncs);
|
||||
|
||||
func_ptr_unref(fc->func);
|
||||
func_ptr_unref(fc->fc_func);
|
||||
vim_free(fc);
|
||||
}
|
||||
|
||||
@ -2169,13 +2169,13 @@ free_funccal_contents(funccall_T *fc)
|
||||
listitem_T *li;
|
||||
|
||||
// Free all l: variables.
|
||||
vars_clear(&fc->l_vars.dv_hashtab);
|
||||
vars_clear(&fc->fc_l_vars.dv_hashtab);
|
||||
|
||||
// Free all a: variables.
|
||||
vars_clear(&fc->l_avars.dv_hashtab);
|
||||
vars_clear(&fc->fc_l_avars.dv_hashtab);
|
||||
|
||||
// Free the a:000 variables.
|
||||
FOR_ALL_LIST_ITEMS(&fc->l_varlist, li)
|
||||
FOR_ALL_LIST_ITEMS(&fc->fc_l_varlist, li)
|
||||
clear_tv(&li->li_tv);
|
||||
|
||||
free_funccal(fc);
|
||||
@ -2191,19 +2191,19 @@ cleanup_function_call(funccall_T *fc)
|
||||
int may_free_fc = fc->fc_refcount <= 0;
|
||||
int free_fc = TRUE;
|
||||
|
||||
current_funccal = fc->caller;
|
||||
current_funccal = fc->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);
|
||||
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->l_avars.dv_refcount == DO_NOT_FREE_CNT)
|
||||
vars_clear_ext(&fc->l_avars.dv_hashtab, FALSE);
|
||||
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,8 +2213,8 @@ cleanup_function_call(funccall_T *fc)
|
||||
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)
|
||||
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,8 +2225,8 @@ cleanup_function_call(funccall_T *fc)
|
||||
}
|
||||
}
|
||||
|
||||
if (may_free_fc && fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT)
|
||||
fc->l_varlist.lv_first = NULL;
|
||||
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,7 +2234,7 @@ cleanup_function_call(funccall_T *fc)
|
||||
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)
|
||||
FOR_ALL_LIST_ITEMS(&fc->fc_l_varlist, li)
|
||||
copy_tv(&li->li_tv, &li->li_tv);
|
||||
}
|
||||
|
||||
@ -2247,7 +2247,7 @@ cleanup_function_call(funccall_T *fc)
|
||||
// "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;
|
||||
fc->fc_caller = previous_funccal;
|
||||
previous_funccal = fc;
|
||||
|
||||
if (want_garbage_collect)
|
||||
@ -2305,21 +2305,21 @@ funccal_unref(funccall_T *fc, ufunc_T *fp, int force)
|
||||
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)
|
||||
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->caller;
|
||||
*pfc = fc->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;
|
||||
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,7 +2599,7 @@ call_user_func(
|
||||
int save_did_emsg;
|
||||
int default_arg_err = FALSE;
|
||||
dictitem_T *v;
|
||||
int fixvar_idx = 0; // index in fixvar[]
|
||||
int fixvar_idx = 0; // index in fc_fixvar[]
|
||||
int i;
|
||||
int ai;
|
||||
int islambda = FALSE;
|
||||
@ -2629,22 +2629,22 @@ call_user_func(
|
||||
fc = ALLOC_CLEAR_ONE(funccall_T);
|
||||
if (fc == NULL)
|
||||
return;
|
||||
fc->caller = current_funccal;
|
||||
fc->fc_caller = current_funccal;
|
||||
current_funccal = fc;
|
||||
fc->func = fp;
|
||||
fc->rettv = rettv;
|
||||
fc->level = ex_nesting_level;
|
||||
fc->fc_func = fp;
|
||||
fc->fc_rettv = rettv;
|
||||
fc->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;
|
||||
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_funcs, sizeof(ufunc_T *), 1);
|
||||
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->caller == NULL ? NULL : fc->caller->func;
|
||||
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,7 +2660,7 @@ call_user_func(
|
||||
|| (caller != NULL && caller->uf_profiling)))
|
||||
profile_may_end_func(&profile_info, fp, caller);
|
||||
#endif
|
||||
current_funccal = fc->caller;
|
||||
current_funccal = fc->fc_caller;
|
||||
free_funccal(fc);
|
||||
sticky_cmdmod_flags = save_sticky_cmdmod_flags;
|
||||
return;
|
||||
@ -2669,23 +2669,23 @@ call_user_func(
|
||||
islambda = fp->uf_flags & FC_LAMBDA;
|
||||
|
||||
/*
|
||||
* Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
|
||||
* 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->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE);
|
||||
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->fixvar[fixvar_idx++].var;
|
||||
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->l_vars.dv_hashtab, DI2HIKEY(v));
|
||||
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,28 +2697,28 @@ call_user_func(
|
||||
* 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);
|
||||
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->l_avars, &fc->fixvar[fixvar_idx++].var, "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->l_avars.dv_lock = VAR_FIXED;
|
||||
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->fixvar[fixvar_idx++].var;
|
||||
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->l_avars.dv_hashtab, DI2HIKEY(v));
|
||||
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->l_varlist;
|
||||
v->di_tv.vval.v_list = &fc->fc_l_varlist;
|
||||
}
|
||||
CLEAR_FIELD(fc->l_varlist);
|
||||
fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT;
|
||||
fc->l_varlist.lv_lock = VAR_FIXED;
|
||||
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,10 +2728,10 @@ call_user_func(
|
||||
*/
|
||||
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);
|
||||
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,7 +2779,7 @@ call_user_func(
|
||||
}
|
||||
if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN)
|
||||
{
|
||||
v = &fc->fixvar[fixvar_idx++].var;
|
||||
v = &fc->fc_fixvar[fixvar_idx++].var;
|
||||
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
|
||||
STRCPY(v->di_key, name);
|
||||
}
|
||||
@ -2805,18 +2805,18 @@ call_user_func(
|
||||
// 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));
|
||||
hash_add(&fc->fc_l_vars.dv_hashtab, DI2HIKEY(v));
|
||||
}
|
||||
else
|
||||
hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
|
||||
hash_add(&fc->fc_l_avars.dv_hashtab, DI2HIKEY(v));
|
||||
|
||||
if (ai >= 0 && ai < MAX_FUNC_ARGS)
|
||||
{
|
||||
listitem_T *li = &fc->l_listitems[ai];
|
||||
listitem_T *li = &fc->fc_l_listitems[ai];
|
||||
|
||||
li->li_tv = argvars[i];
|
||||
li->li_tv.v_lock = VAR_FIXED;
|
||||
list_append(&fc->l_varlist, li);
|
||||
list_append(&fc->fc_l_varlist, li);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2879,7 +2879,7 @@ call_user_func(
|
||||
#ifdef FEAT_PROFILE
|
||||
if (do_profiling == PROF_YES)
|
||||
profile_may_start_func(&profile_info, fp,
|
||||
fc->caller == NULL ? NULL : fc->caller->func);
|
||||
fc->fc_caller == NULL ? NULL : fc->fc_caller->fc_func);
|
||||
#endif
|
||||
|
||||
// "legacy" does not apply to commands in the function
|
||||
@ -2923,7 +2923,7 @@ call_user_func(
|
||||
#ifdef FEAT_PROFILE
|
||||
if (do_profiling == PROF_YES)
|
||||
{
|
||||
ufunc_T *caller = fc->caller == NULL ? NULL : fc->caller->func;
|
||||
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,9 +2938,9 @@ call_user_func(
|
||||
|
||||
if (aborting())
|
||||
smsg(_("%s aborted"), SOURCING_NAME);
|
||||
else if (fc->rettv->v_type == VAR_NUMBER)
|
||||
else if (fc->fc_rettv->v_type == VAR_NUMBER)
|
||||
smsg(_("%s returning #%ld"), SOURCING_NAME,
|
||||
(long)fc->rettv->vval.v_number);
|
||||
(long)fc->fc_rettv->vval.v_number);
|
||||
else
|
||||
{
|
||||
char_u buf[MSG_BUF_LEN];
|
||||
@ -2952,7 +2952,7 @@ call_user_func(
|
||||
// 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);
|
||||
s = tv2string(fc->fc_rettv, &tofree, numbuf2, 0);
|
||||
--emsg_off;
|
||||
if (s != NULL)
|
||||
{
|
||||
@ -3188,7 +3188,7 @@ free_all_functions(void)
|
||||
// Clean up the current_funccal chain and the funccal stack.
|
||||
while (current_funccal != NULL)
|
||||
{
|
||||
clear_tv(current_funccal->rettv);
|
||||
clear_tv(current_funccal->fc_rettv);
|
||||
cleanup_function_call(current_funccal);
|
||||
if (current_funccal == NULL && funccal_stack != NULL)
|
||||
restore_funccal();
|
||||
@ -5418,9 +5418,9 @@ func_ptr_ref(ufunc_T *fp)
|
||||
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
|
||||
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,7 +5696,8 @@ invoke_all_defer(void)
|
||||
{
|
||||
funccall_T *funccal;
|
||||
|
||||
for (funccal = current_funccal; funccal != NULL; funccal = funccal->caller)
|
||||
for (funccal = current_funccal; funccal != NULL;
|
||||
funccal = funccal->fc_caller)
|
||||
if (funccal->fc_ectx != NULL)
|
||||
{
|
||||
// :def function
|
||||
@ -5849,7 +5850,7 @@ do_return(
|
||||
|
||||
if (reanimate)
|
||||
// Undo the return.
|
||||
current_funccal->returned = FALSE;
|
||||
current_funccal->fc_returned = FALSE;
|
||||
|
||||
/*
|
||||
* Cleanup (and inactivate) conditionals, but stop when a try conditional
|
||||
@ -5872,7 +5873,7 @@ do_return(
|
||||
// When undoing a return in order to make it pending, get the stored
|
||||
// return rettv.
|
||||
if (reanimate)
|
||||
rettv = current_funccal->rettv;
|
||||
rettv = current_funccal->fc_rettv;
|
||||
|
||||
if (rettv != NULL)
|
||||
{
|
||||
@ -5890,23 +5891,23 @@ do_return(
|
||||
// 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;
|
||||
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->returned = TRUE;
|
||||
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->rettv);
|
||||
*current_funccal->rettv = *(typval_T *)rettv;
|
||||
clear_tv(current_funccal->fc_rettv);
|
||||
*current_funccal->fc_rettv = *(typval_T *)rettv;
|
||||
if (!is_cmd)
|
||||
vim_free(rettv);
|
||||
}
|
||||
@ -5961,16 +5962,16 @@ get_func_line(
|
||||
getline_opt_T options UNUSED)
|
||||
{
|
||||
funccall_T *fcp = (funccall_T *)cookie;
|
||||
ufunc_T *fp = fcp->func;
|
||||
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->dbg_tick != debug_tick)
|
||||
if (fcp->fc_dbg_tick != debug_tick)
|
||||
{
|
||||
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
|
||||
fcp->fc_breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
|
||||
SOURCING_LNUM);
|
||||
fcp->dbg_tick = debug_tick;
|
||||
fcp->fc_dbg_tick = debug_tick;
|
||||
}
|
||||
#ifdef FEAT_PROFILE
|
||||
if (do_profiling == PROF_YES)
|
||||
@ -5979,20 +5980,20 @@ get_func_line(
|
||||
|
||||
gap = &fp->uf_lines;
|
||||
if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
|
||||
|| fcp->returned)
|
||||
|| fcp->fc_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)
|
||||
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->linenr++]);
|
||||
SOURCING_LNUM = fcp->linenr;
|
||||
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,13 +6002,13 @@ get_func_line(
|
||||
}
|
||||
|
||||
// Did we encounter a breakpoint?
|
||||
if (fcp->breakpoint != 0 && fcp->breakpoint <= SOURCING_LNUM)
|
||||
if (fcp->fc_breakpoint != 0 && fcp->fc_breakpoint <= SOURCING_LNUM)
|
||||
{
|
||||
dbg_breakpoint(fp->uf_name, SOURCING_LNUM);
|
||||
// Find next breakpoint.
|
||||
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
|
||||
fcp->fc_breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
|
||||
SOURCING_LNUM);
|
||||
fcp->dbg_tick = debug_tick;
|
||||
fcp->fc_dbg_tick = debug_tick;
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -6024,8 +6025,9 @@ func_has_ended(void *cookie)
|
||||
|
||||
// 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);
|
||||
return (((fcp->fc_func->uf_flags & FC_ABORT)
|
||||
&& did_emsg && !aborted_in_try())
|
||||
|| fcp->fc_returned);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6035,7 +6037,7 @@ func_has_ended(void *cookie)
|
||||
func_has_abort(
|
||||
void *cookie)
|
||||
{
|
||||
return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT;
|
||||
return ((funccall_T *)cookie)->fc_func->uf_flags & FC_ABORT;
|
||||
}
|
||||
|
||||
|
||||
@ -6143,7 +6145,7 @@ make_partial(dict_T *selfdict_in, typval_T *rettv)
|
||||
char_u *
|
||||
func_name(void *cookie)
|
||||
{
|
||||
return ((funccall_T *)cookie)->func->uf_name;
|
||||
return ((funccall_T *)cookie)->fc_func->uf_name;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6152,7 +6154,7 @@ func_name(void *cookie)
|
||||
linenr_T *
|
||||
func_breakpoint(void *cookie)
|
||||
{
|
||||
return &((funccall_T *)cookie)->breakpoint;
|
||||
return &((funccall_T *)cookie)->fc_breakpoint;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6161,7 +6163,7 @@ func_breakpoint(void *cookie)
|
||||
int *
|
||||
func_dbg_tick(void *cookie)
|
||||
{
|
||||
return &((funccall_T *)cookie)->dbg_tick;
|
||||
return &((funccall_T *)cookie)->fc_dbg_tick;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6170,7 +6172,7 @@ func_dbg_tick(void *cookie)
|
||||
int
|
||||
func_level(void *cookie)
|
||||
{
|
||||
return ((funccall_T *)cookie)->level;
|
||||
return ((funccall_T *)cookie)->fc_level;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6179,7 +6181,7 @@ func_level(void *cookie)
|
||||
int
|
||||
current_func_returned(void)
|
||||
{
|
||||
return current_funccal->returned;
|
||||
return current_funccal->fc_returned;
|
||||
}
|
||||
|
||||
int
|
||||
@ -6194,13 +6196,13 @@ free_unref_funccal(int copyID, int testing)
|
||||
if (can_free_funccal(*pfc, copyID))
|
||||
{
|
||||
fc = *pfc;
|
||||
*pfc = fc->caller;
|
||||
*pfc = fc->fc_caller;
|
||||
free_funccal_contents(fc);
|
||||
did_free = TRUE;
|
||||
did_free_funccal = TRUE;
|
||||
}
|
||||
else
|
||||
pfc = &(*pfc)->caller;
|
||||
pfc = &(*pfc)->fc_caller;
|
||||
}
|
||||
if (did_free_funccal)
|
||||
// When a funccal was freed some more items might be garbage
|
||||
@ -6225,7 +6227,7 @@ get_funccal(void)
|
||||
{
|
||||
for (i = 0; i < debug_backtrace_level; i++)
|
||||
{
|
||||
temp_funccal = funccal->caller;
|
||||
temp_funccal = funccal->fc_caller;
|
||||
if (temp_funccal)
|
||||
funccal = temp_funccal;
|
||||
else
|
||||
@ -6243,9 +6245,9 @@ get_funccal(void)
|
||||
hashtab_T *
|
||||
get_funccal_local_ht()
|
||||
{
|
||||
if (current_funccal == NULL || current_funccal->l_vars.dv_refcount == 0)
|
||||
if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0)
|
||||
return NULL;
|
||||
return &get_funccal()->l_vars.dv_hashtab;
|
||||
return &get_funccal()->fc_l_vars.dv_hashtab;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6255,9 +6257,9 @@ get_funccal_local_ht()
|
||||
dictitem_T *
|
||||
get_funccal_local_var()
|
||||
{
|
||||
if (current_funccal == NULL || current_funccal->l_vars.dv_refcount == 0)
|
||||
if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0)
|
||||
return NULL;
|
||||
return &get_funccal()->l_vars_var;
|
||||
return &get_funccal()->fc_l_vars_var;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6267,9 +6269,9 @@ get_funccal_local_var()
|
||||
hashtab_T *
|
||||
get_funccal_args_ht()
|
||||
{
|
||||
if (current_funccal == NULL || current_funccal->l_vars.dv_refcount == 0)
|
||||
if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0)
|
||||
return NULL;
|
||||
return &get_funccal()->l_avars.dv_hashtab;
|
||||
return &get_funccal()->fc_l_avars.dv_hashtab;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6279,9 +6281,9 @@ get_funccal_args_ht()
|
||||
dictitem_T *
|
||||
get_funccal_args_var()
|
||||
{
|
||||
if (current_funccal == NULL || current_funccal->l_vars.dv_refcount == 0)
|
||||
if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0)
|
||||
return NULL;
|
||||
return &get_funccal()->l_avars_var;
|
||||
return &get_funccal()->fc_l_avars_var;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6290,8 +6292,8 @@ get_funccal_args_var()
|
||||
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,
|
||||
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,8 +6306,8 @@ list_func_vars(int *first)
|
||||
get_current_funccal_dict(hashtab_T *ht)
|
||||
{
|
||||
if (current_funccal != NULL
|
||||
&& ht == ¤t_funccal->l_vars.dv_hashtab)
|
||||
return ¤t_funccal->l_vars;
|
||||
&& ht == ¤t_funccal->fc_l_vars.dv_hashtab)
|
||||
return ¤t_funccal->fc_l_vars;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -6320,11 +6322,11 @@ find_hi_in_scoped_ht(char_u *name, hashtab_T **pht)
|
||||
hashitem_T *hi = NULL;
|
||||
char_u *varname;
|
||||
|
||||
if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL)
|
||||
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->func->uf_scoped;
|
||||
current_funccal = current_funccal->fc_func->uf_scoped;
|
||||
while (current_funccal != NULL)
|
||||
{
|
||||
ht = find_var_ht(name, &varname);
|
||||
@ -6337,9 +6339,9 @@ find_hi_in_scoped_ht(char_u *name, hashtab_T **pht)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (current_funccal == current_funccal->func->uf_scoped)
|
||||
if (current_funccal == current_funccal->fc_func->uf_scoped)
|
||||
break;
|
||||
current_funccal = current_funccal->func->uf_scoped;
|
||||
current_funccal = current_funccal->fc_func->uf_scoped;
|
||||
}
|
||||
current_funccal = old_current_funccal;
|
||||
|
||||
@ -6357,11 +6359,11 @@ find_var_in_scoped_ht(char_u *name, int no_autoload)
|
||||
hashtab_T *ht;
|
||||
char_u *varname;
|
||||
|
||||
if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL)
|
||||
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->func->uf_scoped;
|
||||
current_funccal = current_funccal->fc_func->uf_scoped;
|
||||
while (current_funccal)
|
||||
{
|
||||
ht = find_var_ht(name, &varname);
|
||||
@ -6371,9 +6373,9 @@ find_var_in_scoped_ht(char_u *name, int no_autoload)
|
||||
if (v != NULL)
|
||||
break;
|
||||
}
|
||||
if (current_funccal == current_funccal->func->uf_scoped)
|
||||
if (current_funccal == current_funccal->fc_func->uf_scoped)
|
||||
break;
|
||||
current_funccal = current_funccal->func->uf_scoped;
|
||||
current_funccal = current_funccal->fc_func->uf_scoped;
|
||||
}
|
||||
current_funccal = old_current_funccal;
|
||||
|
||||
@ -6388,12 +6390,12 @@ set_ref_in_previous_funccal(int copyID)
|
||||
{
|
||||
funccall_T *fc;
|
||||
|
||||
for (fc = previous_funccal; fc != NULL; fc = fc->caller)
|
||||
for (fc = previous_funccal; fc != NULL; fc = 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))
|
||||
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,10 +6407,10 @@ set_ref_in_funccal(funccall_T *fc, int copyID)
|
||||
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))
|
||||
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,13 +6425,13 @@ set_ref_in_call_stack(int copyID)
|
||||
funccall_T *fc;
|
||||
funccal_entry_T *entry;
|
||||
|
||||
for (fc = current_funccal; fc != NULL; fc = fc->caller)
|
||||
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->caller)
|
||||
for (fc = entry->top_funccal; fc != NULL; fc = fc->fc_caller)
|
||||
if (set_ref_in_funccal(fc, copyID))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
@ -6500,7 +6502,7 @@ set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID)
|
||||
}
|
||||
if (fp != NULL)
|
||||
{
|
||||
for (fc = fp->uf_scoped; fc != NULL; fc = fc->func->uf_scoped)
|
||||
for (fc = fp->uf_scoped; fc != NULL; fc = fc->fc_func->uf_scoped)
|
||||
abort = abort || set_ref_in_funccal(fc, copyID);
|
||||
}
|
||||
|
||||
|
@ -703,6 +703,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
398,
|
||||
/**/
|
||||
397,
|
||||
/**/
|
||||
|
@ -5080,12 +5080,12 @@ exec_instructions(ectx_T *ectx)
|
||||
case ISN_PROF_END:
|
||||
{
|
||||
#ifdef FEAT_PROFILE
|
||||
funccall_T cookie;
|
||||
ufunc_T *cur_ufunc =
|
||||
funccall_T cookie;
|
||||
ufunc_T *cur_ufunc =
|
||||
(((dfunc_T *)def_functions.ga_data)
|
||||
+ ectx->ec_dfunc_idx)->df_ufunc;
|
||||
|
||||
cookie.func = cur_ufunc;
|
||||
cookie.fc_func = cur_ufunc;
|
||||
if (iptr->isn_type == ISN_PROF_START)
|
||||
{
|
||||
func_line_start(&cookie, iptr->isn_lnum);
|
||||
|
Loading…
x
Reference in New Issue
Block a user