diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-01-02 14:08:18 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-01-02 14:08:18 +0000 |
commit | 2b4ecc2c31c00df6e1c8ad46a3e4eabb1f1f84e3 (patch) | |
tree | 44ed777fd6e6573bb26f7d821cf1ac1133470fb8 /src/vim9cmds.c | |
parent | b3bd1d39e68e2d697c014b9f85482c2c12a3f909 (diff) | |
download | vim-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.c | 38 |
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 |