comparison src/vim9compile.c @ 19864:8288884fdfe1 v8.2.0488

patch 8.2.0488: Vim9: compiling can break when using a lambda inside :def Commit: https://github.com/vim/vim/commit/05afceeddc4afbbca60e4e6a729a50d33d4b19f7 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Mar 31 23:32:31 2020 +0200 patch 8.2.0488: Vim9: compiling can break when using a lambda inside :def Problem: Vim9: Compiling can break when using a lambda inside :def. Solution: Do not keep a pointer to the dfunc_T for longer time.
author Bram Moolenaar <Bram@vim.org>
date Tue, 31 Mar 2020 23:45:04 +0200
parents 846fbbacce3a
children 1136ec381dd2
comparison
equal deleted inserted replaced
19863:b6f8f6d22e8e 19864:8288884fdfe1
5027 * After ex_function() has collected all the function lines: parse and compile 5027 * After ex_function() has collected all the function lines: parse and compile
5028 * the lines into instructions. 5028 * the lines into instructions.
5029 * Adds the function to "def_functions". 5029 * Adds the function to "def_functions".
5030 * When "set_return_type" is set then set ufunc->uf_ret_type to the type of the 5030 * When "set_return_type" is set then set ufunc->uf_ret_type to the type of the
5031 * return statement (used for lambda). 5031 * return statement (used for lambda).
5032 * This can be used recursively through compile_lambda(), which may reallocate
5033 * "def_functions".
5032 */ 5034 */
5033 void 5035 void
5034 compile_def_function(ufunc_T *ufunc, int set_return_type) 5036 compile_def_function(ufunc_T *ufunc, int set_return_type)
5035 { 5037 {
5036 dfunc_T *dfunc;
5037 char_u *line = NULL; 5038 char_u *line = NULL;
5038 char_u *p; 5039 char_u *p;
5039 exarg_T ea; 5040 exarg_T ea;
5040 char *errormsg = NULL; // error message 5041 char *errormsg = NULL; // error message
5041 int had_return = FALSE; 5042 int had_return = FALSE;
5044 int called_emsg_before = called_emsg; 5045 int called_emsg_before = called_emsg;
5045 int ret = FAIL; 5046 int ret = FAIL;
5046 sctx_T save_current_sctx = current_sctx; 5047 sctx_T save_current_sctx = current_sctx;
5047 int emsg_before = called_emsg; 5048 int emsg_before = called_emsg;
5048 5049
5049 if (ufunc->uf_dfunc_idx >= 0) 5050 {
5050 { 5051 dfunc_T *dfunc; // may be invalidated by compile_lambda()
5051 // Redefining a function that was compiled before. 5052
5052 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; 5053 if (ufunc->uf_dfunc_idx >= 0)
5053 5054 {
5054 // Free old instructions. 5055 // Redefining a function that was compiled before.
5055 delete_def_function_contents(dfunc); 5056 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
5056 } 5057
5057 else 5058 // Free old instructions.
5058 { 5059 delete_def_function_contents(dfunc);
5059 // Add the function to "def_functions". 5060 }
5060 if (ga_grow(&def_functions, 1) == FAIL) 5061 else
5061 return; 5062 {
5062 dfunc = ((dfunc_T *)def_functions.ga_data) + def_functions.ga_len; 5063 // Add the function to "def_functions".
5063 vim_memset(dfunc, 0, sizeof(dfunc_T)); 5064 if (ga_grow(&def_functions, 1) == FAIL)
5064 dfunc->df_idx = def_functions.ga_len; 5065 return;
5065 ufunc->uf_dfunc_idx = dfunc->df_idx; 5066 dfunc = ((dfunc_T *)def_functions.ga_data) + def_functions.ga_len;
5066 dfunc->df_ufunc = ufunc; 5067 vim_memset(dfunc, 0, sizeof(dfunc_T));
5067 ++def_functions.ga_len; 5068 dfunc->df_idx = def_functions.ga_len;
5069 ufunc->uf_dfunc_idx = dfunc->df_idx;
5070 dfunc->df_ufunc = ufunc;
5071 ++def_functions.ga_len;
5072 }
5068 } 5073 }
5069 5074
5070 vim_memset(&cctx, 0, sizeof(cctx)); 5075 vim_memset(&cctx, 0, sizeof(cctx));
5071 cctx.ctx_ufunc = ufunc; 5076 cctx.ctx_ufunc = ufunc;
5072 cctx.ctx_lnum = -1; 5077 cctx.ctx_lnum = -1;
5412 // Return zero if there is no return at the end. 5417 // Return zero if there is no return at the end.
5413 generate_PUSHNR(&cctx, 0); 5418 generate_PUSHNR(&cctx, 0);
5414 generate_instr(&cctx, ISN_RETURN); 5419 generate_instr(&cctx, ISN_RETURN);
5415 } 5420 }
5416 5421
5417 dfunc->df_deleted = FALSE; 5422 {
5418 dfunc->df_instr = instr->ga_data; 5423 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
5419 dfunc->df_instr_count = instr->ga_len; 5424 + ufunc->uf_dfunc_idx;
5420 dfunc->df_varcount = cctx.ctx_max_local; 5425 dfunc->df_deleted = FALSE;
5426 dfunc->df_instr = instr->ga_data;
5427 dfunc->df_instr_count = instr->ga_len;
5428 dfunc->df_varcount = cctx.ctx_max_local;
5429 }
5421 5430
5422 ret = OK; 5431 ret = OK;
5423 5432
5424 erret: 5433 erret:
5425 if (ret == FAIL) 5434 if (ret == FAIL)
5426 { 5435 {
5427 int idx; 5436 int idx;
5437 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
5438 + ufunc->uf_dfunc_idx;
5428 5439
5429 for (idx = 0; idx < instr->ga_len; ++idx) 5440 for (idx = 0; idx < instr->ga_len; ++idx)
5430 delete_instr(((isn_T *)instr->ga_data) + idx); 5441 delete_instr(((isn_T *)instr->ga_data) + idx);
5431 ga_clear(instr); 5442 ga_clear(instr);
5432 5443