diff src/vim9instr.c @ 30269:42a6345b91fd v9.0.0470

patch 9.0.0470: in :def function all closures in loop get the same variables Commit: https://github.com/vim/vim/commit/b46c083a5ed9e0c4ac5f3aec577946dcbe8c9dc5 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Sep 15 17:19:37 2022 +0100 patch 9.0.0470: in :def function all closures in loop get the same variables Problem: In a :def function all closures in a loop get the same variables. Solution: When in a loop and a closure refers to a variable declared in the loop, prepare for making a copy of variables for each closure.
author Bram Moolenaar <Bram@vim.org>
date Thu, 15 Sep 2022 18:30:04 +0200
parents d1c04b4dc60d
children 61a688be1899
line wrap: on
line diff
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -1284,6 +1284,27 @@ generate_JUMP(cctx_T *cctx, jumpwhen_T w
 }
 
 /*
+ * Generate an ISN_WHILE instruction.  Similar to ISN_JUMP for :while
+ */
+    int
+generate_WHILE(cctx_T *cctx, int funcref_idx)
+{
+    isn_T	*isn;
+    garray_T	*stack = &cctx->ctx_type_stack;
+
+    RETURN_OK_IF_SKIP(cctx);
+    if ((isn = generate_instr(cctx, ISN_WHILE)) == NULL)
+	return FAIL;
+    isn->isn_arg.whileloop.while_funcref_idx = funcref_idx;
+    isn->isn_arg.whileloop.while_end = 0;  // filled in later
+
+    if (stack->ga_len > 0)
+	--stack->ga_len;
+
+    return OK;
+}
+
+/*
  * Generate an ISN_JUMP_IF_ARG_SET instruction.
  */
     int
@@ -1312,6 +1333,25 @@ generate_FOR(cctx_T *cctx, int loop_idx)
     // type doesn't matter, will be stored next
     return push_type_stack(cctx, &t_any);
 }
+
+    int
+generate_ENDLOOP(
+	cctx_T	*cctx,
+	int	funcref_idx,
+	int	prev_local_count)
+{
+    isn_T	*isn;
+
+    RETURN_OK_IF_SKIP(cctx);
+    if ((isn = generate_instr(cctx, ISN_ENDLOOP)) == NULL)
+	return FAIL;
+    isn->isn_arg.endloop.end_funcref_idx = funcref_idx;
+    isn->isn_arg.endloop.end_var_idx = prev_local_count;
+    isn->isn_arg.endloop.end_var_count =
+				    cctx->ctx_locals.ga_len - prev_local_count;
+    return OK;
+}
+
 /*
  * Generate an ISN_TRYCONT instruction.
  */
@@ -2295,6 +2335,7 @@ delete_instr(isn_T *isn)
 	case ISN_ECHOERR:
 	case ISN_ECHOMSG:
 	case ISN_ECHOWINDOW:
+	case ISN_ENDLOOP:
 	case ISN_ENDTRY:
 	case ISN_EXECCONCAT:
 	case ISN_EXECUTE:
@@ -2341,10 +2382,10 @@ delete_instr(isn_T *isn)
 	case ISN_RETURN_VOID:
 	case ISN_SHUFFLE:
 	case ISN_SLICE:
+	case ISN_SOURCE:
 	case ISN_STORE:
 	case ISN_STOREINDEX:
 	case ISN_STORENR:
-	case ISN_SOURCE:
 	case ISN_STOREOUTER:
 	case ISN_STORERANGE:
 	case ISN_STOREREG:
@@ -2357,6 +2398,7 @@ delete_instr(isn_T *isn)
 	case ISN_UNLETRANGE:
 	case ISN_UNPACK:
 	case ISN_USEDICT:
+	case ISN_WHILE:
 	// nothing allocated
 	break;
     }