Mercurial > vim
comparison src/userfunc.c @ 20433:5950284a517f v8.2.0771
patch 8.2.0771: Vim9: cannot call a compiled closure from not compiled code
Commit: https://github.com/vim/vim/commit/6f5b6dfb16228c0ce1e4379b7bafed02eaddbab2
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat May 16 21:20:12 2020 +0200
patch 8.2.0771: Vim9: cannot call a compiled closure from not compiled code
Problem: Vim9: cannot call a compiled closure from not compiled code.
Solution: Pass funcexe to call_user_func().
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 16 May 2020 21:30:10 +0200 |
parents | c225be44692a |
children | 489cb75c76b6 |
comparison
equal
deleted
inserted
replaced
20432:05b26264315a | 20433:5950284a517f |
---|---|
1060 call_user_func( | 1060 call_user_func( |
1061 ufunc_T *fp, // pointer to function | 1061 ufunc_T *fp, // pointer to function |
1062 int argcount, // nr of args | 1062 int argcount, // nr of args |
1063 typval_T *argvars, // arguments | 1063 typval_T *argvars, // arguments |
1064 typval_T *rettv, // return value | 1064 typval_T *rettv, // return value |
1065 linenr_T firstline, // first line of range | 1065 funcexe_T *funcexe, // context |
1066 linenr_T lastline, // last line of range | |
1067 dict_T *selfdict) // Dictionary for "self" | 1066 dict_T *selfdict) // Dictionary for "self" |
1068 { | 1067 { |
1069 sctx_T save_current_sctx; | 1068 sctx_T save_current_sctx; |
1070 int using_sandbox = FALSE; | 1069 int using_sandbox = FALSE; |
1071 funccall_T *fc; | 1070 funccall_T *fc; |
1118 estack_push_ufunc(ETYPE_UFUNC, fp, 1); | 1117 estack_push_ufunc(ETYPE_UFUNC, fp, 1); |
1119 save_current_sctx = current_sctx; | 1118 save_current_sctx = current_sctx; |
1120 current_sctx = fp->uf_script_ctx; | 1119 current_sctx = fp->uf_script_ctx; |
1121 | 1120 |
1122 // Execute the compiled function. | 1121 // Execute the compiled function. |
1123 call_def_function(fp, argcount, argvars, rettv); | 1122 call_def_function(fp, argcount, argvars, funcexe->partial, rettv); |
1124 --depth; | 1123 --depth; |
1125 current_funccal = fc->caller; | 1124 current_funccal = fc->caller; |
1126 | 1125 |
1127 estack_pop(); | 1126 estack_pop(); |
1128 current_sctx = save_current_sctx; | 1127 current_sctx = save_current_sctx; |
1192 * Skipped when no a: variables used (in lambda). | 1191 * Skipped when no a: variables used (in lambda). |
1193 */ | 1192 */ |
1194 if ((fp->uf_flags & FC_NOARGS) == 0) | 1193 if ((fp->uf_flags & FC_NOARGS) == 0) |
1195 { | 1194 { |
1196 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", | 1195 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", |
1197 (varnumber_T)firstline); | 1196 (varnumber_T)funcexe->firstline); |
1198 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", | 1197 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", |
1199 (varnumber_T)lastline); | 1198 (varnumber_T)funcexe->lastline); |
1200 } | 1199 } |
1201 for (i = 0; i < argcount || i < fp->uf_args.ga_len; ++i) | 1200 for (i = 0; i < argcount || i < fp->uf_args.ga_len; ++i) |
1202 { | 1201 { |
1203 int addlocal = FALSE; | 1202 int addlocal = FALSE; |
1204 typval_T def_rettv; | 1203 typval_T def_rettv; |
1513 { | 1512 { |
1514 saveRedobuff(&save_redo); | 1513 saveRedobuff(&save_redo); |
1515 did_save_redo = TRUE; | 1514 did_save_redo = TRUE; |
1516 } | 1515 } |
1517 ++fp->uf_calls; | 1516 ++fp->uf_calls; |
1518 call_user_func(fp, argcount, argvars, rettv, | 1517 call_user_func(fp, argcount, argvars, rettv, funcexe, |
1519 funcexe->firstline, funcexe->lastline, | 1518 (fp->uf_flags & FC_DICT) ? selfdict : NULL); |
1520 (fp->uf_flags & FC_DICT) ? selfdict : NULL); | |
1521 if (--fp->uf_calls <= 0 && fp->uf_refcount <= 0) | 1519 if (--fp->uf_calls <= 0 && fp->uf_refcount <= 0) |
1522 // Function was unreferenced while being used, free it now. | 1520 // Function was unreferenced while being used, free it now. |
1523 func_clear_free(fp, FALSE); | 1521 func_clear_free(fp, FALSE); |
1524 if (did_save_redo) | 1522 if (did_save_redo) |
1525 restoreRedobuff(&save_redo); | 1523 restoreRedobuff(&save_redo); |
4291 char_u *varname; | 4289 char_u *varname; |
4292 | 4290 |
4293 if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) | 4291 if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) |
4294 return NULL; | 4292 return NULL; |
4295 | 4293 |
4296 // Search in parent scope which is possible to reference from lambda | 4294 // Search in parent scope, which can be referenced from a lambda. |
4297 current_funccal = current_funccal->func->uf_scoped; | 4295 current_funccal = current_funccal->func->uf_scoped; |
4298 while (current_funccal != NULL) | 4296 while (current_funccal != NULL) |
4299 { | 4297 { |
4300 ht = find_var_ht(name, &varname); | 4298 ht = find_var_ht(name, &varname); |
4301 if (ht != NULL && *varname != NUL) | 4299 if (ht != NULL && *varname != NUL) |