patch 9.2.0952: locking a container while stringifying can be improved
Commit:
https://github.com/vim/vim/commit/1af17441296d8e621661b5d04ce58d7c70198b38
Author: Hirohito Higashi <
h.eas...@gmail.com>
Date: Wed Aug 12 20:08:18 2026 +0000
patch 9.2.0952: locking a container while stringifying can be improved
Problem: The comments on locking a list or dict while stringifying its
items say the same thing three times over, and at more length
than the existing comments on the same construct
(after v9.2.0936).
Solution: Shorten them.
related: #21001
closes: #21029
Co-Authored-By: Claude Opus 5 (1M context) <
nor...@anthropic.com>
Signed-off-by: Hirohito Higashi <
h.eas...@gmail.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/dict.c b/src/dict.c
index 029fcfe78..4558272ac 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -816,10 +816,8 @@ dict2string(typval_T *tv, int copyID, int restore_copyID)
ga_init2(&ga, sizeof(char), 80);
ga_append(&ga, '{');
- // Lock the dictionary, so that user code that echo_string_core() below
- // may invoke, such as the string() method of an object, cannot remove
- // an item or add one and cause the hash table to be reallocated while
- // we are iterating over it.
+ // Lock the dict, the string() method of an object item could remove an
+ // item or make the hashtab resize while we iterate over it.
prev_lock = d->dv_lock;
if (d->dv_lock == 0)
d->dv_lock = VAR_LOCKED;
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 472b2fe02..1b8cce9da 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -9359,9 +9359,8 @@ find_some_match(typval_T *argvars, typval_T *rettv, matchtype_T type)
{
regmatch.rm_ic = p_ic;
- // Lock the list, so that the item the loop is standing on cannot
- // be freed by user code that echo_string() below may invoke: the
- // string() method of an object could remove the item.
+ // Lock the list, the string() method of an object item could remove
+ // the item the loop is standing on.
if (l != NULL)
{
prev_lock = l->lv_lock;
diff --git a/src/list.c b/src/list.c
index 7d57b125c..cf5374de2 100644
--- a/src/list.c
+++ b/src/list.c
@@ -1537,9 +1537,8 @@ list_join_inner(
// Stringify each item in the list.
CHECK_LIST_MATERIALIZE(l);
- // Lock the list, so that the item the loop is standing on cannot be
- // freed by user code that echo_string_core() below may invoke: the
- // string() method of an object could remove the item.
+ // Lock the list, the string() method of an object item could remove the
+ // item the loop is standing on.
prev_lock = l->lv_lock;
if (l->lv_lock == 0)
l->lv_lock = VAR_LOCKED;
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index c49d9dba0..7052ad171 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -1280,9 +1280,7 @@ func Test_match_list_changed_while_matching()
unlet g:mlist g:removed
endfunc
-" Same for join() and string(): stringifying an item can run the string()
-" method of an object, which must not be able to free the item the loop is
-" standing on.
+" Same for join() and string().
func Test_join_list_changed_while_stringified()
let lines =<< trim END
vim9script
@@ -1308,9 +1306,8 @@ func Test_join_list_changed_while_stringified()
unlet g:jlist g:removed
endfunc
-" Same for a dict: stringifying a value can run the string() method of an
-" object, which must not be able to remove an item and free it, or grow the
-" dict and reallocate the hash table, while it is being iterated over.
+" Same for a dict, where the item can also be added and reallocate the
+" hash table.
func Test_dict_changed_while_stringified()
let lines =<< trim END
vim9script
diff --git a/src/version.c b/src/version.c
index 31df22a94..b082b2d76 100644
--- a/src/version.c
+++ b/src/version.c
@@ -763,6 +763,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 952,
/**/
951,
/**/