comparison src/eval.c @ 4287:dc3efb6d5a08 v7.3.893

updated for version 7.3.893 Problem: Crash when using b:, w: or t: after closing the buffer, window or tabpage. Solution: Allocate the dictionary instead of having it part of the buffer/window/tabpage struct. (Yukihiro Nakadaira)
author Bram Moolenaar <bram@vim.org>
date Mon, 15 Apr 2013 12:27:36 +0200
parents 23ce9a61bdc2
children 11007e80829c
comparison
equal deleted inserted replaced
4286:afcc61d24129 4287:dc3efb6d5a08
2129 list_buf_vars(first) 2129 list_buf_vars(first)
2130 int *first; 2130 int *first;
2131 { 2131 {
2132 char_u numbuf[NUMBUFLEN]; 2132 char_u numbuf[NUMBUFLEN];
2133 2133
2134 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", 2134 list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
2135 TRUE, first); 2135 TRUE, first);
2136 2136
2137 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 2137 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
2138 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, 2138 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
2139 numbuf, first); 2139 numbuf, first);
2144 */ 2144 */
2145 static void 2145 static void
2146 list_win_vars(first) 2146 list_win_vars(first)
2147 int *first; 2147 int *first;
2148 { 2148 {
2149 list_hashtable_vars(&curwin->w_vars.dv_hashtab, 2149 list_hashtable_vars(&curwin->w_vars->dv_hashtab,
2150 (char_u *)"w:", TRUE, first); 2150 (char_u *)"w:", TRUE, first);
2151 } 2151 }
2152 2152
2153 #ifdef FEAT_WINDOWS 2153 #ifdef FEAT_WINDOWS
2154 /* 2154 /*
2156 */ 2156 */
2157 static void 2157 static void
2158 list_tab_vars(first) 2158 list_tab_vars(first)
2159 int *first; 2159 int *first;
2160 { 2160 {
2161 list_hashtable_vars(&curtab->tp_vars.dv_hashtab, 2161 list_hashtable_vars(&curtab->tp_vars->dv_hashtab,
2162 (char_u *)"t:", TRUE, first); 2162 (char_u *)"t:", TRUE, first);
2163 } 2163 }
2164 #endif 2164 #endif
2165 2165
2166 /* 2166 /*
3946 return cat_prefix_varname('g', hi->hi_key); 3946 return cat_prefix_varname('g', hi->hi_key);
3947 return hi->hi_key; 3947 return hi->hi_key;
3948 } 3948 }
3949 3949
3950 /* b: variables */ 3950 /* b: variables */
3951 ht = &curbuf->b_vars.dv_hashtab; 3951 ht = &curbuf->b_vars->dv_hashtab;
3952 if (bdone < ht->ht_used) 3952 if (bdone < ht->ht_used)
3953 { 3953 {
3954 if (bdone++ == 0) 3954 if (bdone++ == 0)
3955 hi = ht->ht_array; 3955 hi = ht->ht_array;
3956 else 3956 else
3964 ++bdone; 3964 ++bdone;
3965 return (char_u *)"b:changedtick"; 3965 return (char_u *)"b:changedtick";
3966 } 3966 }
3967 3967
3968 /* w: variables */ 3968 /* w: variables */
3969 ht = &curwin->w_vars.dv_hashtab; 3969 ht = &curwin->w_vars->dv_hashtab;
3970 if (wdone < ht->ht_used) 3970 if (wdone < ht->ht_used)
3971 { 3971 {
3972 if (wdone++ == 0) 3972 if (wdone++ == 0)
3973 hi = ht->ht_array; 3973 hi = ht->ht_array;
3974 else 3974 else
3978 return cat_prefix_varname('w', hi->hi_key); 3978 return cat_prefix_varname('w', hi->hi_key);
3979 } 3979 }
3980 3980
3981 #ifdef FEAT_WINDOWS 3981 #ifdef FEAT_WINDOWS
3982 /* t: variables */ 3982 /* t: variables */
3983 ht = &curtab->tp_vars.dv_hashtab; 3983 ht = &curtab->tp_vars->dv_hashtab;
3984 if (tdone < ht->ht_used) 3984 if (tdone < ht->ht_used)
3985 { 3985 {
3986 if (tdone++ == 0) 3986 if (tdone++ == 0)
3987 hi = ht->ht_array; 3987 hi = ht->ht_array;
3988 else 3988 else
6785 for (i = 1; i <= ga_scripts.ga_len; ++i) 6785 for (i = 1; i <= ga_scripts.ga_len; ++i)
6786 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 6786 set_ref_in_ht(&SCRIPT_VARS(i), copyID);
6787 6787
6788 /* buffer-local variables */ 6788 /* buffer-local variables */
6789 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6789 for (buf = firstbuf; buf != NULL; buf = buf->b_next)
6790 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 6790 set_ref_in_item(&buf->b_bufvar.di_tv, copyID);
6791 6791
6792 /* window-local variables */ 6792 /* window-local variables */
6793 FOR_ALL_TAB_WINDOWS(tp, wp) 6793 FOR_ALL_TAB_WINDOWS(tp, wp)
6794 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 6794 set_ref_in_item(&wp->w_winvar.di_tv, copyID);
6795 6795
6796 #ifdef FEAT_WINDOWS 6796 #ifdef FEAT_WINDOWS
6797 /* tabpage-local variables */ 6797 /* tabpage-local variables */
6798 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6798 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
6799 set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); 6799 set_ref_in_item(&tp->tp_winvar.di_tv, copyID);
6800 #endif 6800 #endif
6801 6801
6802 /* global variables */ 6802 /* global variables */
6803 set_ref_in_ht(&globvarht, copyID); 6803 set_ref_in_ht(&globvarht, copyID);
6804 6804
11154 /* let getbufvar({nr}, "") return the "b:" dictionary. The 11154 /* let getbufvar({nr}, "") return the "b:" dictionary. The
11155 * scope prefix before the NUL byte is required by 11155 * scope prefix before the NUL byte is required by
11156 * find_var_in_ht(). */ 11156 * find_var_in_ht(). */
11157 varname = (char_u *)"b:" + 2; 11157 varname = (char_u *)"b:" + 2;
11158 /* look up the variable */ 11158 /* look up the variable */
11159 v = find_var_in_ht(&curbuf->b_vars.dv_hashtab, varname, FALSE); 11159 v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, varname, FALSE);
11160 if (v != NULL) 11160 if (v != NULL)
11161 copy_tv(&v->di_tv, rettv); 11161 copy_tv(&v->di_tv, rettv);
11162 } 11162 }
11163 11163
11164 /* restore previous notion of curbuf */ 11164 /* restore previous notion of curbuf */
11777 varname = get_tv_string_chk(&argvars[1]); 11777 varname = get_tv_string_chk(&argvars[1]);
11778 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 11778 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
11779 if (tp != NULL && varname != NULL) 11779 if (tp != NULL && varname != NULL)
11780 { 11780 {
11781 /* look up the variable */ 11781 /* look up the variable */
11782 v = find_var_in_ht(&tp->tp_vars.dv_hashtab, varname, FALSE); 11782 v = find_var_in_ht(&tp->tp_vars->dv_hashtab, varname, FALSE);
11783 if (v != NULL) 11783 if (v != NULL)
11784 copy_tv(&v->di_tv, rettv); 11784 copy_tv(&v->di_tv, rettv);
11785 else if (argvars[2].v_type != VAR_UNKNOWN) 11785 else if (argvars[2].v_type != VAR_UNKNOWN)
11786 copy_tv(&argvars[2], rettv); 11786 copy_tv(&argvars[2], rettv);
11787 } 11787 }
11933 /* let getwinvar({nr}, "") return the "w:" dictionary. The 11933 /* let getwinvar({nr}, "") return the "w:" dictionary. The
11934 * scope prefix before the NUL byte is required by 11934 * scope prefix before the NUL byte is required by
11935 * find_var_in_ht(). */ 11935 * find_var_in_ht(). */
11936 varname = (char_u *)"w:" + 2; 11936 varname = (char_u *)"w:" + 2;
11937 /* look up the variable */ 11937 /* look up the variable */
11938 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 11938 v = find_var_in_ht(&win->w_vars->dv_hashtab, varname, FALSE);
11939 if (v != NULL) 11939 if (v != NULL)
11940 copy_tv(&v->di_tv, rettv); 11940 copy_tv(&v->di_tv, rettv);
11941 } 11941 }
11942 11942
11943 /* restore previous notion of curwin */ 11943 /* restore previous notion of curwin */
14331 14331
14332 rettv->vval.v_string = vim_strsave(buf); 14332 rettv->vval.v_string = vim_strsave(buf);
14333 rettv->v_type = VAR_STRING; 14333 rettv->v_type = VAR_STRING;
14334 } 14334 }
14335 14335
14336 #ifdef FEAT_MZSCHEME 14336 #if defined(FEAT_MZSCHEME) || defined(PROTO)
14337 /* 14337 /*
14338 * "mzeval()" function 14338 * "mzeval()" function
14339 */ 14339 */
14340 static void 14340 static void
14341 f_mzeval(argvars, rettv) 14341 f_mzeval(argvars, rettv)
20132 */ 20132 */
20133 if (vim_strchr(name + 2, ':') != NULL 20133 if (vim_strchr(name + 2, ':') != NULL
20134 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 20134 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL)
20135 return NULL; 20135 return NULL;
20136 if (*name == 'b') /* buffer variable */ 20136 if (*name == 'b') /* buffer variable */
20137 return &curbuf->b_vars.dv_hashtab; 20137 return &curbuf->b_vars->dv_hashtab;
20138 if (*name == 'w') /* window variable */ 20138 if (*name == 'w') /* window variable */
20139 return &curwin->w_vars.dv_hashtab; 20139 return &curwin->w_vars->dv_hashtab;
20140 #ifdef FEAT_WINDOWS 20140 #ifdef FEAT_WINDOWS
20141 if (*name == 't') /* tab page variable */ 20141 if (*name == 't') /* tab page variable */
20142 return &curtab->tp_vars.dv_hashtab; 20142 return &curtab->tp_vars->dv_hashtab;
20143 #endif 20143 #endif
20144 if (*name == 'v') /* v: variable */ 20144 if (*name == 'v') /* v: variable */
20145 return &vimvarht; 20145 return &vimvarht;
20146 if (*name == 'a' && current_funccal != NULL) /* function argument */ 20146 if (*name == 'a' && current_funccal != NULL) /* function argument */
20147 return &current_funccal->l_avars.dv_hashtab; 20147 return &current_funccal->l_avars.dv_hashtab;
20224 dict_var->di_tv.vval.v_dict = dict; 20224 dict_var->di_tv.vval.v_dict = dict;
20225 dict_var->di_tv.v_type = VAR_DICT; 20225 dict_var->di_tv.v_type = VAR_DICT;
20226 dict_var->di_tv.v_lock = VAR_FIXED; 20226 dict_var->di_tv.v_lock = VAR_FIXED;
20227 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 20227 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
20228 dict_var->di_key[0] = NUL; 20228 dict_var->di_key[0] = NUL;
20229 }
20230
20231 /*
20232 * Unreference a dictionary initialized by init_var_dict().
20233 */
20234 void
20235 unref_var_dict(dict)
20236 dict_T *dict;
20237 {
20238 /* Now the dict needs to be freed if no one else is using it, go back to
20239 * normal reference counting. */
20240 dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
20241 dict_unref(dict);
20229 } 20242 }
20230 20243
20231 /* 20244 /*
20232 * Clean up a list of internal variables. 20245 * Clean up a list of internal variables.
20233 * Frees all allocated variables and the value they contain. 20246 * Frees all allocated variables and the value they contain.