Skip to content

Commit 7ebcba6

Browse files
committed
patch 8.2.0114: info about sourced scripts is scattered
Problem: Info about sourced scripts is scattered. Solution: Use scriptitem_T for info about a script, including s: variables. Drop ga_scripts.
1 parent 9b24dfc commit 7ebcba6

5 files changed

Lines changed: 45 additions & 53 deletions

File tree

src/eval.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ eval_init(void)
149149
eval_clear(void)
150150
{
151151
evalvars_clear();
152-
153-
free_scriptnames();
152+
free_scriptnames(); // must come after evalvars_clear().
154153
free_locales();
155154

156155
// autoloaded script names

src/evalvars.c

Lines changed: 14 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -163,18 +163,7 @@ static dict_T vimvardict; // Dictionary with v: variables
163163
// for VIM_VERSION_ defines
164164
#include "version.h"
165165

166-
/*
167-
* Array to hold the hashtab with variables local to each sourced script.
168-
* Each item holds a variable (nameless) that points to the dict_T.
169-
*/
170-
typedef struct
171-
{
172-
dictitem_T sv_var;
173-
dict_T sv_dict;
174-
} scriptvar_T;
175-
176-
static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
177-
#define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1])
166+
#define SCRIPT_SV(id) (SCRIPT_ITEM(id).sn_vars)
178167
#define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
179168

180169
static void ex_let_const(exarg_T *eap, int is_const);
@@ -289,14 +278,12 @@ evalvars_clear(void)
289278
// global variables
290279
vars_clear(&globvarht);
291280

292-
// Script-local variables. First clear all the variables and in a second
293-
// loop free the scriptvar_T, because a variable in one script might hold
294-
// a reference to the whole scope of another script.
295-
for (i = 1; i <= ga_scripts.ga_len; ++i)
281+
// Script-local variables. Clear all the variables here.
282+
// The scriptvar_T is cleared later in free_scriptnames(), because a
283+
// variable in one script might hold a reference to the whole scope of
284+
// another script.
285+
for (i = 1; i <= script_items.ga_len; ++i)
296286
vars_clear(&SCRIPT_VARS(i));
297-
for (i = 1; i <= ga_scripts.ga_len; ++i)
298-
vim_free(SCRIPT_SV(i));
299-
ga_clear(&ga_scripts);
300287
}
301288
#endif
302289

@@ -318,7 +305,7 @@ garbage_collect_scriptvars(int copyID)
318305
int i;
319306
int abort = FALSE;
320307

321-
for (i = 1; i <= ga_scripts.ga_len; ++i)
308+
for (i = 1; i <= script_items.ga_len; ++i)
322309
abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL);
323310

324311
return abort;
@@ -538,7 +525,7 @@ list_vim_vars(int *first)
538525
static void
539526
list_script_vars(int *first)
540527
{
541-
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= ga_scripts.ga_len)
528+
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
542529
list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid),
543530
"s:", FALSE, first);
544531
}
@@ -2433,7 +2420,7 @@ find_var_ht(char_u *name, char_u **varname)
24332420
return get_funccal_local_ht();
24342421
if (*name == 's' // script variable
24352422
&& current_sctx.sc_sid > 0
2436-
&& current_sctx.sc_sid <= ga_scripts.ga_len)
2423+
&& current_sctx.sc_sid <= script_items.ga_len)
24372424
return &SCRIPT_VARS(current_sctx.sc_sid);
24382425
return NULL;
24392426
}
@@ -2461,32 +2448,13 @@ get_var_value(char_u *name)
24612448
void
24622449
new_script_vars(scid_T id)
24632450
{
2464-
int i;
2465-
hashtab_T *ht;
24662451
scriptvar_T *sv;
24672452

2468-
if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
2469-
{
2470-
// Re-allocating ga_data means that an ht_array pointing to
2471-
// ht_smallarray becomes invalid. We can recognize this: ht_mask is
2472-
// at its init value. Also reset "v_dict", it's always the same.
2473-
for (i = 1; i <= ga_scripts.ga_len; ++i)
2474-
{
2475-
ht = &SCRIPT_VARS(i);
2476-
if (ht->ht_mask == HT_INIT_SIZE - 1)
2477-
ht->ht_array = ht->ht_smallarray;
2478-
sv = SCRIPT_SV(i);
2479-
sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict;
2480-
}
2481-
2482-
while (ga_scripts.ga_len < id)
2483-
{
2484-
sv = SCRIPT_SV(ga_scripts.ga_len + 1) =
2485-
ALLOC_CLEAR_ONE(scriptvar_T);
2486-
init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
2487-
++ga_scripts.ga_len;
2488-
}
2489-
}
2453+
sv = ALLOC_CLEAR_ONE(scriptvar_T);
2454+
if (sv == NULL)
2455+
return;
2456+
init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
2457+
SCRIPT_ITEM(id).sn_vars = sv;
24902458
}
24912459

