summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-06-30 20:39:15 +0200
committerBram Moolenaar <Bram@vim.org>2021-06-30 20:39:15 +0200
commit834193afd7195bc96026d2aed696d64f8075cd35 (patch)
treec1e71ec5daddb8b3406fb2d3e7bc91965231c7c6
parentd3d8feeb897a6b956fc82c81448b938a53312d71 (diff)
patch 8.2.3078: Vim9: profile test failsv8.2.3078
Problem: Vim9: profile test fails. Solution: Make throw in :catch jump to :finally.
-rw-r--r--src/testdir/test_vim9_script.vim19
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c9
-rw-r--r--src/vim9execute.c13
4 files changed, 39 insertions, 4 deletions
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index a258bcb7a8..dfb1a41bb1 100644
--- 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
diff --git a/src/version.c b/src/version.c
index 655aaaea33..3c626bb670 100644
--- 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,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index e3e1721f13..533c0b33eb 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -8397,10 +8397,17 @@ compile_finally(char_u *arg, cctx_T *cctx)
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.
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 4013c06cda..b194e6a2a2 100644
--- 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;
}