diff options
Diffstat (limited to 'src/vim9instr.c')
-rw-r--r-- | src/vim9instr.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/src/vim9instr.c b/src/vim9instr.c index edc6cb61d..85a49a893 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -997,6 +997,7 @@ generate_LOADOUTER( cctx_T *cctx, int idx, int nesting, + int loop_depth, int loop_idx, type_T *type) { @@ -1008,9 +1009,9 @@ generate_LOADOUTER( if (nesting == 1 && loop_idx >= 0 && idx >= loop_idx) { // Load a variable defined in a loop. A copy will be made at the end - // of the loop. TODO: how about deeper nesting? + // of the loop. isn->isn_arg.outer.outer_idx = idx - loop_idx; - isn->isn_arg.outer.outer_depth = OUTER_LOOP_DEPTH; + isn->isn_arg.outer.outer_depth = -loop_depth - 1; } else { @@ -1207,8 +1208,8 @@ generate_FUNCREF( isn_T *isn; type_T *type; funcref_extra_T *extra; - short loop_var_idx; - short loop_var_count; + loopvarinfo_T loopinfo; + int has_vars; RETURN_OK_IF_SKIP(cctx); if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) @@ -1216,20 +1217,22 @@ generate_FUNCREF( if (isnp != NULL) *isnp = isn; - loop_var_count = get_loop_var_info(cctx, &loop_var_idx); - if (ufunc->uf_def_status == UF_NOT_COMPILED || loop_var_count > 0) + has_vars = get_loop_var_info(cctx, &loopinfo); + if (ufunc->uf_def_status == UF_NOT_COMPILED || has_vars) { extra = ALLOC_CLEAR_ONE(funcref_extra_T); if (extra == NULL) return FAIL; isn->isn_arg.funcref.fr_extra = extra; - extra->fre_loop_var_idx = loop_var_idx; - extra->fre_loop_var_count = loop_var_count; + extra->fre_loopvar_info = loopinfo; } if (ufunc->uf_def_status == UF_NOT_COMPILED) extra->fre_func_name = vim_strsave(ufunc->uf_name); else isn->isn_arg.funcref.fr_dfunc_idx = ufunc->uf_dfunc_idx; + + // Reserve an extra variable to keep track of the number of closures + // created. cctx->ctx_has_closure = 1; // If the referenced function is a closure, it may use items further up in @@ -1252,9 +1255,7 @@ generate_FUNCREF( generate_NEWFUNC( cctx_T *cctx, char_u *lambda_name, - char_u *func_name, - short loop_var_idx, - short loop_var_count) + char_u *func_name) { isn_T *isn; int ret = OK; @@ -1271,11 +1272,14 @@ generate_NEWFUNC( ret = FAIL; else { + // Reserve an extra variable to keep track of the number of + // closures created. + cctx->ctx_has_closure = 1; + isn->isn_arg.newfunc.nf_arg = arg; arg->nfa_lambda = lambda_name; arg->nfa_global = func_name; - arg->nfa_loop_var_idx = loop_var_idx; - arg->nfa_loop_var_count = loop_var_count; + (void)get_loop_var_info(cctx, &arg->nfa_loopvar_info); return OK; } } @@ -1371,27 +1375,25 @@ generate_FOR(cctx_T *cctx, int loop_idx) RETURN_OK_IF_SKIP(cctx); if ((isn = generate_instr(cctx, ISN_FOR)) == NULL) return FAIL; - isn->isn_arg.forloop.for_idx = loop_idx; + isn->isn_arg.forloop.for_loop_idx = 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) +generate_ENDLOOP(cctx_T *cctx, loop_info_T *loop_info) { 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_depth = loop_info->li_depth; + isn->isn_arg.endloop.end_funcref_idx = loop_info->li_funcref_idx; + isn->isn_arg.endloop.end_var_idx = loop_info->li_local_count; isn->isn_arg.endloop.end_var_count = - cctx->ctx_locals.ga_len - prev_local_count; + cctx->ctx_locals.ga_len - loop_info->li_local_count; return OK; } |