changeset 25004:70f55a30f03c v8.2.3039

patch 8.2.3039: Vim9: breakpoint at a comment line does not work Commit: https://github.com/vim/vim/commit/8cec9273d2518f2a9abcbd326722a2eba38d2a13 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jun 23 20:20:53 2021 +0200 patch 8.2.3039: Vim9: breakpoint at a comment line does not work Problem: Vim9: breakpoint at a comment line does not work. Solution: Add the comment line number to the debug instruction. (closes #8429)
author Bram Moolenaar <Bram@vim.org>
date Wed, 23 Jun 2021 20:30:03 +0200
parents 264025157c93
children 791ae2f86aa4
files src/testdir/test_debugger.vim src/testdir/test_vim9_disassemble.vim src/version.c src/vim9.h src/vim9compile.c src/vim9execute.c
diffstat 6 files changed, 48 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_debugger.vim
+++ b/src/testdir/test_debugger.vim
@@ -947,7 +947,7 @@ func Test_debug_DefFunction()
     def LocalFunc()
       echo "first"
       echo "second"
-      breakadd func 1 LegacyFunc
+      breakadd func LegacyFunc
       LegacyFunc()
     enddef
 
@@ -1010,6 +1010,13 @@ func Test_debug_def_function()
            eval 1
          enddef
     enddef
+    def g:FuncComment()
+      # comment
+      echo "first"
+         .. "one"
+      # comment
+      echo "second"
+    enddef
   END
   call writefile(file, 'Xtest.vim')
 
@@ -1049,6 +1056,12 @@ func Test_debug_def_function()
                 \ ['cmd: call FuncWithDict()'])
   call RunDbgCmd(buf, 'step', ['line 1: var d = {  a: 1,  b: 2,  }'])
   call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
+  call RunDbgCmd(buf, 'cont')
+
+  call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
+  call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first"  .. "one"'])
+  call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
+  call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
 
   call RunDbgCmd(buf, 'cont')
   call StopVimInTerminal(buf)
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -2176,7 +2176,9 @@ def Test_silent_return()
 enddef
 
 def s:Profiled(): string
+  # comment
   echo "profiled"
+  # comment
   var some = "some text"
   return "done"
 enddef
