comparison src/userfunc.c @ 21558:1c4d4aa22b37 v8.2.1329

patch 8.2.1329: Vim9: cannot define global function inside :def function Commit: https://github.com/vim/vim/commit/38ddf333f6b2806b0ea2dd052ee1cd50dd7f4525 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Jul 31 22:05:04 2020 +0200 patch 8.2.1329: Vim9: cannot define global function inside :def function Problem: Vim9: cannot define global function inside :def function. Solution: Assign to global variable instead of local. (closes https://github.com/vim/vim/issues/6584)
author Bram Moolenaar <Bram@vim.org>
date Fri, 31 Jul 2020 22:15:04 +0200
parents cbc570e66d11
children 30a997217524
comparison
equal deleted inserted replaced
21557:00c9f8522652 21558:1c4d4aa22b37
364 364
365 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); 365 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
366 if (fp == NULL) 366 if (fp == NULL)
367 return NULL; 367 return NULL;
368 368
369 fp->uf_dfunc_idx = UF_NOT_COMPILED; 369 fp->uf_def_status = UF_NOT_COMPILED;
370 fp->uf_refcount = 1; 370 fp->uf_refcount = 1;
371 fp->uf_varargs = TRUE; 371 fp->uf_varargs = TRUE;
372 fp->uf_flags = FC_CFUNC; 372 fp->uf_flags = FC_CFUNC;
373 fp->uf_calls = 0; 373 fp->uf_calls = 0;
374 fp->uf_script_ctx = current_sctx; 374 fp->uf_script_ctx = current_sctx;
1067 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 1067 hi = hash_find(&func_hashtab, UF2HIKEY(fp));
1068 if (!HASHITEM_EMPTY(hi)) 1068 if (!HASHITEM_EMPTY(hi))
1069 { 1069 {
1070 // When there is a def-function index do not actually remove the 1070 // When there is a def-function index do not actually remove the
1071 // function, so we can find the index when defining the function again. 1071 // function, so we can find the index when defining the function again.
1072 if (fp->uf_def_status == UF_COMPILED) 1072 // Do remove it when it's a copy.
1073 if (fp->uf_def_status == UF_COMPILED && (fp->uf_flags & FC_COPY) == 0)
1073 fp->uf_flags |= FC_DEAD; 1074 fp->uf_flags |= FC_DEAD;
1074 else 1075 else
1075 hash_remove(&func_hashtab, hi); 1076 hash_remove(&func_hashtab, hi);
1076 return TRUE; 1077 return TRUE;
1077 } 1078 }
1120 fp->uf_cleared = TRUE; 1121 fp->uf_cleared = TRUE;
1121 1122
1122 // clear this function 1123 // clear this function
1123 func_clear_items(fp); 1124 func_clear_items(fp);
1124 funccal_unref(fp->uf_scoped, fp, force); 1125 funccal_unref(fp->uf_scoped, fp, force);
1125 clear_def_function(fp); 1126 if ((fp->uf_flags & FC_COPY) == 0)
1127 clear_def_function(fp);
1126 } 1128 }
1127 1129
1128 /* 1130 /*
1129 * Free a function and remove it from the list of functions. Does not free 1131 * Free a function and remove it from the list of functions. Does not free
1130 * what a function contains, call func_clear() first. 1132 * what a function contains, call func_clear() first.
1148 */ 1150 */
1149 static void 1151 static void
1150 func_clear_free(ufunc_T *fp, int force) 1152 func_clear_free(ufunc_T *fp, int force)
1151 { 1153 {
1152 func_clear(fp, force); 1154 func_clear(fp, force);
1153 if (force || fp->uf_dfunc_idx == 0) 1155 if (force || fp->uf_dfunc_idx == 0 || (fp->uf_flags & FC_COPY))
1154 func_free(fp, force); 1156 func_free(fp, force);
1155 else 1157 else
1156 fp->uf_flags |= FC_DEAD; 1158 fp->uf_flags |= FC_DEAD;
1159 }
1160
1161 /*
1162 * Copy already defined function "lambda" to a new function with name "global".
1163 * This is for when a compiled function defines a global function.
1164 */
1165 void
1166 copy_func(char_u *lambda, char_u *global)
1167 {
1168 ufunc_T *ufunc = find_func_even_dead(lambda, TRUE, NULL);
1169 ufunc_T *fp;
1170
1171 if (ufunc == NULL)
1172 semsg(_("E1102: lambda function not found: %s"), lambda);
1173 else
1174 {
1175 // TODO: handle ! to overwrite
1176 fp = find_func(global, TRUE, NULL);
1177 if (fp != NULL)
1178 {
1179 semsg(_(e_funcexts), global);
1180 return;
1181 }
1182
1183 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(global) + 1);
1184 if (fp == NULL)
1185 return;
1186
1187 fp->uf_varargs = ufunc->uf_varargs;
1188 fp->uf_flags = (ufunc->uf_flags & ~FC_VIM9) | FC_COPY;
1189 fp->uf_def_status = ufunc->uf_def_status;
1190 fp->uf_dfunc_idx = ufunc->uf_dfunc_idx;
1191 if (ga_copy_strings(&fp->uf_args, &ufunc->uf_args) == FAIL
1192 || ga_copy_strings(&fp->uf_def_args, &ufunc->uf_def_args)
1193 == FAIL
1194 || ga_copy_strings(&fp->uf_lines, &ufunc->uf_lines) == FAIL)
1195 goto failed;
1196
1197 fp->uf_name_exp = ufunc->uf_name_exp == NULL ? NULL
1198 : vim_strsave(ufunc->uf_name_exp);
1199 if (ufunc->uf_arg_types != NULL)
1200 {
1201 fp->uf_arg_types = ALLOC_MULT(type_T *, fp->uf_args.ga_len);
1202 if (fp->uf_arg_types == NULL)
1203 goto failed;
1204 mch_memmove(fp->uf_arg_types, ufunc->uf_arg_types,
1205 sizeof(type_T *) * fp->uf_args.ga_len);
1206 }
1207 if (ufunc->uf_def_arg_idx != NULL)
1208 {
1209 fp->uf_def_arg_idx = ALLOC_MULT(int, fp->uf_def_args.ga_len + 1);
1210 if (fp->uf_def_arg_idx == NULL)
1211 goto failed;
1212 mch_memmove(fp->uf_def_arg_idx, ufunc->uf_def_arg_idx,
1213 sizeof(int) * fp->uf_def_args.ga_len + 1);
1214 }
1215 if (ufunc->uf_va_name != NULL)
1216 {
1217 fp->uf_va_name = vim_strsave(ufunc->uf_va_name);
1218 if (fp->uf_va_name == NULL)
1219 goto failed;
1220 }
1221
1222 fp->uf_refcount = 1;
1223 STRCPY(fp->uf_name, global);
1224 hash_add(&func_hashtab, UF2HIKEY(fp));
1225 }
1226 return;
1227
1228 failed:
1229 func_clear_free(fp, TRUE);
1157 } 1230 }
1158 1231
1159 1232
1160 /* 1233 /*
1161 * Call a user function. 1234 * Call a user function.
2519 } 2592 }
2520 } 2593 }
2521 2594
2522 /* 2595 /*
2523 * ":function" also supporting nested ":def". 2596 * ":function" also supporting nested ":def".
2597 * When "name_arg" is not NULL this is a nested function, using "name_arg" for
2598 * the function name.
2524 * Returns a pointer to the function or NULL if no function defined. 2599 * Returns a pointer to the function or NULL if no function defined.
2525 */ 2600 */
2526 ufunc_T * 2601 ufunc_T *
2527 def_function(exarg_T *eap, char_u *name_arg) 2602 def_function(exarg_T *eap, char_u *name_arg)
2528 { 2603 {