Ken Takata wrote:

> 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()?

I have started looking into this and found several related problems.
Not resetting uf_scoped was the main thing, fixed in 7.4.2136.

I can't really make a patch that fixes part of the problem, because the
tests would break or memory leaks appear.

I also found several existing problems with function reference counts.
They went unnoticed because until now it only mattered for numbered
functions and lambdas.

I'll try to get my change in a working state, perhaps with some
remaining leaks to fix.

-- 
NEIL INNES PLAYED: THE FIRST SELF-DESTRUCTIVE MONK, ROBIN'S LEAST FAVORITE
                   MINSTREL, THE PAGE CRUSHED BY A RABBIT, THE OWNER OF A DUCK
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
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.

Raspunde prin e-mail lui