# HG changeset patch # User Bram Moolenaar # Date 1624473003 -7200 # Node ID 70f55a30f03c36d3cd7a31eef133f5ae11ddef01 # Parent 264025157c93869ab4a18ca8866430884a309839 patch 8.2.3039: Vim9: breakpoint at a comment line does not work Commit: https://github.com/vim/vim/commit/8cec9273d2518f2a9abcbd326722a2eba38d2a13 Author: Bram Moolenaar 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) diff --git a/src/testdir/test_debugger.vim b/src/testdir/test_debugger.vim --- 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) diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim --- 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('\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('\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) diff --git a/src/version.c b/src/version.c --- 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, diff --git a/src/vim9.h b/src/vim9.h --- 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; }; diff --git a/src/vim9compile.c b/src/vim9compile.c --- 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) diff --git a/src/vim9execute.c b/src/vim9execute.c --- 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,