Patch 8.2.0488

11 views
Skip to first unread message

Bram Moolenaar

unread,
Mar 31, 2020, 5:33:08 PM3/31/20
to vim...@googlegroups.com

Patch 8.2.0488
Problem: Vim9: Compiling can break when using a lambda inside :def.
Solution: Do not keep a pointer to the dfunc_T for longer time.
Files: src/vim9compile.c, src/vim9.h


*** ../vim-8.2.0487/src/vim9compile.c 2020-03-31 23:13:05.758568664 +0200
--- src/vim9compile.c 2020-03-31 23:28:43.711140249 +0200
***************
*** 5029,5039 ****
* Adds the function to "def_functions".
* When "set_return_type" is set then set ufunc->uf_ret_type to the type of the
* return statement (used for lambda).
*/
void
compile_def_function(ufunc_T *ufunc, int set_return_type)
{
- dfunc_T *dfunc;
char_u *line = NULL;
char_u *p;
exarg_T ea;
--- 5029,5040 ----
* Adds the function to "def_functions".
* When "set_return_type" is set then set ufunc->uf_ret_type to the type of the
* return statement (used for lambda).
+ * This can be used recursively through compile_lambda(), which may reallocate
+ * "def_functions".
*/
void
compile_def_function(ufunc_T *ufunc, int set_return_type)
{
char_u *line = NULL;
char_u *p;
exarg_T ea;
***************
*** 5046,5070 ****
sctx_T save_current_sctx = current_sctx;
int emsg_before = called_emsg;

- if (ufunc->uf_dfunc_idx >= 0)
{
! // Redefining a function that was compiled before.
! dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;

! // Free old instructions.
! delete_def_function_contents(dfunc);
! }
! else
! {
! // Add the function to "def_functions".
! if (ga_grow(&def_functions, 1) == FAIL)
! return;
! dfunc = ((dfunc_T *)def_functions.ga_data) + def_functions.ga_len;
! vim_memset(dfunc, 0, sizeof(dfunc_T));
! dfunc->df_idx = def_functions.ga_len;
! ufunc->uf_dfunc_idx = dfunc->df_idx;
! dfunc->df_ufunc = ufunc;
! ++def_functions.ga_len;
}

vim_memset(&cctx, 0, sizeof(cctx));
--- 5047,5075 ----
sctx_T save_current_sctx = current_sctx;
int emsg_before = called_emsg;

{
! dfunc_T *dfunc; // may be invalidated by compile_lambda()

! if (ufunc->uf_dfunc_idx >= 0)
! {
! // Redefining a function that was compiled before.
! dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
!
! // Free old instructions.
! delete_def_function_contents(dfunc);
! }
! else
! {
! // Add the function to "def_functions".
! if (ga_grow(&def_functions, 1) == FAIL)
! return;
! dfunc = ((dfunc_T *)def_functions.ga_data) + def_functions.ga_len;
! vim_memset(dfunc, 0, sizeof(dfunc_T));
! dfunc->df_idx = def_functions.ga_len;
! ufunc->uf_dfunc_idx = dfunc->df_idx;
! dfunc->df_ufunc = ufunc;
! ++def_functions.ga_len;
! }
}

vim_memset(&cctx, 0, sizeof(cctx));
***************
*** 5414,5423 ****
generate_instr(&cctx, ISN_RETURN);
}

! dfunc->df_deleted = FALSE;
! dfunc->df_instr = instr->ga_data;
! dfunc->df_instr_count = instr->ga_len;
! dfunc->df_varcount = cctx.ctx_max_local;

ret = OK;

--- 5419,5432 ----
generate_instr(&cctx, ISN_RETURN);
}

! {
! dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
! + ufunc->uf_dfunc_idx;
! dfunc->df_deleted = FALSE;
! dfunc->df_instr = instr->ga_data;
! dfunc->df_instr_count = instr->ga_len;
! dfunc->df_varcount = cctx.ctx_max_local;
! }

ret = OK;

***************
*** 5425,5430 ****
--- 5434,5441 ----
if (ret == FAIL)
{
int idx;
+ dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
+ + ufunc->uf_dfunc_idx;

for (idx = 0; idx < instr->ga_len; ++idx)
delete_instr(((isn_T *)instr->ga_data) + idx);
*** ../vim-8.2.0487/src/vim9.h 2020-03-31 23:13:05.758568664 +0200
--- src/vim9.h 2020-03-31 23:29:10.395041154 +0200
***************
*** 257,263 ****
// Functions defined with :def are stored in this growarray.
// They are never removed, so that they can be found by index.
// Deleted functions have the df_deleted flag set.
! garray_T def_functions = {0, 0, sizeof(dfunc_T), 200, NULL};
#else
extern garray_T def_functions;
#endif
--- 257,263 ----
// Functions defined with :def are stored in this growarray.
// They are never removed, so that they can be found by index.
// Deleted functions have the df_deleted flag set.
! garray_T def_functions = {0, 0, sizeof(dfunc_T), 50, NULL};
#else
extern garray_T def_functions;
#endif
*** ../vim-8.2.0487/src/version.c 2020-03-31 23:13:05.762568650 +0200
--- src/version.c 2020-03-31 23:30:53.690659160 +0200
***************
*** 740,741 ****
--- 740,743 ----
{ /* Add new patch number below this line */
+ /**/
+ 488,
/**/

--
If "R" is Reverse, how come "D" is FORWARD?

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages