Mercurial > vim
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: |