Patch 8.2.1778
Problem:    Vim9: returning from a partial call clears outer context, causing
            a crash.
Solution:   Put the outer context in the stack frame. (closes #7044)
Files:      src/vim9execute.c, src/vim9.h, src/testdir/test_vim9_func.vim


*** ../vim-8.2.1777/src/vim9execute.c   2020-09-26 19:59:34.097707443 +0200
--- src/vim9execute.c   2020-10-01 12:58:40.913421189 +0200
***************
*** 239,245 ****
      // Store current execution state in stack frame for ISN_RETURN.
      STACK_TV_BOT(0)->vval.v_number = ectx->ec_dfunc_idx;
      STACK_TV_BOT(1)->vval.v_number = ectx->ec_iidx;
!     STACK_TV_BOT(2)->vval.v_number = ectx->ec_frame_idx;
      ectx->ec_frame_idx = ectx->ec_stack.ga_len;
  
      // Initialize local variables
--- 239,247 ----
      // Store current execution state in stack frame for ISN_RETURN.
      STACK_TV_BOT(0)->vval.v_number = ectx->ec_dfunc_idx;
      STACK_TV_BOT(1)->vval.v_number = ectx->ec_iidx;
!     STACK_TV_BOT(2)->vval.v_string = (void *)ectx->ec_outer_stack;
!     STACK_TV_BOT(3)->vval.v_number = ectx->ec_outer_frame;
!     STACK_TV_BOT(4)->vval.v_number = ectx->ec_frame_idx;
      ectx->ec_frame_idx = ectx->ec_stack.ga_len;
  
      // Initialize local variables
***************
*** 455,461 ****
      // 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;
!     ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx + 2)->vval.v_number;
      dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
      ectx->ec_instr = dfunc->df_instr;
  
--- 457,467 ----
      // 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;
!     ectx->ec_outer_stack =
!                      (void *)STACK_TV(ectx->ec_frame_idx + 2)->vval.v_string;
!     ectx->ec_outer_frame = STACK_TV(ectx->ec_frame_idx + 3)->vval.v_number;
!     // restoring ec_frame_idx must be last
!     ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx + 4)->vval.v_number;
      dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
      ectx->ec_instr = dfunc->df_instr;
  
*** ../vim-8.2.1777/src/vim9.h  2020-09-23 21:57:16.637934721 +0200
--- src/vim9.h  2020-10-01 12:58:03.181530741 +0200
***************
*** 326,335 ****
  };
  
  // Number of entries used by stack frame for a function call.
! // - function index
! // - instruction index
! // - previous frame index
! #define STACK_FRAME_SIZE 3
  
  
  #ifdef DEFINE_VIM9_GLOBALS
--- 326,337 ----
  };
  
  // Number of entries used by stack frame for a function call.
! // - ec_dfunc_idx:   function index
! // - ec_iidx:        instruction index
! // - ec_outer_stack: stack used for closures  TODO: can we avoid this?
! // - ec_outer_frame: stack frame for closures
! // - ec_frame_idx:   previous frame index
! #define STACK_FRAME_SIZE 5
  
  
  #ifdef DEFINE_VIM9_GLOBALS
*** ../vim-8.2.1777/src/testdir/test_vim9_func.vim      2020-09-27 
23:33:56.241527069 +0200
--- src/testdir/test_vim9_func.vim      2020-10-01 12:55:12.946032363 +0200
***************
*** 1384,1389 ****
--- 1384,1404 ----
    CheckScriptFailure(lines, 'E1012:')
  enddef
  
+ def Test_nested_lambda()
+   var lines =<< trim END
+     vim9script
+     def Func()
+       var x = 4
+       var Lambda1 = {-> 7}
+       var Lambda2 = {-> [Lambda1(), x]}
+       var res = Lambda2()
+       assert_equal([7, 4], res)
+     enddef
+     Func()
+   END
+   CheckScriptSuccess(lines)
+ enddef
+ 
  def Test_sort_return_type()
    var res: list<number>
    res = [1, 2, 3]->sort()
*** ../vim-8.2.1777/src/version.c       2020-09-30 22:59:37.904243979 +0200
--- src/version.c       2020-10-01 13:00:48.113055257 +0200
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     1778,
  /**/

-- 
Bypasses are devices that allow some people to dash from point A to
point B very fast while other people dash from point B to point A very
fast.  People living at point C, being a point directly in between, are
often given to wonder what's so great about point A that so many people
from point B are so keen to get there and what's so great about point B
that so many people from point A are so keen to get there.  They often
wish that people would just once and for all work out where the hell
they wanted to be.
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202010011102.091B2JmL1217345%40masaka.moolenaar.net.

Raspunde prin e-mail lui