summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-08-22 13:35:31 +0200
committerBram Moolenaar <Bram@vim.org>2021-08-22 13:35:31 +0200
commit093165c899f1620543844d1c1a7a05975697c286 (patch)
tree2f70c53ba7537c6c3d195a7b82d6a6e84af0c6c0
parentbf5f2878333da934a8bdc560bf0bcf9a88ff86a1 (diff)
patch 8.2.3366: Vim9: debugging elseif does not stop before conditionv8.2.3366
Problem: Vim9: debugging elseif does not stop before condition. Solution: Move debug statement to after the jump. (closes #8781)
-rw-r--r--src/testdir/test_vim9_disassemble.vim47
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c27
3 files changed, 74 insertions, 2 deletions
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim
index 710c8ee3a6..e7c574673f 100644
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -2255,6 +2255,53 @@ def Test_debugged()
res)
enddef
+def s:DebugElseif()
+ var b = false
+ if b
+ eval 1 + 0
+ silent elseif !b
+ eval 2 + 0
+ endif
+enddef
+
+def Test_debug_elseif()
+ var res = execute('disass debug s:DebugElseif')
+ assert_match('<SNR>\d*_DebugElseif\_s*' ..
+ 'var b = false\_s*' ..
+ '0 DEBUG line 1-1 varcount 0\_s*' ..
+ '1 PUSH false\_s*' ..
+ '2 STORE $0\_s*' ..
+
+ 'if b\_s*' ..
+ '3 DEBUG line 2-2 varcount 1\_s*' ..
+ '4 LOAD $0\_s*' ..
+ '5 JUMP_IF_FALSE -> 10\_s*' ..
+
+ 'eval 1 + 0\_s*' ..
+ '6 DEBUG line 3-3 varcount 1\_s*' ..
+ '7 PUSHNR 1\_s*' ..
+ '8 DROP\_s*' ..
+
+ 'silent elseif !b\_s*' ..
+ '9 JUMP -> 20\_s*' ..
+ '10 CMDMOD silent\_s*' ..
+ '11 DEBUG line 4-4 varcount 1\_s*' ..
+ '12 LOAD $0\_s*' ..
+ '13 INVERT -1 (!val)\_s*' ..
+ '14 CMDMOD_REV\_s*' ..
+ '15 JUMP_IF_FALSE -> 20\_s*' ..
+
+ 'eval 2 + 0\_s*' ..
+ '16 DEBUG line 5-5 varcount 1\_s*' ..
+ '17 PUSHNR 2\_s*' ..
+ '18 DROP\_s*' ..
+
+ 'endif\_s*' ..
+ '19 DEBUG line 6-6 varcount 1\_s*' ..
+ '20 RETURN void*',
+ res)
+enddef
+
def s:EchoMessages()
echohl ErrorMsg | echom v:exception | echohl NONE
enddef
diff --git a/src/version.c b/src/version.c
index 1130e6f7e0..ca5402fdad 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 */
/**/
+ 3366,
+/**/
3365,
/**/
3364,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 17aba4a698..90e6bf2677 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -2387,7 +2387,7 @@ misplaced_cmdmod(cctx_T *cctx)
/*
* Get the index of the current instruction.
- * This compenstates for a preceding ISN_CMDMOD and ISN_PROF_START.
+ * This compensates for a preceding ISN_CMDMOD and ISN_PROF_START.
*/
static int
current_instr_idx(cctx_T *cctx)
@@ -7732,7 +7732,9 @@ compile_elseif(char_u *arg, cctx_T *cctx)
if (cctx->ctx_skip == SKIP_UNKNOWN)
{
- int moved_cmdmod = FALSE;
+ int moved_cmdmod = FALSE;
+ int saved_debug = FALSE;
+ isn_T debug_isn;
// Move any CMDMOD instruction to after the jump
if (((isn_T *)instr->ga_data)[instr->ga_len - 1].isn_type == ISN_CMDMOD)
@@ -7745,14 +7747,35 @@ compile_elseif(char_u *arg, cctx_T *cctx)
moved_cmdmod = TRUE;
}
+ // Remove the already generated ISN_DEBUG, it is written below the
+ // ISN_FOR instruction.
+ if (cctx->ctx_compile_type == CT_DEBUG && instr->ga_len > 0
+ && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
+ .isn_type == ISN_DEBUG)
+ {
+ --instr->ga_len;
+ debug_isn = ((isn_T *)instr->ga_data)[instr->ga_len];
+ saved_debug = TRUE;
+ }
+
if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
JUMP_ALWAYS, cctx) == FAIL)
return NULL;
// previous "if" or "elseif" jumps here
isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
isn->isn_arg.jump.jump_where = instr->ga_len;
+
if (moved_cmdmod)
++instr->ga_len;
+
+ if (saved_debug)
+ {
+ // move the debug instruction here
+ if (GA_GROW_FAILS(instr, 1))
+ return NULL;
+ ((isn_T *)instr->ga_data)[instr->ga_len] = debug_isn;
+ ++instr->ga_len;
+ }
}
// compile "expr"; if we know it evaluates to FALSE skip the block