Patch 8.2.1210
Problem: Using ht_used when looping through a hashtab is less reliable.
Solution: Use ht_changed in a few more places.
Files: src/userfunc.c, src/if_py_both.h
*** ../vim-8.2.1209/src/userfunc.c 2020-07-14 15:01:00.468662548 +0200
--- src/userfunc.c 2020-07-14 20:03:58.144390030 +0200
***************
*** 1712,1718 ****
ufunc_T *fp;
long_u skipped = 0;
long_u todo = 1;
! long_u used;
// Clean up the current_funccal chain and the funccal stack.
while (current_funccal != NULL)
--- 1712,1718 ----
ufunc_T *fp;
long_u skipped = 0;
long_u todo = 1;
! int changed;
// Clean up the current_funccal chain and the funccal stack.
while (current_funccal != NULL)
***************
*** 1743,1751 ****
++skipped;
else
{
! used = func_hashtab.ht_used;
func_clear(fp, TRUE);
! if (used != func_hashtab.ht_used)
{
skipped = 0;
break;
--- 1743,1751 ----
++skipped;
else
{
! changed = func_hashtab.ht_changed;
func_clear(fp, TRUE);
! if (changed != func_hashtab.ht_changed)
{
skipped = 0;
break;
***************
*** 2484,2495 ****
static void
list_functions(regmatch_T *regmatch)
{
! long_u used = func_hashtab.ht_used;
! long_u todo = used;
! hashitem_T *ht_array = func_hashtab.ht_array;
hashitem_T *hi;
! for (hi = ht_array; todo > 0 && !got_int; ++hi)
{
if (!HASHITEM_EMPTY(hi))
{
--- 2484,2494 ----
static void
list_functions(regmatch_T *regmatch)
{
! int changed = func_hashtab.ht_changed;
! long_u todo = func_hashtab.ht_used;
hashitem_T *hi;
! for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
{
if (!HASHITEM_EMPTY(hi))
{
***************
*** 2504,2511 ****
&& vim_regexec(regmatch, fp->uf_name, 0)))
{
list_func_head(fp, FALSE);
! if (used != func_hashtab.ht_used
! || ht_array != func_hashtab.ht_array)
{
emsg(_("E454: function list was modified"));
return;
--- 2503,2509 ----
&& vim_regexec(regmatch, fp->uf_name, 0)))
{
list_func_head(fp, FALSE);
! if (changed != func_hashtab.ht_changed)
{
emsg(_("E454: function list was modified"));
return;
***************
*** 3564,3569 ****
--- 3562,3568 ----
get_user_func_name(expand_T *xp, int idx)
{
static long_u done;
+ static int changed;
static hashitem_T *hi;
ufunc_T *fp;
***************
*** 3571,3578 ****
{
done = 0;
hi = func_hashtab.ht_array;
}
! if (done < func_hashtab.ht_used)
{
if (done++ > 0)
++hi;
--- 3570,3578 ----
{
done = 0;
hi = func_hashtab.ht_array;
+ changed = func_hashtab.ht_changed;
}
! if (changed == func_hashtab.ht_changed && done < func_hashtab.ht_used)
{
if (done++ > 0)
++hi;
*** ../vim-8.2.1209/src/if_py_both.h 2020-07-07 20:12:48.472693157 +0200
--- src/if_py_both.h 2020-07-14 19:30:48.990471480 +0200
***************
*** 1792,1802 ****
typedef struct
{
! hashitem_T *ht_array;
! long_u ht_used;
! hashtab_T *ht;
! hashitem_T *hi;
! long_u todo;
} dictiterinfo_T;
static PyObject *
--- 1792,1801 ----
typedef struct
{
! int dii_changed;
! hashtab_T *dii_ht;
! hashitem_T *dii_hi;
! long_u dii_todo;
} dictiterinfo_T;
static PyObject *
***************
*** 1804,1826 ****
{
PyObject *ret;
! if (!(*dii)->todo)
return NULL;
! if ((*dii)->ht->ht_array != (*dii)->ht_array ||
! (*dii)->ht->ht_used != (*dii)->ht_used)
{
PyErr_SET_STRING(PyExc_RuntimeError,
N_("hashtab changed during iteration"));
return NULL;
}
! while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi))
! ++((*dii)->hi);
! --((*dii)->todo);
! if (!(ret = PyBytes_FromString((char *)(*dii)->hi->hi_key)))
return NULL;
return ret;
--- 1803,1824 ----
{
PyObject *ret;
! if (!(*dii)->dii_todo)
return NULL;
! if ((*dii)->dii_ht->ht_changed != (*dii)->dii_changed)
{
PyErr_SET_STRING(PyExc_RuntimeError,
N_("hashtab changed during iteration"));
return NULL;
}
! while (((*dii)->dii_todo) && HASHITEM_EMPTY((*dii)->dii_hi))
! ++((*dii)->dii_hi);
! --((*dii)->dii_todo);
! if (!(ret = PyBytes_FromString((char *)(*dii)->dii_hi->hi_key)))
return NULL;
return ret;
***************
*** 1839,1849 ****
}
ht = &self->dict->dv_hashtab;
! dii->ht_array = ht->ht_array;
! dii->ht_used = ht->ht_used;
! dii->ht = ht;
! dii->hi = dii->ht_array;
! dii->todo = dii->ht_used;
return IterNew(dii,
(destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
--- 1837,1846 ----
}
ht = &self->dict->dv_hashtab;
! dii->dii_changed = ht->ht_changed;
! dii->dii_ht = ht;
! dii->dii_hi = ht->ht_array;
! dii->dii_todo = ht->ht_used;
return IterNew(dii,
(destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
*** ../vim-8.2.1209/src/version.c 2020-07-14 16:15:27.576652590 +0200
--- src/version.c 2020-07-14 19:17:44.316593201 +0200
***************
*** 756,757 ****
--- 756,759 ----
{ /* Add new patch number below this line */
+ /**/
+ 1210,
/**/
--
How To Keep A Healthy Level Of Insanity:
4. Put your garbage can on your desk and label it "in".
/// Bram Moolenaar -- Br...@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 ///