diff src/vim9compile.c @ 22326:fb69b43d73f3 v8.2.1712

patch 8.2.1712: Vim9: leaking memory when calling a lambda Commit: https://github.com/vim/vim/commit/a05e524f3aa8eadc2dbd0ad8ff6db9407ac7ac7e Author: Bram Moolenaar <Bram@vim.org> Date: Sat Sep 19 18:19:19 2020 +0200 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.
author Bram Moolenaar <Bram@vim.org>
date Sat, 19 Sep 2020 18:30:04 +0200
parents a4ed0de125d9
children fc3350a38389
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1452,7 +1452,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufu
 		    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 @@ compile_lambda_call(char_u **arg, cctx_T
     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 @@ delete_instr(isn_T *isn)
 	    {
 		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 @@ delete_instr(isn_T *isn)
 	case ISN_COMPARESPECIAL:
 	case ISN_COMPARESTRING:
 	case ISN_CONCAT:
-	case ISN_DCALL:
 	case ISN_DROP:
 	case ISN_ECHO:
 	case ISN_ECHOERR: