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:
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user