0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

patch 8.1.0475: memory not freed on exit when quit in autocmd

Problem:    Memory not freed on exit when quit in autocmd.
Solution:   Remember funccal stack when executing autocmd.
This commit is contained in:
Bram Moolenaar
2018-10-14 21:41:01 +02:00
parent a16bc54503
commit 27e80c885b
8 changed files with 68 additions and 67 deletions

View File

@@ -1175,6 +1175,33 @@ func_name_refcount(char_u *name)
return isdigit(*name) || *name == '<';
}
static funccal_entry_T *funccal_stack = NULL;
/*
* Save the current function call pointer, and set it to NULL.
* Used when executing autocommands and for ":source".
*/
void
save_funccal(funccal_entry_T *entry)
{
entry->top_funccal = current_funccal;
entry->next = funccal_stack;
funccal_stack = entry;
current_funccal = NULL;
}
void
restore_funccal(void)
{
if (funccal_stack == NULL)
IEMSG("INTERNAL: restore_funccal()");
else
{
current_funccal = funccal_stack->top_funccal;
funccal_stack = funccal_stack->next;
}
}
#if defined(EXITFREE) || defined(PROTO)
void
free_all_functions(void)
@@ -1185,11 +1212,13 @@ free_all_functions(void)
long_u todo = 1;
long_u used;
/* Clean up the call stack. */
/* Clean up the current_funccal chain and the funccal stack. */
while (current_funccal != NULL)
{
clear_tv(current_funccal->rettv);
cleanup_function_call(current_funccal);
if (current_funccal == NULL && funccal_stack != NULL)
restore_funccal();
}
/* First clear what the functions contain. Since this may lower the
@@ -3578,27 +3607,6 @@ current_func_returned(void)
return current_funccal->returned;
}
/*
* Save the current function call pointer, and set it to NULL.
* Used when executing autocommands and for ":source".
*/
void *
save_funccal(void)
{
funccall_T *fc = current_funccal;
current_funccal = NULL;
return (void *)fc;
}
void
restore_funccal(void *vfc)
{
funccall_T *fc = (funccall_T *)vfc;
current_funccal = fc;
}
int
free_unref_funccal(int copyID, int testing)
{
@@ -3701,25 +3709,6 @@ get_funccal_args_var()
return &get_funccal()->l_avars_var;
}
/*
* Clear the current_funccal and return the old value.
* Caller is expected to invoke restore_current_funccal().
*/
void *
clear_current_funccal()
{
funccall_T *f = current_funccal;
current_funccal = NULL;
return f;
}
void
restore_current_funccal(void *f)
{
current_funccal = f;
}
/*
* List function variables, if there is a function.
*/