patch 8.2.1712: Vim9: leaking memory when calling a lambda
Problem: Vim9: leaking memory when calling a lambda.
Solution: Decrement function reference from ISN_DCALL.
diff --git a/src/vim9compile.c b/src/vim9compile.c
index a6b4ba4..0db5162 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1452,7 +1452,7 @@
ufunc->uf_def_status != UF_NOT_COMPILED ? ISN_DCALL
: ISN_UCALL)) == NULL)
return FAIL;
- if (ufunc->uf_def_status != UF_NOT_COMPILED)
+ if (isn->isn_type == ISN_DCALL)
{
isn->isn_arg.dfunc.cdf_idx = ufunc->uf_dfunc_idx;
isn->isn_arg.dfunc.cdf_argcount = argcount;
@@ -2634,8 +2634,8 @@
clear_tv(&rettv);
ga_init2(&ufunc->uf_type_list, sizeof(type_T *), 10);
- // The function will have one line: "return {expr}".
- // Compile it into instructions.
+ // The function will have one line: "return {expr}". Compile it into
+ // instructions so that we get any errors right now.
compile_def_function(ufunc, TRUE, cctx);
// compile the arguments
@@ -7285,7 +7285,19 @@
{
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
+ isn->isn_arg.funcref.fr_func;
- func_ptr_unref(dfunc->df_ufunc);
+
+ if (func_name_refcount(dfunc->df_ufunc->uf_name))
+ func_ptr_unref(dfunc->df_ufunc);
+ }
+ break;
+
+ case ISN_DCALL:
+ {
+ dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
+ + isn->isn_arg.dfunc.cdf_idx;
+
+ if (func_name_refcount(dfunc->df_ufunc->uf_name))
+ func_ptr_unref(dfunc->df_ufunc);
}
break;
@@ -7333,7 +7345,6 @@
case ISN_COMPARESPECIAL:
case ISN_COMPARESTRING:
case ISN_CONCAT:
- case ISN_DCALL:
case ISN_DROP:
case ISN_ECHO:
case ISN_ECHOERR: