diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-03-22 21:00:09 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-03-22 21:00:09 +0100 |
commit | e4eb6ff089e79e659acf33c17dd0fda7177de526 (patch) | |
tree | 910b326824ce60fea246dcf913735c61610b29d9 | |
parent | 6c0e984f263fc1eef42c9b34a80eff1bceb8d05b (diff) | |
download | vim-e4eb6ff089e79e659acf33c17dd0fda7177de526.zip |
patch 7.4.1638
Problem: When binding a function to a dict the reference count is wrong.
Solution: Decrement dict reference count, only reference the function when
actually making a copy. (Ken Takata)
-rw-r--r-- | src/eval.c | 10 | ||||
-rw-r--r-- | src/testdir/test_partial.vim | 10 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 19 insertions, 3 deletions
diff --git a/src/eval.c b/src/eval.c index b2338331f..d922e6aef 100644 --- a/src/eval.c +++ b/src/eval.c @@ -12019,6 +12019,7 @@ partial_free(partial_T *pt) for (i = 0; i < pt->pt_argc; ++i) clear_tv(&pt->pt_argv[i]); vim_free(pt->pt_argv); + dict_unref(pt->pt_dict); func_unref(pt->pt_name); vim_free(pt->pt_name); vim_free(pt); @@ -21797,7 +21798,8 @@ handle_subscript( selfdict = NULL; if (rettv->v_type == VAR_FUNC) { - /* just a function: use selfdict */ + /* Just a function: Take over the function name and use + * selfdict. */ pt->pt_name = rettv->vval.v_string; } else @@ -21805,8 +21807,11 @@ handle_subscript( partial_T *ret_pt = rettv->vval.v_partial; int i; - /* partial: use selfdict and copy args */ + /* Partial: copy the function name, use selfdict and copy + * args. Can't take over name or args, the partial might + * be referenced elsewhere. */ pt->pt_name = vim_strsave(ret_pt->pt_name); + func_ref(pt->pt_name); if (ret_pt->pt_argc > 0) { pt->pt_argv = (typval_T *)alloc( @@ -21823,7 +21828,6 @@ handle_subscript( } partial_unref(ret_pt); } - func_ref(pt->pt_name); rettv->v_type = VAR_PARTIAL; rettv->vval.v_partial = pt; } diff --git a/src/testdir/test_partial.vim b/src/testdir/test_partial.vim index 3764f221f..f67bb41dd 100644 --- a/src/testdir/test_partial.vim +++ b/src/testdir/test_partial.vim @@ -170,3 +170,13 @@ func Test_partial_string() let F = function('MyFunc', ['foo'], d) call assert_equal("function('MyFunc', ['foo'], {'one': 1})", string(F)) endfunc + +func Test_func_unref() + let obj = {} + function! obj.func() abort + endfunction + let funcnumber = matchstr(string(obj.func), '^function(''\zs.\{-}\ze''') + call assert_true(exists('*{' . funcnumber . '}')) + unlet obj + call assert_false(exists('*{' . funcnumber . '}')) +endfunc diff --git a/src/version.c b/src/version.c index c9f1926ac..1a02fbe92 100644 --- a/src/version.c +++ b/src/version.c @@ -749,6 +749,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1638, +/**/ 1637, /**/ 1636, |