Mercurial > vim
diff src/vim9execute.c @ 24895:e61a2085c89b v8.2.2985
patch 8.2.2985: Vim9: a compiled function cannot be debugged
Commit: https://github.com/vim/vim/commit/e99d422bbd3e47620915bf89671673f0711671b4
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jun 13 14:01:26 2021 +0200
patch 8.2.2985: Vim9: a compiled function cannot be debugged
Problem: Vim9: a compiled function cannot be debugged.
Solution: Add initial debugging support.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 13 Jun 2021 14:15:04 +0200 |
parents | 193cc8bd8a2f |
children | 701e4a2576dd |
line wrap: on
line diff
--- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -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 *inst 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); }