diff src/vim9execute.c @ 24918:f11779c1d123 v8.2.2996

patch 8.2.2996: Vim9: when debugging cannot inspect local variables Commit: https://github.com/vim/vim/commit/b69c6fb7b423ddc4578b093cb19257cad459dfae Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jun 14 20:40:37 2021 +0200 patch 8.2.2996: Vim9: when debugging cannot inspect local variables Problem: Vim9: when debugging cannot inspect local variables. Solution: Make local variables available when debugging.
author Bram Moolenaar <Bram@vim.org>
date Mon, 14 Jun 2021 20:45:03 +0200
parents 09d222e89a84
children afaa7f3aae56
line wrap: on
line diff
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -172,6 +172,7 @@ call_dfunc(
     int		argcount = argcount_arg;
     dfunc_T	*dfunc = ((dfunc_T *)def_functions.ga_data) + cdf_idx;
     ufunc_T	*ufunc = dfunc->df_ufunc;
+    int		did_emsg_before = did_emsg_cumul + did_emsg;
     int		arg_to_add;
     int		vararg_count = 0;
     int		varcount;
@@ -211,6 +212,19 @@ call_dfunc(
     }
 #endif
 
+    // When debugging and using "cont" switches to the not-debugged
+    // instructions, may need to still compile them.
+    if ((func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
+	       && compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), NULL)
+								      == FAIL)
+	    || INSTRUCTIONS(dfunc) == NULL)
+    {
+	if (did_emsg_cumul + did_emsg == did_emsg_before)
+	    semsg(_(e_function_is_not_compiled_str),
+						   printable_func_name(ufunc));
+	return FAIL;
+    }
+
     if (ufunc->uf_va_name != NULL)
     {
 	// Need to make a list out of the vararg arguments.
@@ -1382,6 +1396,36 @@ typedef struct subs_expr_S {
 // Get pointer to a local variable on the stack.  Negative for arguments.
 #define STACK_TV_VAR(idx) (((typval_T *)ectx->ec_stack.ga_data) + ectx->ec_frame_idx + STACK_FRAME_SIZE + idx)
 
+// Set when calling do_debug().
+static ectx_T	*debug_context = NULL;
+static int	debug_arg_count;
+
+/*
+ * When debugging lookup "name" and return the typeval.
+ * When not found return NULL.
+ */
+    typval_T *
+lookup_debug_var(char_u *name)
+{
+    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;
+}
+
 /*
  * Execute instructions in execution context "ectx".
  * Return OK or FAIL;
@@ -4087,7 +4131,7 @@ exec_instructions(ectx_T *ectx)
 		    funccall_T cookie;
 		    ufunc_T	    *cur_ufunc =
 				    (((dfunc_T *)def_functions.ga_data)
-						 + ectx->ec_dfunc_idx)->df_ufunc;
+					       + ectx->ec_dfunc_idx)->df_ufunc;
 
 		    cookie.func = cur_ufunc;
 		    if (iptr->isn_type == ISN_PROF_START)
@@ -4110,11 +4154,14 @@ exec_instructions(ectx_T *ectx)
 					       + ectx->ec_dfunc_idx)->df_ufunc;
 
 		    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)
 			line = (char_u *)"[empty]";
 		    do_debug(line);
+		    debug_context = NULL;
 		}
 		break;
 
@@ -5346,7 +5393,8 @@ list_instructions(char *pfx, isn_T *inst
 		break;
 
 	    case ISN_DEBUG:
-		smsg("%s%4d DEBUG line %d", pfx, current, iptr->isn_lnum);
+		smsg("%s%4d DEBUG line %d varcount %lld", pfx, current,
+					 iptr->isn_lnum, iptr->isn_arg.number);
 		break;
 
 	    case ISN_UNPACK: smsg("%s%4d UNPACK %d%s", pfx, current,