Mercurial > vim
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 /* |