Mercurial > vim
comparison src/vim9execute.c @ 20297:5f0611bc6377 v8.2.0704
patch 8.2.0704: Vim9: memory leak in disassemble test
Commit: https://github.com/vim/vim/commit/f821ddaa0c27230012a6bffbec6fb0ab2f101171
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed May 6 22:18:17 2020 +0200
patch 8.2.0704: Vim9: memory leak in disassemble test
Problem: Vim9: memory leak in disassemble test.
Solution: Decrement refcount when creating funccal.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 06 May 2020 22:30:04 +0200 |
parents | bc2c9ea94ec1 |
children | e1a8d2040bd7 |
comparison
equal
deleted
inserted
replaced
20296:f76a55f87992 | 20297:5f0611bc6377 |
---|---|
268 && tv->vval.v_partial->pt_refcount > 1) | 268 && tv->vval.v_partial->pt_refcount > 1) |
269 { | 269 { |
270 int refcount = tv->vval.v_partial->pt_refcount; | 270 int refcount = tv->vval.v_partial->pt_refcount; |
271 int i; | 271 int i; |
272 | 272 |
273 // A Reference in a local variables doesn't count, its get | 273 // A Reference in a local variables doesn't count, it gets |
274 // unreferenced on return. | 274 // unreferenced on return. |
275 for (i = 0; i < dfunc->df_varcount; ++i) | 275 for (i = 0; i < dfunc->df_varcount; ++i) |
276 { | 276 { |
277 typval_T *stv = STACK_TV(ectx->ec_frame_idx | 277 typval_T *stv = STACK_TV(ectx->ec_frame_idx |
278 + STACK_FRAME_SIZE + i); | 278 + STACK_FRAME_SIZE + i); |
321 } | 321 } |
322 // Move the local variables. | 322 // Move the local variables. |
323 for (idx = 0; idx < dfunc->df_varcount; ++idx) | 323 for (idx = 0; idx < dfunc->df_varcount; ++idx) |
324 { | 324 { |
325 tv = STACK_TV(ectx->ec_frame_idx + STACK_FRAME_SIZE + idx); | 325 tv = STACK_TV(ectx->ec_frame_idx + STACK_FRAME_SIZE + idx); |
326 | |
327 // Do not copy a partial created for a local function. | |
328 // TODO: this won't work if the closure actually uses it. But when | |
329 // keeping it it gets complicated: it will create a reference cycle | |
330 // inside the partial, thus needs special handling for garbage | |
331 // collection. | |
332 if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL) | |
333 { | |
334 int i; | |
335 typval_T *ctv; | |
336 | |
337 for (i = 0; i < dfunc->df_closure_count; ++i) | |
338 { | |
339 ctv = STACK_TV(ectx->ec_frame_idx + STACK_FRAME_SIZE | |
340 + dfunc->df_varcount + i); | |
341 if (tv->vval.v_partial == ctv->vval.v_partial) | |
342 break; | |
343 } | |
344 if (i < dfunc->df_closure_count) | |
345 { | |
346 (stack + argcount + STACK_FRAME_SIZE + idx)->v_type = | |
347 VAR_UNKNOWN; | |
348 continue; | |
349 } | |
350 } | |
351 | |
326 *(stack + argcount + STACK_FRAME_SIZE + idx) = *tv; | 352 *(stack + argcount + STACK_FRAME_SIZE + idx) = *tv; |
327 tv->v_type = VAR_UNKNOWN; | 353 tv->v_type = VAR_UNKNOWN; |
328 } | 354 } |
329 | 355 |
330 for (idx = 0; idx < dfunc->df_closure_count; ++idx) | 356 for (idx = 0; idx < dfunc->df_closure_count; ++idx) |