Mercurial > vim
comparison src/vim9compile.c @ 20247:e46e72aaff74 v8.2.0679
patch 8.2.0679: Vim9: incomplete support for closures
Commit: https://github.com/vim/vim/commit/bf67ea1af05cbb30cd8f0b665fb567c0dca79796
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat May 2 17:52:42 2020 +0200
patch 8.2.0679: Vim9: incomplete support for closures
Problem: Vim9: incomplete support for closures.
Solution: At the end of a function copy arguments and local variables if
they are still used by a referenced closure.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 02 May 2020 18:00:04 +0200 |
parents | 23d75968ca5e |
children | 6f9010b6f7f9 |
comparison
equal
deleted
inserted
replaced
20246:ef2250432801 | 20247:e46e72aaff74 |
---|---|
113 char_u *ctx_line_start; // start of current line or NULL | 113 char_u *ctx_line_start; // start of current line or NULL |
114 garray_T ctx_instr; // generated instructions | 114 garray_T ctx_instr; // generated instructions |
115 | 115 |
116 garray_T ctx_locals; // currently visible local variables | 116 garray_T ctx_locals; // currently visible local variables |
117 int ctx_locals_count; // total number of local variables | 117 int ctx_locals_count; // total number of local variables |
118 | |
119 int ctx_closure_count; // number of closures created in the | |
120 // function | |
118 | 121 |
119 garray_T ctx_imports; // imported items | 122 garray_T ctx_imports; // imported items |
120 | 123 |
121 int ctx_skip; // when TRUE skip commands, when FALSE skip | 124 int ctx_skip; // when TRUE skip commands, when FALSE skip |
122 // commands after "else" | 125 // commands after "else" |
1252 garray_T *stack = &cctx->ctx_type_stack; | 1255 garray_T *stack = &cctx->ctx_type_stack; |
1253 | 1256 |
1254 RETURN_OK_IF_SKIP(cctx); | 1257 RETURN_OK_IF_SKIP(cctx); |
1255 if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) | 1258 if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) |
1256 return FAIL; | 1259 return FAIL; |
1257 isn->isn_arg.number = dfunc_idx; | 1260 isn->isn_arg.funcref.fr_func = dfunc_idx; |
1261 isn->isn_arg.funcref.fr_var_idx = cctx->ctx_closure_count++; | |
1258 | 1262 |
1259 if (ga_grow(stack, 1) == FAIL) | 1263 if (ga_grow(stack, 1) == FAIL) |
1260 return FAIL; | 1264 return FAIL; |
1261 ((type_T **)stack->ga_data)[stack->ga_len] = &t_func_any; | 1265 ((type_T **)stack->ga_data)[stack->ga_len] = &t_func_any; |
1262 // TODO: argument and return types | 1266 // TODO: argument and return types |
6393 + ufunc->uf_dfunc_idx; | 6397 + ufunc->uf_dfunc_idx; |
6394 dfunc->df_deleted = FALSE; | 6398 dfunc->df_deleted = FALSE; |
6395 dfunc->df_instr = instr->ga_data; | 6399 dfunc->df_instr = instr->ga_data; |
6396 dfunc->df_instr_count = instr->ga_len; | 6400 dfunc->df_instr_count = instr->ga_len; |
6397 dfunc->df_varcount = cctx.ctx_locals_count; | 6401 dfunc->df_varcount = cctx.ctx_locals_count; |
6402 dfunc->df_closure_count = cctx.ctx_closure_count; | |
6398 if (cctx.ctx_outer_used) | 6403 if (cctx.ctx_outer_used) |
6399 ufunc->uf_flags |= FC_CLOSURE; | 6404 ufunc->uf_flags |= FC_CLOSURE; |
6400 } | 6405 } |
6401 | 6406 |
6402 { | 6407 { |
6618 { | 6623 { |
6619 for (idx = 0; idx < dfunc->df_instr_count; ++idx) | 6624 for (idx = 0; idx < dfunc->df_instr_count; ++idx) |
6620 delete_instr(dfunc->df_instr + idx); | 6625 delete_instr(dfunc->df_instr + idx); |
6621 VIM_CLEAR(dfunc->df_instr); | 6626 VIM_CLEAR(dfunc->df_instr); |
6622 } | 6627 } |
6628 if (dfunc->df_funcstack != NULL) | |
6629 { | |
6630 // Decrease the reference count for the context of a closure. If down | |
6631 // to zero free it and clear the variables on the stack. | |
6632 if (--dfunc->df_funcstack->fs_refcount == 0) | |
6633 { | |
6634 garray_T *gap = &dfunc->df_funcstack->fs_ga; | |
6635 typval_T *stack = gap->ga_data; | |
6636 int i; | |
6637 | |
6638 for (i = 0; i < gap->ga_len; ++i) | |
6639 clear_tv(stack + i); | |
6640 ga_clear(gap); | |
6641 vim_free(dfunc->df_funcstack); | |
6642 } | |
6643 dfunc->df_funcstack = NULL; | |
6644 } | |
6623 | 6645 |
6624 dfunc->df_deleted = TRUE; | 6646 dfunc->df_deleted = TRUE; |
6625 } | 6647 } |
6626 | 6648 |
6627 /* | 6649 /* |