Patch 8.2.3011

6 views
Skip to first unread message

Bram Moolenaar

unread,
Jun 16, 2021, 1:20:31 PM6/16/21
to vim...@googlegroups.com

Patch 8.2.3011
Problem: Vim9: cannot get argument values during debugging.
Solution: Lookup names in the list of arguments. Put debug instruction
halfway for command.
Files: src/vim9compile.c, src/vim9execute.c,
src/testdir/test_debugger.vim


*** ../vim-8.2.3010/src/vim9compile.c 2021-06-15 22:13:23.829621578 +0200
--- src/vim9compile.c 2021-06-16 19:17:42.875046459 +0200
***************
*** 7711,7716 ****
--- 7711,7717 ----
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,7742 ****
--- 7738,7750 ----
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,7798 ****
item_type = vartype->tt_member->tt_member;
}

! // 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;
--- 7796,7807 ----
item_type = vartype->tt_member->tt_member;
}

! // 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,7898 ****
--- 7902,7911 ----
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,7933 ****
// 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
isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label;
isn->isn_arg.forloop.for_end = instr->ga_len;

--- 7940,7946 ----
// 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.
isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label;
isn->isn_arg.forloop.for_end = instr->ga_len;

***************
*** 8234,8239 ****
--- 8247,8253 ----
#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;
*** ../vim-8.2.3010/src/vim9execute.c 2021-06-15 22:13:23.829621578 +0200
--- src/vim9execute.c 2021-06-16 17:25:48.614112545 +0200
***************
*** 1394,1400 ****

// Set when calling do_debug().
static ectx_T *debug_context = NULL;
! static int debug_arg_count;

/*
* When debugging lookup "name" and return the typeval.
--- 1394,1400 ----

// Set when calling do_debug().
static ectx_T *debug_context = NULL;
! static int debug_var_count;

/*
* When debugging lookup "name" and return the typeval.
***************
*** 1405,1424 ****
{
int idx;
dfunc_T *dfunc;
ectx_T *ectx = debug_context;

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)
{
! char_u *s = ((char_u **)dfunc->df_var_names.ga_data)[idx];
! if (STRCMP(s, name) == 0)
return STACK_TV_VAR(idx);
}

return NULL;
}

--- 1405,1435 ----
{
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_var_count - 1; idx >= 0; --idx)
{
! 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,4158 ****

SOURCING_LNUM = iptr->isn_lnum;
debug_context = ectx;
! debug_arg_count = iptr->isn_arg.number;
line = ((char_u **)ufunc->uf_lines.ga_data)[
iptr->isn_lnum - 1];
if (line == NULL)
--- 4163,4169 ----

SOURCING_LNUM = iptr->isn_lnum;
debug_context = ectx;
! debug_var_count = iptr->isn_arg.number;
line = ((char_u **)ufunc->uf_lines.ga_data)[
iptr->isn_lnum - 1];
if (line == NULL)
*** ../vim-8.2.3010/src/testdir/test_debugger.vim 2021-06-15 19:32:35.638516519 +0200
--- src/testdir/test_debugger.vim 2021-06-16 19:15:05.087417584 +0200
***************
*** 937,948 ****
let file =<< trim END
vim9script
def g:Func()
! var n: number
! def Closure(): number
! return n + 3
! enddef
! n += Closure()
! echo 'result: ' .. n
enddef
END
call writefile(file, 'Xtest.vim')
--- 937,956 ----
let file =<< trim END
vim9script
def g:Func()
! 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,960 ****
--- 962,991 ----
\ ['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
*** ../vim-8.2.3010/src/version.c 2021-06-16 15:53:13.072696639 +0200
--- src/version.c 2021-06-16 16:46:53.039862308 +0200
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 3011,
/**/

--
A consultant is a person who takes your money and annoys your employees while
tirelessly searching for the best way to extend the consulting contract.
(Scott Adams - The Dilbert principle)

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages