To: vim_dev@googlegroups.com Subject: Patch 8.2.0114 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0114 Problem: Info about sourced scripts is scattered. Solution: Use scriptitem_T for info about a script, including s: variables. Drop ga_scripts. Files: src/structs.h, src/evalvars.c, src/scriptfile.c, src/eval.c *** ../vim-8.2.0113/src/structs.h 2020-01-11 16:05:19.586287644 +0100 --- src/structs.h 2020-01-12 17:16:04.888562699 +0100 *************** *** 74,79 **** --- 74,81 ---- * function was defined, "sourcing_lnum" is the line number inside the * function. When stored with a function, mapping, option, etc. "sc_lnum" is * the line number in the script "sc_sid". + * + * sc_version is also here, for convenience. */ typedef struct { scid_T sc_sid; // script ID *************** *** 1566,1578 **** #define HI2UF(hi) HIKEY2UF((hi)->hi_key) /* * Growarray to store info about already sourced scripts. * For Unix also store the dev/ino, so that we don't have to stat() each * script when going through the list. */ ! typedef struct scriptitem_S { char_u *sn_name; # ifdef UNIX int sn_dev_valid; dev_t sn_dev; --- 1568,1595 ---- #define HI2UF(hi) HIKEY2UF((hi)->hi_key) /* + * Holds the hashtab with variables local to each sourced script. + * Each item holds a variable (nameless) that points to the dict_T. + */ + typedef struct + { + dictitem_T sv_var; + dict_T sv_dict; + } scriptvar_T; + + /* * Growarray to store info about already sourced scripts. * For Unix also store the dev/ino, so that we don't have to stat() each * script when going through the list. */ ! typedef struct { + scriptvar_T *sn_vars; // stores s: variables for this script + char_u *sn_name; + + int sn_version; // :scriptversion + # ifdef UNIX int sn_dev_valid; dev_t sn_dev; *** ../vim-8.2.0113/src/evalvars.c 2020-01-11 16:05:19.590287629 +0100 --- src/evalvars.c 2020-01-12 16:56:05.221008363 +0100 *************** *** 163,180 **** // for VIM_VERSION_ defines #include "version.h" ! /* ! * Array to hold the hashtab with variables local to each sourced script. ! * Each item holds a variable (nameless) that points to the dict_T. ! */ ! typedef struct ! { ! dictitem_T sv_var; ! dict_T sv_dict; ! } scriptvar_T; ! ! static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL}; ! #define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1]) #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) static void ex_let_const(exarg_T *eap, int is_const); --- 163,169 ---- // for VIM_VERSION_ defines #include "version.h" ! #define SCRIPT_SV(id) (SCRIPT_ITEM(id).sn_vars) #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) static void ex_let_const(exarg_T *eap, int is_const); *************** *** 289,302 **** // global variables vars_clear(&globvarht); ! // Script-local variables. First clear all the variables and in a second ! // loop free the scriptvar_T, because a variable in one script might hold ! // a reference to the whole scope of another script. ! for (i = 1; i <= ga_scripts.ga_len; ++i) vars_clear(&SCRIPT_VARS(i)); - for (i = 1; i <= ga_scripts.ga_len; ++i) - vim_free(SCRIPT_SV(i)); - ga_clear(&ga_scripts); } #endif --- 278,289 ---- // global variables vars_clear(&globvarht); ! // Script-local variables. Clear all the variables here. ! // The scriptvar_T is cleared later in free_scriptnames(), because a ! // variable in one script might hold a reference to the whole scope of ! // another script. ! for (i = 1; i <= script_items.ga_len; ++i) vars_clear(&SCRIPT_VARS(i)); } #endif *************** *** 318,324 **** int i; int abort = FALSE; ! for (i = 1; i <= ga_scripts.ga_len; ++i) abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL); return abort; --- 305,311 ---- int i; int abort = FALSE; ! for (i = 1; i <= script_items.ga_len; ++i) abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL); return abort; *************** *** 538,544 **** static void list_script_vars(int *first) { ! if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= ga_scripts.ga_len) list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), "s:", FALSE, first); } --- 525,531 ---- static void list_script_vars(int *first) { ! if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), "s:", FALSE, first); } *************** *** 2433,2439 **** return get_funccal_local_ht(); if (*name == 's' // script variable && current_sctx.sc_sid > 0 ! && current_sctx.sc_sid <= ga_scripts.ga_len) return &SCRIPT_VARS(current_sctx.sc_sid); return NULL; } --- 2420,2426 ---- return get_funccal_local_ht(); if (*name == 's' // script variable && current_sctx.sc_sid > 0 ! && current_sctx.sc_sid <= script_items.ga_len) return &SCRIPT_VARS(current_sctx.sc_sid); return NULL; } *************** *** 2461,2492 **** void new_script_vars(scid_T id) { - int i; - hashtab_T *ht; scriptvar_T *sv; ! if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) ! { ! // Re-allocating ga_data means that an ht_array pointing to ! // ht_smallarray becomes invalid. We can recognize this: ht_mask is ! // at its init value. Also reset "v_dict", it's always the same. ! for (i = 1; i <= ga_scripts.ga_len; ++i) ! { ! ht = &SCRIPT_VARS(i); ! if (ht->ht_mask == HT_INIT_SIZE - 1) ! ht->ht_array = ht->ht_smallarray; ! sv = SCRIPT_SV(i); ! sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; ! } ! ! while (ga_scripts.ga_len < id) ! { ! sv = SCRIPT_SV(ga_scripts.ga_len + 1) = ! ALLOC_CLEAR_ONE(scriptvar_T); ! init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE); ! ++ga_scripts.ga_len; ! } ! } } /* --- 2448,2460 ---- void new_script_vars(scid_T id) { scriptvar_T *sv; ! sv = ALLOC_CLEAR_ONE(scriptvar_T); ! if (sv == NULL) ! return; ! init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE); ! SCRIPT_ITEM(id).sn_vars = sv; } /* *** ../vim-8.2.0113/src/scriptfile.c 2020-01-07 20:59:30.528926519 +0100 --- src/scriptfile.c 2020-01-12 17:32:14.280791534 +0100 *************** *** 1236,1242 **** save_current_sctx = current_sctx; current_sctx.sc_lnum = 0; ! current_sctx.sc_version = 1; // Check if this script was sourced before to finds its SID. // If it's new, generate a new SID. --- 1236,1242 ---- save_current_sctx = current_sctx; current_sctx.sc_lnum = 0; ! current_sctx.sc_version = 1; // default script version // Check if this script was sourced before to finds its SID. // If it's new, generate a new SID. *************** *** 1272,1277 **** --- 1272,1281 ---- { ++script_items.ga_len; SCRIPT_ITEM(script_items.ga_len).sn_name = NULL; + SCRIPT_ITEM(script_items.ga_len).sn_version = 1; + + // Allocate the local script variables to use for this script. + new_script_vars(script_items.ga_len); # ifdef FEAT_PROFILE SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE; # endif *************** *** 1289,1297 **** else si->sn_dev_valid = FALSE; # endif - - // Allocate the local script variables to use for this script. - new_script_vars(current_sctx.sc_sid); } # ifdef FEAT_PROFILE --- 1293,1298 ---- *************** *** 1483,1488 **** --- 1484,1491 ---- for (i = script_items.ga_len; i > 0; --i) { + // the variables themselves are cleared in evalvars_clear() + vim_free(SCRIPT_ITEM(i).sn_vars); vim_free(SCRIPT_ITEM(i).sn_name); # ifdef FEAT_PROFILE ga_clear(&SCRIPT_ITEM(i).sn_prl_ga); *************** *** 1791,1797 **** --- 1794,1803 ---- else if (nr > 4) semsg(_("E999: scriptversion not supported: %d"), nr); else + { current_sctx.sc_version = nr; + SCRIPT_ITEM(current_sctx.sc_sid).sn_version = nr; + } #endif } *** ../vim-8.2.0113/src/eval.c 2020-01-11 16:05:19.590287629 +0100 --- src/eval.c 2020-01-12 16:48:22.734902347 +0100 *************** *** 149,156 **** eval_clear(void) { evalvars_clear(); ! ! free_scriptnames(); free_locales(); // autoloaded script names --- 149,155 ---- eval_clear(void) { evalvars_clear(); ! free_scriptnames(); // must come after evalvars_clear(). free_locales(); // autoloaded script names *** ../vim-8.2.0113/src/version.c 2020-01-12 15:46:01.962935912 +0100 --- src/version.c 2020-01-12 16:56:59.836782312 +0100 *************** *** 744,745 **** --- 744,747 ---- { /* Add new patch number below this line */ + /**/ + 114, /**/ -- LETTERS TO THE EDITOR (The Times of London) Dear Sir, I am firmly opposed to the spread of microchips either to the home or to the office.  We have more than enough of them foisted upon us in public places.  They are a disgusting Americanism, and can only result in the farmers being forced to grow smaller potatoes, which in turn will cause massive unemployment in the already severely depressed agricultural industry. Yours faithfully,         Capt. Quinton D'Arcy, J. P.         Sevenoaks /// Bram Moolenaar -- Bram@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 ///