diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-08-22 13:35:31 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-08-22 13:35:31 +0200 |
commit | 093165c899f1620543844d1c1a7a05975697c286 (patch) | |
tree | 2f70c53ba7537c6c3d195a7b82d6a6e84af0c6c0 | |
parent | bf5f2878333da934a8bdc560bf0bcf9a88ff86a1 (diff) | |
download | vim-git-093165c899f1620543844d1c1a7a05975697c286.tar.gz |
patch 8.2.3366: Vim9: debugging elseif does not stop before conditionv8.2.3366
Problem: Vim9: debugging elseif does not stop before condition.
Solution: Move debug statement to after the jump. (closes #8781)
-rw-r--r-- | src/testdir/test_vim9_disassemble.vim | 47 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 27 |
3 files changed, 74 insertions, 2 deletions
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 710c8ee3a..e7c574673 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -2255,6 +2255,53 @@ def Test_debugged() res) enddef +def s:DebugElseif() + var b = false + if b + eval 1 + 0 + silent elseif !b + eval 2 + 0 + endif +enddef + +def Test_debug_elseif() + var res = execute('disass debug s:DebugElseif') + assert_match('<SNR>\d*_DebugElseif\_s*' .. + 'var b = false\_s*' .. + '0 DEBUG line 1-1 varcount 0\_s*' .. + '1 PUSH false\_s*' .. + '2 STORE $0\_s*' .. + + 'if b\_s*' .. + '3 DEBUG line 2-2 varcount 1\_s*' .. + '4 LOAD $0\_s*' .. + '5 JUMP_IF_FALSE -> 10\_s*' .. + + 'eval 1 + 0\_s*' .. + '6 DEBUG line 3-3 varcount 1\_s*' .. + '7 PUSHNR 1\_s*' .. + '8 DROP\_s*' .. + + 'silent elseif !b\_s*' .. + '9 JUMP -> 20\_s*' .. + '10 CMDMOD silent\_s*' .. + '11 DEBUG line 4-4 varcount 1\_s*' .. + '12 LOAD $0\_s*' .. + '13 INVERT -1 (!val)\_s*' .. + '14 CMDMOD_REV\_s*' .. + '15 JUMP_IF_FALSE -> 20\_s*' .. + + 'eval 2 + 0\_s*' .. + '16 DEBUG line 5-5 varcount 1\_s*' .. + '17 PUSHNR 2\_s*' .. + '18 DROP\_s*' .. + + 'endif\_s*' .. + '19 DEBUG line 6-6 varcount 1\_s*' .. + '20 RETURN void*', + res) +enddef + def s:EchoMessages() echohl ErrorMsg | echom v:exception | echohl NONE enddef diff --git a/src/version.c b/src/version.c index 1130e6f7e..ca5402fda 100644 --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3366, +/**/ 3365, /**/ 3364, diff --git a/src/vim9compile.c b/src/vim9compile.c index 17aba4a69..90e6bf267 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2387,7 +2387,7 @@ misplaced_cmdmod(cctx_T *cctx) /* * Get the index of the current instruction. - * This compenstates for a preceding ISN_CMDMOD and ISN_PROF_START. + * This compensates for a preceding ISN_CMDMOD and ISN_PROF_START. */ static int current_instr_idx(cctx_T *cctx) @@ -7732,7 +7732,9 @@ compile_elseif(char_u *arg, cctx_T *cctx) if (cctx->ctx_skip == SKIP_UNKNOWN) { - int moved_cmdmod = FALSE; + int moved_cmdmod = FALSE; + int saved_debug = FALSE; + isn_T debug_isn; // Move any CMDMOD instruction to after the jump if (((isn_T *)instr->ga_data)[instr->ga_len - 1].isn_type == ISN_CMDMOD) @@ -7745,14 +7747,35 @@ compile_elseif(char_u *arg, cctx_T *cctx) moved_cmdmod = TRUE; } + // 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; + debug_isn = ((isn_T *)instr->ga_data)[instr->ga_len]; + saved_debug = TRUE; + } + if (compile_jump_to_end(&scope->se_u.se_if.is_end_label, JUMP_ALWAYS, cctx) == FAIL) return NULL; // previous "if" or "elseif" jumps here isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label; isn->isn_arg.jump.jump_where = instr->ga_len; + if (moved_cmdmod) ++instr->ga_len; + + if (saved_debug) + { + // move the debug instruction here + if (GA_GROW_FAILS(instr, 1)) + return NULL; + ((isn_T *)instr->ga_data)[instr->ga_len] = debug_isn; + ++instr->ga_len; + } } // compile "expr"; if we know it evaluates to FALSE skip the block |