Problem: Reallocating the list of scripts is inefficient.
Solution: Instead of using a growarray of scriptitem_T, store pointers and
allocate each scriptitem_T separately. Also avoids that the
growarray pointers change when sourcing a new script.
if (current_sctx.sc_version == SCRIPT_VERSION_VIM9 && *p == ':')
{
- scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
char_u *tp = skipwhite(p + 1);
// parse the type after the name
// imported variable from another script
if (import != NULL)
{
- scriptitem_T *si = &SCRIPT_ITEM(import->imp_sid);
+ scriptitem_T *si = SCRIPT_ITEM(import->imp_sid);
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
+ import->imp_var_vals_idx;
tv = sv->sv_tv;
if (sv == NULL)
return;
init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
- SCRIPT_ITEM(id).sn_vars = sv;
+ SCRIPT_ITEM(id)->sn_vars = sv;
}
/*
if (is_script_local && current_sctx.sc_version == SCRIPT_VERSION_VIM9)
{
- scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
// Store a pointer to the typval_T, so that it can be found by
// index instead of using a hastab lookup.
#ifdef FEAT_EVAL
// Set flag that any command was executed, used by ex_vim9script().
if (getline_equal(ea.getline, ea.cookie, getsourceline))
- SCRIPT_ITEM(current_sctx.sc_sid).sn_had_command = TRUE;
+ SCRIPT_ITEM(current_sctx.sc_sid)->sn_had_command = TRUE;
/*
* If the command just executed called do_cmdline(), any throw or ":return"
# ifdef FEAT_PROFILE
EXTERN int do_profiling INIT(= PROF_NONE); // PROF_ values
# endif
-EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T), 4, NULL);
-# define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
-# define SCRIPT_SV(id) (SCRIPT_ITEM(id).sn_vars)
+EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T *), 20, NULL);
+# define SCRIPT_ITEM(id) (((scriptitem_T **)script_items.ga_data)[(id) - 1])
+# define SCRIPT_SV(id) (SCRIPT_ITEM(id)->sn_vars)
# define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
# define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j]
prof_def_func(void)
{
if (current_sctx.sc_sid > 0)
- return SCRIPT_ITEM(current_sctx.sc_sid).sn_pr_force;
+ return SCRIPT_ITEM(current_sctx.sc_sid)->sn_pr_force;
return FALSE;
}
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
{
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
if (si->sn_prof_on && si->sn_pr_nest++ == 0)
profile_start(&si->sn_pr_child);
}
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
{
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
if (si->sn_prof_on && --si->sn_pr_nest == 0)
{
profile_end(&si->sn_pr_child);
for (id = 1; id <= script_items.ga_len; ++id)
{
- si = &SCRIPT_ITEM(id);
+ si = SCRIPT_ITEM(id);
if (si->sn_prof_on)
{
fprintf(fd, "SCRIPT %s\n", si->sn_name);
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
return;
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
if (si->sn_prof_on && SOURCING_LNUM >= 1)
{
// Grow the array before starting the timer, so that the time spent
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
return;
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
if (si->sn_prof_on && si->sn_prl_idx >= 0)
si->sn_prl_execed = TRUE;
}
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
return;
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
if (si->sn_prof_on && si->sn_prl_idx >= 0
&& si->sn_prl_idx < si->sn_prl_ga.ga_len)
{
// inode number, even though to the user it is the same script.
// - If a script is deleted and another script is written, with a
// different name, the inode may be re-used.
- si = &SCRIPT_ITEM(sid);
+ si = SCRIPT_ITEM(sid);
if (si->sn_name != NULL && fnamecmp(si->sn_name, fname_exp) == 0)
// Found it!
break;
goto almosttheend;
while (script_items.ga_len < current_sctx.sc_sid)
{
+ si = ALLOC_CLEAR_ONE(scriptitem_T);
+ if (si == NULL)
+ goto almosttheend;
++script_items.ga_len;
- si = &SCRIPT_ITEM(script_items.ga_len);
+ SCRIPT_ITEM(script_items.ga_len) = si;
si->sn_name = NULL;
si->sn_version = 1;
si->sn_prof_on = FALSE;
# endif
}
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
si->sn_name = fname_exp;
fname_exp = vim_strsave(si->sn_name); // used for autocmd
if (ret_sid != NULL)
if (do_profiling == PROF_YES)
{
// Get "si" again, "script_items" may have been reallocated.
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
if (si->sn_prof_on)
{
profile_end(&si->sn_pr_start);
#ifdef FEAT_EVAL
almosttheend:
// Get "si" again, "script_items" may have been reallocated.
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
if (si->sn_save_cpo != NULL)
{
free_string_option(p_cpo);
emsg(_(e_invarg));
else
{
- eap->arg = SCRIPT_ITEM(eap->line2).sn_name;
+ eap->arg = SCRIPT_ITEM(eap->line2)->sn_name;
do_exedit(eap, NULL);
}
return;
}
for (i = 1; i <= script_items.ga_len && !got_int; ++i)
- if (SCRIPT_ITEM(i).sn_name != NULL)
+ if (SCRIPT_ITEM(i)->sn_name != NULL)
{
- home_replace(NULL, SCRIPT_ITEM(i).sn_name,
+ home_replace(NULL, SCRIPT_ITEM(i)->sn_name,
NameBuff, MAXPATHL, TRUE);
smsg("%3d: %s", i, NameBuff);
}
int i;
for (i = 1; i <= script_items.ga_len; ++i)
- if (SCRIPT_ITEM(i).sn_name != NULL)
- slash_adjust(SCRIPT_ITEM(i).sn_name);
+ if (SCRIPT_ITEM(i)->sn_name != NULL)
+ slash_adjust(SCRIPT_ITEM(i)->sn_name);
}
# endif
return (char_u *)_("environment variable");
if (id == SID_ERROR)
return (char_u *)_("error handler");
- return SCRIPT_ITEM(id).sn_name;
+ return SCRIPT_ITEM(id)->sn_name;
}
# if defined(EXITFREE) || defined(PROTO)
for (i = script_items.ga_len; i > 0; --i)
{
+ scriptitem_T *si = SCRIPT_ITEM(i);
+
// the variables themselves are cleared in evalvars_clear()
- vim_free(SCRIPT_ITEM(i).sn_vars);
+ vim_free(si->sn_vars);
- vim_free(SCRIPT_ITEM(i).sn_name);
- free_string_option(SCRIPT_ITEM(i).sn_save_cpo);
+ vim_free(si->sn_name);
+ free_string_option(si->sn_save_cpo);
# ifdef FEAT_PROFILE
- ga_clear(&SCRIPT_ITEM(i).sn_prl_ga);
+ ga_clear(&si->sn_prl_ga);
# endif
+ vim_free(si);
}
ga_clear(&script_items);
}
else
{
current_sctx.sc_version = nr;
- SCRIPT_ITEM(current_sctx.sc_sid).sn_version = nr;
+ SCRIPT_ITEM(current_sctx.sc_sid)->sn_version = nr;
}
#endif
}
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 154,
/**/
153,
/**/
{
hashtab_T *ht;
dictitem_T *di;
- scriptitem_T *si = &SCRIPT_ITEM(sid);
+ scriptitem_T *si = SCRIPT_ITEM(sid);
int idx;
// First look the name up in the hashtable.
imported_T *
find_imported(char_u *name, cctx_T *cctx)
{
- scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
int idx;
if (cctx != NULL)
static int
compile_load_scriptvar(cctx_T *cctx, char_u *name)
{
- scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
int idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE);
imported_T *import;
case ISN_LOADSCRIPT:
{
scriptitem_T *si =
- &SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
+ SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
svar_T *sv;
sv = ((svar_T *)si->sn_var_vals.ga_data)
// store script-local variable
case ISN_STORESCRIPT:
{
- scriptitem_T *si = &SCRIPT_ITEM(
+ scriptitem_T *si = SCRIPT_ITEM(
iptr->isn_arg.script.script_sid);
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
+ iptr->isn_arg.script.script_idx;
case ISN_LOADSCRIPT:
{
scriptitem_T *si =
- &SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
+ SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
+ iptr->isn_arg.script.script_idx;
break;
case ISN_LOADS:
{
- scriptitem_T *si = &SCRIPT_ITEM(iptr->isn_arg.loads.ls_sid);
+ scriptitem_T *si = SCRIPT_ITEM(iptr->isn_arg.loads.ls_sid);
smsg("%4d LOADS s:%s from %s", current,
iptr->isn_arg.string, si->sn_name);
case ISN_STORESCRIPT:
{
scriptitem_T *si =
- &SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
+ SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
+ iptr->isn_arg.script.script_idx;
void
ex_vim9script(exarg_T *eap)
{
- scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
if (!getline_equal(eap->getline, eap->cookie, getsourceline))
{
void
free_imports(int sid)
{
- scriptitem_T *si = &SCRIPT_ITEM(sid);
+ scriptitem_T *si = SCRIPT_ITEM(sid);
int idx;
for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
if (*tv.vval.v_string == '.')
{
size_t len;
- scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+ scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
char_u *tail = gettail(si->sn_name);
char_u *from_name;
if (*arg_start == '*')
{
imported_T *imported = new_imported(gap != NULL ? gap
- : &SCRIPT_ITEM(import_sid).sn_imports);
+ : &SCRIPT_ITEM(import_sid)->sn_imports);
if (imported == NULL)
return NULL;
}
else
{
- scriptitem_T *script = &SCRIPT_ITEM(sid);
+ scriptitem_T *script = SCRIPT_ITEM(sid);
arg = arg_start;
if (*arg == '{')
}
imported = new_imported(gap != NULL ? gap
- : &SCRIPT_ITEM(import_sid).sn_imports);
+ : &SCRIPT_ITEM(import_sid)->sn_imports);
if (imported == NULL)
return NULL;