summaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-09-17 15:44:52 +0100
committerBram Moolenaar <Bram@vim.org>2022-09-17 15:44:52 +0100
commit0cdfb7ce462393595b0308dcabf343e82f05319d (patch)
treebce26a7c87ee0f99bc30006d3c0b02d813afc6da /src/eval.c
parent8abb584ab85d5855d810d1c6e2b260f45ec839b7 (diff)
patch 9.0.0485: in :def function all closures in loop get the same variablesv9.0.0485
Problem: In a :def function all closures in a loop get the same variables. Solution: Make a copy of loop variables used in a closure.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/eval.c b/src/eval.c
index d0957a145b..f280e2afc6 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -4857,6 +4857,12 @@ partial_free(partial_T *pt)
--pt->pt_funcstack->fs_refcount;
funcstack_check_refcount(pt->pt_funcstack);
}
+ // Similarly for loop variables.
+ if (pt->pt_loopvars != NULL)
+ {
+ --pt->pt_loopvars->lvs_refcount;
+ loopvars_check_refcount(pt->pt_loopvars);
+ }
vim_free(pt);
}
@@ -4875,8 +4881,13 @@ partial_unref(partial_T *pt)
// If the reference count goes down to one, the funcstack may be the
// only reference and can be freed if no other partials reference it.
- else if (pt->pt_refcount == 1 && pt->pt_funcstack != NULL)
- funcstack_check_refcount(pt->pt_funcstack);
+ else if (pt->pt_refcount == 1)
+ {
+ if (pt->pt_funcstack != NULL)
+ funcstack_check_refcount(pt->pt_funcstack);
+ if (pt->pt_loopvars != NULL)
+ loopvars_check_refcount(pt->pt_loopvars);
+ }
}
}
@@ -5016,6 +5027,9 @@ garbage_collect(int testing)
// funcstacks keep variables for closures
abort = abort || set_ref_in_funcstacks(copyID);
+ // loopvars keep variables for loop blocks
+ abort = abort || set_ref_in_loopvars(copyID);
+
// v: vars
abort = abort || garbage_collect_vimvars(copyID);
@@ -5379,6 +5393,7 @@ set_ref_in_item(
abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
ht_stack, list_stack);
// pt_funcstack is handled in set_ref_in_funcstacks()
+ // pt_loopvars is handled in set_ref_in_loopvars()
}
}
#ifdef FEAT_JOB_CHANNEL