To: vim_dev@googlegroups.com Subject: Patch 8.2.2051 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2051 Problem: Vim9: crash when aborting a user function call. Solution: Do not use the return value when aboring. (closes #7372) Files: src/vim9execute.c, src/testdir/test_vim9_func.vim *** ../vim-8.2.2050/src/vim9execute.c 2020-11-23 08:31:14.101789113 +0100 --- src/vim9execute.c 2020-11-25 18:30:17.391701164 +0100 *************** *** 467,472 **** --- 467,473 ---- func_return(ectx_T *ectx) { int idx; + int ret_idx; dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx; int argcount = ufunc_argcount(dfunc->df_ufunc); *************** *** 490,495 **** --- 491,502 ---- idx < ectx->ec_stack.ga_len - 1; ++idx) clear_tv(STACK_TV(idx)); + // The return value should be on top of the stack. However, when aborting + // it may not be there and ec_frame_idx is the top of the stack. + ret_idx = ectx->ec_stack.ga_len - 1; + if (ret_idx == ectx->ec_frame_idx + 4) + ret_idx = 0; + // Restore the previous frame. ectx->ec_dfunc_idx = STACK_TV(ectx->ec_frame_idx)->vval.v_number; ectx->ec_iidx = STACK_TV(ectx->ec_frame_idx + 1)->vval.v_number; *************** *** 501,511 **** dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx; ectx->ec_instr = dfunc->df_instr; ! // Reset the stack to the position before the call, move the return value ! // to the top of the stack. ! idx = ectx->ec_stack.ga_len - 1; ! ectx->ec_stack.ga_len = top + 1; ! *STACK_TV_BOT(-1) = *STACK_TV(idx); funcdepth_decrement(); return OK; --- 508,523 ---- dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx; ectx->ec_instr = dfunc->df_instr; ! if (ret_idx > 0) ! { ! // Reset the stack to the position before the call, with a spot for the ! // return value, moved there from above the frame. ! ectx->ec_stack.ga_len = top + 1; ! *STACK_TV_BOT(-1) = *STACK_TV(ret_idx); ! } ! else ! // Reset the stack to the position before the call. ! ectx->ec_stack.ga_len = top; funcdepth_decrement(); return OK; *** ../vim-8.2.2050/src/testdir/test_vim9_func.vim 2020-11-22 18:15:40.171258382 +0100 --- src/testdir/test_vim9_func.vim 2020-11-25 18:18:12.821564819 +0100 *************** *** 1468,1473 **** --- 1468,1496 ---- CheckScriptFailure(lines, 'E1012:') enddef + def Test_failure_in_called_function() + # this was using the frame index as the return value + var lines =<< trim END + vim9script + au TerminalWinOpen * eval [][0] + def PopupTerm(a: any) + # make sure typvals on stack are string + ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join() + FireEvent() + enddef + def FireEvent() + do TerminalWinOpen + enddef + # use try/catch to make eval fail + try + call PopupTerm(0) + catch + endtry + au! TerminalWinOpen + END + CheckScriptSuccess(lines) + enddef + def Test_nested_lambda() var lines =<< trim END vim9script *** ../vim-8.2.2050/src/version.c 2020-11-25 17:41:16.453206458 +0100 --- src/version.c 2020-11-25 18:19:14.369357647 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2051, /**/ -- Computers are not intelligent. They only think they are. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///