Skip to content

Commit e4eb6ff

Browse files
committed
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)
1 parent 6c0e984 commit e4eb6ff

3 files changed

Lines changed: 19 additions & 3 deletions

File tree

src/eval.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12019,6 +12019,7 @@ partial_free(partial_T *pt)
1201912019
for (i = 0; i < pt->pt_argc; ++i)
1202012020
clear_tv(&pt->pt_argv[i]);
1202112021
vim_free(pt->pt_argv);
12022+
dict_unref(pt->pt_dict);
1202212023
func_unref(pt->pt_name);
1202312024
vim_free(pt->pt_name);
1202412025
vim_free(pt);
@@ -21797,16 +21798,20 @@ handle_subscript(
2179721798
selfdict = NULL;
2179821799
if (rettv->v_type == VAR_FUNC)
2179921800
{
21800-
/* just a function: use selfdict */
21801+
/* Just a function: Take over the function name and use
21802+
* selfdict. */
2180121803
pt->pt_name = rettv->vval.v_string;
2180221804
}
2180321805
else
2180421806
{
2180521807
partial_T *ret_pt = rettv->vval.v_partial;
2180621808
int i;
2180721809

21808-
/* partial: use selfdict and copy args */
21810+
/* Partial: copy the function name, use selfdict and copy
21811+
* args. Can't take over name or args, the partial might
21812+
* be referenced elsewhere. */
2180921813
pt->pt_name = vim_strsave(ret_pt->pt_name);
21814+
func_ref(pt->pt_name);
2181021815
if (ret_pt->pt_argc > 0)
2181121816
{
2181221817
pt->pt_argv = (typval_T *)alloc(
@@ -21823,7 +21828,6 @@ handle_subscript(
2182321828
}
2182421829
partial_unref(ret_pt);
2182521830
}
21826-
func_ref(pt->pt_name);
2182721831
rettv->v_type = VAR_PARTIAL;
2182821832
rettv->vval.v_partial = pt;
2182921833
}

src/testdir/test_partial.vim

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,13 @@ func Test_partial_string()
170170
let F = function('MyFunc', ['foo'], d)
171171
call assert_equal("function('MyFunc', ['foo'], {'one': 1})", string(F))
172172
endfunc
173+
174+
func Test_func_unref()
175+
let obj = {}
176+
function! obj.func() abort
177+
endfunction
178+
let funcnumber = matchstr(string(obj.func), '^function(''\zs.\{-}\ze''')
179+
call assert_true(exists('*{' . funcnumber . '}'))
180+
unlet obj
181+
call assert_false(exists('*{' . funcnumber . '}'))
182+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,8 @@ static char *(features[]) =
748748

749749
static int included_patches[] =
750750
{ /* Add new patch number below this line */
751+
/**/
752+
1638,
751753
/**/
752754
1637,
753755
/**/

0 commit comments

Comments
 (0)