diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-09-17 15:44:52 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-09-17 15:44:52 +0100 |
commit | 0cdfb7ce462393595b0308dcabf343e82f05319d (patch) | |
tree | bce26a7c87ee0f99bc30006d3c0b02d813afc6da /src/eval.c | |
parent | 8abb584ab85d5855d810d1c6e2b260f45ec839b7 (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.c | 19 |
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 |