changeset 24122:e8b21a3bb0d5 v8.2.2602

patch 8.2.2602: Vim9: continue doesn't work if :while is very first command Commit: https://github.com/vim/vim/commit/2e34c34be1393027a761ecbccd8f267d52ca7bc1 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Mar 14 12:13:33 2021 +0100 patch 8.2.2602: Vim9: continue doesn't work if :while is very first command Problem: Vim9: continue doesn't work if :while is very first command. (Yegappan Lakshmanan) Solution: Add one to the continue instruction index.
author Bram Moolenaar <Bram@vim.org>
date Sun, 14 Mar 2021 12:15:03 +0100
parents 14d6de7b07b3
children d97cddd9f357
files src/testdir/test_vim9_script.vim src/version.c src/vim9execute.c
diffstat 3 files changed, 32 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -592,6 +592,31 @@ def Test_try_catch_throw()
   assert_equal(4, ReturnInFinally())
 enddef
 
+" :while at the very start of a function that :continue jumps to
+def TryContinueFunc()
+ while g:Count < 2
+   g:sequence ..= 't'
+    try
+      echoerr 'Test'
+    catch
+      g:Count += 1
+      g:sequence ..= 'c'
+      continue
+    endtry
+    g:sequence ..= 'e'
+    g:Count += 1
+  endwhile
+enddef
+
+def Test_continue_in_try_in_while()
+  g:Count = 0
+  g:sequence = ''
+  TryContinueFunc()
+  assert_equal('tctc', g:sequence)
+  unlet g:Count
+  unlet g:sequence
+enddef
+
 def Test_nocatch_return_in_try()
   # return in try block returns normally
   def ReturnInTry(): string
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2602,
+/**/
     2601,
 /**/
     2600,
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -30,7 +30,7 @@ typedef struct {
     int	    tcd_finally_idx;	// instruction of the :finally block or zero
     int	    tcd_endtry_idx;	// instruction of the :endtry
     int	    tcd_caught;		// catch block entered
-    int	    tcd_cont;		// :continue encountered, jump here
+    int	    tcd_cont;		// :continue encountered, jump here (minus one)
     int	    tcd_return;		// when TRUE return from end of :finally
 } trycmd_T;
 
@@ -2757,7 +2757,9 @@ call_def_function(
 		    {
 			trycmd = ((trycmd_T *)trystack->ga_data)
 							+ trystack->ga_len - i;
-			trycmd->tcd_cont = iidx;
+			// Add one to tcd_cont to be able to jump to
+			// instruction with index zero.
+			trycmd->tcd_cont = iidx + 1;
 			iidx = trycmd->tcd_finally_idx == 0
 			    ? trycmd->tcd_endtry_idx : trycmd->tcd_finally_idx;
 		    }
@@ -2811,7 +2813,7 @@ call_def_function(
 			if (trycmd->tcd_cont != 0)
 			    // handling :continue: jump to outer try block or
 			    // start of the loop
-			    ectx.ec_iidx = trycmd->tcd_cont;
+			    ectx.ec_iidx = trycmd->tcd_cont - 1;
 		    }
 		}
 		break;