comparison src/if_py_both.h @ 21319:fb3dcd8ed14d v8.2.1210

patch 8.2.1210: using ht_used when looping through a hashtab is less reliable Commit: https://github.com/vim/vim/commit/1f22cc5cdb2da867d6bbf54dd371f279c38a2f56 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jul 14 21:08:49 2020 +0200 patch 8.2.1210: using ht_used when looping through a hashtab is less reliable Problem: Using ht_used when looping through a hashtab is less reliable. Solution: Use ht_changed in a few more places.
author Bram Moolenaar <Bram@vim.org>
date Tue, 14 Jul 2020 21:15:04 +0200
parents 8531ddd7dd63
children d1a7088c6efe
comparison
equal deleted inserted replaced
21318:b1121f5c029a 21319:fb3dcd8ed14d
1790 return ret; 1790 return ret;
1791 } 1791 }
1792 1792
1793 typedef struct 1793 typedef struct
1794 { 1794 {
1795 hashitem_T *ht_array; 1795 int dii_changed;
1796 long_u ht_used; 1796 hashtab_T *dii_ht;
1797 hashtab_T *ht; 1797 hashitem_T *dii_hi;
1798 hashitem_T *hi; 1798 long_u dii_todo;
1799 long_u todo;
1800 } dictiterinfo_T; 1799 } dictiterinfo_T;
1801 1800
1802 static PyObject * 1801 static PyObject *
1803 DictionaryIterNext(dictiterinfo_T **dii) 1802 DictionaryIterNext(dictiterinfo_T **dii)
1804 { 1803 {
1805 PyObject *ret; 1804 PyObject *ret;
1806 1805
1807 if (!(*dii)->todo) 1806 if (!(*dii)->dii_todo)
1808 return NULL; 1807 return NULL;
1809 1808
1810 if ((*dii)->ht->ht_array != (*dii)->ht_array || 1809 if ((*dii)->dii_ht->ht_changed != (*dii)->dii_changed)
1811 (*dii)->ht->ht_used != (*dii)->ht_used)
1812 { 1810 {
1813 PyErr_SET_STRING(PyExc_RuntimeError, 1811 PyErr_SET_STRING(PyExc_RuntimeError,
1814 N_("hashtab changed during iteration")); 1812 N_("hashtab changed during iteration"));
1815 return NULL; 1813 return NULL;
1816 } 1814 }
1817 1815
1818 while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi)) 1816 while (((*dii)->dii_todo) && HASHITEM_EMPTY((*dii)->dii_hi))
1819 ++((*dii)->hi); 1817 ++((*dii)->dii_hi);
1820 1818
1821 --((*dii)->todo); 1819 --((*dii)->dii_todo);
1822 1820
1823 if (!(ret = PyBytes_FromString((char *)(*dii)->hi->hi_key))) 1821 if (!(ret = PyBytes_FromString((char *)(*dii)->dii_hi->hi_key)))
1824 return NULL; 1822 return NULL;
1825 1823
1826 return ret; 1824 return ret;
1827 } 1825 }
1828 1826
1837 PyErr_NoMemory(); 1835 PyErr_NoMemory();
1838 return NULL; 1836 return NULL;
1839 } 1837 }
1840 1838
1841 ht = &self->dict->dv_hashtab; 1839 ht = &self->dict->dv_hashtab;
1842 dii->ht_array = ht->ht_array; 1840 dii->dii_changed = ht->ht_changed;
1843 dii->ht_used = ht->ht_used; 1841 dii->dii_ht = ht;
1844 dii->ht = ht; 1842 dii->dii_hi = ht->ht_array;
1845 dii->hi = dii->ht_array; 1843 dii->dii_todo = ht->ht_used;
1846 dii->todo = dii->ht_used;
1847 1844
1848 return IterNew(dii, 1845 return IterNew(dii,
1849 (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext, 1846 (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
1850 NULL, NULL); 1847 NULL, NULL);
1851 } 1848 }