aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval/userfunc.c
diff options
context:
space:
mode:
authorerw7 <erw7.github@gmail.com>2019-08-31 15:09:30 +0900
committererw7 <erw7.github@gmail.com>2020-05-07 16:00:46 +0900
commit17f067f4b4799dde06be78f9b7c9e7c7d60900a2 (patch)
treec67ce740707feb31fe6bf55d8fbbd3ff3503d4ab /src/nvim/eval/userfunc.c
parentf04a9a2c9aa68f98a79b8d7e9917719a8be6049b (diff)
downloadrneovim-17f067f4b4799dde06be78f9b7c9e7c7d60900a2.tar.gz
rneovim-17f067f4b4799dde06be78f9b7c9e7c7d60900a2.tar.bz2
rneovim-17f067f4b4799dde06be78f9b7c9e7c7d60900a2.zip
vim-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. https://github.com/vim/vim/commit/27e80c885bcb5c5cf6a6462d71d6c81b06ba2451
Diffstat (limited to 'src/nvim/eval/userfunc.c')
-rw-r--r--src/nvim/eval/userfunc.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index ae8557a8bc..9e123e505f 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -1106,21 +1106,26 @@ static bool func_name_refcount(char_u *name)
return isdigit(*name) || *name == '<';
}
-/*
- * 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;
+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;
- return (void *)fc;
}
-void restore_funccal(void *vfc)
+void restore_funccal(void)
{
- current_funccal = (funccall_T *)vfc;
+ if (funccal_stack == NULL) {
+ IEMSG("INTERNAL: restore_funccal()");
+ } else {
+ current_funccal = funccal_stack->top_funccal;
+ funccal_stack = funccal_stack->next;
+ }
}
funccall_T *get_current_funccal(void)
@@ -1128,6 +1133,11 @@ funccall_T *get_current_funccal(void)
return current_funccal;
}
+void set_current_funccal(funccall_T *fc)
+{
+ current_funccal = fc;
+}
+
#if defined(EXITFREE)
void free_all_functions(void)
{
@@ -1137,10 +1147,13 @@ void free_all_functions(void)
uint64_t todo = 1;
uint64_t used;
- // Clean up the call stack.
+ // Clean up the current_funccal chain and the funccal stack.
while (current_funccal != NULL) {
tv_clear(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