mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.2.3011: Vim9: cannot get argument values during debugging
Problem: Vim9: cannot get argument values during debugging. Solution: Lookup names in the list of arguments. Put debug instruction halfway for command.
This commit is contained in:
parent
41a7f82dea
commit
6bc30b05e6
@ -944,6 +944,14 @@ func Test_debug_def_function()
|
|||||||
n += Closure()
|
n += Closure()
|
||||||
echo 'result: ' .. n
|
echo 'result: ' .. n
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def g:FuncWithArgs(text: string, nr: number, ...items: list<number>)
|
||||||
|
echo text .. nr
|
||||||
|
for it in items
|
||||||
|
echo it
|
||||||
|
endfor
|
||||||
|
echo "done"
|
||||||
|
enddef
|
||||||
END
|
END
|
||||||
call writefile(file, 'Xtest.vim')
|
call writefile(file, 'Xtest.vim')
|
||||||
|
|
||||||
@ -954,7 +962,30 @@ func Test_debug_def_function()
|
|||||||
\ ['cmd: call Func()'])
|
\ ['cmd: call Func()'])
|
||||||
call RunDbgCmd(buf, 'next', ['result: 3'])
|
call RunDbgCmd(buf, 'next', ['result: 3'])
|
||||||
call term_sendkeys(buf, "\r")
|
call term_sendkeys(buf, "\r")
|
||||||
|
call RunDbgCmd(buf, 'cont')
|
||||||
|
|
||||||
|
call RunDbgCmd(buf,
|
||||||
|
\ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
|
||||||
|
\ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
|
||||||
|
call RunDbgCmd(buf, 'echo text', ['asdf'])
|
||||||
|
call RunDbgCmd(buf, 'echo nr', ['42'])
|
||||||
|
call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
|
||||||
|
call RunDbgCmd(buf, 'echo it', ['1'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['line 3: echo it'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
|
||||||
|
call RunDbgCmd(buf, 'echo it', ['2'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['line 3: echo it'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
|
||||||
|
call RunDbgCmd(buf, 'echo it', ['3'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['line 3: echo it'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
|
||||||
|
call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
|
||||||
|
|
||||||
|
call RunDbgCmd(buf, 'cont')
|
||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
call delete('Xtest.vim')
|
call delete('Xtest.vim')
|
||||||
endfunc
|
endfunc
|
||||||
|
@ -750,6 +750,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 */
|
||||||
|
/**/
|
||||||
|
3011,
|
||||||
/**/
|
/**/
|
||||||
3010,
|
3010,
|
||||||
/**/
|
/**/
|
||||||
|
@ -7711,6 +7711,7 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
int semicolon = FALSE;
|
int semicolon = FALSE;
|
||||||
size_t varlen;
|
size_t varlen;
|
||||||
garray_T *stack = &cctx->ctx_type_stack;
|
garray_T *stack = &cctx->ctx_type_stack;
|
||||||
|
garray_T *instr = &cctx->ctx_instr;
|
||||||
scope_T *scope;
|
scope_T *scope;
|
||||||
lvar_T *loop_lvar; // loop iteration variable
|
lvar_T *loop_lvar; // loop iteration variable
|
||||||
lvar_T *var_lvar; // variable for "var"
|
lvar_T *var_lvar; // variable for "var"
|
||||||
@ -7737,6 +7738,13 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
if (may_get_next_line_error(wp, &p, cctx) == FAIL)
|
if (may_get_next_line_error(wp, &p, cctx) == FAIL)
|
||||||
return NULL;
|
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;
|
||||||
|
|
||||||
scope = new_scope(cctx, FOR_SCOPE);
|
scope = new_scope(cctx, FOR_SCOPE);
|
||||||
if (scope == NULL)
|
if (scope == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -7788,11 +7796,12 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
item_type = vartype->tt_member->tt_member;
|
item_type = vartype->tt_member->tt_member;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CMDMOD_REV must come before the FOR instruction
|
// CMDMOD_REV must come before the FOR instruction.
|
||||||
generate_undo_cmdmods(cctx);
|
generate_undo_cmdmods(cctx);
|
||||||
|
|
||||||
// "for_end" is set when ":endfor" is found
|
// "for_end" is set when ":endfor" is found
|
||||||
scope->se_u.se_for.fs_top_label = current_instr_idx(cctx);
|
scope->se_u.se_for.fs_top_label = current_instr_idx(cctx);
|
||||||
|
|
||||||
generate_FOR(cctx, loop_lvar->lv_idx);
|
generate_FOR(cctx, loop_lvar->lv_idx);
|
||||||
|
|
||||||
arg = arg_start;
|
arg = arg_start;
|
||||||
@ -7893,6 +7902,10 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
vim_free(name);
|
vim_free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cctx->ctx_compile_type == CT_DEBUG)
|
||||||
|
// Add ISN_DEBUG here, so that the loop variables can be inspected.
|
||||||
|
generate_instr_debug(cctx);
|
||||||
|
|
||||||
return arg_end;
|
return arg_end;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
@ -7927,7 +7940,7 @@ compile_endfor(char_u *arg, cctx_T *cctx)
|
|||||||
// At end of ":for" scope jump back to the FOR instruction.
|
// At end of ":for" scope jump back to the FOR instruction.
|
||||||
generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label);
|
generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label);
|
||||||
|
|
||||||
// Fill in the "end" label in the FOR statement so it can jump here
|
// 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_T *)instr->ga_data) + forscope->fs_top_label;
|
||||||
isn->isn_arg.forloop.for_end = instr->ga_len;
|
isn->isn_arg.forloop.for_end = instr->ga_len;
|
||||||
|
|
||||||
@ -8234,6 +8247,7 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
|
|||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
// the profile-start should be after the jump
|
// the profile-start should be after the jump
|
||||||
if (cctx->ctx_compile_type == CT_PROFILE
|
if (cctx->ctx_compile_type == CT_PROFILE
|
||||||
|
&& instr->ga_len > 0
|
||||||
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
|
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
|
||||||
.isn_type == ISN_PROF_START)
|
.isn_type == ISN_PROF_START)
|
||||||
--instr->ga_len;
|
--instr->ga_len;
|
||||||
|
@ -1394,7 +1394,7 @@ typedef struct subs_expr_S {
|
|||||||
|
|
||||||
// Set when calling do_debug().
|
// Set when calling do_debug().
|
||||||
static ectx_T *debug_context = NULL;
|
static ectx_T *debug_context = NULL;
|
||||||
static int debug_arg_count;
|
static int debug_var_count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When debugging lookup "name" and return the typeval.
|
* When debugging lookup "name" and return the typeval.
|
||||||
@ -1405,20 +1405,31 @@ lookup_debug_var(char_u *name)
|
|||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
dfunc_T *dfunc;
|
dfunc_T *dfunc;
|
||||||
|
ufunc_T *ufunc;
|
||||||
ectx_T *ectx = debug_context;
|
ectx_T *ectx = debug_context;
|
||||||
|
int varargs_off;
|
||||||
|
|
||||||
if (ectx == NULL)
|
if (ectx == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
|
dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
|
||||||
|
|
||||||
// Go through the local variable names, from last to first.
|
// Go through the local variable names, from last to first.
|
||||||
for (idx = debug_arg_count - 1; idx >= 0; --idx)
|
for (idx = debug_var_count - 1; idx >= 0; --idx)
|
||||||
{
|
{
|
||||||
char_u *s = ((char_u **)dfunc->df_var_names.ga_data)[idx];
|
if (STRCMP(((char_u **)dfunc->df_var_names.ga_data)[idx], name) == 0)
|
||||||
if (STRCMP(s, name) == 0)
|
|
||||||
return STACK_TV_VAR(idx);
|
return STACK_TV_VAR(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Go through argument names.
|
||||||
|
ufunc = dfunc->df_ufunc;
|
||||||
|
varargs_off = ufunc->uf_va_name == NULL ? 0 : 1;
|
||||||
|
for (idx = 0; idx < ufunc->uf_args.ga_len; ++idx)
|
||||||
|
if (STRCMP(((char_u **)(ufunc->uf_args.ga_data))[idx], name) == 0)
|
||||||
|
return STACK_TV(ectx->ec_frame_idx - ufunc->uf_args.ga_len
|
||||||
|
- varargs_off + idx);
|
||||||
|
if (ufunc->uf_va_name != NULL && STRCMP(ufunc->uf_va_name, name) == 0)
|
||||||
|
return STACK_TV(ectx->ec_frame_idx - 1);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4152,7 +4163,7 @@ exec_instructions(ectx_T *ectx)
|
|||||||
|
|
||||||
SOURCING_LNUM = iptr->isn_lnum;
|
SOURCING_LNUM = iptr->isn_lnum;
|
||||||
debug_context = ectx;
|
debug_context = ectx;
|
||||||
debug_arg_count = iptr->isn_arg.number;
|
debug_var_count = iptr->isn_arg.number;
|
||||||
line = ((char_u **)ufunc->uf_lines.ga_data)[
|
line = ((char_u **)ufunc->uf_lines.ga_data)[
|
||||||
iptr->isn_lnum - 1];
|
iptr->isn_lnum - 1];
|
||||||
if (line == NULL)
|
if (line == NULL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user