Mercurial > vim
diff src/vim9script.c @ 22643:71b57779177d v8.2.1870
patch 8.2.1870: Vim9: no need to keep all script variables
Commit: https://github.com/vim/vim/commit/39ca4127a094d8aca6f77c01be4f3fea506d5cb7
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Oct 20 14:25:07 2020 +0200
patch 8.2.1870: Vim9: no need to keep all script variables
Problem: Vim9: no need to keep all script variables.
Solution: Only keep script variables when a function was defined that could
use them. Fix freeing static string on exit.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 20 Oct 2020 14:30:04 +0200 |
parents | 107eae953b87 |
children | 05ecd9d23c1d |
line wrap: on
line diff
--- a/src/vim9script.c +++ b/src/vim9script.c @@ -51,8 +51,8 @@ ex_vim9script(exarg_T *eap) if (STRCMP(p_cpo, CPO_VIM) != 0) { - si->sn_save_cpo = p_cpo; - p_cpo = vim_strsave((char_u *)CPO_VIM); + si->sn_save_cpo = vim_strsave(p_cpo); + set_option_value((char_u *)"cpo", 0L, (char_u *)CPO_VIM, 0); } } @@ -569,8 +569,8 @@ vim9_declare_scriptvar(exarg_T *eap, cha } /* - * Vim9 part of adding a script variable: add it to sn_all_vars and - * sn_var_vals. + * Vim9 part of adding a script variable: add it to sn_all_vars (lookup by name + * with a hashtable) and sn_var_vals (lookup by index). * When "type" is NULL use "tv" for the type. */ void @@ -628,9 +628,11 @@ add_vim9_script_var(dictitem_T *di, typv /* * Hide a script variable when leaving a block. * "idx" is de index in sn_var_vals. + * When "func_defined" is non-zero then a function was defined in this block, + * the variable may be accessed by it. Otherwise the variable can be cleared. */ void -hide_script_var(scriptitem_T *si, int idx) +hide_script_var(scriptitem_T *si, int idx, int func_defined) { svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx; hashtab_T *script_ht = get_script_local_ht(); @@ -639,6 +641,7 @@ hide_script_var(scriptitem_T *si, int id hashitem_T *all_hi; // Remove a variable declared inside the block, if it still exists. + // If it was added in a nested block it will already have been removed. // The typval is moved into the sallvar_T. script_hi = hash_find(script_ht, sv->sv_name); all_hi = hash_find(all_ht, sv->sv_name); @@ -646,19 +649,36 @@ hide_script_var(scriptitem_T *si, int id { dictitem_T *di = HI2DI(script_hi); sallvar_T *sav = HI2SAV(all_hi); + sallvar_T *sav_prev = NULL; // There can be multiple entries with the same name in different // blocks, find the right one. while (sav != NULL && sav->sav_var_vals_idx != idx) + { + sav_prev = sav; sav = sav->sav_next; + } if (sav != NULL) { - sav->sav_tv = di->di_tv; - di->di_tv.v_type = VAR_UNKNOWN; - sav->sav_flags = di->di_flags; - sav->sav_di = NULL; + if (func_defined) + { + // move the typval from the dictitem to the sallvar + sav->sav_tv = di->di_tv; + di->di_tv.v_type = VAR_UNKNOWN; + sav->sav_flags = di->di_flags; + sav->sav_di = NULL; + sv->sv_tv = &sav->sav_tv; + } + else + { + if (sav_prev == NULL) + hash_remove(all_ht, all_hi); + else + sav_prev->sav_next = sav->sav_next; + sv->sv_name = NULL; + vim_free(sav); + } delete_var(script_ht, script_hi); - sv->sv_tv = &sav->sav_tv; } } }