patch 8.2.4040: keeping track of allocated lines is too complicated
Problem: Keeping track of allocated lines in user functions is too
complicated.
Solution: Instead of freeing individual lines keep them all until the end.
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 5af30fd..90d7adb 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -810,7 +810,7 @@
* Compile a nested :def command.
*/
static char_u *
-compile_nested_function(exarg_T *eap, cctx_T *cctx, char_u **line_to_free)
+compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
{
int is_global = *eap->arg == 'g' && eap->arg[1] == ':';
char_u *name_start = eap->arg;
@@ -876,7 +876,7 @@
goto theend;
}
- ufunc = define_function(eap, lambda_name, line_to_free);
+ ufunc = define_function(eap, lambda_name, lines_to_free);
if (ufunc == NULL)
{
r = eap->skip ? OK : FAIL;
@@ -2496,7 +2496,7 @@
cctx_T *outer_cctx)
{
char_u *line = NULL;
- char_u *line_to_free = NULL;
+ garray_T lines_to_free;
char_u *p;
char *errormsg = NULL; // error message
cctx_T cctx;
@@ -2514,6 +2514,9 @@
#endif
int debug_lnum = -1;
+ // allocated lines are freed at the end
+ ga_init2(&lines_to_free, sizeof(char_u *), 50);
+
// When using a function that was compiled before: Free old instructions.
// The index is reused. Otherwise add a new entry in "def_functions".
if (ufunc->uf_dfunc_idx > 0)
@@ -2681,8 +2684,8 @@
if (line != NULL)
{
line = vim_strsave(line);
- vim_free(line_to_free);
- line_to_free = line;
+ if (ga_add_string(&lines_to_free, line) == FAIL)
+ goto erret;
}
}
@@ -2926,7 +2929,7 @@
case CMD_def:
case CMD_function:
ea.arg = p;
- line = compile_nested_function(&ea, &cctx, &line_to_free);
+ line = compile_nested_function(&ea, &cctx, &lines_to_free);
break;
case CMD_return:
@@ -3236,7 +3239,7 @@
if (do_estack_push)
estack_pop();
- vim_free(line_to_free);
+ ga_clear_strings(&lines_to_free);
free_imported(&cctx);
free_locals(&cctx);
ga_clear(&cctx.ctx_type_stack);