Mercurial > vim
comparison src/userfunc.c @ 20943:1693ca876049 v8.2.1023
patch 8.2.1023: Vim9: redefining a function uses a new index every time
Commit: https://github.com/vim/vim/commit/0cb5bcf5836de83f7d64fb01d3ce708caacaf66c
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jun 20 18:19:09 2020 +0200
patch 8.2.1023: Vim9: redefining a function uses a new index every time
Problem: Vim9: redefining a function uses a new index every time.
Solution: When redefining a function clear the contents and re-use the
index.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 20 Jun 2020 18:30:04 +0200 |
parents | 9064044fd4f6 |
children | 0653b9b72091 |
comparison
equal
deleted
inserted
replaced
20942:484ce6d14734 | 20943:1693ca876049 |
---|---|
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 = UF_NOT_COMPILED; | 412 fp->uf_def_status = 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); |
999 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); | 999 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); |
1000 if (!HASHITEM_EMPTY(hi)) | 1000 if (!HASHITEM_EMPTY(hi)) |
1001 { | 1001 { |
1002 // When there is a def-function index do not actually remove the | 1002 // When there is a def-function index do not actually remove the |
1003 // function, so we can find the index when defining the function again. | 1003 // function, so we can find the index when defining the function again. |
1004 if (fp->uf_dfunc_idx >= 0) | 1004 if (fp->uf_def_status == UF_COMPILED) |
1005 fp->uf_flags |= FC_DEAD; | 1005 fp->uf_flags |= FC_DEAD; |
1006 else | 1006 else |
1007 hash_remove(&func_hashtab, hi); | 1007 hash_remove(&func_hashtab, hi); |
1008 return TRUE; | 1008 return TRUE; |
1009 } | 1009 } |
1044 fp->uf_cleared = TRUE; | 1044 fp->uf_cleared = TRUE; |
1045 | 1045 |
1046 // clear this function | 1046 // clear this function |
1047 func_clear_items(fp); | 1047 func_clear_items(fp); |
1048 funccal_unref(fp->uf_scoped, fp, force); | 1048 funccal_unref(fp->uf_scoped, fp, force); |
1049 delete_def_function(fp); | 1049 clear_def_function(fp); |
1050 } | 1050 } |
1051 | 1051 |
1052 /* | 1052 /* |
1053 * Free a function and remove it from the list of functions. Does not free | 1053 * Free a function and remove it from the list of functions. Does not free |
1054 * what a function contains, call func_clear() first. | 1054 * what a function contains, call func_clear() first. |
1072 */ | 1072 */ |
1073 static void | 1073 static void |
1074 func_clear_free(ufunc_T *fp, int force) | 1074 func_clear_free(ufunc_T *fp, int force) |
1075 { | 1075 { |
1076 func_clear(fp, force); | 1076 func_clear(fp, force); |
1077 func_free(fp, force); | 1077 if (force || fp->uf_dfunc_idx == 0) |
1078 func_free(fp, force); | |
1078 } | 1079 } |
1079 | 1080 |
1080 | 1081 |
1081 /* | 1082 /* |
1082 * Call a user function. | 1083 * Call a user function. |
1135 fc->dbg_tick = debug_tick; | 1136 fc->dbg_tick = debug_tick; |
1136 // Set up fields for closure. | 1137 // Set up fields for closure. |
1137 ga_init2(&fc->fc_funcs, sizeof(ufunc_T *), 1); | 1138 ga_init2(&fc->fc_funcs, sizeof(ufunc_T *), 1); |
1138 func_ptr_ref(fp); | 1139 func_ptr_ref(fp); |
1139 | 1140 |
1140 if (fp->uf_dfunc_idx != UF_NOT_COMPILED) | 1141 if (fp->uf_def_status != UF_NOT_COMPILED) |
1141 { | 1142 { |
1142 estack_push_ufunc(fp, 1); | 1143 estack_push_ufunc(fp, 1); |
1143 save_current_sctx = current_sctx; | 1144 save_current_sctx = current_sctx; |
1144 current_sctx = fp->uf_script_ctx; | 1145 current_sctx = fp->uf_script_ctx; |
1145 | 1146 |
1660 if (!HASHITEM_EMPTY(hi)) | 1661 if (!HASHITEM_EMPTY(hi)) |
1661 { | 1662 { |
1662 // clear the def function index now | 1663 // clear the def function index now |
1663 fp = HI2UF(hi); | 1664 fp = HI2UF(hi); |
1664 fp->uf_flags &= ~FC_DEAD; | 1665 fp->uf_flags &= ~FC_DEAD; |
1665 fp->uf_dfunc_idx = UF_NOT_COMPILED; | 1666 fp->uf_def_status = UF_NOT_COMPILED; |
1666 | 1667 |
1667 // Only free functions that are not refcounted, those are | 1668 // Only free functions that are not refcounted, those are |
1668 // supposed to be freed when no longer referenced. | 1669 // supposed to be freed when no longer referenced. |
1669 if (func_name_refcount(fp->uf_name)) | 1670 if (func_name_refcount(fp->uf_name)) |
1670 ++skipped; | 1671 ++skipped; |
2056 int j; | 2057 int j; |
2057 | 2058 |
2058 msg_start(); | 2059 msg_start(); |
2059 if (indent) | 2060 if (indent) |
2060 msg_puts(" "); | 2061 msg_puts(" "); |
2061 if (fp->uf_dfunc_idx != UF_NOT_COMPILED) | 2062 if (fp->uf_def_status != UF_NOT_COMPILED) |
2062 msg_puts("def "); | 2063 msg_puts("def "); |
2063 else | 2064 else |
2064 msg_puts("function "); | 2065 msg_puts("function "); |
2065 msg_puts((char *)printable_func_name(fp)); | 2066 msg_puts((char *)printable_func_name(fp)); |
2066 msg_putchar('('); | 2067 msg_putchar('('); |
2105 vim_free(tofree); | 2106 vim_free(tofree); |
2106 } | 2107 } |
2107 } | 2108 } |
2108 msg_putchar(')'); | 2109 msg_putchar(')'); |
2109 | 2110 |
2110 if (fp->uf_dfunc_idx != UF_NOT_COMPILED) | 2111 if (fp->uf_def_status != UF_NOT_COMPILED) |
2111 { | 2112 { |
2112 if (fp->uf_ret_type != &t_void) | 2113 if (fp->uf_ret_type != &t_void) |
2113 { | 2114 { |
2114 char *tofree; | 2115 char *tofree; |
2115 | 2116 |
2622 ui_breakcheck(); | 2623 ui_breakcheck(); |
2623 } | 2624 } |
2624 if (!got_int) | 2625 if (!got_int) |
2625 { | 2626 { |
2626 msg_putchar('\n'); | 2627 msg_putchar('\n'); |
2627 if (fp->uf_dfunc_idx != UF_NOT_COMPILED) | 2628 if (fp->uf_def_status != UF_NOT_COMPILED) |
2628 msg_puts(" enddef"); | 2629 msg_puts(" enddef"); |
2629 else | 2630 else |
2630 msg_puts(" endfunction"); | 2631 msg_puts(" endfunction"); |
2631 } | 2632 } |
2632 } | 2633 } |
3095 fp->uf_flags &= ~FC_DEAD; | 3096 fp->uf_flags &= ~FC_DEAD; |
3096 #ifdef FEAT_PROFILE | 3097 #ifdef FEAT_PROFILE |
3097 fp->uf_profiling = FALSE; | 3098 fp->uf_profiling = FALSE; |
3098 fp->uf_prof_initialized = FALSE; | 3099 fp->uf_prof_initialized = FALSE; |
3099 #endif | 3100 #endif |
3101 clear_def_function(fp); | |
3100 } | 3102 } |
3101 } | 3103 } |
3102 } | 3104 } |
3103 else | 3105 else |
3104 { | 3106 { |
3160 } | 3162 } |
3161 | 3163 |
3162 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); | 3164 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); |
3163 if (fp == NULL) | 3165 if (fp == NULL) |
3164 goto erret; | 3166 goto erret; |
3165 fp->uf_dfunc_idx = eap->cmdidx == CMD_def ? UF_TO_BE_COMPILED | 3167 fp->uf_def_status = eap->cmdidx == CMD_def ? UF_TO_BE_COMPILED |
3166 : UF_NOT_COMPILED; | 3168 : UF_NOT_COMPILED; |
3167 | 3169 |
3168 if (fudi.fd_dict != NULL) | 3170 if (fudi.fd_dict != NULL) |
3169 { | 3171 { |
3170 if (fudi.fd_di == NULL) | 3172 if (fudi.fd_di == NULL) |
3217 | 3219 |
3218 if (eap->cmdidx == CMD_def) | 3220 if (eap->cmdidx == CMD_def) |
3219 { | 3221 { |
3220 int lnum_save = SOURCING_LNUM; | 3222 int lnum_save = SOURCING_LNUM; |
3221 | 3223 |
3222 fp->uf_dfunc_idx = UF_TO_BE_COMPILED; | 3224 fp->uf_def_status = UF_TO_BE_COMPILED; |
3223 | 3225 |
3224 // error messages are for the first function line | 3226 // error messages are for the first function line |
3225 SOURCING_LNUM = sourcing_lnum_top; | 3227 SOURCING_LNUM = sourcing_lnum_top; |
3226 | 3228 |
3227 // parse the argument types | 3229 // parse the argument types |
3287 fp->uf_ret_type = parse_type(&p, &fp->uf_type_list); | 3289 fp->uf_ret_type = parse_type(&p, &fp->uf_type_list); |
3288 } | 3290 } |
3289 SOURCING_LNUM = lnum_save; | 3291 SOURCING_LNUM = lnum_save; |
3290 } | 3292 } |
3291 else | 3293 else |
3292 fp->uf_dfunc_idx = UF_NOT_COMPILED; | 3294 fp->uf_def_status = UF_NOT_COMPILED; |
3293 | 3295 |
3294 fp->uf_lines = newlines; | 3296 fp->uf_lines = newlines; |
3295 if ((flags & FC_CLOSURE) != 0) | 3297 if ((flags & FC_CLOSURE) != 0) |
3296 { | 3298 { |
3297 if (register_closure(fp) == FAIL) | 3299 if (register_closure(fp) == FAIL) |
3370 if (!HASHITEM_EMPTY(hi)) | 3372 if (!HASHITEM_EMPTY(hi)) |
3371 { | 3373 { |
3372 --todo; | 3374 --todo; |
3373 ufunc = HI2UF(hi); | 3375 ufunc = HI2UF(hi); |
3374 if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid | 3376 if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid |
3375 && ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED) | 3377 && ufunc->uf_def_status == UF_TO_BE_COMPILED) |
3376 { | 3378 { |
3377 compile_def_function(ufunc, FALSE, NULL); | 3379 compile_def_function(ufunc, FALSE, NULL); |
3378 | 3380 |
3379 if (func_hashtab.ht_used != ht_used) | 3381 if (func_hashtab.ht_used != ht_used) |
3380 { | 3382 { |