comparison src/userfunc.c @ 20528:489cb75c76b6 v8.2.0818

patch 8.2.0818: Vim9: using a discovery phase doesn't work well Commit: https://github.com/vim/vim/commit/822ba24743af9ee1b5e7f656a7a61a38f3638bca Author: Bram Moolenaar <Bram@vim.org> Date: Sun May 24 23:00:18 2020 +0200 patch 8.2.0818: Vim9: using a discovery phase doesn't work well Problem: Vim9: using a discovery phase doesn't work well. Solution: Remove the discovery phase, instead compile a function only when it is used. Add :defcompile to compile def functions earlier.
author Bram Moolenaar <Bram@vim.org>
date Sun, 24 May 2020 23:15:04 +0200
parents 5950284a517f
children cb4831fa7e25
comparison
equal deleted inserted replaced
20527:37ac4c5b4d27 20528:489cb75c76b6
407 char_u *name = get_lambda_name(); 407 char_u *name = get_lambda_name();
408 408
409 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); 409 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
410 if (fp == NULL) 410 if (fp == NULL)
411 goto errret; 411 goto errret;
412 fp->uf_dfunc_idx = -1; 412 fp->uf_dfunc_idx = UF_NOT_COMPILED;
413 pt = ALLOC_CLEAR_ONE(partial_T); 413 pt = ALLOC_CLEAR_ONE(partial_T);
414 if (pt == NULL) 414 if (pt == NULL)
415 goto errret; 415 goto errret;
416 416
417 ga_init2(&newlines, (int)sizeof(char_u *), 1); 417 ga_init2(&newlines, (int)sizeof(char_u *), 1);
1110 fc->dbg_tick = debug_tick; 1110 fc->dbg_tick = debug_tick;
1111 // Set up fields for closure. 1111 // Set up fields for closure.
1112 ga_init2(&fc->fc_funcs, sizeof(ufunc_T *), 1); 1112 ga_init2(&fc->fc_funcs, sizeof(ufunc_T *), 1);
1113 func_ptr_ref(fp); 1113 func_ptr_ref(fp);
1114 1114
1115 if (fp->uf_dfunc_idx >= 0) 1115 if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
1116 { 1116 {
1117 estack_push_ufunc(ETYPE_UFUNC, fp, 1); 1117 estack_push_ufunc(ETYPE_UFUNC, fp, 1);
1118 save_current_sctx = current_sctx; 1118 save_current_sctx = current_sctx;
1119 current_sctx = fp->uf_script_ctx; 1119 current_sctx = fp->uf_script_ctx;
1120 1120
1635 if (!HASHITEM_EMPTY(hi)) 1635 if (!HASHITEM_EMPTY(hi))
1636 { 1636 {
1637 // clear the def function index now 1637 // clear the def function index now
1638 fp = HI2UF(hi); 1638 fp = HI2UF(hi);
1639 fp->uf_flags &= ~FC_DEAD; 1639 fp->uf_flags &= ~FC_DEAD;
1640 fp->uf_dfunc_idx = -1; 1640 fp->uf_dfunc_idx = UF_NOT_COMPILED;
1641 1641
1642 // Only free functions that are not refcounted, those are 1642 // Only free functions that are not refcounted, those are
1643 // supposed to be freed when no longer referenced. 1643 // supposed to be freed when no longer referenced.
1644 if (func_name_refcount(fp->uf_name)) 1644 if (func_name_refcount(fp->uf_name))
1645 ++skipped; 1645 ++skipped;
2031 int j; 2031 int j;
2032 2032
2033 msg_start(); 2033 msg_start();
2034 if (indent) 2034 if (indent)
2035 msg_puts(" "); 2035 msg_puts(" ");
2036 if (fp->uf_dfunc_idx >= 0) 2036 if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
2037 msg_puts("def "); 2037 msg_puts("def ");
2038 else 2038 else
2039 msg_puts("function "); 2039 msg_puts("function ");
2040 msg_puts((char *)printable_func_name(fp)); 2040 msg_puts((char *)printable_func_name(fp));
2041 msg_putchar('('); 2041 msg_putchar('(');
2080 vim_free(tofree); 2080 vim_free(tofree);
2081 } 2081 }
2082 } 2082 }
2083 msg_putchar(')'); 2083 msg_putchar(')');
2084 2084
2085 if (fp->uf_dfunc_idx >= 0) 2085 if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
2086 { 2086 {
2087 if (fp->uf_ret_type != &t_void) 2087 if (fp->uf_ret_type != &t_void)
2088 { 2088 {
2089 char *tofree; 2089 char *tofree;
2090 2090
2375 /* 2375 /*
2376 * ":function" also supporting nested ":def". 2376 * ":function" also supporting nested ":def".
2377 * Returns a pointer to the function or NULL if no function defined. 2377 * Returns a pointer to the function or NULL if no function defined.
2378 */ 2378 */
2379 ufunc_T * 2379 ufunc_T *
2380 def_function(exarg_T *eap, char_u *name_arg, void *context, int compile) 2380 def_function(exarg_T *eap, char_u *name_arg)
2381 { 2381 {
2382 char_u *theline; 2382 char_u *theline;
2383 char_u *line_to_free = NULL; 2383 char_u *line_to_free = NULL;
2384 int j; 2384 int j;
2385 int c; 2385 int c;
2414 linenr_T sourcing_lnum_top; 2414 linenr_T sourcing_lnum_top;
2415 int is_heredoc = FALSE; 2415 int is_heredoc = FALSE;
2416 char_u *skip_until = NULL; 2416 char_u *skip_until = NULL;
2417 char_u *heredoc_trimmed = NULL; 2417 char_u *heredoc_trimmed = NULL;
2418 2418
2419 if (in_vim9script() && eap->forceit)
2420 {
2421 emsg(_(e_nobang));
2422 return NULL;
2423 }
2424
2419 /* 2425 /*
2420 * ":function" without argument: list functions. 2426 * ":function" without argument: list functions.
2421 */ 2427 */
2422 if (ends_excmd2(eap->cmd, eap->arg)) 2428 if (ends_excmd2(eap->cmd, eap->arg))
2423 { 2429 {
2582 ui_breakcheck(); 2588 ui_breakcheck();
2583 } 2589 }
2584 if (!got_int) 2590 if (!got_int)
2585 { 2591 {
2586 msg_putchar('\n'); 2592 msg_putchar('\n');
2587 if (fp->uf_dfunc_idx >= 0) 2593 if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
2588 msg_puts(" enddef"); 2594 msg_puts(" enddef");
2589 else 2595 else
2590 msg_puts(" endfunction"); 2596 msg_puts(" endfunction");
2591 } 2597 }
2592 } 2598 }
3120 } 3126 }
3121 3127
3122 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); 3128 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
3123 if (fp == NULL) 3129 if (fp == NULL)
3124 goto erret; 3130 goto erret;
3125 fp->uf_dfunc_idx = -1; 3131 fp->uf_dfunc_idx = eap->cmdidx == CMD_def ? UF_TO_BE_COMPILED
3132 : UF_NOT_COMPILED;
3126 3133
3127 if (fudi.fd_dict != NULL) 3134 if (fudi.fd_dict != NULL)
3128 { 3135 {
3129 if (fudi.fd_di == NULL) 3136 if (fudi.fd_di == NULL)
3130 { 3137 {
3172 fp->uf_func_type = &t_func_any; 3179 fp->uf_func_type = &t_func_any;
3173 3180
3174 if (eap->cmdidx == CMD_def) 3181 if (eap->cmdidx == CMD_def)
3175 { 3182 {
3176 int lnum_save = SOURCING_LNUM; 3183 int lnum_save = SOURCING_LNUM;
3184
3185 fp->uf_dfunc_idx = UF_TO_BE_COMPILED;
3177 3186
3178 // error messages are for the first function line 3187 // error messages are for the first function line
3179 SOURCING_LNUM = sourcing_lnum_top; 3188 SOURCING_LNUM = sourcing_lnum_top;
3180 3189
3181 // parse the argument types 3190 // parse the argument types
3240 p = ret_type; 3249 p = ret_type;
3241 fp->uf_ret_type = parse_type(&p, &fp->uf_type_list); 3250 fp->uf_ret_type = parse_type(&p, &fp->uf_type_list);
3242 } 3251 }
3243 SOURCING_LNUM = lnum_save; 3252 SOURCING_LNUM = lnum_save;
3244 } 3253 }
3254 else
3255 fp->uf_dfunc_idx = UF_NOT_COMPILED;
3245 3256
3246 fp->uf_lines = newlines; 3257 fp->uf_lines = newlines;
3247 if ((flags & FC_CLOSURE) != 0) 3258 if ((flags & FC_CLOSURE) != 0)
3248 { 3259 {
3249 if (register_closure(fp) == FAIL) 3260 if (register_closure(fp) == FAIL)
3271 fp->uf_flags |= FC_EXPORT; 3282 fp->uf_flags |= FC_EXPORT;
3272 // let ex_export() know the export worked. 3283 // let ex_export() know the export worked.
3273 is_export = FALSE; 3284 is_export = FALSE;
3274 } 3285 }
3275 3286
3276 // ":def Func()" may need to be compiled
3277 if (eap->cmdidx == CMD_def && compile)
3278 compile_def_function(fp, FALSE, context);
3279
3280 goto ret_free; 3287 goto ret_free;
3281 3288
3282 erret: 3289 erret:
3283 ga_clear_strings(&newargs); 3290 ga_clear_strings(&newargs);
3284 ga_clear_strings(&default_args); 3291 ga_clear_strings(&default_args);
3302 * ":function" 3309 * ":function"
3303 */ 3310 */
3304 void 3311 void
3305 ex_function(exarg_T *eap) 3312 ex_function(exarg_T *eap)
3306 { 3313 {
3307 (void)def_function(eap, NULL, NULL, TRUE); 3314 (void)def_function(eap, NULL);
3315 }
3316
3317 /*
3318 * :defcompile - compile all :def functions in the current script.
3319 */
3320 void
3321 ex_defcompile(exarg_T *eap UNUSED)
3322 {
3323 int todo = (int)func_hashtab.ht_used;
3324 hashitem_T *hi;
3325 ufunc_T *ufunc;
3326
3327 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
3328 {
3329 if (!HASHITEM_EMPTY(hi))
3330 {
3331 --todo;
3332 ufunc = HI2UF(hi);
3333 if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid
3334 && ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED)
3335 compile_def_function(ufunc, FALSE, NULL);
3336 }
3337 }
3308 } 3338 }
3309 3339
3310 /* 3340 /*
3311 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 3341 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
3312 * Return 2 if "p" starts with "s:". 3342 * Return 2 if "p" starts with "s:".