Mercurial > vim
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 |