diff src/autocmd.c @ 18991:847cc7932c42 v8.2.0056

patch 8.2.0056: execution stack is incomplete and inefficient Commit: https://github.com/vim/vim/commit/1a47ae32cdc19b0fd5a82e19fe5fddf45db1a506 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Dec 29 23:04:25 2019 +0100 patch 8.2.0056: execution stack is incomplete and inefficient Problem: Execution stack is incomplete and inefficient. Solution: Introduce a proper execution stack and use it instead of sourcing_name/sourcing_lnum. Create a string only when used.
author Bram Moolenaar <Bram@vim.org>
date Sun, 29 Dec 2019 23:15:04 +0100
parents c469e1930456
children af1eca322b9e
line wrap: on
line diff
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -218,7 +218,7 @@ static AutoPat *last_autopat[NUM_EVENTS]
 /*
  * struct used to keep status while executing autocommands for an event.
  */
-typedef struct AutoPatCmd
+struct AutoPatCmd_S
 {
     AutoPat	*curpat;	// next AutoPat to examine
     AutoCmd	*nextcmd;	// next AutoCmd to execute
@@ -229,8 +229,8 @@ typedef struct AutoPatCmd
     event_T	event;		// current event
     int		arg_bufnr;	// Initially equal to <abuf>, set to zero when
 				// buf is deleted.
-    struct AutoPatCmd   *next;	// chain of active apc-s for auto-invalidation
-} AutoPatCmd;
+    AutoPatCmd   *next;		// chain of active apc-s for auto-invalidation
+};
 
 static AutoPatCmd *active_apc_list = NULL; // stack of active autocommands
 
@@ -1242,7 +1242,7 @@ do_autocmd_event(
 	    ac->cmd = vim_strsave(cmd);
 #ifdef FEAT_EVAL
 	    ac->script_ctx = current_sctx;
-	    ac->script_ctx.sc_lnum += sourcing_lnum;
+	    ac->script_ctx.sc_lnum += SOURCING_LNUM;
 #endif
 	    if (ac->cmd == NULL)
 	    {
@@ -1805,8 +1805,6 @@ apply_autocmds_group(
     int		save_changed;
     buf_T	*old_curbuf;
     int		retval = FALSE;
-    char_u	*save_sourcing_name;
-    linenr_T	save_sourcing_lnum;
     char_u	*save_autocmd_fname;
     int		save_autocmd_fname_full;
     int		save_autocmd_bufnr;
@@ -2020,10 +2018,9 @@ apply_autocmds_group(
 
     // Don't redraw while doing autocommands.
     ++RedrawingDisabled;
-    save_sourcing_name = sourcing_name;
-    sourcing_name = NULL;	// don't free this one
-    save_sourcing_lnum = sourcing_lnum;
-    sourcing_lnum = 0;		// no line number here
+
+    // name and lnum are filled in later
+    estack_push(ETYPE_AUCMD, NULL, 0);
 
 #ifdef FEAT_EVAL
     save_current_sctx = current_sctx;
@@ -2126,9 +2123,8 @@ apply_autocmds_group(
     autocmd_busy = save_autocmd_busy;
     filechangeshell_busy = FALSE;
     autocmd_nested = save_autocmd_nested;
-    vim_free(sourcing_name);
-    sourcing_name = save_sourcing_name;
-    sourcing_lnum = save_sourcing_lnum;
+    vim_free(SOURCING_NAME);
+    estack_pop();
     vim_free(autocmd_fname);
     autocmd_fname = save_autocmd_fname;
     autocmd_fname_full = save_autocmd_fname_full;
@@ -2256,8 +2252,9 @@ auto_next_pat(
     AutoCmd	*cp;
     char_u	*name;
     char	*s;
+    char_u	**sourcing_namep = &SOURCING_NAME;
 
-    VIM_CLEAR(sourcing_name);
+    VIM_CLEAR(*sourcing_namep);
 
     for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
     {
@@ -2277,16 +2274,16 @@ auto_next_pat(
 	    {
 		name = event_nr2name(apc->event);
 		s = _("%s Autocommands for \"%s\"");
-		sourcing_name = alloc(STRLEN(s)
+		*sourcing_namep = alloc(STRLEN(s)
 					      + STRLEN(name) + ap->patlen + 1);
-		if (sourcing_name != NULL)
+		if (*sourcing_namep != NULL)
 		{
-		    sprintf((char *)sourcing_name, s,
+		    sprintf((char *)*sourcing_namep, s,
 					       (char *)name, (char *)ap->pat);
 		    if (p_verbose >= 8)
 		    {
 			verbose_enter();
-			smsg(_("Executing %s"), sourcing_name);
+			smsg(_("Executing %s"), *sourcing_namep);
 			verbose_leave();
 		    }
 		}