patch 8.2.1049: Vim9: leaking memory when using continuation line

Problem:    Vim9: leaking memory when using continuation line.
Solution:   Keep a pointer to the continuation line in evalarg_T.  Centralize
            checking for a next command.
diff --git a/src/eval.c b/src/eval.c
index ffb69de..79944c8 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -161,7 +161,7 @@
 eval_to_bool(
     char_u	*arg,
     int		*error,
-    char_u	**nextcmd,
+    exarg_T	*eap,
     int		skip)	    // only parse, don't execute
 {
     typval_T	tv;
@@ -169,7 +169,7 @@
 
     if (skip)
 	++emsg_skip;
-    if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE) == FAIL)
+    if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE) == FAIL)
 	*error = TRUE;
     else
     {
@@ -317,7 +317,7 @@
     char_u *
 eval_to_string_skip(
     char_u	*arg,
-    char_u	**nextcmd,
+    exarg_T	*eap,
     int		skip)	    // only parse, don't execute
 {
     typval_T	tv;
@@ -325,7 +325,7 @@
 
     if (skip)
 	++emsg_skip;
-    if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE)
+    if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE)
 							       == FAIL || skip)
 	retval = NULL;
     else
@@ -361,7 +361,6 @@
     char_u *
 eval_to_string(
     char_u	*arg,
-    char_u	**nextcmd,
     int		convert)
 {
     typval_T	tv;
@@ -371,7 +370,7 @@
     char_u	numbuf[NUMBUFLEN];
 #endif
 
-    if (eval0(arg, &tv, nextcmd, &EVALARG_EVALUATE) == FAIL)
+    if (eval0(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL)
 	retval = NULL;
     else
     {
@@ -409,7 +408,6 @@
     char_u *
 eval_to_string_safe(
     char_u	*arg,
-    char_u	**nextcmd,
     int		use_sandbox)
 {
     char_u	*retval;
@@ -419,7 +417,7 @@
     if (use_sandbox)
 	++sandbox;
     ++textwinlock;
-    retval = eval_to_string(arg, nextcmd, FALSE);
+    retval = eval_to_string(arg, FALSE);
     if (use_sandbox)
 	--sandbox;
     --textwinlock;
@@ -459,12 +457,12 @@
  * Returns NULL when there is an error.
  */
     typval_T *
-eval_expr(char_u *arg, char_u **nextcmd)
+eval_expr(char_u *arg, exarg_T *eap)
 {
     typval_T	*tv;
 
     tv = ALLOC_ONE(typval_T);
-    if (tv != NULL && eval0(arg, tv, nextcmd, &EVALARG_EVALUATE) == FAIL)
+    if (tv != NULL && eval0(arg, tv, eap, &EVALARG_EVALUATE) == FAIL)
 	VIM_CLEAR(tv);
 
     return tv;
@@ -1418,7 +1416,7 @@
 eval_for_line(
     char_u	*arg,
     int		*errp,
-    char_u	**nextcmdp,
+    exarg_T	*eap,
     int		skip)
 {
     forinfo_T	*fi;
@@ -1448,7 +1446,7 @@
 
     if (skip)
 	++emsg_skip;
-    if (eval0(skipwhite(expr + 2), &tv, nextcmdp, &evalarg) == OK)
+    if (eval0(skipwhite(expr + 2), &tv, eap, &evalarg) == OK)
     {
 	*errp = FALSE;
 	if (!skip)
@@ -1796,6 +1794,17 @@
 }
 
 /*
+ * To be called when eval_next_non_blank() sets "getnext" to TRUE.
+ */
+    static char_u *
+eval_next_line(evalarg_T *evalarg)
+{
+    vim_free(evalarg->eval_tofree);
+    evalarg->eval_tofree = getsourceline(0, evalarg->eval_cookie, 0, TRUE);
+    return skipwhite(evalarg->eval_tofree);
+}
+
+/*
  * The "evaluate" argument: When FALSE, the argument is only parsed but not
  * executed.  The function may return OK, but the rettv will be of type
  * VAR_UNKNOWN.  The function still returns FAIL for a syntax error.
@@ -1813,7 +1822,7 @@
 eval0(
     char_u	*arg,
     typval_T	*rettv,
-    char_u	**nextcmd,
+    exarg_T	*eap,
     evalarg_T	*evalarg)
 {
     int		ret;
@@ -1822,8 +1831,11 @@
     int		called_emsg_before = called_emsg;
     int		flags = evalarg == NULL ? 0 : evalarg->eval_flags;
 
+    if (evalarg != NULL)
+	evalarg->eval_tofree = NULL;
     p = skipwhite(arg);
     ret = eval1(&p, rettv, evalarg);
+
     if (ret == FAIL || !ends_excmd2(arg, p))
     {
 	if (ret != FAIL)
@@ -1841,8 +1853,27 @@
 	    semsg(_(e_invexpr2), arg);
 	ret = FAIL;
     }
-    if (nextcmd != NULL)
-	*nextcmd = check_nextcmd(p);
+
+    if (eap != NULL)
+	eap->nextcmd = check_nextcmd(p);
+
+    if (evalarg != NULL)
+    {
+	if (eap != NULL)
+	{
+	    if (evalarg->eval_tofree != NULL)
+	    {
+		// We may need to keep the original command line, e.g. for
+		// ":let" it has the variable names.  But we may also need the
+		// new one, "nextcmd" points into it.  Keep both.
+		vim_free(eap->cmdline_tofree);
+		eap->cmdline_tofree = *eap->cmdlinep;
+		*eap->cmdlinep = evalarg->eval_tofree;
+	    }
+	}
+	else
+	    vim_free(evalarg->eval_tofree);
+    }
 
     return ret;
 }
@@ -2305,7 +2336,7 @@
 	if (op != '+' && op != '-' && !concat)
 	    break;
 	if (getnext)
-	    *arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE));
+	    *arg = eval_next_line(evalarg);
 
 	if ((op != '+' || (rettv->v_type != VAR_LIST
 						 && rettv->v_type != VAR_BLOB))
@@ -2497,7 +2528,7 @@
 	if (op != '*' && op != '/' && op != '%')
 	    break;
 	if (getnext)
-	    *arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE));
+	    *arg = eval_next_line(evalarg);
 
 	if (evaluate)
 	{
@@ -4734,7 +4765,6 @@
     char_u	c1;
     char_u	*retval = NULL;
     char_u	*temp_result;
-    char_u	*nextcmd = NULL;
 
     if (expr_end == NULL || in_end == NULL)
 	return NULL;
@@ -4743,8 +4773,8 @@
     c1 = *in_end;
     *in_end = NUL;
 
-    temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE);
-    if (temp_result != NULL && nextcmd == NULL)
+    temp_result = eval_to_string(expr_start + 1, FALSE);
+    if (temp_result != NULL)
     {
 	retval = alloc(STRLEN(temp_result) + (expr_start - in_start)
 						   + (in_end - expr_end) + 1);