]> granicus.if.org Git - vim/commitdiff
patch 8.2.3366: Vim9: debugging elseif does not stop before condition v8.2.3366
authorBram Moolenaar <Bram@vim.org>
Sun, 22 Aug 2021 11:35:31 +0000 (13:35 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 22 Aug 2021 11:35:31 +0000 (13:35 +0200)
Problem:    Vim9: debugging elseif does not stop before condition.
Solution:   Move debug statement to after the jump. (closes #8781)

src/testdir/test_vim9_disassemble.vim
src/version.c
src/vim9compile.c

index 710c8ee3a650add7a3bba7819861c1f18ad248b4..e7c574673fc4b33e2a2f42482901cc6037afda56 100644 (file)
@@ -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
index 1130e6f7e02c456f32c9d90d27278e121f708341..ca5402fdad8a426bae8c2d84f7b25a1dec812c6a 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3366,
 /**/
     3365,
 /**/
index 17aba4a6989a0142c5955c6dbc9a9f7d47a125a6..90e6bf2677024c4ddc7094728e27969d93623f49 100644 (file)
@@ -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