Mercurial > vim
comparison src/eval.c @ 364:5332dd13733c v7.0094
updated for version 7.0094
author | vimboss |
---|---|
date | Sun, 26 Jun 2005 22:34:35 +0000 |
parents | 6c62b9b939bd |
children | 4b9fef49d7ff |
comparison
equal
deleted
inserted
replaced
363:dbf2e948e7e6 | 364:5332dd13733c |
---|---|
121 * Also in functions. We need a special hashtable for them. | 121 * Also in functions. We need a special hashtable for them. |
122 */ | 122 */ |
123 static hashtab_T compat_hashtab; | 123 static hashtab_T compat_hashtab; |
124 | 124 |
125 /* | 125 /* |
126 * When recursively copying lists and dicts we need to remember which ones we | |
127 * have done to avoid endless recursiveness. This unique ID is used for that. | |
128 */ | |
129 static int current_copyID = 0; | |
130 | |
131 /* | |
126 * Array to hold the hashtab with variables local to each sourced script. | 132 * Array to hold the hashtab with variables local to each sourced script. |
127 * Each item holds a variable (nameless) that points to the dict_T. | 133 * Each item holds a variable (nameless) that points to the dict_T. |
128 */ | 134 */ |
129 typedef struct | 135 typedef struct |
130 { | 136 { |
182 | 188 |
183 /* function flags */ | 189 /* function flags */ |
184 #define FC_ABORT 1 /* abort function on error */ | 190 #define FC_ABORT 1 /* abort function on error */ |
185 #define FC_RANGE 2 /* function accepts range */ | 191 #define FC_RANGE 2 /* function accepts range */ |
186 #define FC_DICT 4 /* Dict function, uses "self" */ | 192 #define FC_DICT 4 /* Dict function, uses "self" */ |
193 | |
194 #define DEL_REFCOUNT 999999 /* list/dict is being deleted */ | |
187 | 195 |
188 /* | 196 /* |
189 * All user-defined functions are found in this hash table. | 197 * All user-defined functions are found in this hash table. |
190 */ | 198 */ |
191 static hashtab_T func_hashtab; | 199 static hashtab_T func_hashtab; |
371 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); | 379 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); |
372 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); | 380 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); |
373 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); | 381 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); |
374 static char_u *list2string __ARGS((typval_T *tv)); | 382 static char_u *list2string __ARGS((typval_T *tv)); |
375 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); | 383 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); |
384 | |
385 static int count_self_ref __ARGS((void *p, int type)); | |
386 static int count_ref_in_dict __ARGS((dict_T *d, void *rp, int copyID, garray_T *gap)); | |
387 static int count_ref_in_list __ARGS((list_T *l, void *rp, int copyID, garray_T *gap)); | |
388 static int count_ref_item __ARGS((typval_T *tv, void *rp, int copyID, garray_T *gap)); | |
376 | 389 |
377 static void dict_unref __ARGS((dict_T *d)); | 390 static void dict_unref __ARGS((dict_T *d)); |
378 static void dict_free __ARGS((dict_T *d)); | 391 static void dict_free __ARGS((dict_T *d)); |
379 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); | 392 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); |
380 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); | 393 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); |
717 | 730 |
718 for (i = 0; i < VV_LEN; ++i) | 731 for (i = 0; i < VV_LEN; ++i) |
719 { | 732 { |
720 p = &vimvars[i]; | 733 p = &vimvars[i]; |
721 if (p->vv_di.di_tv.v_type == VAR_STRING) | 734 if (p->vv_di.di_tv.v_type == VAR_STRING) |
735 { | |
722 vim_free(p->vv_di.di_tv.vval.v_string); | 736 vim_free(p->vv_di.di_tv.vval.v_string); |
737 p->vv_di.di_tv.vval.v_string = NULL; | |
738 } | |
723 } | 739 } |
724 hash_clear(&vimvarht); | 740 hash_clear(&vimvarht); |
725 hash_clear(&compat_hashtab); | 741 hash_clear(&compat_hashtab); |
726 | 742 |
727 /* script-local variables */ | 743 /* script-local variables */ |
728 for (i = 1; i <= ga_scripts.ga_len; ++i) | 744 for (i = 1; i <= ga_scripts.ga_len; ++i) |
729 vars_clear(&SCRIPT_VARS(i)); | 745 vars_clear(&SCRIPT_VARS(i)); |
730 ga_clear(&ga_scripts); | 746 ga_clear(&ga_scripts); |
747 free_scriptnames(); | |
731 | 748 |
732 /* global variables */ | 749 /* global variables */ |
733 vars_clear(&globvarht); | 750 vars_clear(&globvarht); |
751 | |
752 free_all_functions(); | |
734 } | 753 } |
735 #endif | 754 #endif |
736 | 755 |
737 /* | 756 /* |
738 * Return the name of the executed function. | 757 * Return the name of the executed function. |
4935 */ | 4954 */ |
4936 static void | 4955 static void |
4937 list_unref(l) | 4956 list_unref(l) |
4938 list_T *l; | 4957 list_T *l; |
4939 { | 4958 { |
4940 if (l != NULL && --l->lv_refcount <= 0) | 4959 int selfref; |
4941 list_free(l); | 4960 |
4961 if (l != NULL && l->lv_refcount != DEL_REFCOUNT) | |
4962 { | |
4963 if (--l->lv_refcount > 0) | |
4964 { | |
4965 /* Check if the dict contains references to itself. These need to | |
4966 * be subtracted from the reference count to find out if we can | |
4967 * delete the dict. */ | |
4968 selfref = count_self_ref(l, VAR_LIST); | |
4969 } | |
4970 else | |
4971 selfref = 0; | |
4972 if (l->lv_refcount - selfref == 0) | |
4973 /* No references to the list now, free it. */ | |
4974 list_free(l); | |
4975 } | |
4942 } | 4976 } |
4943 | 4977 |
4944 /* | 4978 /* |
4945 * Free a list, including all items it points to. | 4979 * Free a list, including all items it points to. |
4946 * Ignores the reference count. | 4980 * Ignores the reference count. |
4948 static void | 4982 static void |
4949 list_free(l) | 4983 list_free(l) |
4950 list_T *l; | 4984 list_T *l; |
4951 { | 4985 { |
4952 listitem_T *item; | 4986 listitem_T *item; |
4953 listitem_T *next; | 4987 |
4954 | 4988 /* Avoid that recursive reference to the list frees us again. */ |
4955 for (item = l->lv_first; item != NULL; item = next) | 4989 l->lv_refcount = DEL_REFCOUNT; |
4956 { | 4990 |
4957 next = item->li_next; | 4991 for (item = l->lv_first; item != NULL; item = l->lv_first) |
4992 { | |
4993 /* Remove the item before deleting it. */ | |
4994 l->lv_first = item->li_next; | |
4958 listitem_free(item); | 4995 listitem_free(item); |
4959 } | 4996 } |
4960 vim_free(l); | 4997 vim_free(l); |
4961 } | 4998 } |
4962 | 4999 |
5529 } | 5566 } |
5530 return OK; | 5567 return OK; |
5531 } | 5568 } |
5532 | 5569 |
5533 /* | 5570 /* |
5571 * Count the number of references for list/dict "p" inside itself. | |
5572 * This is used to find out if there are no more references elsewhere. | |
5573 * The tricky bit is that we must not count references in lists/dicts that are | |
5574 * used elsewhere, but we can only know by counting their references... | |
5575 * This is a bit slow, but required to avoid leaking memory. | |
5576 */ | |
5577 static int | |
5578 count_self_ref(p, type) | |
5579 void *p; | |
5580 int type; | |
5581 { | |
5582 garray_T ga; | |
5583 typval_T *tv; | |
5584 int selfref; | |
5585 int i; | |
5586 int n; | |
5587 | |
5588 ga_init2(&ga, sizeof(typval_T *), 10); | |
5589 if (type == VAR_DICT) | |
5590 selfref = count_ref_in_dict(p, p, ++current_copyID, &ga); | |
5591 else | |
5592 selfref = count_ref_in_list(p, p, ++current_copyID, &ga); | |
5593 for (i = 0; i < ga.ga_len; ++i) | |
5594 { | |
5595 tv = ((typval_T **)ga.ga_data)[i]; | |
5596 if (tv->v_type == VAR_DICT) | |
5597 { | |
5598 n = count_ref_in_dict(tv->vval.v_dict, tv->vval.v_dict, | |
5599 ++current_copyID, NULL); | |
5600 if (n < tv->vval.v_dict->dv_refcount) | |
5601 { | |
5602 selfref = 0; | |
5603 break; | |
5604 } | |
5605 } | |
5606 else | |
5607 { | |
5608 n = count_ref_in_list(tv->vval.v_list, tv->vval.v_list, | |
5609 ++current_copyID, NULL); | |
5610 if (n < tv->vval.v_list->lv_refcount) | |
5611 { | |
5612 selfref = 0; | |
5613 break; | |
5614 } | |
5615 } | |
5616 } | |
5617 | |
5618 ga_clear(&ga); | |
5619 return selfref; | |
5620 } | |
5621 | |
5622 /* | |
5623 * Count number of references to "rp" in dictionary "d" and its members. | |
5624 * We use "copyID" to avoid recursing into the same list/dict twice. | |
5625 */ | |
5626 static int | |
5627 count_ref_in_dict(d, rp, copyID, gap) | |
5628 dict_T *d; | |
5629 void *rp; | |
5630 int copyID; | |
5631 garray_T *gap; | |
5632 { | |
5633 int todo; | |
5634 hashitem_T *hi; | |
5635 int n = 0; | |
5636 | |
5637 todo = d->dv_hashtab.ht_used; | |
5638 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) | |
5639 if (!HASHITEM_EMPTY(hi)) | |
5640 { | |
5641 --todo; | |
5642 n += count_ref_item(&HI2DI(hi)->di_tv, rp, copyID, gap); | |
5643 } | |
5644 return n; | |
5645 } | |
5646 | |
5647 /* | |
5648 * Count number of references to "rp" in list "l" and its members. | |
5649 * We use "copyID" to avoid recursing into the same list/dict twice. | |
5650 */ | |
5651 static int | |
5652 count_ref_in_list(l, rp, copyID, gap) | |
5653 list_T *l; | |
5654 void *rp; | |
5655 int copyID; | |
5656 garray_T *gap; | |
5657 { | |
5658 listitem_T *li; | |
5659 int n = 0; | |
5660 | |
5661 for (li = l->lv_first; li != NULL; li = li->li_next) | |
5662 n += count_ref_item(&li->li_tv, rp, copyID, gap); | |
5663 return n; | |
5664 } | |
5665 | |
5666 /* | |
5667 * Count number of references to "rp" in item "tv" and any members. | |
5668 * We use "copyID" to avoid recursing into the same list/dict twice. | |
5669 * When "gap" is not NULL store items that require checking for only | |
5670 * references inside the structure. | |
5671 */ | |
5672 static int | |
5673 count_ref_item(tv, rp, copyID, gap) | |
5674 typval_T *tv; | |
5675 void *rp; | |
5676 int copyID; | |
5677 garray_T *gap; | |
5678 { | |
5679 dict_T *dd; | |
5680 list_T *ll; | |
5681 int n; | |
5682 | |
5683 switch (tv->v_type) | |
5684 { | |
5685 case VAR_DICT: | |
5686 dd = tv->vval.v_dict; | |
5687 if (dd == rp) | |
5688 return 1; /* match, count it */ | |
5689 if (dd->dv_copyID == copyID) | |
5690 return 0; /* already inspected this dict */ | |
5691 dd->dv_copyID = copyID; | |
5692 n = count_ref_in_dict(dd, rp, copyID, gap); | |
5693 if (n > 0 && gap != NULL && dd->dv_refcount > 1) | |
5694 { | |
5695 /* We must later check that the references to this dict are | |
5696 * all in the structure we are freeing. */ | |
5697 if (ga_grow(gap, 1) == FAIL) | |
5698 return 0; | |
5699 ((typval_T **)gap->ga_data)[gap->ga_len++] = tv; | |
5700 } | |
5701 return n; | |
5702 | |
5703 case VAR_LIST: | |
5704 ll = tv->vval.v_list; | |
5705 if (ll == rp) | |
5706 return 1; /* match, count it */ | |
5707 if (ll->lv_copyID == copyID) | |
5708 return 0; /* already inspected this list */ | |
5709 ll->lv_copyID = copyID; | |
5710 n = count_ref_in_list(ll, rp, copyID, gap); | |
5711 if (n > 0 && gap != NULL && ll->lv_refcount > 1) | |
5712 { | |
5713 /* We must later check that the references to this list are | |
5714 * all in the structure we are freeing. */ | |
5715 if (ga_grow(gap, 1) == FAIL) | |
5716 return 0; | |
5717 ((typval_T **)gap->ga_data)[gap->ga_len++] = tv; | |
5718 } | |
5719 return n; | |
5720 } | |
5721 return 0; | |
5722 } | |
5723 | |
5724 /* | |
5534 * Allocate an empty header for a dictionary. | 5725 * Allocate an empty header for a dictionary. |
5535 */ | 5726 */ |
5536 dict_T * | 5727 dict_T * |
5537 dict_alloc() | 5728 dict_alloc() |
5538 { | 5729 { |
5555 */ | 5746 */ |
5556 static void | 5747 static void |
5557 dict_unref(d) | 5748 dict_unref(d) |
5558 dict_T *d; | 5749 dict_T *d; |
5559 { | 5750 { |
5560 if (d != NULL && --d->dv_refcount <= 0) | 5751 int selfref; |
5561 dict_free(d); | 5752 |
5753 if (d != NULL && d->dv_refcount != DEL_REFCOUNT) | |
5754 { | |
5755 if (--d->dv_refcount > 0) | |
5756 { | |
5757 /* Check if the dict contains references to itself. These need to | |
5758 * be subtracted from the reference count to find out if we can | |
5759 * delete the dict. */ | |
5760 selfref = count_self_ref(d, VAR_DICT); | |
5761 } | |
5762 else | |
5763 selfref = 0; | |
5764 if (d->dv_refcount - selfref == 0) | |
5765 /* No references to the dict now, free it. */ | |
5766 dict_free(d); | |
5767 } | |
5562 } | 5768 } |
5563 | 5769 |
5564 /* | 5770 /* |
5565 * Free a Dictionary, including all items it contains. | 5771 * Free a Dictionary, including all items it contains. |
5566 * Ignores the reference count. | 5772 * Ignores the reference count. |
5569 dict_free(d) | 5775 dict_free(d) |
5570 dict_T *d; | 5776 dict_T *d; |
5571 { | 5777 { |
5572 int todo; | 5778 int todo; |
5573 hashitem_T *hi; | 5779 hashitem_T *hi; |
5574 | 5780 dictitem_T *di; |
5575 /* Careful: we free the dictitems while they still appear in the | 5781 |
5576 * hashtab. Must not try to resize the hashtab! */ | 5782 /* Avoid that recursive reference to the dict frees us again. */ |
5783 d->dv_refcount = DEL_REFCOUNT; | |
5784 | |
5785 /* Lock the hashtab, we don't want it to resize while looping through it. | |
5786 * */ | |
5787 hash_lock(&d->dv_hashtab); | |
5577 todo = d->dv_hashtab.ht_used; | 5788 todo = d->dv_hashtab.ht_used; |
5578 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) | 5789 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) |
5579 { | 5790 { |
5580 if (!HASHITEM_EMPTY(hi)) | 5791 if (!HASHITEM_EMPTY(hi)) |
5581 { | 5792 { |
5582 dictitem_free(HI2DI(hi)); | 5793 /* Remove the item before deleting it, just in case there is |
5794 * something recursive causing trouble. */ | |
5795 di = HI2DI(hi); | |
5796 hash_remove(&d->dv_hashtab, hi); | |
5797 dictitem_free(di); | |
5583 --todo; | 5798 --todo; |
5584 } | 5799 } |
5585 } | 5800 } |
5586 hash_clear(&d->dv_hashtab); | 5801 hash_clear(&d->dv_hashtab); |
5587 vim_free(d); | 5802 vim_free(d); |
7661 static void | 7876 static void |
7662 f_deepcopy(argvars, rettv) | 7877 f_deepcopy(argvars, rettv) |
7663 typval_T *argvars; | 7878 typval_T *argvars; |
7664 typval_T *rettv; | 7879 typval_T *rettv; |
7665 { | 7880 { |
7666 static int copyID = 0; | |
7667 int noref = 0; | 7881 int noref = 0; |
7668 | 7882 |
7669 if (argvars[1].v_type != VAR_UNKNOWN) | 7883 if (argvars[1].v_type != VAR_UNKNOWN) |
7670 noref = get_tv_number_chk(&argvars[1], NULL); | 7884 noref = get_tv_number_chk(&argvars[1], NULL); |
7671 if (noref < 0 || noref > 1) | 7885 if (noref < 0 || noref > 1) |
7672 EMSG(_(e_invarg)); | 7886 EMSG(_(e_invarg)); |
7673 else | 7887 else |
7674 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++copyID : 0); | 7888 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); |
7675 } | 7889 } |
7676 | 7890 |
7677 /* | 7891 /* |
7678 * "delete()" function | 7892 * "delete()" function |
7679 */ | 7893 */ |
8038 } | 8252 } |
8039 else | 8253 else |
8040 item = NULL; | 8254 item = NULL; |
8041 list_extend(l1, l2, item); | 8255 list_extend(l1, l2, item); |
8042 | 8256 |
8043 ++l1->lv_refcount; | |
8044 copy_tv(&argvars[0], rettv); | 8257 copy_tv(&argvars[0], rettv); |
8045 } | 8258 } |
8046 } | 8259 } |
8047 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) | 8260 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) |
8048 { | 8261 { |
8104 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); | 8317 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); |
8105 } | 8318 } |
8106 } | 8319 } |
8107 } | 8320 } |
8108 | 8321 |
8109 ++d1->dv_refcount; | |
8110 copy_tv(&argvars[0], rettv); | 8322 copy_tv(&argvars[0], rettv); |
8111 } | 8323 } |
8112 } | 8324 } |
8113 else | 8325 else |
8114 EMSG2(_(e_listdictarg), "extend()"); | 8326 EMSG2(_(e_listdictarg), "extend()"); |
10419 } | 10631 } |
10420 } | 10632 } |
10421 if (l != NULL) | 10633 if (l != NULL) |
10422 { | 10634 { |
10423 list_insert_tv(l, &argvars[1], item); | 10635 list_insert_tv(l, &argvars[1], item); |
10424 ++l->lv_refcount; | |
10425 copy_tv(&argvars[0], rettv); | 10636 copy_tv(&argvars[0], rettv); |
10426 } | 10637 } |
10427 } | 10638 } |
10428 } | 10639 } |
10429 | 10640 |
14932 { | 15143 { |
14933 int ret = OK; | 15144 int ret = OK; |
14934 dict_T *selfdict = NULL; | 15145 dict_T *selfdict = NULL; |
14935 char_u *s; | 15146 char_u *s; |
14936 int len; | 15147 int len; |
15148 typval_T functv; | |
14937 | 15149 |
14938 while (ret == OK | 15150 while (ret == OK |
14939 && (**arg == '[' | 15151 && (**arg == '[' |
14940 || (**arg == '.' && rettv->v_type == VAR_DICT) | 15152 || (**arg == '.' && rettv->v_type == VAR_DICT) |
14941 || (**arg == '(' && rettv->v_type == VAR_FUNC)) | 15153 || (**arg == '(' && rettv->v_type == VAR_FUNC)) |
14942 && !vim_iswhite(*(*arg - 1))) | 15154 && !vim_iswhite(*(*arg - 1))) |
14943 { | 15155 { |
14944 if (**arg == '(') | 15156 if (**arg == '(') |
14945 { | 15157 { |
14946 s = rettv->vval.v_string; | 15158 /* need to copy the funcref so that we can clear rettv */ |
15159 functv = *rettv; | |
15160 rettv->v_type = VAR_UNKNOWN; | |
14947 | 15161 |
14948 /* Invoke the function. Recursive! */ | 15162 /* Invoke the function. Recursive! */ |
15163 s = functv.vval.v_string; | |
14949 ret = get_func_tv(s, STRLEN(s), rettv, arg, | 15164 ret = get_func_tv(s, STRLEN(s), rettv, arg, |
14950 curwin->w_cursor.lnum, curwin->w_cursor.lnum, | 15165 curwin->w_cursor.lnum, curwin->w_cursor.lnum, |
14951 &len, evaluate, selfdict); | 15166 &len, evaluate, selfdict); |
15167 | |
15168 /* Clear the funcref afterwards, so that deleting it while | |
15169 * evaluating the arguments is possible (see test55). */ | |
15170 clear_tv(&functv); | |
14952 | 15171 |
14953 /* Stop the expression evaluation when immediately aborting on | 15172 /* Stop the expression evaluation when immediately aborting on |
14954 * error, or when an interrupt occurred or an exception was thrown | 15173 * error, or when an interrupt occurred or an exception was thrown |
14955 * but not caught. */ | 15174 * but not caught. */ |
14956 if (aborting()) | 15175 if (aborting()) |