patch 9.0.0397: :defer not tested with exceptions and ":qa!"

Problem:    :defer not tested with exceptions and ":qa!".
Solution:   Test :defer works when exceptions are thrown and when ":qa!" is
            used.  Invoke the deferred calls on exit.
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 08774fe..0b50ace 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -5171,13 +5171,7 @@
 done:
     ret = OK;
 theend:
-    {
-	dfunc_T	*dfunc = ((dfunc_T *)def_functions.ga_data)
-							  + ectx->ec_dfunc_idx;
-
-	if (dfunc->df_defer_var_idx > 0)
-	    invoke_defer_funcs(ectx);
-    }
+    may_invoke_defer_funcs(ectx);
 
     dict_stack_clear(dict_stack_len_at_start);
     ectx->ec_trylevel_at_start = save_trylevel_at_start;
@@ -5258,6 +5252,7 @@
     int		argc_arg,	// nr of arguments
     typval_T	*argv,		// arguments
     partial_T	*partial,	// optional partial for context
+    funccall_T	*funccal,
     typval_T	*rettv)		// return value
 {
     ectx_T	ectx;		// execution context
@@ -5494,6 +5489,10 @@
 	ectx.ec_instr = INSTRUCTIONS(dfunc);
     }
 
+    // Store the execution context in funccal, used by invoke_all_defer().
+    if (funccal != NULL)
+	funccal->fc_ectx = &ectx;
+
     // Following errors are in the function, not the caller.
     // Commands behave like vim9script.
     estack_push_ufunc(ufunc, 1);
@@ -5537,8 +5536,7 @@
     }
 
     // When failed need to unwind the call stack.
-    while (ectx.ec_frame_idx != ectx.ec_initial_frame_idx)
-	func_return(&ectx);
+    unwind_def_callstack(&ectx);
 
     // Deal with any remaining closures, they may be in use somewhere.
     if (ectx.ec_funcrefs.ga_len > 0)
@@ -5604,6 +5602,30 @@
 }
 
 /*
+ * Called when a def function has finished (possibly failed).
+ * Invoke all the function returns to clean up and invoke deferred functions,
+ * except the toplevel one.
+ */
+    void
+unwind_def_callstack(ectx_T *ectx)
+{
+    while (ectx->ec_frame_idx != ectx->ec_initial_frame_idx)
+	func_return(ectx);
+}
+
+/*
+ * Invoke any deffered functions for the top function in "ectx".
+ */
+    void
+may_invoke_defer_funcs(ectx_T *ectx)
+{
+    dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
+
+    if (dfunc->df_defer_var_idx > 0)
+	invoke_defer_funcs(ectx);
+}
+
+/*
  * List instructions "instr" up to "instr_count" or until ISN_FINISH.
  * "ufunc" has the source lines, NULL for the instructions of ISN_SUBSTITUTE.
  * "pfx" is prefixed to every line.