0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

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.
This commit is contained in:
Bram Moolenaar
2022-09-15 17:19:37 +01:00
parent 3735f11050
commit b46c083a5e
8 changed files with 315 additions and 58 deletions

View File

@@ -1283,6 +1283,27 @@ generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where)
return OK;
}
/*
* 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.
*/
@@ -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;
}