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