Hi Bram,
2016/8/1 Mon 0:29:26 UTC+9 Bram Moolenaar wrote:
> Ken Takata wrote:
>
> > 2016/7/31 Sun 4:17:46 UTC+9 Bram Moolenaar wrote:
> > > Ken Takata wrote:
> > >
> > > > 2016/7/30 Sat 5:38:42 UTC+9 Bram Moolenaar wrote:
> > > > > Patch 7.4.2120
> > > > > Problem: User defined functions can't be a closure.
> > > > > Solution: Add the "closure" argument. Allow using :unlet on a bound
> > > > > variable. (Yasuhiro Matsumoto, Ken Takata)
> > > > > Files: runtime/doc/eval.txt, src/testdir/test_lambda.vim,
> > > > > src/userfunc.c,
> > > > > src/eval.c src/proto/userfunc.pro
> > > >
> > > > I had a report that this patch doesn't work as expected:
> > > >
> > > > function! Foo()
> > > > let x = 0
> > > > function! Bar() closure
> > > > let x += 1
> > > > return x
> > > > endfunction
> > > > return function('Bar')
> > > > endfunction
> > > >
> > > > let Count = Foo()
> > > > echo Count() " => 1
> > > > echo Count() " => 2
> > > > echo Count() " => 3
> > > >
> > > > let Count2 = Foo()
> > > > echo Count() " => 1 (Should be 4)
> >
> > I found another problem. The following causes an error:
> >
> > function! Foo()
> > let x = 0
> > function! Bar() closure
> > let x += 1
> > return x
> > endfunction
> > return function('Bar')
> > endfunction
> >
> > let Count = Foo()
> > call test_garbagecollect_now()
> > echo Count() " Cannot access x
> >
> > Reference counting was wrong. The following patch fixes the problem:
> > https://bitbucket.org/k_takata/vim-ktakata-mq/src/7685fd93bf6a1ea0079d7c7da537dc062a67bc9f/fix-closure-refcount.patch?at=default
>
> I had trouble reproducing this problem. Looks like Foo() needs to be
> called twice. But then your patch doesn't fix it...
Thank you for fixing this. BTW, refcount seems wrong when using dict function
with closure. E.g.:
let d = {}
function! d.Bar() closure
...
The refcount becomes 2 instead of 1. I think this should fix the problem:
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -2326,7 +2326,8 @@ ex_function(exarg_T *eap)
fp->uf_lines = newlines;
if ((flags & FC_CLOSURE) != 0)
{
- ++fp->uf_refcount;
+ if (fudi.fd_dict == NULL)
+ ++fp->uf_refcount;
if (register_closure(fp) == FAIL)
goto erret;
}
> While trying to write a test I also noticed memory access errors when
> using :delfunction.
I will look at this.
Maybe uf_calls should be incremented in register_closure()?
Regards,
Ken Takata
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.