To: vim_dev@googlegroups.com Subject: Patch 9.0.0399 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0399 Problem: Using :defer in expression funcref not tested. Solution: Add a test. Fix uncovered problems. Files: src/vim9execute.c, src/proto/vim9execute.pro, src/userfunc.c, src/testdir/test_user_func.vim *** ../vim-9.0.0398/src/vim9execute.c 2022-09-06 18:57:04.927749453 +0100 --- src/vim9execute.c 2022-09-06 21:01:11.764427525 +0100 *************** *** 860,865 **** --- 860,886 ---- } /* + * Clear "current_ectx" and return the previous value. To be used when calling + * a user function. + */ + ectx_T * + clear_currrent_ectx(void) + { + ectx_T *r = current_ectx; + + current_ectx = NULL; + return r; + } + + void + restore_current_ectx(ectx_T *ectx) + { + if (current_ectx != NULL) + iemsg("Restoring current_ectx while it is not NULL"); + current_ectx = ectx; + } + + /* * Add an entry for a deferred function call to the currently executing * function. * Return the list or NULL when failed. *************** *** 5335,5341 **** if (idx < 0) { semsg(NGETTEXT(e_one_argument_too_few, e_nr_arguments_too_few, ! -idx), -idx); goto failed_early; } --- 5356,5362 ---- if (idx < 0) { semsg(NGETTEXT(e_one_argument_too_few, e_nr_arguments_too_few, ! -idx), -idx); goto failed_early; } *** ../vim-9.0.0398/src/proto/vim9execute.pro 2022-09-06 18:31:09.074310277 +0100 --- src/proto/vim9execute.pro 2022-09-06 20:00:27.480709893 +0100 *************** *** 4,9 **** --- 4,11 ---- void funcstack_check_refcount(funcstack_T *funcstack); int set_ref_in_funcstacks(int copyID); int in_def_function(void); + ectx_T *clear_currrent_ectx(void); + void restore_current_ectx(ectx_T *ectx); int add_defer_function(char_u *name, int argcount, typval_T *argvars); char_u *char_from_string(char_u *str, varnumber_T index); char_u *string_slice(char_u *str, varnumber_T first, varnumber_T last, int exclusive); *** ../vim-9.0.0398/src/userfunc.c 2022-09-06 18:57:04.927749453 +0100 --- src/userfunc.c 2022-09-06 19:58:01.089023267 +0100 *************** *** 2593,2598 **** --- 2593,2599 ---- dict_T *selfdict) // Dictionary for "self" { sctx_T save_current_sctx; + ectx_T *save_current_ectx; int using_sandbox = FALSE; int save_sticky_cmdmod_flags = sticky_cmdmod_flags; funccall_T *fc; *************** *** 2669,2677 **** islambda = fp->uf_flags & FC_LAMBDA; /* ! * Note about using fc->fc_fixvar[]: This is an array of FIXVAR_CNT variables ! * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free ! * each argument variable and saves a lot of time. */ /* * Init l: variables. --- 2670,2678 ---- islambda = fp->uf_flags & FC_LAMBDA; /* ! * Note about using fc->fc_fixvar[]: This is an array of FIXVAR_CNT ! * variables with names up to VAR_SHORT_LEN long. This avoids having to ! * alloc/free each argument variable and saves a lot of time. */ /* * Init l: variables. *************** *** 2885,2890 **** --- 2886,2896 ---- // "legacy" does not apply to commands in the function sticky_cmdmod_flags = 0; + // If called from a compiled :def function the execution context must be + // hidden, any deferred functions need to be added to the function being + // executed here. + save_current_ectx = clear_currrent_ectx(); + save_current_sctx = current_sctx; current_sctx = fp->uf_script_ctx; save_did_emsg = did_emsg; *************** *** 2974,2979 **** --- 2980,2987 ---- ESTACK_CHECK_NOW estack_pop(); current_sctx = save_current_sctx; + restore_current_ectx(save_current_ectx); + #ifdef FEAT_PROFILE if (do_profiling == PROF_YES) script_prof_restore(&profile_info.pi_wait_start); *** ../vim-9.0.0398/src/testdir/test_user_func.vim 2022-09-06 18:31:09.074310277 +0100 --- src/testdir/test_user_func.vim 2022-09-06 20:30:15.605653065 +0100 *************** *** 625,629 **** --- 625,661 ---- call assert_false(filereadable('XQuitallTwo')) endfunc + func FuncIndex(idx, val) + call writefile([a:idx .. ': ' .. a:val], 'Xentry' .. a:idx, 'D') + return a:val == 'c' + endfunc + + def DefIndex(idx: number, val: string): bool + call writefile([idx .. ': ' .. val], 'Xentry' .. idx, 'D') + return val == 'c' + enddef + + def Test_defer_in_funcref() + assert_equal(2, indexof(['a', 'b', 'c'], function('g:FuncIndex'))) + assert_false(filereadable('Xentry0')) + assert_false(filereadable('Xentry1')) + assert_false(filereadable('Xentry2')) + + assert_equal(2, indexof(['a', 'b', 'c'], g:DefIndex)) + assert_false(filereadable('Xentry0')) + assert_false(filereadable('Xentry1')) + assert_false(filereadable('Xentry2')) + + assert_equal(2, indexof(['a', 'b', 'c'], function('g:DefIndex'))) + assert_false(filereadable('Xentry0')) + assert_false(filereadable('Xentry1')) + assert_false(filereadable('Xentry2')) + + assert_equal(2, indexof(['a', 'b', 'c'], funcref(g:DefIndex))) + assert_false(filereadable('Xentry0')) + assert_false(filereadable('Xentry1')) + assert_false(filereadable('Xentry2')) + enddef + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-9.0.0398/src/version.c 2022-09-06 18:57:04.927749453 +0100 --- src/version.c 2022-09-06 19:15:47.222499671 +0100 *************** *** 705,706 **** --- 705,708 ---- { /* Add new patch number below this line */ + /**/ + 399, /**/ -- hundred-and-one symptoms of being an internet addict: 19. All of your friends have an @ in their names. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///