1
0
forked from aniani/vim

patch 8.2.2985: Vim9: a compiled function cannot be debugged

Problem:    Vim9: a compiled function cannot be debugged.
Solution:   Add initial debugging support.
This commit is contained in:
Bram Moolenaar
2021-06-13 14:01:26 +02:00
parent e6174fd58d
commit e99d422bbd
11 changed files with 196 additions and 77 deletions

View File

@@ -204,8 +204,8 @@ call_dfunc(
// Profiling might be enabled/disabled along the way. This should not
// fail, since the function was compiled before and toggling profiling
// doesn't change any errors.
if (func_needs_compiling(ufunc, PROFILING(ufunc))
&& compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
&& compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), NULL)
== FAIL)
return FAIL;
}
@@ -264,6 +264,7 @@ call_dfunc(
// If depth of calling is getting too high, don't execute the function.
if (funcdepth_increment() == FAIL)
return FAIL;
++ex_nesting_level;
// Only make a copy of funclocal if it contains something to restore.
if (ectx->ec_funclocal.floc_restore_cmdmod)
@@ -647,6 +648,7 @@ func_return(ectx_T *ectx)
ectx->ec_stack.ga_len = top;
funcdepth_decrement();
--ex_nesting_level;
return OK;
}
@@ -737,13 +739,15 @@ call_ufunc(
int idx;
int did_emsg_before = did_emsg;
#ifdef FEAT_PROFILE
int profiling = do_profiling == PROF_YES && ufunc->uf_profiling;
compiletype_T compile_type = do_profiling == PROF_YES
&& ufunc->uf_profiling ? CT_PROFILE : CT_NONE;
#else
# define profiling FALSE
# define compile_type CT_NONE
#endif
if (func_needs_compiling(ufunc, profiling)
&& compile_def_function(ufunc, FALSE, profiling, NULL) == FAIL)
if (func_needs_compiling(ufunc, compile_type)
&& compile_def_function(ufunc, FALSE, compile_type, NULL)
== FAIL)
return FAIL;
if (ufunc->uf_def_status == UF_COMPILED)
{
@@ -4099,6 +4103,22 @@ exec_instructions(ectx_T *ectx)
}
break;
case ISN_DEBUG:
if (ex_nesting_level <= debug_break_level)
{
char_u *line;
ufunc_T *ufunc = (((dfunc_T *)def_functions.ga_data)
+ ectx->ec_dfunc_idx)->df_ufunc;
SOURCING_LNUM = iptr->isn_lnum;
line = ((char_u **)ufunc->uf_lines.ga_data)[
iptr->isn_lnum - 1];
if (line == NULL)
line = (char_u *)"[empty]";
do_debug(line);
}
break;
case ISN_SHUFFLE:
{
typval_T tmp_tv;
@@ -4258,6 +4278,7 @@ call_def_function(
int save_emsg_silent_def = emsg_silent_def;
int save_did_emsg_def = did_emsg_def;
int orig_funcdepth;
int orig_nesting_level = ex_nesting_level;
// Get pointer to item in the stack.
#undef STACK_TV
@@ -4273,8 +4294,8 @@ call_def_function(
if (ufunc->uf_def_status == UF_NOT_COMPILED
|| ufunc->uf_def_status == UF_COMPILE_ERROR
|| (func_needs_compiling(ufunc, PROFILING(ufunc))
&& compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
|| (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
&& compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), NULL)
== FAIL))
{
if (did_emsg_cumul + did_emsg == did_emsg_before)
@@ -4310,6 +4331,7 @@ call_def_function(
ga_init2(&ectx.ec_trystack, sizeof(trycmd_T), 10);
ga_init2(&ectx.ec_funcrefs, sizeof(partial_T *), 10);
ectx.ec_did_emsg_before = did_emsg_before;
++ex_nesting_level;
idx = argc - ufunc->uf_args.ga_len;
if (idx > 0 && ufunc->uf_va_name == NULL)
@@ -4553,6 +4575,7 @@ failed_early:
// Free all local variables, but not arguments.
for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx)
clear_tv(STACK_TV(idx));
ex_nesting_level = orig_nesting_level;
vim_free(ectx.ec_stack.ga_data);
vim_free(ectx.ec_trystack.ga_data);
@@ -5315,13 +5338,18 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
case ISN_CMDMOD_REV: smsg("%s%4d CMDMOD_REV", pfx, current); break;
case ISN_PROF_START:
smsg("%s%4d PROFILE START line %d", pfx, current, iptr->isn_lnum);
smsg("%s%4d PROFILE START line %d", pfx, current,
iptr->isn_lnum);
break;
case ISN_PROF_END:
smsg("%s%4d PROFILE END", pfx, current);
break;
case ISN_DEBUG:
smsg("%s%4d DEBUG line %d", pfx, current, iptr->isn_lnum);
break;
case ISN_UNPACK: smsg("%s%4d UNPACK %d%s", pfx, current,
iptr->isn_arg.unpack.unp_count,
iptr->isn_arg.unpack.unp_semicolon ? " semicolon" : "");
@@ -5358,6 +5386,18 @@ ex_disassemble(exarg_T *eap)
isn_T *instr;
int instr_count;
int is_global = FALSE;
compiletype_T compile_type = CT_NONE;
if (STRNCMP(arg, "profile", 7) == 0)
{
compile_type = CT_PROFILE;
arg = skipwhite(arg + 7);
}
else if (STRNCMP(arg, "debug", 5) == 0)
{
compile_type = CT_DEBUG;
arg = skipwhite(arg + 5);
}
if (STRNCMP(arg, "<lambda>", 8) == 0)
{
@@ -5389,8 +5429,8 @@ ex_disassemble(exarg_T *eap)
semsg(_(e_cannot_find_function_str), eap->arg);
return;
}
if (func_needs_compiling(ufunc, eap->forceit)
&& compile_def_function(ufunc, FALSE, eap->forceit, NULL) == FAIL)
if (func_needs_compiling(ufunc, compile_type)
&& compile_def_function(ufunc, FALSE, compile_type, NULL) == FAIL)
return;
if (ufunc->uf_def_status != UF_COMPILED)
{
@@ -5403,14 +5443,24 @@ ex_disassemble(exarg_T *eap)
msg((char *)ufunc->uf_name);
dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
switch (compile_type)
{
case CT_PROFILE:
#ifdef FEAT_PROFILE
instr = eap->forceit ? dfunc->df_instr_prof : dfunc->df_instr;
instr_count = eap->forceit ? dfunc->df_instr_prof_count
: dfunc->df_instr_count;
#else
instr = dfunc->df_instr;
instr_count = dfunc->df_instr_count;
instr = dfunc->df_instr_prof;
instr_count = dfunc->df_instr_prof_count;
break;
#endif
// FALLTHROUGH
case CT_NONE:
instr = dfunc->df_instr;
instr_count = dfunc->df_instr_count;
break;
case CT_DEBUG:
instr = dfunc->df_instr_debug;
instr_count = dfunc->df_instr_debug_count;
break;
}
list_instructions("", instr, instr_count, ufunc);
}