summaryrefslogtreecommitdiff
path: root/src/vim9cmds.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-01-02 14:08:18 +0000
committerBram Moolenaar <Bram@vim.org>2022-01-02 14:08:18 +0000
commit2b4ecc2c31c00df6e1c8ad46a3e4eabb1f1f84e3 (patch)
tree44ed777fd6e6573bb26f7d821cf1ac1133470fb8 /src/vim9cmds.c
parentb3bd1d39e68e2d697c014b9f85482c2c12a3f909 (diff)
downloadvim-git-2b4ecc2c31c00df6e1c8ad46a3e4eabb1f1f84e3.tar.gz
patch 8.2.3981: Vim9: debugging a for loop doesn't stop before it startsv8.2.3981
Problem: Vim9: debugging a for loop doesn't stop before it starts. Solution: Keep the DEBUG instruction before the expression is evaluated. (closes #9456)
Diffstat (limited to 'src/vim9cmds.c')
-rw-r--r--src/vim9cmds.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/src/vim9cmds.c b/src/vim9cmds.c
index 5a86a940c..e11825dde 100644
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -803,14 +803,13 @@ compile_for(char_u *arg_start, cctx_T *cctx)
if (may_get_next_line_error(wp, &p, cctx) == FAIL)
return NULL;
- // Remove the already generated ISN_DEBUG, it is written below the ISN_FOR
- // instruction.
+ // Find the already generated ISN_DEBUG to get the line number for the
+ // instruction 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;
- prev_lnum = ((isn_T *)instr->ga_data)[instr->ga_len]
+ prev_lnum = ((isn_T *)instr->ga_data)[instr->ga_len - 1]
.isn_arg.debug.dbg_break_lnum;
}
@@ -875,6 +874,22 @@ compile_for(char_u *arg_start, cctx_T *cctx)
// "for_end" is set when ":endfor" is found
scope->se_u.se_for.fs_top_label = current_instr_idx(cctx);
+ if (cctx->ctx_compile_type == CT_DEBUG)
+ {
+ int save_prev_lnum = cctx->ctx_prev_lnum;
+ isn_T *isn;
+
+ // Add ISN_DEBUG here, before deciding to end the loop. There will
+ // be another ISN_DEBUG before the next instruction.
+ // Use the prev_lnum from the ISN_DEBUG instruction removed above.
+ // Increment the variable count so that the loop variable can be
+ // inspected.
+ cctx->ctx_prev_lnum = prev_lnum;
+ isn = generate_instr_debug(cctx);
+ ++isn->isn_arg.debug.dbg_var_names_len;
+ cctx->ctx_prev_lnum = save_prev_lnum;
+ }
+
generate_FOR(cctx, loop_lvar->lv_idx);
arg = arg_start;
@@ -979,17 +994,6 @@ compile_for(char_u *arg_start, cctx_T *cctx)
arg = skipwhite(p);
vim_free(name);
}
-
- if (cctx->ctx_compile_type == CT_DEBUG)
- {
- int save_prev_lnum = cctx->ctx_prev_lnum;
-
- // Add ISN_DEBUG here, so that the loop variables can be inspected.
- // Use the prev_lnum from the ISN_DEBUG instruction removed above.
- cctx->ctx_prev_lnum = prev_lnum;
- generate_instr_debug(cctx);
- cctx->ctx_prev_lnum = save_prev_lnum;
- }
}
return arg_end;
@@ -1029,7 +1033,9 @@ compile_endfor(char_u *arg, cctx_T *cctx)
generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label);
// Fill in the "end" label in the FOR statement so it can jump here.
- isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label;
+ // In debug mode an ISN_DEBUG was inserted.
+ isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label
+ + (cctx->ctx_compile_type == CT_DEBUG ? 1 : 0);
isn->isn_arg.forloop.for_end = instr->ga_len;
// Fill in the "end" label any BREAK statements