changeset 25082:5c7a09cf97a1 v8.2.3078

patch 8.2.3078: Vim9: profile test fails Commit: https://github.com/vim/vim/commit/834193afd7195bc96026d2aed696d64f8075cd35 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jun 30 20:39:15 2021 +0200 patch 8.2.3078: Vim9: profile test fails Problem: Vim9: profile test fails. Solution: Make throw in :catch jump to :finally.
author Bram Moolenaar <Bram@vim.org>
date Wed, 30 Jun 2021 20:45:04 +0200
parents 8266083db124
children 05c4686c56d2
files src/testdir/test_vim9_script.vim src/version.c src/vim9compile.c src/vim9execute.c
diffstat 4 files changed, 39 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -803,6 +803,25 @@ def Test_try_catch_nested()
     endtry
   endtry
   assert_equal(['1', '2', '3', '4', '5', '6'], l)
+
+  l = []
+  try
+    try
+      l->add('1')
+      throw 'foo'
+      l->add('x')
+    catch
+      l->add('2')
+      throw 'bar'
+      l->add('x')
+    finally
+      l->add('3')
+    endtry
+    l->add('x')
+  catch /bar/
+    l->add('4')
+  endtry
+  assert_equal(['1', '2', '3', '4'], l)
 enddef
 
 def TryOne(): number
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3078,
+/**/
     3077,
 /**/
     3076,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -8397,10 +8397,17 @@ compile_finally(char_u *arg, cctx_T *cct
     this_instr = instr->ga_len;
 #ifdef FEAT_PROFILE
     if (cctx->ctx_compile_type == CT_PROFILE
-	    && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
+	    && ((isn_T *)instr->ga_data)[this_instr - 1]
 						   .isn_type == ISN_PROF_START)
+    {
 	// jump to the profile start of the "finally"
 	--this_instr;
+
+	// jump to the profile end above it
+	if (this_instr > 0 && ((isn_T *)instr->ga_data)[this_instr - 1]
+						     .isn_type == ISN_PROF_END)
+	    --this_instr;
+    }
 #endif
 
     // Fill in the "end" label in jumps at the end of the blocks.
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -1577,7 +1577,7 @@ exec_instructions(ectx_T *ectx)
 	    while (index > 0)
 	    {
 		trycmd = ((trycmd_T *)trystack->ga_data) + index - 1;
-		if (!trycmd->tcd_in_catch)
+		if (!trycmd->tcd_in_catch || trycmd->tcd_finally_idx != 0)
 		    break;
 		// In the catch and finally block of this try we have to go up
 		// one level.
@@ -1586,9 +1586,16 @@ exec_instructions(ectx_T *ectx)
 	    }
 	    if (trycmd != NULL && trycmd->tcd_frame_idx == ectx->ec_frame_idx)
 	    {
-		// jump to ":catch" or ":finally"
+		if (trycmd->tcd_in_catch)
+		{
+		    // exception inside ":catch", jump to ":finally" once
+		    ectx->ec_iidx = trycmd->tcd_finally_idx;
+		    trycmd->tcd_finally_idx = 0;
+		}
+		else
+		    // jump to first ":catch"
+		    ectx->ec_iidx = trycmd->tcd_catch_idx;
 		trycmd->tcd_in_catch = TRUE;
-		ectx->ec_iidx = trycmd->tcd_catch_idx;
 		did_throw = FALSE;  // don't come back here until :endtry
 		trycmd->tcd_did_throw = TRUE;
 	    }