mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.0697: Vim9: memory leak when using nested function
Problem: Vim9: memory leak when using nested function. Solution: Unreference function when deleting instructions. Adjust reference count for local variables.
This commit is contained in:
@@ -746,6 +746,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
697,
|
||||||
/**/
|
/**/
|
||||||
696,
|
696,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -6629,6 +6629,14 @@ delete_instr(isn_T *isn)
|
|||||||
vim_free(isn->isn_arg.ufunc.cuf_name);
|
vim_free(isn->isn_arg.ufunc.cuf_name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ISN_FUNCREF:
|
||||||
|
{
|
||||||
|
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||||
|
+ isn->isn_arg.funcref.fr_func;
|
||||||
|
func_ptr_unref(dfunc->df_ufunc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ISN_2BOOL:
|
case ISN_2BOOL:
|
||||||
case ISN_2STRING:
|
case ISN_2STRING:
|
||||||
case ISN_ADDBLOB:
|
case ISN_ADDBLOB:
|
||||||
@@ -6657,7 +6665,6 @@ delete_instr(isn_T *isn)
|
|||||||
case ISN_EXECCONCAT:
|
case ISN_EXECCONCAT:
|
||||||
case ISN_EXECUTE:
|
case ISN_EXECUTE:
|
||||||
case ISN_FOR:
|
case ISN_FOR:
|
||||||
case ISN_FUNCREF:
|
|
||||||
case ISN_INDEX:
|
case ISN_INDEX:
|
||||||
case ISN_JUMP:
|
case ISN_JUMP:
|
||||||
case ISN_LOAD:
|
case ISN_LOAD:
|
||||||
|
@@ -264,10 +264,27 @@ handle_closure_in_use(ectx_T *ectx, int free_arguments)
|
|||||||
{
|
{
|
||||||
tv = STACK_TV(ectx->ec_frame_idx + STACK_FRAME_SIZE
|
tv = STACK_TV(ectx->ec_frame_idx + STACK_FRAME_SIZE
|
||||||
+ dfunc->df_varcount + idx);
|
+ dfunc->df_varcount + idx);
|
||||||
if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial->pt_refcount > 1)
|
if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL
|
||||||
|
&& tv->vval.v_partial->pt_refcount > 1)
|
||||||
{
|
{
|
||||||
closure_in_use = TRUE;
|
int refcount = tv->vval.v_partial->pt_refcount;
|
||||||
break;
|
int i;
|
||||||
|
|
||||||
|
// A Reference in a local variables doesn't count, its get
|
||||||
|
// unreferenced on return.
|
||||||
|
for (i = 0; i < dfunc->df_varcount; ++i)
|
||||||
|
{
|
||||||
|
typval_T *stv = STACK_TV(ectx->ec_frame_idx
|
||||||
|
+ STACK_FRAME_SIZE + i);
|
||||||
|
if (stv->v_type == VAR_PARTIAL
|
||||||
|
&& tv->vval.v_partial == stv->vval.v_partial)
|
||||||
|
--refcount;
|
||||||
|
}
|
||||||
|
if (refcount > 1)
|
||||||
|
{
|
||||||
|
closure_in_use = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user