comparison src/userfunc.c @ 9721:79862f44c647 v7.4.2136

commit https://github.com/vim/vim/commit/580164481924ed8611eb79f0247a0eb1ca0b3b9a Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jul 31 18:30:22 2016 +0200 patch 7.4.2136 Problem: Closure function fails. Solution: Don't reset uf_scoped when it points to another funccal.
author Christian Brabandt <cb@256bit.org>
date Sun, 31 Jul 2016 18:45:06 +0200
parents 6226de5f8137
children 80ac9cf77c9b
comparison
equal deleted inserted replaced
9720:8c110d08b87f 9721:79862f44c647
148 # ifdef __BORLANDC__ 148 # ifdef __BORLANDC__
149 _RTLENTRYF 149 _RTLENTRYF
150 # endif 150 # endif
151 prof_self_cmp(const void *s1, const void *s2); 151 prof_self_cmp(const void *s1, const void *s2);
152 #endif 152 #endif
153 static void funccal_unref(funccall_T *fc, ufunc_T *fp);
153 154
154 void 155 void
155 func_init() 156 func_init()
156 { 157 {
157 hash_init(&func_hashtab); 158 hash_init(&func_hashtab);
256 ga_clear_strings(newargs); 257 ga_clear_strings(newargs);
257 return FAIL; 258 return FAIL;
258 } 259 }
259 260
260 /* 261 /*
262 * Register function "fp" as using "current_funccal" as its scope.
263 */
264 static int
265 register_closure(ufunc_T *fp)
266 {
267 funccal_unref(fp->uf_scoped, NULL);
268 fp->uf_scoped = current_funccal;
269 current_funccal->fc_refcount++;
270 if (ga_grow(&current_funccal->fc_funcs, 1) == FAIL)
271 return FAIL;
272 ((ufunc_T **)current_funccal->fc_funcs.ga_data)
273 [current_funccal->fc_funcs.ga_len++] = fp;
274 func_ref(current_funccal->func->uf_name);
275 return OK;
276 }
277
278 /*
261 * Parse a lambda expression and get a Funcref from "*arg". 279 * Parse a lambda expression and get a Funcref from "*arg".
262 * Return OK or FAIL. Returns NOTDONE for dict or {expr}. 280 * Return OK or FAIL. Returns NOTDONE for dict or {expr}.
263 */ 281 */
264 int 282 int
265 get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate) 283 get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate)
316 int len, flags = 0; 334 int len, flags = 0;
317 char_u *p; 335 char_u *p;
318 336
319 sprintf((char*)name, "<lambda>%d", ++lambda_no); 337 sprintf((char*)name, "<lambda>%d", ++lambda_no);
320 338
321 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 339 fp = (ufunc_T *)alloc_clear((unsigned)(sizeof(ufunc_T) + STRLEN(name)));
322 if (fp == NULL) 340 if (fp == NULL)
323 goto errret; 341 goto errret;
324 342
325 ga_init2(&newlines, (int)sizeof(char_u *), 1); 343 ga_init2(&newlines, (int)sizeof(char_u *), 1);
326 if (ga_grow(&newlines, 1) == FAIL) 344 if (ga_grow(&newlines, 1) == FAIL)
341 fp->uf_args = newargs; 359 fp->uf_args = newargs;
342 fp->uf_lines = newlines; 360 fp->uf_lines = newlines;
343 if (current_funccal != NULL && eval_lavars) 361 if (current_funccal != NULL && eval_lavars)
344 { 362 {
345 flags |= FC_CLOSURE; 363 flags |= FC_CLOSURE;
346 fp->uf_scoped = current_funccal; 364 if (register_closure(fp) == FAIL)
347 current_funccal->fc_refcount++;
348 if (ga_grow(&current_funccal->fc_funcs, 1) == FAIL)
349 goto errret; 365 goto errret;
350 ((ufunc_T **)current_funccal->fc_funcs.ga_data)
351 [current_funccal->fc_funcs.ga_len++] = fp;
352 func_ref(current_funccal->func->uf_name);
353 } 366 }
354 else 367 else
355 fp->uf_scoped = NULL; 368 fp->uf_scoped = NULL;
356 369
357 #ifdef FEAT_PROFILE 370 #ifdef FEAT_PROFILE
658 for (i = 0; i < fc->fc_funcs.ga_len; ++i) 671 for (i = 0; i < fc->fc_funcs.ga_len; ++i)
659 { 672 {
660 ufunc_T *fp = ((ufunc_T **)(fc->fc_funcs.ga_data))[i]; 673 ufunc_T *fp = ((ufunc_T **)(fc->fc_funcs.ga_data))[i];
661 674
662 if (fp != NULL) 675 if (fp != NULL)
663 fp->uf_scoped = NULL; 676 {
664 } 677 /* Function may have been redefined and point to another
678 * funccall_T, don't clear it then. */
679 if (fp->uf_scoped == fc)
680 fp->uf_scoped = NULL;
681 func_unref(fc->func->uf_name);
682 }
683 }
684 ga_clear(&fc->fc_funcs);
665 685
666 /* The a: variables typevals may not have been allocated, only free the 686 /* The a: variables typevals may not have been allocated, only free the
667 * allocated variables. */ 687 * allocated variables. */
668 vars_clear_ext(&fc->l_avars.dv_hashtab, free_val); 688 vars_clear_ext(&fc->l_avars.dv_hashtab, free_val);
669 689
672 692
673 /* Free the a:000 variables if they were allocated. */ 693 /* Free the a:000 variables if they were allocated. */
674 if (free_val) 694 if (free_val)
675 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 695 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
676 clear_tv(&li->li_tv); 696 clear_tv(&li->li_tv);
677
678 for (i = 0; i < fc->fc_funcs.ga_len; ++i)
679 {
680 ufunc_T *fp = ((ufunc_T **)(fc->fc_funcs.ga_data))[i];
681
682 if (fp != NULL)
683 func_unref(fc->func->uf_name);
684 }
685 ga_clear(&fc->fc_funcs);
686 697
687 func_unref(fc->func->uf_name); 698 func_unref(fc->func->uf_name);
688 vim_free(fc); 699 vim_free(fc);
689 } 700 }
690 701
1044 1055
1045 did_emsg |= save_did_emsg; 1056 did_emsg |= save_did_emsg;
1046 current_funccal = fc->caller; 1057 current_funccal = fc->caller;
1047 --depth; 1058 --depth;
1048 1059
1049 /* If the a:000 list and the l: and a: dicts are not referenced we can 1060 /* If the a:000 list and the l: and a: dicts are not referenced and there
1050 * free the funccall_T and what's in it. */ 1061 * is no closure using it, we can free the funccall_T and what's in it. */
1051 if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT 1062 if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
1052 && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT 1063 && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
1053 && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT 1064 && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT
1054 && fc->fc_refcount <= 0) 1065 && fc->fc_refcount <= 0)
1055 { 1066 {
1059 { 1070 {
1060 hashitem_T *hi; 1071 hashitem_T *hi;
1061 listitem_T *li; 1072 listitem_T *li;
1062 int todo; 1073 int todo;
1063 1074
1064 /* "fc" is still in use. This can happen when returning "a:000" or 1075 /* "fc" is still in use. This can happen when returning "a:000",
1065 * assigning "l:" to a global variable. 1076 * assigning "l:" to a global variable or defining a closure.
1066 * Link "fc" in the list for garbage collection later. */ 1077 * Link "fc" in the list for garbage collection later. */
1067 fc->caller = previous_funccal; 1078 fc->caller = previous_funccal;
1068 previous_funccal = fc; 1079 previous_funccal = fc;
1069 1080
1070 /* Make a copy of the a: variables, since we didn't do that above. */ 1081 /* Make a copy of the a: variables, since we didn't do that above. */
1119 if (!freed) 1130 if (!freed)
1120 { 1131 {
1121 func_unref(fc->func->uf_name); 1132 func_unref(fc->func->uf_name);
1122 1133
1123 if (fp != NULL) 1134 if (fp != NULL)
1124 {
1125 for (i = 0; i < fc->fc_funcs.ga_len; ++i) 1135 for (i = 0; i < fc->fc_funcs.ga_len; ++i)
1126 { 1136 {
1127 if (((ufunc_T **)(fc->fc_funcs.ga_data))[i] == fp) 1137 if (((ufunc_T **)(fc->fc_funcs.ga_data))[i] == fp)
1128 ((ufunc_T **)(fc->fc_funcs.ga_data))[i] = NULL; 1138 ((ufunc_T **)(fc->fc_funcs.ga_data))[i] = NULL;
1129 } 1139 }
1130 }
1131 } 1140 }
1132 } 1141 }
1133 1142
1134 /* 1143 /*
1135 * Free a function and remove it from the list of functions. 1144 * Free a function and remove it from the list of functions.
1974 } 1983 }
1975 else if (STRNCMP(p, "closure", 7) == 0) 1984 else if (STRNCMP(p, "closure", 7) == 0)
1976 { 1985 {
1977 flags |= FC_CLOSURE; 1986 flags |= FC_CLOSURE;
1978 p += 7; 1987 p += 7;
1988 if (current_funccal == NULL)
1989 {
1990 emsg_funcname(N_("E932 Closure function should not be at top level: %s"),
1991 name == NULL ? (char_u *)"" : name);
1992 goto erret;
1993 }
1979 } 1994 }
1980 else 1995 else
1981 break; 1996 break;
1982 } 1997 }
1983 1998
2263 EMSG2(_("E746: Function name does not match script file name: %s"), name); 2278 EMSG2(_("E746: Function name does not match script file name: %s"), name);
2264 goto erret; 2279 goto erret;
2265 } 2280 }
2266 } 2281 }
2267 2282
2268 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 2283 fp = (ufunc_T *)alloc_clear((unsigned)(sizeof(ufunc_T) + STRLEN(name)));
2269 if (fp == NULL) 2284 if (fp == NULL)
2270 goto erret; 2285 goto erret;
2271 2286
2272 if (fudi.fd_dict != NULL) 2287 if (fudi.fd_dict != NULL)
2273 { 2288 {
2309 } 2324 }
2310 fp->uf_args = newargs; 2325 fp->uf_args = newargs;
2311 fp->uf_lines = newlines; 2326 fp->uf_lines = newlines;
2312 if ((flags & FC_CLOSURE) != 0) 2327 if ((flags & FC_CLOSURE) != 0)
2313 { 2328 {
2314 if (current_funccal == NULL) 2329 ++fp->uf_refcount;
2315 { 2330 if (register_closure(fp) == FAIL)
2316 emsg_funcname(N_("E932 Closure function should not be at top level: %s"),
2317 name);
2318 goto erret; 2331 goto erret;
2319 }
2320 fp->uf_scoped = current_funccal;
2321 current_funccal->fc_refcount++;
2322 if (ga_grow(&current_funccal->fc_funcs, 1) == FAIL)
2323 goto erret;
2324 ((ufunc_T **)current_funccal->fc_funcs.ga_data)
2325 [current_funccal->fc_funcs.ga_len++] = fp;
2326 func_ref(current_funccal->func->uf_name);
2327 } 2332 }
2328 else 2333 else
2329 fp->uf_scoped = NULL; 2334 fp->uf_scoped = NULL;
2330 2335
2331 #ifdef FEAT_PROFILE 2336 #ifdef FEAT_PROFILE
3580 if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) 3585 if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL)
3581 return NULL; 3586 return NULL;
3582 3587
3583 /* Search in parent scope which is possible to reference from lambda */ 3588 /* Search in parent scope which is possible to reference from lambda */
3584 current_funccal = current_funccal->func->uf_scoped; 3589 current_funccal = current_funccal->func->uf_scoped;
3585 while (current_funccal) 3590 while (current_funccal != NULL)
3586 { 3591 {
3587 ht = find_var_ht(name, varname); 3592 ht = find_var_ht(name, varname);
3588 if (ht != NULL && **varname != NUL) 3593 if (ht != NULL && **varname != NUL)
3589 { 3594 {
3590 hi = hash_find(ht, *varname); 3595 hi = hash_find(ht, *varname);
3591 if (!HASHITEM_EMPTY(hi)) 3596 if (!HASHITEM_EMPTY(hi))
3592 { 3597 {
3593 *pht = ht; 3598 *pht = ht;
3594 break; 3599 break;
3595 } 3600 }
3596 } 3601 }
3597 if (current_funccal == current_funccal->func->uf_scoped) 3602 if (current_funccal == current_funccal->func->uf_scoped)
3598 break; 3603 break;
3599 current_funccal = current_funccal->func->uf_scoped; 3604 current_funccal = current_funccal->func->uf_scoped;
3600 } 3605 }
3601 current_funccal = old_current_funccal; 3606 current_funccal = old_current_funccal;
3602 3607
3603 return hi; 3608 return hi;
3604 } 3609 }