]> granicus.if.org Git - vim/commitdiff
patch 7.4.1638 v7.4.1638
authorBram Moolenaar <Bram@vim.org>
Tue, 22 Mar 2016 20:00:09 +0000 (21:00 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 22 Mar 2016 20:00:09 +0000 (21:00 +0100)
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)

src/eval.c
src/testdir/test_partial.vim
src/version.c

index b2338331f55c5a6c11be4e3cda69bb7b2eec4f12..d922e6aef943bd6dd1d71e9784df5b12abe41957 100644 (file)
@@ -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;
            }
index 3764f221fcd9b50283929307832531422bd30fbd..f67bb41dd8a74bc7cdb8fe6082529ff701058839 100644 (file)
@@ -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
index c9f1926acf3bfb64f1da0aff6489454500e1fca1..1a02fbe921cdd7c84495eabad3b3c924681c9090 100644 (file)
@@ -748,6 +748,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1638,
 /**/
     1637,
 /**/