@@ -2187,18 +2189,20 @@ def Test_profiled()
   endif
   var res = execute('disass profile s:Profiled')
   assert_match('<SNR>\d*_Profiled\_s*' ..
+        '# comment\_s*' ..
         'echo "profiled"\_s*' ..
-        '\d PROFILE START line 1\_s*' ..
+        '\d PROFILE START line 2\_s*' ..
         '\d PUSHS "profiled"\_s*' ..
         '\d ECHO 1\_s*' ..
+        '# comment\_s*' ..
         'var some = "some text"\_s*' ..
         '\d PROFILE END\_s*' ..
-        '\d PROFILE START line 2\_s*' ..
+        '\d PROFILE START line 4\_s*' ..
         '\d PUSHS "some text"\_s*' ..
         '\d STORE $0\_s*' ..
         'return "done"\_s*' ..
         '\d PROFILE END\_s*' ..
-        '\d PROFILE START line 3\_s*' ..
+        '\d PROFILE START line 5\_s*' ..
         '\d PUSHS "done"\_s*' ..
         '\d\+ RETURN\_s*' ..
         '\d\+ PROFILE END',
@@ -2208,16 +2212,18 @@ enddef
 def Test_debugged()
   var res = execute('disass debug s:Profiled')
   assert_match('<SNR>\d*_Profiled\_s*' ..
+        '# comment\_s*' ..
         'echo "profiled"\_s*' ..
-        '\d DEBUG line 1 varcount 0\_s*' ..
+        '\d DEBUG line 1-2 varcount 0\_s*' ..
         '\d PUSHS "profiled"\_s*' ..
         '\d ECHO 1\_s*' ..
+        '# comment\_s*' ..
         'var some = "some text"\_s*' ..
-        '\d DEBUG line 2 varcount 0\_s*' ..
+        '\d DEBUG line 3-4 varcount 0\_s*' ..
         '\d PUSHS "some text"\_s*' ..
         '\d STORE $0\_s*' ..
         'return "done"\_s*' ..
-        '\d DEBUG line 3 varcount 1\_s*' ..
+        '\d DEBUG line 5-5 varcount 1\_s*' ..
         '\d PUSHS "done"\_s*' ..
         '\d RETURN\_s*',
         res)
--- 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 */
 /**/
+    3039,
+/**/
     3038,
 /**/
     3037,
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -168,8 +168,7 @@ typedef enum {
     ISN_PROF_START, // start a line for profiling
     ISN_PROF_END,   // end a line for profiling
 
-    ISN_DEBUG,	    // check for debug breakpoint, isn_arg.number is current
-		    // number of local variables
+    ISN_DEBUG,	    // check for debug breakpoint, uses isn_arg.debug
 
     ISN_UNPACK,	    // unpack list into items, uses isn_arg.unpack
     ISN_SHUFFLE,    // move item on stack up or down
@@ -391,6 +390,12 @@ typedef struct {
     int		invert;
 } tobool_T;
 
+// arguments to ISN_DEBUG
+typedef struct {
+    varnumber_T	dbg_var_names_len;  // current number of local variables
+    int		dbg_break_lnum;	    // first line to break after
+} debug_T;
+
 /*
  * Instruction
  */
@@ -439,6 +444,7 @@ struct isn_S {
 	tostring_T	    tostring;
 	tobool_T	    tobool;
 	getitem_T	    getitem;
+	debug_T		    debug;
     } isn_arg;
 };
 
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -174,6 +174,9 @@ struct cctx_S {
     char_u	*ctx_line_start;    // start of current line or NULL
     garray_T	ctx_instr;	    // generated instructions
 
+    int		ctx_prev_lnum;	    // line number below previous command, for
+				    // debugging
+
     compiletype_T ctx_compile_type;
 
     garray_T	ctx_locals;	    // currently visible local variables
@@ -585,7 +588,8 @@ generate_instr_debug(cctx_T *cctx)
 
     if ((isn = generate_instr(cctx, ISN_DEBUG)) == NULL)
 	return NULL;
-    isn->isn_arg.number = dfunc->df_var_names.ga_len;
+    isn->isn_arg.debug.dbg_var_names_len = dfunc->df_var_names.ga_len;
+    isn->isn_arg.debug.dbg_break_lnum = cctx->ctx_prev_lnum;
     return isn;
 }
 
@@ -9270,6 +9274,7 @@ compile_def_function(
 	    debug_lnum = cctx.ctx_lnum;
 	    generate_instr_debug(&cctx);
 	}
+	cctx.ctx_prev_lnum = cctx.ctx_lnum + 1;
 
 	// Some things can be recognized by the first character.
 	switch (*ea.cmd)
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -1473,14 +1473,14 @@ handle_debug(isn_T *iptr, ectx_T *ectx)
 
 	// check for the next breakpoint if needed
 	breakpoint = dbg_find_breakpoint(FALSE, ufunc->uf_name,
-							   iptr->isn_lnum - 1);
+					   iptr->isn_arg.debug.dbg_break_lnum);
 	if (breakpoint <= 0 || breakpoint > iptr->isn_lnum)
 	    return;
     }
 
     SOURCING_LNUM = iptr->isn_lnum;
     debug_context = ectx;
-    debug_var_count = iptr->isn_arg.number;
+    debug_var_count = iptr->isn_arg.debug.dbg_var_names_len;
 
     for (ni = iptr + 1; ni->isn_type != ISN_FINISH; ++ni)
 	if (ni->isn_type == ISN_DEBUG
@@ -5476,8 +5476,10 @@ list_instructions(char *pfx, isn_T *inst
 		break;
 
 	    case ISN_DEBUG:
-		smsg("%s%4d DEBUG line %d varcount %lld", pfx, current,
-					 iptr->isn_lnum, iptr->isn_arg.number);
+		smsg("%s%4d DEBUG line %d-%d varcount %lld", pfx, current,
+			iptr->isn_arg.debug.dbg_break_lnum + 1,
+			iptr->isn_lnum,
+			iptr->isn_arg.debug.dbg_var_names_len);
 		break;
 
 	    case ISN_UNPACK: smsg("%s%4d UNPACK %d%s", pfx, current,