Mercurial > vim
comparison src/vim9cmds.c @ 26905:c2186e32ae42 v8.2.3981
patch 8.2.3981: Vim9: debugging a for loop doesn't stop before it starts
Commit: https://github.com/vim/vim/commit/2b4ecc2c31c00df6e1c8ad46a3e4eabb1f1f84e3
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 2 14:08:18 2022 +0000
patch 8.2.3981: Vim9: debugging a for loop doesn't stop before it starts
Problem: Vim9: debugging a for loop doesn't stop before it starts.
Solution: Keep the DEBUG instruction before the expression is evaluated.
(closes #9456)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 02 Jan 2022 15:15:03 +0100 |
parents | 612339679616 |
children | ccb9be1cdd71 |
comparison
equal
deleted
inserted
replaced
26904:06cc23a34556 | 26905:c2186e32ae42 |
---|---|
801 } | 801 } |
802 wp = p + 2; | 802 wp = p + 2; |
803 if (may_get_next_line_error(wp, &p, cctx) == FAIL) | 803 if (may_get_next_line_error(wp, &p, cctx) == FAIL) |
804 return NULL; | 804 return NULL; |
805 | 805 |
806 // Remove the already generated ISN_DEBUG, it is written below the ISN_FOR | 806 // Find the already generated ISN_DEBUG to get the line number for the |
807 // instruction. | 807 // instruction written below the ISN_FOR instruction. |
808 if (cctx->ctx_compile_type == CT_DEBUG && instr->ga_len > 0 | 808 if (cctx->ctx_compile_type == CT_DEBUG && instr->ga_len > 0 |
809 && ((isn_T *)instr->ga_data)[instr->ga_len - 1] | 809 && ((isn_T *)instr->ga_data)[instr->ga_len - 1] |
810 .isn_type == ISN_DEBUG) | 810 .isn_type == ISN_DEBUG) |
811 { | 811 { |
812 --instr->ga_len; | 812 prev_lnum = ((isn_T *)instr->ga_data)[instr->ga_len - 1] |
813 prev_lnum = ((isn_T *)instr->ga_data)[instr->ga_len] | |
814 .isn_arg.debug.dbg_break_lnum; | 813 .isn_arg.debug.dbg_break_lnum; |
815 } | 814 } |
816 | 815 |
817 scope = new_scope(cctx, FOR_SCOPE); | 816 scope = new_scope(cctx, FOR_SCOPE); |
818 if (scope == NULL) | 817 if (scope == NULL) |
872 // CMDMOD_REV must come before the FOR instruction. | 871 // CMDMOD_REV must come before the FOR instruction. |
873 generate_undo_cmdmods(cctx); | 872 generate_undo_cmdmods(cctx); |
874 | 873 |
875 // "for_end" is set when ":endfor" is found | 874 // "for_end" is set when ":endfor" is found |
876 scope->se_u.se_for.fs_top_label = current_instr_idx(cctx); | 875 scope->se_u.se_for.fs_top_label = current_instr_idx(cctx); |
876 | |
877 if (cctx->ctx_compile_type == CT_DEBUG) | |
878 { | |
879 int save_prev_lnum = cctx->ctx_prev_lnum; | |
880 isn_T *isn; | |
881 | |
882 // Add ISN_DEBUG here, before deciding to end the loop. There will | |
883 // be another ISN_DEBUG before the next instruction. | |
884 // Use the prev_lnum from the ISN_DEBUG instruction removed above. | |
885 // Increment the variable count so that the loop variable can be | |
886 // inspected. | |
887 cctx->ctx_prev_lnum = prev_lnum; | |
888 isn = generate_instr_debug(cctx); | |
889 ++isn->isn_arg.debug.dbg_var_names_len; | |
890 cctx->ctx_prev_lnum = save_prev_lnum; | |
891 } | |
877 | 892 |
878 generate_FOR(cctx, loop_lvar->lv_idx); | 893 generate_FOR(cctx, loop_lvar->lv_idx); |
879 | 894 |
880 arg = arg_start; | 895 arg = arg_start; |
881 if (var_list) | 896 if (var_list) |
977 if (*p == ',' || *p == ';') | 992 if (*p == ',' || *p == ';') |
978 ++p; | 993 ++p; |
979 arg = skipwhite(p); | 994 arg = skipwhite(p); |
980 vim_free(name); | 995 vim_free(name); |
981 } | 996 } |
982 | |
983 if (cctx->ctx_compile_type == CT_DEBUG) | |
984 { | |
985 int save_prev_lnum = cctx->ctx_prev_lnum; | |
986 | |
987 // Add ISN_DEBUG here, so that the loop variables can be inspected. | |
988 // Use the prev_lnum from the ISN_DEBUG instruction removed above. | |
989 cctx->ctx_prev_lnum = prev_lnum; | |
990 generate_instr_debug(cctx); | |
991 cctx->ctx_prev_lnum = save_prev_lnum; | |
992 } | |
993 } | 997 } |
994 | 998 |
995 return arg_end; | 999 return arg_end; |
996 | 1000 |
997 failed: | 1001 failed: |
1027 | 1031 |
1028 // At end of ":for" scope jump back to the FOR instruction. | 1032 // At end of ":for" scope jump back to the FOR instruction. |
1029 generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label); | 1033 generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label); |
1030 | 1034 |
1031 // Fill in the "end" label in the FOR statement so it can jump here. | 1035 // Fill in the "end" label in the FOR statement so it can jump here. |
1032 isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label; | 1036 // In debug mode an ISN_DEBUG was inserted. |
1037 isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label | |
1038 + (cctx->ctx_compile_type == CT_DEBUG ? 1 : 0); | |
1033 isn->isn_arg.forloop.for_end = instr->ga_len; | 1039 isn->isn_arg.forloop.for_end = instr->ga_len; |
1034 | 1040 |
1035 // Fill in the "end" label any BREAK statements | 1041 // Fill in the "end" label any BREAK statements |
1036 compile_fill_jump_to_end(&forscope->fs_end_label, instr->ga_len, cctx); | 1042 compile_fill_jump_to_end(&forscope->fs_end_label, instr->ga_len, cctx); |
1037 | 1043 |