comparison src/userfunc.c @ 23249:43532077b5ff v8.2.2170

patch 8.2.2170: Vim9: a global function defined in a :def function fails Commit: https://github.com/vim/vim/commit/f112f30a82f17114d8b08a0fb90928cd19440581 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Dec 20 17:47:52 2020 +0100 patch 8.2.2170: Vim9: a global function defined in a :def function fails Problem: Vim9: a global function defined in a :def function fails if it uses the context. Solution: Create a partial to store the closure context. (see #7410)
author Bram Moolenaar <Bram@vim.org>
date Sun, 20 Dec 2020 18:00:06 +0100
parents 033b2a97d59b
children 35583da6397e
comparison
equal deleted inserted replaced
23248:a0e114c6b39e 23249:43532077b5ff
1223 VIM_CLEAR(fp->uf_arg_types); 1223 VIM_CLEAR(fp->uf_arg_types);
1224 VIM_CLEAR(fp->uf_def_arg_idx); 1224 VIM_CLEAR(fp->uf_def_arg_idx);
1225 VIM_CLEAR(fp->uf_block_ids); 1225 VIM_CLEAR(fp->uf_block_ids);
1226 VIM_CLEAR(fp->uf_va_name); 1226 VIM_CLEAR(fp->uf_va_name);
1227 clear_type_list(&fp->uf_type_list); 1227 clear_type_list(&fp->uf_type_list);
1228 partial_unref(fp->uf_partial);
1229 fp->uf_partial = NULL;
1228 1230
1229 #ifdef FEAT_LUA 1231 #ifdef FEAT_LUA
1230 if (fp->uf_cb_free != NULL) 1232 if (fp->uf_cb_free != NULL)
1231 { 1233 {
1232 fp->uf_cb_free(fp->uf_cb_state); 1234 fp->uf_cb_free(fp->uf_cb_state);
1303 } 1305 }
1304 1306
1305 /* 1307 /*
1306 * Copy already defined function "lambda" to a new function with name "global". 1308 * Copy already defined function "lambda" to a new function with name "global".
1307 * This is for when a compiled function defines a global function. 1309 * This is for when a compiled function defines a global function.
1308 */ 1310 * Caller should take care of adding a partial for a closure.
1309 void 1311 */
1312 ufunc_T *
1310 copy_func(char_u *lambda, char_u *global) 1313 copy_func(char_u *lambda, char_u *global)
1311 { 1314 {
1312 ufunc_T *ufunc = find_func_even_dead(lambda, TRUE, NULL); 1315 ufunc_T *ufunc = find_func_even_dead(lambda, TRUE, NULL);
1313 ufunc_T *fp; 1316 ufunc_T *fp = NULL;
1314 1317
1315 if (ufunc == NULL) 1318 if (ufunc == NULL)
1316 semsg(_(e_lambda_function_not_found_str), lambda); 1319 semsg(_(e_lambda_function_not_found_str), lambda);
1317 else 1320 else
1318 { 1321 {
1319 // TODO: handle ! to overwrite 1322 // TODO: handle ! to overwrite
1320 fp = find_func(global, TRUE, NULL); 1323 fp = find_func(global, TRUE, NULL);
1321 if (fp != NULL) 1324 if (fp != NULL)
1322 { 1325 {
1323 semsg(_(e_funcexts), global); 1326 semsg(_(e_funcexts), global);
1324 return; 1327 return NULL;
1325 } 1328 }
1326 1329
1327 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(global) + 1); 1330 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(global) + 1);
1328 if (fp == NULL) 1331 if (fp == NULL)
1329 return; 1332 return NULL;
1330 1333
1331 fp->uf_varargs = ufunc->uf_varargs; 1334 fp->uf_varargs = ufunc->uf_varargs;
1332 fp->uf_flags = (ufunc->uf_flags & ~FC_VIM9) | FC_COPY; 1335 fp->uf_flags = (ufunc->uf_flags & ~FC_VIM9) | FC_COPY;
1333 fp->uf_def_status = ufunc->uf_def_status; 1336 fp->uf_def_status = ufunc->uf_def_status;
1334 fp->uf_dfunc_idx = ufunc->uf_dfunc_idx; 1337 fp->uf_dfunc_idx = ufunc->uf_dfunc_idx;
1360 { 1363 {
1361 fp->uf_va_name = vim_strsave(ufunc->uf_va_name); 1364 fp->uf_va_name = vim_strsave(ufunc->uf_va_name);
1362 if (fp->uf_va_name == NULL) 1365 if (fp->uf_va_name == NULL)
1363 goto failed; 1366 goto failed;
1364 } 1367 }
1368 fp->uf_ret_type = ufunc->uf_ret_type;
1365 1369
1366 fp->uf_refcount = 1; 1370 fp->uf_refcount = 1;
1367 STRCPY(fp->uf_name, global); 1371 STRCPY(fp->uf_name, global);
1368 hash_add(&func_hashtab, UF2HIKEY(fp)); 1372 hash_add(&func_hashtab, UF2HIKEY(fp));
1369 } 1373 }
1370 return; 1374 return fp;
1371 1375
1372 failed: 1376 failed:
1373 func_clear_free(fp, TRUE); 1377 func_clear_free(fp, TRUE);
1378 return NULL;
1374 } 1379 }
1375 1380
1376 static int funcdepth = 0; 1381 static int funcdepth = 0;
1377 1382
1378 /* 1383 /*