summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-06-16 19:19:55 +0200
committerBram Moolenaar <Bram@vim.org>2021-06-16 19:19:55 +0200
commit6bc30b05e6081bcaece6d1a7fcfca238ea5a194f (patch)
tree32f3fdd08c680d474aaa761cc289ee6cd6238038
parent41a7f82dea525b3398bf372cbb9c268455845800 (diff)
patch 8.2.3011: Vim9: cannot get argument values during debuggingv8.2.3011
Problem: Vim9: cannot get argument values during debugging. Solution: Lookup names in the list of arguments. Put debug instruction halfway for command.
-rw-r--r--src/testdir/test_debugger.vim43
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c18
-rw-r--r--src/vim9execute.c21
4 files changed, 71 insertions, 13 deletions
diff --git a/src/testdir/test_debugger.vim b/src/testdir/test_debugger.vim
index bbf74258b2..5326576d02 100644
--- a/src/testdir/test_debugger.vim
+++ b/src/testdir/test_debugger.vim
@@ -937,12 +937,20 @@ func Test_debug_def_function()
let file =<< trim END
vim9script
def g:Func()
- var n: number
- def Closure(): number
- return n + 3
- enddef
- n += Closure()
- echo 'result: ' .. n
+ var n: number
+ def Closure(): number
+ return n + 3
+ enddef
+ n += Closure()
+ echo 'result: ' .. n
+ 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
call writefile(file, 'Xtest.vim')
@@ -954,7 +962,30 @@ func Test_debug_def_function()
\ ['cmd: call Func()'])
call RunDbgCmd(buf, 'next', ['result: 3'])
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 delete('Xtest.vim')
endfunc
diff --git a/src/version.c b/src/version.c
index 9198e2cb3a..dbb6d7ecda 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3011,
+/**/
3010,
/**/
3009,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 663a52dc7b..404c819e78 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -7711,6 +7711,7 @@ compile_for(char_u *arg_start, cctx_T *cctx)
int semicolon = FALSE;
size_t varlen;
garray_T *stack = &cctx->ctx_type_stack;
+ garray_T *instr = &cctx->ctx_instr;
scope_T *scope;
lvar_T *loop_lvar; // loop iteration variable
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)
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);
if (scope == NULL)
return NULL;
@@ -7788,11 +7796,12 @@ compile_for(char_u *arg_start, cctx_T *cctx)
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);
// "for_end" is set when ":endfor" is found
scope->se_u.se_for.fs_top_label = current_instr_idx(cctx);
+
generate_FOR(cctx, loop_lvar->lv_idx);
arg = arg_start;
@@ -7893,6 +7902,10 @@ compile_for(char_u *arg_start, cctx_T *cctx)
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;
failed:
@@ -7927,7 +7940,7 @@ compile_endfor(char_u *arg, cctx_T *cctx)
// At end of ":for" scope jump back to the FOR instruction.
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_arg.forloop.for_end = instr->ga_len;
@@ -8234,6 +8247,7 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
#ifdef FEAT_PROFILE
// the profile-start should be after the jump
if (cctx->ctx_compile_type == CT_PROFILE
+ && instr->ga_len > 0
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
.isn_type == ISN_PROF_START)
--instr->ga_len;
diff --git a/src/vim9execute.c b/src/vim9execute.c
index e464732dda..bbcf7ffc3c 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -1394,7 +1394,7 @@ typedef struct subs_expr_S {
// Set when calling do_debug().
static ectx_T *debug_context = NULL;
-static int debug_arg_count;
+static int debug_var_count;
/*
* When debugging lookup "name" and return the typeval.
@@ -1405,20 +1405,31 @@ lookup_debug_var(char_u *name)
{
int idx;
dfunc_T *dfunc;
+ ufunc_T *ufunc;
ectx_T *ectx = debug_context;
+ int varargs_off;
if (ectx == NULL)
return NULL;
dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
// 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(s, name) == 0)
+ if (STRCMP(((char_u **)dfunc->df_var_names.ga_data)[idx], name) == 0)
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;
}
@@ -4152,7 +4163,7 @@ exec_instructions(ectx_T *ectx)
SOURCING_LNUM = iptr->isn_lnum;
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)[
iptr->isn_lnum - 1];
if (line == NULL)