To: vim_dev@googlegroups.com Subject: Patch 8.2.1210 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- 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 ///