comparison src/eval.c @ 9723:80ac9cf77c9b v7.4.2137

commit https://github.com/vim/vim/commit/437bafe4c8a83ed71ee006eda7f54b65a90f0d4c Author: Bram Moolenaar <Bram@vim.org> Date: Mon Aug 1 15:40:54 2016 +0200 patch 7.4.2137 Problem: Using function() with a name will find another function when it is redefined. Solution: Add funcref(). Refer to lambda using a partial. Fix several reference counting issues.
author Christian Brabandt <cb@256bit.org>
date Mon, 01 Aug 2016 15:45:07 +0200
parents 6226de5f8137
children f85d94eee05b
comparison
equal deleted inserted replaced
9722:1557241fd3a7 9723:80ac9cf77c9b
5009 *arg = p + 1; 5009 *arg = p + 1;
5010 5010
5011 return OK; 5011 return OK;
5012 } 5012 }
5013 5013
5014 /*
5015 * Return the function name of the partial.
5016 */
5017 char_u *
5018 partial_name(partial_T *pt)
5019 {
5020 if (pt->pt_name != NULL)
5021 return pt->pt_name;
5022 return pt->pt_func->uf_name;
5023 }
5024
5014 static void 5025 static void
5015 partial_free(partial_T *pt) 5026 partial_free(partial_T *pt)
5016 { 5027 {
5017 int i; 5028 int i;
5018 5029
5019 for (i = 0; i < pt->pt_argc; ++i) 5030 for (i = 0; i < pt->pt_argc; ++i)
5020 clear_tv(&pt->pt_argv[i]); 5031 clear_tv(&pt->pt_argv[i]);
5021 vim_free(pt->pt_argv); 5032 vim_free(pt->pt_argv);
5022 dict_unref(pt->pt_dict); 5033 dict_unref(pt->pt_dict);
5023 func_unref(pt->pt_name); 5034 if (pt->pt_name != NULL)
5024 vim_free(pt->pt_name); 5035 {
5036 func_unref(pt->pt_name);
5037 vim_free(pt->pt_name);
5038 }
5039 else
5040 func_ptr_unref(pt->pt_func);
5025 vim_free(pt); 5041 vim_free(pt);
5026 } 5042 }
5027 5043
5028 /* 5044 /*
5029 * Unreference a closure: decrement the reference count and free it when it 5045 * Unreference a closure: decrement the reference count and free it when it
5049 int a1, a2; 5065 int a1, a2;
5050 int i; 5066 int i;
5051 5067
5052 /* empty and NULL function name considered the same */ 5068 /* empty and NULL function name considered the same */
5053 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string 5069 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
5054 : tv1->vval.v_partial->pt_name; 5070 : partial_name(tv1->vval.v_partial);
5055 if (s1 != NULL && *s1 == NUL) 5071 if (s1 != NULL && *s1 == NUL)
5056 s1 = NULL; 5072 s1 = NULL;
5057 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string 5073 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
5058 : tv2->vval.v_partial->pt_name; 5074 : partial_name(tv2->vval.v_partial);
5059 if (s2 != NULL && *s2 == NUL) 5075 if (s2 != NULL && *s2 == NUL)
5060 s2 = NULL; 5076 s2 = NULL;
5061 if (s1 == NULL || s2 == NULL) 5077 if (s1 == NULL || s2 == NULL)
5062 { 5078 {
5063 if (s1 != s2) 5079 if (s1 != s2)
5548 } 5564 }
5549 } 5565 }
5550 } 5566 }
5551 else if (tv->v_type == VAR_FUNC) 5567 else if (tv->v_type == VAR_FUNC)
5552 { 5568 {
5553 abort = set_ref_in_func(tv->vval.v_string, copyID); 5569 abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
5554 } 5570 }
5555 else if (tv->v_type == VAR_PARTIAL) 5571 else if (tv->v_type == VAR_PARTIAL)
5556 { 5572 {
5557 partial_T *pt = tv->vval.v_partial; 5573 partial_T *pt = tv->vval.v_partial;
5558 int i; 5574 int i;
5559 5575
5560 /* A partial does not have a copyID, because it cannot contain itself. 5576 /* A partial does not have a copyID, because it cannot contain itself.
5561 */ 5577 */
5562 if (pt != NULL) 5578 if (pt != NULL)
5563 { 5579 {
5564 abort = set_ref_in_func(pt->pt_name, copyID); 5580 abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
5565 5581
5566 if (pt->pt_dict != NULL) 5582 if (pt->pt_dict != NULL)
5567 { 5583 {
5568 typval_T dtv; 5584 typval_T dtv;
5569 5585
5733 5749
5734 case VAR_PARTIAL: 5750 case VAR_PARTIAL:
5735 { 5751 {
5736 partial_T *pt = tv->vval.v_partial; 5752 partial_T *pt = tv->vval.v_partial;
5737 char_u *fname = string_quote(pt == NULL ? NULL 5753 char_u *fname = string_quote(pt == NULL ? NULL
5738 : pt->pt_name, FALSE); 5754 : partial_name(pt), FALSE);
5739 garray_T ga; 5755 garray_T ga;
5740 int i; 5756 int i;
5741 char_u *tf; 5757 char_u *tf;
5742 5758
5743 ga_init2(&ga, 1, 100); 5759 ga_init2(&ga, 1, 100);
6869 6885
6870 /* Invoke the function. Recursive! */ 6886 /* Invoke the function. Recursive! */
6871 if (functv.v_type == VAR_PARTIAL) 6887 if (functv.v_type == VAR_PARTIAL)
6872 { 6888 {
6873 pt = functv.vval.v_partial; 6889 pt = functv.vval.v_partial;
6874 s = pt->pt_name; 6890 s = partial_name(pt);
6875 } 6891 }
6876 else 6892 else
6877 s = functv.vval.v_string; 6893 s = functv.vval.v_string;
6878 } 6894 }
6879 else 6895 else
10023 } 10039 }
10024 else if (expr->v_type == VAR_PARTIAL) 10040 else if (expr->v_type == VAR_PARTIAL)
10025 { 10041 {
10026 partial_T *partial = expr->vval.v_partial; 10042 partial_T *partial = expr->vval.v_partial;
10027 10043
10028 s = partial->pt_name; 10044 s = partial_name(partial);
10029 if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL, 10045 if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
10030 0L, 0L, &dummy, TRUE, partial, NULL) == FAIL) 10046 0L, 0L, &dummy, TRUE, partial, NULL) == FAIL)
10031 goto theend; 10047 goto theend;
10032 } 10048 }
10033 else 10049 else