forked from aniani/vim
patch 8.2.3366: Vim9: debugging elseif does not stop before condition
Problem: Vim9: debugging elseif does not stop before condition. Solution: Move debug statement to after the jump. (closes #8781)
This commit is contained in:
@@ -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
|
||||
|
@@ -755,6 +755,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3366,
|
||||
/**/
|
||||
3365,
|
||||
/**/
|
||||
|
@@ -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)
|
||||
@@ -7733,6 +7733,8 @@ compile_elseif(char_u *arg, cctx_T *cctx)
|
||||
if (cctx->ctx_skip == SKIP_UNKNOWN)
|
||||
{
|
||||
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
|
||||
|
Reference in New Issue
Block a user