comparison src/userfunc.c @ 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 e641f678bdb9
children aa7675a4a0cd
comparison
equal deleted inserted replaced
21318:b1121f5c029a 21319:fb3dcd8ed14d
1710 { 1710 {
1711 hashitem_T *hi; 1711 hashitem_T *hi;
1712 ufunc_T *fp; 1712 ufunc_T *fp;
1713 long_u skipped = 0; 1713 long_u skipped = 0;
1714 long_u todo = 1; 1714 long_u todo = 1;
1715 long_u used; 1715 int changed;
1716 1716
1717 // Clean up the current_funccal chain and the funccal stack. 1717 // Clean up the current_funccal chain and the funccal stack.
1718 while (current_funccal != NULL) 1718 while (current_funccal != NULL)
1719 { 1719 {
1720 clear_tv(current_funccal->rettv); 1720 clear_tv(current_funccal->rettv);
1741 // supposed to be freed when no longer referenced. 1741 // supposed to be freed when no longer referenced.
1742 if (func_name_refcount(fp->uf_name)) 1742 if (func_name_refcount(fp->uf_name))
1743 ++skipped; 1743 ++skipped;
1744 else 1744 else
1745 { 1745 {
1746 used = func_hashtab.ht_used; 1746 changed = func_hashtab.ht_changed;
1747 func_clear(fp, TRUE); 1747 func_clear(fp, TRUE);
1748 if (used != func_hashtab.ht_used) 1748 if (changed != func_hashtab.ht_changed)
1749 { 1749 {
1750 skipped = 0; 1750 skipped = 0;
1751 break; 1751 break;
1752 } 1752 }
1753 } 1753 }
2482 * Otherwise functions matching "regmatch". 2482 * Otherwise functions matching "regmatch".
2483 */ 2483 */
2484 static void 2484 static void
2485 list_functions(regmatch_T *regmatch) 2485 list_functions(regmatch_T *regmatch)
2486 { 2486 {
2487 long_u used = func_hashtab.ht_used; 2487 int changed = func_hashtab.ht_changed;
2488 long_u todo = used; 2488 long_u todo = func_hashtab.ht_used;
2489 hashitem_T *ht_array = func_hashtab.ht_array;
2490 hashitem_T *hi; 2489 hashitem_T *hi;
2491 2490
2492 for (hi = ht_array; todo > 0 && !got_int; ++hi) 2491 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
2493 { 2492 {
2494 if (!HASHITEM_EMPTY(hi)) 2493 if (!HASHITEM_EMPTY(hi))
2495 { 2494 {
2496 ufunc_T *fp = HI2UF(hi); 2495 ufunc_T *fp = HI2UF(hi);
2497 2496
2502 && !func_name_refcount(fp->uf_name) 2501 && !func_name_refcount(fp->uf_name)
2503 : !isdigit(*fp->uf_name) 2502 : !isdigit(*fp->uf_name)
2504 && vim_regexec(regmatch, fp->uf_name, 0))) 2503 && vim_regexec(regmatch, fp->uf_name, 0)))
2505 { 2504 {
2506 list_func_head(fp, FALSE); 2505 list_func_head(fp, FALSE);
2507 if (used != func_hashtab.ht_used 2506 if (changed != func_hashtab.ht_changed)
2508 || ht_array != func_hashtab.ht_array)
2509 { 2507 {
2510 emsg(_("E454: function list was modified")); 2508 emsg(_("E454: function list was modified"));
2511 return; 2509 return;
2512 } 2510 }
2513 } 2511 }
3562 */ 3560 */
3563 char_u * 3561 char_u *
3564 get_user_func_name(expand_T *xp, int idx) 3562 get_user_func_name(expand_T *xp, int idx)
3565 { 3563 {
3566 static long_u done; 3564 static long_u done;
3565 static int changed;
3567 static hashitem_T *hi; 3566 static hashitem_T *hi;
3568 ufunc_T *fp; 3567 ufunc_T *fp;
3569 3568
3570 if (idx == 0) 3569 if (idx == 0)
3571 { 3570 {
3572 done = 0; 3571 done = 0;
3573 hi = func_hashtab.ht_array; 3572 hi = func_hashtab.ht_array;
3574 } 3573 changed = func_hashtab.ht_changed;
3575 if (done < func_hashtab.ht_used) 3574 }
3575 if (changed == func_hashtab.ht_changed && done < func_hashtab.ht_used)
3576 { 3576 {
3577 if (done++ > 0) 3577 if (done++ > 0)
3578 ++hi; 3578 ++hi;
3579 while (HASHITEM_EMPTY(hi)) 3579 while (HASHITEM_EMPTY(hi))
3580 ++hi; 3580 ++hi;