Patch 8.2.3026
Problem:    Vim9: cannot set breakpoint in compiled function.
Solution:   Check for breakpoint when calling a function.
Files:      src/vim9execute.c, src/structs.h, src/vim.h, src/vim9.h,
            src/debugger.c, src/testdir/test_debugger.vim


*** ../vim-8.2.3025/src/vim9execute.c   2021-06-17 22:27:44.505773022 +0200
--- src/vim9execute.c   2021-06-20 19:00:23.188366040 +0200
***************
*** 148,153 ****
--- 148,170 ----
  }
  
  /*
+  * If debug_tick changed check if "ufunc" has a breakpoint and update
+  * "uf_has_breakpoint".
+  */
+     static void
+ update_has_breakpoint(ufunc_T *ufunc)
+ {
+     if (ufunc->uf_debug_tick != debug_tick)
+     {
+       linenr_T breakpoint;
+ 
+       ufunc->uf_debug_tick = debug_tick;
+       breakpoint = dbg_find_breakpoint(FALSE, ufunc->uf_name, 0);
+       ufunc->uf_has_breakpoint = breakpoint > 0;
+     }
+ }
+ 
+ /*
   * Call compiled function "cdf_idx" from compiled code.
   * This adds a stack frame and sets the instruction pointer to the start of 
the
   * called function.
***************
*** 1444,1449 ****
--- 1461,1480 ----
      garray_T  ga;
      int               lnum;
  
+     if (ex_nesting_level > debug_break_level)
+     {
+       linenr_T breakpoint;
+ 
+       if (!ufunc->uf_has_breakpoint)
+           return;
+ 
+       // check for the next breakpoint if needed
+       breakpoint = dbg_find_breakpoint(FALSE, ufunc->uf_name,
+                                                          iptr->isn_lnum - 1);
+       if (breakpoint <= 0 || breakpoint > iptr->isn_lnum)
+           return;
+     }
+ 
      SOURCING_LNUM = iptr->isn_lnum;
      debug_context = ectx;
      debug_var_count = iptr->isn_arg.number;
***************
*** 4206,4213 ****
                break;
  
            case ISN_DEBUG:
!               if (ex_nesting_level <= debug_break_level)
!                   handle_debug(iptr, ectx);
                break;
  
            case ISN_SHUFFLE:
--- 4237,4243 ----
                break;
  
            case ISN_DEBUG:
!               handle_debug(iptr, ectx);
                break;
  
            case ISN_SHUFFLE:
***************
*** 4383,4388 ****
--- 4413,4421 ----
  #undef STACK_TV_VAR
  #define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + 
ectx.ec_frame_idx + STACK_FRAME_SIZE + idx)
  
+     // Update uf_has_breakpoint if needed.
+     update_has_breakpoint(ufunc);
+ 
      if (ufunc->uf_def_status == UF_NOT_COMPILED
            || ufunc->uf_def_status == UF_COMPILE_ERROR
            || (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
*** ../vim-8.2.3025/src/structs.h       2021-06-20 14:01:25.988924596 +0200
--- src/structs.h       2021-06-20 18:10:57.138484917 +0200
***************
*** 1629,1634 ****
--- 1629,1639 ----
  # endif
  
      garray_T  uf_lines;       // function lines
+ 
+     int               uf_debug_tick;  // when last checked for a breakpoint 
in this
+                               // function.
+     int               uf_has_breakpoint;  // TRUE when a breakpoint has been 
set in
+                                   // this function.
  # ifdef FEAT_PROFILE
      int               uf_profiling;   // TRUE when func is being profiled
      int               uf_prof_initialized;
*** ../vim-8.2.3025/src/vim.h   2021-06-13 18:38:44.688673497 +0200
--- src/vim.h   2021-06-20 18:12:53.846173285 +0200
***************
*** 1804,1812 ****
  
  // Keep in sync with INSTRUCTIONS().
  #ifdef FEAT_PROFILE
! # define COMPILE_TYPE(ufunc) (debug_break_level > 0 ? CT_DEBUG : do_profiling 
== PROF_YES && (ufunc)->uf_profiling ? CT_PROFILE : CT_NONE)
  #else
! # define COMPILE_TYPE(ufunc) debug_break_level > 0 ? CT_DEBUG : CT_NONE
  #endif
  
  /*
--- 1804,1812 ----
  
  // Keep in sync with INSTRUCTIONS().
  #ifdef FEAT_PROFILE
! # define COMPILE_TYPE(ufunc) (debug_break_level > 0 || 
ufunc->uf_has_breakpoint ? CT_DEBUG : do_profiling == PROF_YES && 
(ufunc)->uf_profiling ? CT_PROFILE : CT_NONE)
  #else
! # define COMPILE_TYPE(ufunc) debug_break_level > 0 || 
ufunc->uf_has_breakpoint ? CT_DEBUG : CT_NONE
  #endif
  
  /*
*** ../vim-8.2.3025/src/vim9.h  2021-06-15 22:13:23.829621578 +0200
--- src/vim9.h  2021-06-20 18:14:07.469968104 +0200
***************
*** 498,504 ****
  // Keep in sync with COMPILE_TYPE()
  #ifdef FEAT_PROFILE
  # define INSTRUCTIONS(dfunc) \
!       (debug_break_level > 0 \
            ? (dfunc)->df_instr_debug \
            : ((do_profiling == PROF_YES && (dfunc->df_ufunc)->uf_profiling) \
                ? (dfunc)->df_instr_prof \
--- 498,504 ----
  // Keep in sync with COMPILE_TYPE()
  #ifdef FEAT_PROFILE
  # define INSTRUCTIONS(dfunc) \
!       (debug_break_level > 0 || dfunc->df_ufunc->uf_has_breakpoint \
            ? (dfunc)->df_instr_debug \
            : ((do_profiling == PROF_YES && (dfunc->df_ufunc)->uf_profiling) \
                ? (dfunc)->df_instr_prof \
*** ../vim-8.2.3025/src/debugger.c      2021-06-14 20:40:33.590233925 +0200
--- src/debugger.c      2021-06-20 18:54:58.649524682 +0200
***************
*** 606,612 ****
      }
  
      if (bp->dbg_type == DBG_FUNC)
!       bp->dbg_name = vim_strsave(p);
      else if (here)
        bp->dbg_name = vim_strsave(curbuf->b_ffname);
      else if (bp->dbg_type == DBG_EXPR)
--- 606,612 ----
      }
  
      if (bp->dbg_type == DBG_FUNC)
!       bp->dbg_name = vim_strsave(STRNCMP(p, "g:", 2) == 0 ? p + 2 : p);
      else if (here)
        bp->dbg_name = vim_strsave(curbuf->b_ffname);
      else if (bp->dbg_type == DBG_EXPR)
*** ../vim-8.2.3025/src/testdir/test_debugger.vim       2021-06-17 
22:27:44.505773022 +0200
--- src/testdir/test_debugger.vim       2021-06-20 19:09:30.134448094 +0200
***************
*** 932,937 ****
--- 932,962 ----
    call delete('Xtest2.vim')
  endfunc
  
+ func Test_debug_DefFunction()
+   CheckCWD
+   let file =<< trim END
+     vim9script
+     def g:SomeFunc()
+       echo "here"
+       echo "and"
+       echo "there"
+     enddef
+     breakadd func 2 g:SomeFunc
+   END
+   call writefile(file, 'XtestDebug.vim')
+ 
+   let buf = RunVimInTerminal('-S XtestDebug.vim', {})
+ 
+   call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
+   call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
+ 
+   call RunDbgCmd(buf, 'cont')
+ 
+   call StopVimInTerminal(buf)
+   call delete('Xtest1.vim')
+   call delete('Xtest2.vim')
+ endfunc
+ 
  func Test_debug_def_function()
    CheckCWD
    let file =<< trim END
*** ../vim-8.2.3025/src/version.c       2021-06-20 16:30:53.032313321 +0200
--- src/version.c       2021-06-20 19:22:43.029569196 +0200
***************
*** 757,758 ****
--- 757,760 ----
  {   /* Add new patch number below this line */
+ /**/
+     3026,
  /**/

-- 
Bypasses are devices that allow some people to dash from point A to
point B very fast while other people dash from point B to point A very
fast.  People living at point C, being a point directly in between, are
often given to wonder what's so great about point A that so many people
from point B are so keen to get there and what's so great about point B
that so many people from point A are so keen to get there.  They often
wish that people would just once and for all work out where the hell
they wanted to be.
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202106201728.15KHSpQN388012%40masaka.moolenaar.net.

Raspunde prin e-mail lui