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)
|
res)
|
||||||
enddef
|
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()
|
def s:EchoMessages()
|
||||||
echohl ErrorMsg | echom v:exception | echohl NONE
|
echohl ErrorMsg | echom v:exception | echohl NONE
|
||||||
enddef
|
enddef
|
||||||
|
@@ -755,6 +755,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
3366,
|
||||||
/**/
|
/**/
|
||||||
3365,
|
3365,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -2387,7 +2387,7 @@ misplaced_cmdmod(cctx_T *cctx)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the index of the current instruction.
|
* 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
|
static int
|
||||||
current_instr_idx(cctx_T *cctx)
|
current_instr_idx(cctx_T *cctx)
|
||||||
@@ -7733,6 +7733,8 @@ compile_elseif(char_u *arg, cctx_T *cctx)
|
|||||||
if (cctx->ctx_skip == SKIP_UNKNOWN)
|
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
|
// Move any CMDMOD instruction to after the jump
|
||||||
if (((isn_T *)instr->ga_data)[instr->ga_len - 1].isn_type == ISN_CMDMOD)
|
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;
|
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,
|
if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
|
||||||
JUMP_ALWAYS, cctx) == FAIL)
|
JUMP_ALWAYS, cctx) == FAIL)
|
||||||
return NULL;
|
return NULL;
|
||||||
// previous "if" or "elseif" jumps here
|
// previous "if" or "elseif" jumps here
|
||||||
isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
|
isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
|
||||||
isn->isn_arg.jump.jump_where = instr->ga_len;
|
isn->isn_arg.jump.jump_where = instr->ga_len;
|
||||||
|
|
||||||
if (moved_cmdmod)
|
if (moved_cmdmod)
|
||||||
++instr->ga_len;
|
++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
|
// compile "expr"; if we know it evaluates to FALSE skip the block
|
||||||
|
Reference in New Issue
Block a user