summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2013-04-15 12:27:36 +0200
committerBram Moolenaar <Bram@vim.org>2013-04-15 12:27:36 +0200
commit429fa85392a934b34ba7b394558900cbb8786454 (patch)
tree2efc8dbb0c4727471c970f4c96ea37a9e9ba67e6 /src/eval.c
parent07219f911c86a50840050282baafe896284a5588 (diff)
downloadvim-429fa85392a934b34ba7b394558900cbb8786454.zip
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)
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/src/eval.c b/src/eval.c
index 49120b8c0..5f9ddb4d7 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2131,7 +2131,7 @@ list_buf_vars(first)
{
char_u numbuf[NUMBUFLEN];
- list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:",
+ list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
TRUE, first);
sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
@@ -2146,7 +2146,7 @@ list_buf_vars(first)
list_win_vars(first)
int *first;
{
- list_hashtable_vars(&curwin->w_vars.dv_hashtab,
+ list_hashtable_vars(&curwin->w_vars->dv_hashtab,
(char_u *)"w:", TRUE, first);
}
@@ -2158,7 +2158,7 @@ list_win_vars(first)
list_tab_vars(first)
int *first;
{
- list_hashtable_vars(&curtab->tp_vars.dv_hashtab,
+ list_hashtable_vars(&curtab->tp_vars->dv_hashtab,
(char_u *)"t:", TRUE, first);
}
#endif
@@ -3948,7 +3948,7 @@ get_user_var_name(xp, idx)
}
/* b: variables */
- ht = &curbuf->b_vars.dv_hashtab;
+ ht = &curbuf->b_vars->dv_hashtab;
if (bdone < ht->ht_used)
{
if (bdone++ == 0)
@@ -3966,7 +3966,7 @@ get_user_var_name(xp, idx)
}
/* w: variables */
- ht = &curwin->w_vars.dv_hashtab;
+ ht = &curwin->w_vars->dv_hashtab;
if (wdone < ht->ht_used)
{
if (wdone++ == 0)
@@ -3980,7 +3980,7 @@ get_user_var_name(xp, idx)
#ifdef FEAT_WINDOWS
/* t: variables */
- ht = &curtab->tp_vars.dv_hashtab;
+ ht = &curtab->tp_vars->dv_hashtab;
if (tdone < ht->ht_used)
{
if (tdone++ == 0)
@@ -6787,16 +6787,16 @@ garbage_collect()
/* buffer-local variables */
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
- set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID);
+ set_ref_in_item(&buf->b_bufvar.di_tv, copyID);
/* window-local variables */
FOR_ALL_TAB_WINDOWS(tp, wp)
- set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID);
+ set_ref_in_item(&wp->w_winvar.di_tv, copyID);
#ifdef FEAT_WINDOWS
/* tabpage-local variables */
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
- set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID);
+ set_ref_in_item(&tp->tp_winvar.di_tv, copyID);
#endif
/* global variables */
@@ -11156,7 +11156,7 @@ f_getbufvar(argvars, rettv)
* find_var_in_ht(). */
varname = (char_u *)"b:" + 2;
/* look up the variable */
- v = find_var_in_ht(&curbuf->b_vars.dv_hashtab, varname, FALSE);
+ v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, varname, FALSE);
if (v != NULL)
copy_tv(&v->di_tv, rettv);
}
@@ -11779,7 +11779,7 @@ f_gettabvar(argvars, rettv)
if (tp != NULL && varname != NULL)
{
/* look up the variable */
- v = find_var_in_ht(&tp->tp_vars.dv_hashtab, varname, FALSE);
+ v = find_var_in_ht(&tp->tp_vars->dv_hashtab, varname, FALSE);
if (v != NULL)
copy_tv(&v->di_tv, rettv);
else if (argvars[2].v_type != VAR_UNKNOWN)
@@ -11935,7 +11935,7 @@ getwinvar(argvars, rettv, off)
* find_var_in_ht(). */
varname = (char_u *)"w:" + 2;
/* look up the variable */
- v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE);
+ v = find_var_in_ht(&win->w_vars->dv_hashtab, varname, FALSE);
if (v != NULL)
copy_tv(&v->di_tv, rettv);
}
@@ -14333,7 +14333,7 @@ f_mode(argvars, rettv)
rettv->v_type = VAR_STRING;
}
-#ifdef FEAT_MZSCHEME
+#if defined(FEAT_MZSCHEME) || defined(PROTO)
/*
* "mzeval()" function
*/
@@ -20134,12 +20134,12 @@ find_var_ht(name, varname)
|| vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL)
return NULL;
if (*name == 'b') /* buffer variable */
- return &curbuf->b_vars.dv_hashtab;
+ return &curbuf->b_vars->dv_hashtab;
if (*name == 'w') /* window variable */
- return &curwin->w_vars.dv_hashtab;
+ return &curwin->w_vars->dv_hashtab;
#ifdef FEAT_WINDOWS
if (*name == 't') /* tab page variable */
- return &curtab->tp_vars.dv_hashtab;
+ return &curtab->tp_vars->dv_hashtab;
#endif
if (*name == 'v') /* v: variable */
return &vimvarht;
@@ -20229,6 +20229,19 @@ init_var_dict(dict, dict_var, scope)
}
/*
+ * Unreference a dictionary initialized by init_var_dict().
+ */
+ void
+unref_var_dict(dict)
+ dict_T *dict;
+{
+ /* Now the dict needs to be freed if no one else is using it, go back to
+ * normal reference counting. */
+ dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
+ dict_unref(dict);
+}
+
+/*
* Clean up a list of internal variables.
* Frees all allocated variables and the value they contain.
* Clears hashtab "ht", does not free it.