patch 9.0.0370: cleaning up afterwards can make a function messy

Problem:    Cleaning up afterwards can make a function messy.
Solution:   Add the :defer command.
diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro
index 427d47b..3e417dd 100644
--- a/src/proto/userfunc.pro
+++ b/src/proto/userfunc.pro
@@ -58,6 +58,7 @@
 void func_ref(char_u *name);
 void func_ptr_ref(ufunc_T *fp);
 void ex_return(exarg_T *eap);
+void handle_defer(void);
 void ex_call(exarg_T *eap);
 int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv);
 void discard_pending_return(void *rettv);
diff --git a/src/proto/vim9cmds.pro b/src/proto/vim9cmds.pro
index 7529d63..10fc2c7 100644
--- a/src/proto/vim9cmds.pro
+++ b/src/proto/vim9cmds.pro
@@ -21,6 +21,7 @@
 char_u *compile_endtry(char_u *arg, cctx_T *cctx);
 char_u *compile_throw(char_u *arg, cctx_T *cctx);
 char_u *compile_eval(char_u *arg, cctx_T *cctx);
+char_u *compile_defer(char_u *arg_start, cctx_T *cctx);
 char_u *compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx);
 char_u *compile_put(char_u *arg, exarg_T *eap, cctx_T *cctx);
 char_u *compile_exec(char_u *line_arg, exarg_T *eap, cctx_T *cctx);
diff --git a/src/proto/vim9expr.pro b/src/proto/vim9expr.pro
index 233cfa2..f58e346 100644
--- a/src/proto/vim9expr.pro
+++ b/src/proto/vim9expr.pro
@@ -4,6 +4,7 @@
 int compile_member(int is_slice, int *keeping_dict, cctx_T *cctx);
 int compile_load_scriptvar(cctx_T *cctx, char_u *name, char_u *start, char_u **end);
 int compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int is_expr, int error);
+int compile_arguments(char_u **arg, cctx_T *cctx, int *argcount, ca_special_T special_fn);
 char_u *to_name_end(char_u *arg, int use_namespace);
 char_u *to_name_const_end(char_u *arg);
 int get_lambda_tv_and_compile(char_u **arg, typval_T *rettv, int types_optional, evalarg_T *evalarg);
diff --git a/src/proto/vim9instr.pro b/src/proto/vim9instr.pro
index 8a3254b..b0f3aa4 100644
--- a/src/proto/vim9instr.pro
+++ b/src/proto/vim9instr.pro
@@ -23,7 +23,7 @@
 int generate_PUSHCHANNEL(cctx_T *cctx);
 int generate_PUSHJOB(cctx_T *cctx);
 int generate_PUSHBLOB(cctx_T *cctx, blob_T *blob);
-int generate_PUSHFUNC(cctx_T *cctx, char_u *name, type_T *type);
+int generate_PUSHFUNC(cctx_T *cctx, char_u *name, type_T *type, int may_prefix);
 int generate_AUTOLOAD(cctx_T *cctx, char_u *name, type_T *type);
 int generate_GETITEM(cctx_T *cctx, int index, int with_op);
 int generate_SLICE(cctx_T *cctx, int count);
@@ -52,6 +52,7 @@
 int generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount);
 int generate_UCALL(cctx_T *cctx, char_u *name, int argcount);
 int generate_PCALL(cctx_T *cctx, int argcount, char_u *name, type_T *type, int at_top);
+int generate_DEFER(cctx_T *cctx, int var_idx, int argcount);
 int generate_STRINGMEMBER(cctx_T *cctx, char_u *name, size_t len);
 int generate_ECHO(cctx_T *cctx, int with_white, int count);
 int generate_MULT_EXPR(cctx_T *cctx, isntype_T isn_type, int count);