To: vim_dev@googlegroups.com Subject: Patch 8.2.3981 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.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) Files: src/vim9cmds.c, src/testdir/test_vim9_disassemble.vim *** ../vim-8.2.3980/src/vim9cmds.c 2022-01-01 16:20:56.900401501 +0000 --- src/vim9cmds.c 2022-01-02 14:02:16.495771618 +0000 *************** *** 803,816 **** 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. 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] .isn_arg.debug.dbg_break_lnum; } --- 803,815 ---- if (may_get_next_line_error(wp, &p, cctx) == FAIL) return NULL; ! // 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) { ! prev_lnum = ((isn_T *)instr->ga_data)[instr->ga_len - 1] .isn_arg.debug.dbg_break_lnum; } *************** *** 875,880 **** --- 874,895 ---- // "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,995 **** 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; --- 994,999 ---- *************** *** 1029,1035 **** 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; isn->isn_arg.forloop.for_end = instr->ga_len; // Fill in the "end" label any BREAK statements --- 1033,1041 ---- generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label); // Fill in the "end" label in the FOR statement so it can jump here. ! // 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 *** ../vim-8.2.3980/src/testdir/test_vim9_disassemble.vim 2021-12-25 22:00:45.858688819 +0000 --- src/testdir/test_vim9_disassemble.vim 2022-01-02 14:06:54.630481145 +0000 *************** *** 2434,2439 **** --- 2434,2476 ---- res) enddef + def s:DebugFor() + echo "hello" + for a in [0] + echo a + endfor + enddef + + def Test_debug_for() + var res = execute('disass debug s:DebugFor') + assert_match('\d*_DebugFor\_s*' .. + 'echo "hello"\_s*' .. + '0 DEBUG line 1-1 varcount 0\_s*' .. + '1 PUSHS "hello"\_s*' .. + '2 ECHO 1\_s*' .. + + 'for a in \[0\]\_s*' .. + '3 DEBUG line 2-2 varcount 0\_s*' .. + '4 STORE -1 in $0\_s*' .. + '5 PUSHNR 0\_s*' .. + '6 NEWLIST size 1\_s*' .. + '7 DEBUG line 2-2 varcount 2\_s*' .. + '8 FOR $0 -> 15\_s*' .. + '9 STORE $1\_s*' .. + + 'echo a\_s*' .. + '10 DEBUG line 3-3 varcount 2\_s*' .. + '11 LOAD $1\_s*' .. + '12 ECHO 1\_s*' .. + + 'endfor\_s*' .. + '13 DEBUG line 4-4 varcount 2\_s*' .. + '14 JUMP -> 7\_s*' .. + '15 DROP\_s*' .. + '16 RETURN void*', + res) + enddef + func Legacy() dict echo 'legacy' endfunc *** ../vim-8.2.3980/src/version.c 2022-01-02 13:05:41.992274960 +0000 --- src/version.c 2022-01-02 13:43:12.773947519 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 3981, /**/ -- What is the difference between a professional and an amateur? The ark was built by an amateur; professionals gave us the Titanic. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///