24922460
/*

src/scriptfile.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ do_source(
12361236

12371237
save_current_sctx = current_sctx;
12381238
current_sctx.sc_lnum = 0;
1239-
current_sctx.sc_version = 1;
1239+
current_sctx.sc_version = 1; // default script version
12401240

12411241
// Check if this script was sourced before to finds its SID.
12421242
// If it's new, generate a new SID.
@@ -1272,6 +1272,10 @@ do_source(
12721272
{
12731273
++script_items.ga_len;
12741274
SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
1275+
SCRIPT_ITEM(script_items.ga_len).sn_version = 1;
1276+
1277+
// Allocate the local script variables to use for this script.
1278+
new_script_vars(script_items.ga_len);
12751279
# ifdef FEAT_PROFILE
12761280
SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
12771281
# endif
@@ -1289,9 +1293,6 @@ do_source(
12891293
else
12901294
si->sn_dev_valid = FALSE;
12911295
# endif
1292-
1293-
// Allocate the local script variables to use for this script.
1294-
new_script_vars(current_sctx.sc_sid);
12951296
}
12961297

12971298
# ifdef FEAT_PROFILE
@@ -1483,6 +1484,8 @@ free_scriptnames(void)
14831484

14841485
for (i = script_items.ga_len; i > 0; --i)
14851486
{
1487+
// the variables themselves are cleared in evalvars_clear()
1488+
vim_free(SCRIPT_ITEM(i).sn_vars);
14861489
vim_free(SCRIPT_ITEM(i).sn_name);
14871490
# ifdef FEAT_PROFILE
14881491
ga_clear(&SCRIPT_ITEM(i).sn_prl_ga);
@@ -1791,7 +1794,10 @@ ex_scriptversion(exarg_T *eap UNUSED)
17911794
else if (nr > 4)
17921795
semsg(_("E999: scriptversion not supported: %d"), nr);
17931796
else
1797+
{
17941798
current_sctx.sc_version = nr;
1799+
SCRIPT_ITEM(current_sctx.sc_sid).sn_version = nr;
1800+
}
17951801
#endif
17961802
}
17971803

src/structs.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ typedef struct VimMenu vimmenu_T;
7474
* function was defined, "sourcing_lnum" is the line number inside the
7575
* function. When stored with a function, mapping, option, etc. "sc_lnum" is
7676
* the line number in the script "sc_sid".
77+
*
78+
* sc_version is also here, for convenience.
7779
*/
7880
typedef struct {
7981
scid_T sc_sid; // script ID
@@ -1565,14 +1567,29 @@ struct funccal_entry {
15651567
#define HIKEY2UF(p) ((ufunc_T *)((p) - offsetof(ufunc_T, uf_name)))
15661568
#define HI2UF(hi) HIKEY2UF((hi)->hi_key)
15671569

1570+
/*
1571+
* Holds the hashtab with variables local to each sourced script.
1572+
* Each item holds a variable (nameless) that points to the dict_T.
1573+
*/
1574+
typedef struct
1575+
{
1576+
dictitem_T sv_var;
1577+
dict_T sv_dict;
1578+
} scriptvar_T;
1579+
15681580
/*
15691581
* Growarray to store info about already sourced scripts.
15701582
* For Unix also store the dev/ino, so that we don't have to stat() each
15711583
* script when going through the list.
15721584
*/
1573-
typedef struct scriptitem_S
1585+
typedef struct
15741586
{
1587+
scriptvar_T *sn_vars; // stores s: variables for this script
1588+
15751589
char_u *sn_name;
1590+
1591+
int sn_version; // :scriptversion
1592+
15761593
# ifdef UNIX
15771594
int sn_dev_valid;
15781595
dev_t sn_dev;

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,8 @@ static char *(features[]) =
742742

743743
static int included_patches[] =
744744
{ /* Add new patch number below this line */
745+
/**/
746+
114,
745747
/**/
746748
113,
747749
/**/

0 commit comments

Comments
 (0)