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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202007141909.06EJ9J073125495%40masaka.moolenaar.net.

Raspunde prin e-mail lui