diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-07-14 21:08:49 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-07-14 21:08:49 +0200 |
commit | 1f22cc5cdb2da867d6bbf54dd371f279c38a2f56 (patch) | |
tree | 32d3ebe3de935d0e295c8725b160b1a723f5cfd7 | |
parent | 21c16f868d725fffc8fa36620cba33dd5f2ed576 (diff) | |
download | vim-git-1f22cc5cdb2da867d6bbf54dd371f279c38a2f56.tar.gz |
patch 8.2.1210: using ht_used when looping through a hashtab is less reliablev8.2.1210
Problem: Using ht_used when looping through a hashtab is less reliable.
Solution: Use ht_changed in a few more places.
-rw-r--r-- | src/if_py_both.h | 31 | ||||
-rw-r--r-- | src/userfunc.c | 20 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 26 insertions, 27 deletions
diff --git a/src/if_py_both.h b/src/if_py_both.h index 5bd6a0e67..8eb77470a 100644 --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -1792,11 +1792,10 @@ DictionaryContains(DictionaryObject *self, PyObject *keyObject) typedef struct { - hashitem_T *ht_array; - long_u ht_used; - hashtab_T *ht; - hashitem_T *hi; - long_u todo; + int dii_changed; + hashtab_T *dii_ht; + hashitem_T *dii_hi; + long_u dii_todo; } dictiterinfo_T; static PyObject * @@ -1804,23 +1803,22 @@ DictionaryIterNext(dictiterinfo_T **dii) { PyObject *ret; - if (!(*dii)->todo) + if (!(*dii)->dii_todo) return NULL; - if ((*dii)->ht->ht_array != (*dii)->ht_array || - (*dii)->ht->ht_used != (*dii)->ht_used) + if ((*dii)->dii_ht->ht_changed != (*dii)->dii_changed) { PyErr_SET_STRING(PyExc_RuntimeError, N_("hashtab changed during iteration")); return NULL; } - while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi)) - ++((*dii)->hi); + while (((*dii)->dii_todo) && HASHITEM_EMPTY((*dii)->dii_hi)) + ++((*dii)->dii_hi); - --((*dii)->todo); + --((*dii)->dii_todo); - if (!(ret = PyBytes_FromString((char *)(*dii)->hi->hi_key))) + if (!(ret = PyBytes_FromString((char *)(*dii)->dii_hi->hi_key))) return NULL; return ret; @@ -1839,11 +1837,10 @@ DictionaryIter(DictionaryObject *self) } 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; + 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, diff --git a/src/userfunc.c b/src/userfunc.c index 6e49c035c..b4b8ccf91 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1712,7 +1712,7 @@ free_all_functions(void) ufunc_T *fp; long_u skipped = 0; long_u todo = 1; - long_u used; + int changed; // Clean up the current_funccal chain and the funccal stack. while (current_funccal != NULL) @@ -1743,9 +1743,9 @@ free_all_functions(void) ++skipped; else { - used = func_hashtab.ht_used; + changed = func_hashtab.ht_changed; func_clear(fp, TRUE); - if (used != func_hashtab.ht_used) + if (changed != func_hashtab.ht_changed) { skipped = 0; break; @@ -2484,12 +2484,11 @@ untrans_function_name(char_u *name) 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; + int changed = func_hashtab.ht_changed; + long_u todo = func_hashtab.ht_used; hashitem_T *hi; - for (hi = ht_array; todo > 0 && !got_int; ++hi) + for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) { if (!HASHITEM_EMPTY(hi)) { @@ -2504,8 +2503,7 @@ list_functions(regmatch_T *regmatch) && vim_regexec(regmatch, fp->uf_name, 0))) { list_func_head(fp, FALSE); - if (used != func_hashtab.ht_used - || ht_array != func_hashtab.ht_array) + if (changed != func_hashtab.ht_changed) { emsg(_("E454: function list was modified")); return; @@ -3564,6 +3562,7 @@ get_expanded_name(char_u *name, int check) get_user_func_name(expand_T *xp, int idx) { static long_u done; + static int changed; static hashitem_T *hi; ufunc_T *fp; @@ -3571,8 +3570,9 @@ get_user_func_name(expand_T *xp, int idx) { done = 0; hi = func_hashtab.ht_array; + changed = func_hashtab.ht_changed; } - if (done < func_hashtab.ht_used) + if (changed == func_hashtab.ht_changed && done < func_hashtab.ht_used) { if (done++ > 0) ++hi; diff --git a/src/version.c b/src/version.c index f49eec973..6be113dca 100644 --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1210, +/**/ 1209, /**/ 1208, |