comparison src/vim9compile.c @ 22371:15003353a464 v8.2.1734

patch 8.2.1734: Vim9: cannot use a funcref for a closure twice Commit: https://github.com/vim/vim/commit/148ce7ae62e92ecf6487a4ba5902ddb7e699074b Author: Bram Moolenaar <Bram@vim.org> Date: Wed Sep 23 21:57:23 2020 +0200 patch 8.2.1734: Vim9: cannot use a funcref for a closure twice Problem: Vim9: cannot use a funcref for a closure twice. Solution: Instead of putting the funcref on the stack use a growarray on the execution context.
author Bram Moolenaar <Bram@vim.org>
date Wed, 23 Sep 2020 22:00:06 +0200
parents 62192fd08e0e
children 6fe9536694ff
comparison
equal deleted inserted replaced
22370:9a06648f05d3 22371:15003353a464
124 garray_T ctx_instr; // generated instructions 124 garray_T ctx_instr; // generated instructions
125 125
126 garray_T ctx_locals; // currently visible local variables 126 garray_T ctx_locals; // currently visible local variables
127 int ctx_locals_count; // total number of local variables 127 int ctx_locals_count; // total number of local variables
128 128
129 int ctx_closure_count; // number of closures created in the 129 int ctx_has_closure; // set to one if a closures was created in
130 // function 130 // the function
131 131
132 garray_T ctx_imports; // imported items 132 garray_T ctx_imports; // imported items
133 133
134 skip_T ctx_skip; 134 skip_T ctx_skip;
135 scope_T *ctx_scope; // current scope, NULL at toplevel 135 scope_T *ctx_scope; // current scope, NULL at toplevel
1271 1271
1272 RETURN_OK_IF_SKIP(cctx); 1272 RETURN_OK_IF_SKIP(cctx);
1273 if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) 1273 if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL)
1274 return FAIL; 1274 return FAIL;
1275 isn->isn_arg.funcref.fr_func = ufunc->uf_dfunc_idx; 1275 isn->isn_arg.funcref.fr_func = ufunc->uf_dfunc_idx;
1276 isn->isn_arg.funcref.fr_var_idx = cctx->ctx_closure_count++; 1276 cctx->ctx_has_closure = 1;
1277 1277
1278 if (ga_grow(stack, 1) == FAIL) 1278 if (ga_grow(stack, 1) == FAIL)
1279 return FAIL; 1279 return FAIL;
1280 ((type_T **)stack->ga_data)[stack->ga_len] = 1280 ((type_T **)stack->ga_data)[stack->ga_len] =
1281 ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type; 1281 ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type;
7136 + ufunc->uf_dfunc_idx; 7136 + ufunc->uf_dfunc_idx;
7137 dfunc->df_deleted = FALSE; 7137 dfunc->df_deleted = FALSE;
7138 dfunc->df_instr = instr->ga_data; 7138 dfunc->df_instr = instr->ga_data;
7139 dfunc->df_instr_count = instr->ga_len; 7139 dfunc->df_instr_count = instr->ga_len;
7140 dfunc->df_varcount = cctx.ctx_locals_count; 7140 dfunc->df_varcount = cctx.ctx_locals_count;
7141 dfunc->df_closure_count = cctx.ctx_closure_count; 7141 dfunc->df_has_closure = cctx.ctx_has_closure;
7142 if (cctx.ctx_outer_used) 7142 if (cctx.ctx_outer_used)
7143 ufunc->uf_flags |= FC_CLOSURE; 7143 ufunc->uf_flags |= FC_CLOSURE;
7144 ufunc->uf_def_status = UF_COMPILED; 7144 ufunc->uf_def_status = UF_COMPILED;
7145 } 7145 }
7146 7146
7310 case ISN_DCALL: 7310 case ISN_DCALL:
7311 { 7311 {
7312 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) 7312 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
7313 + isn->isn_arg.dfunc.cdf_idx; 7313 + isn->isn_arg.dfunc.cdf_idx;
7314 7314
7315 if (func_name_refcount(dfunc->df_ufunc->uf_name)) 7315 if (dfunc->df_ufunc != NULL
7316 && func_name_refcount(dfunc->df_ufunc->uf_name))
7316 func_ptr_unref(dfunc->df_ufunc); 7317 func_ptr_unref(dfunc->df_ufunc);
7317 } 7318 }
7318 break; 7319 break;
7319 7320
7320 case ISN_NEWFUNC: 7321 case ISN_NEWFUNC: