diff src/vim9instr.c @ 30065:6cf788ab844c v9.0.0370

patch 9.0.0370: cleaning up afterwards can make a function messy Commit: https://github.com/vim/vim/commit/1d84f7608f1e41dad03b8cc7925895437775f7c0 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Sep 3 21:35:53 2022 +0100 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.
author Bram Moolenaar <Bram@vim.org>
date Sat, 03 Sep 2022 22:45:03 +0200
parents 30c642c58cd4
children d45ee1f829ba
line wrap: on
line diff
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -616,7 +616,7 @@ generate_tv_PUSH(cctx_T *cctx, typval_T 
 	case VAR_FUNC:
 	    if (tv->vval.v_string != NULL)
 		iemsg("non-null function constant not supported");
-	    generate_PUSHFUNC(cctx, NULL, &t_func_unknown);
+	    generate_PUSHFUNC(cctx, NULL, &t_func_unknown, TRUE);
 	    break;
 	case VAR_PARTIAL:
 	    if (tv->vval.v_partial != NULL)
@@ -796,9 +796,11 @@ generate_PUSHBLOB(cctx_T *cctx, blob_T *
 
 /*
  * Generate an ISN_PUSHFUNC instruction with name "name".
+ * When "may_prefix" is TRUE prefix "g:" unless "name" is script-local or
+ * autoload.
  */
     int
-generate_PUSHFUNC(cctx_T *cctx, char_u *name, type_T *type)
+generate_PUSHFUNC(cctx_T *cctx, char_u *name, type_T *type, int may_prefix)
 {
     isn_T	*isn;
     char_u	*funcname;
@@ -808,7 +810,8 @@ generate_PUSHFUNC(cctx_T *cctx, char_u *
 	return FAIL;
     if (name == NULL)
 	funcname = NULL;
-    else if (*name == K_SPECIAL				    // script-local
+    else if (!may_prefix
+	    || *name == K_SPECIAL			    // script-local
 	    || vim_strchr(name, AUTOLOAD_CHAR) != NULL)	    // autoload
 	funcname = vim_strsave(name);
     else
@@ -1679,6 +1682,22 @@ generate_PCALL(
 }
 
 /*
+ * Generate an ISN_DEFER instruction.
+ */
+    int
+generate_DEFER(cctx_T *cctx, int var_idx, int argcount)
+{
+    isn_T *isn;
+
+    RETURN_OK_IF_SKIP(cctx);
+    if ((isn = generate_instr_drop(cctx, ISN_DEFER, argcount + 1)) == NULL)
+	return FAIL;
+    isn->isn_arg.defer.defer_var_idx = var_idx;
+    isn->isn_arg.defer.defer_argcount = argcount;
+    return OK;
+}
+
+/*
  * Generate an ISN_STRINGMEMBER instruction.
  */
     int
@@ -2240,6 +2259,7 @@ delete_instr(isn_T *isn)
 	case ISN_CONCAT:
 	case ISN_COND2BOOL:
 	case ISN_DEBUG:
+	case ISN_DEFER:
 	case ISN_DROP:
 	case ISN_ECHO:
 	case ISN_ECHOCONSOLE:
@@ -2296,21 +2316,21 @@ delete_instr(isn_T *isn)
 	case ISN_STOREINDEX:
 	case ISN_STORENR:
 	case ISN_SOURCE:
-    case ISN_STOREOUTER:
-    case ISN_STORERANGE:
-    case ISN_STOREREG:
-    case ISN_STOREV:
-    case ISN_STRINDEX:
-    case ISN_STRSLICE:
-    case ISN_THROW:
-    case ISN_TRYCONT:
-    case ISN_UNLETINDEX:
-    case ISN_UNLETRANGE:
-    case ISN_UNPACK:
-    case ISN_USEDICT:
+	case ISN_STOREOUTER:
+	case ISN_STORERANGE:
+	case ISN_STOREREG:
+	case ISN_STOREV:
+	case ISN_STRINDEX:
+	case ISN_STRSLICE:
+	case ISN_THROW:
+	case ISN_TRYCONT:
+	case ISN_UNLETINDEX:
+	case ISN_UNLETRANGE:
+	case ISN_UNPACK:
+	case ISN_USEDICT:
 	// nothing allocated
 	break;
-}
+    }
 }
 
     void