2016-07-22 14:09 GMT+03:00 Nikolay Aleksandrovich Pavlov <[email protected]>:
> 2016-07-20 21:23 GMT+03:00 Ken Takata <[email protected]>:
>> Hi,
>>
>> 2016/7/19 Tue 23:18:30 UTC+9 ZyX wrote:
>>> 2016-07-19 17:15 GMT+03:00 Nikolay Aleksandrovich Pavlov 
>>> <[email protected]>:
>>> > 2016-07-19 16:46 GMT+03:00 Ken Takata <[email protected]>:
>>> >> Hi,
>>> >>
>>> >> 2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
>>> >>> Hi,
>>> >>>
>>> >>> 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
>>> >>> > I additionally submit another test case.
>>> >>> >
>>> >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> 
>>> >>> > x(x)(y)})}))}
>>> >>> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>>> >>> > echo Y(Fact)(5)
>>> >>> >
>>> >>> > I expect this script prints 120 but I got E110: Missing ')' in 
>>> >>> > 7.4.2049 (and also with the experimental patch).
>>> >>> > Is there something wrong with the above code or is there some bug in 
>>> >>> > the parsing code in eval.c?
>>> >>> >
>>> >>> > Here are the counterparts in Python
>>> >>> > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda 
>>> >>> > y: x(x)(y)))
>>> >>> > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
>>> >>> > print Y(Fact)(5)
>>> >>> >
>>> >>> > and in JavaScript
>>> >>> > var Y = function(f){ return (function(x){ return f (function(y){ 
>>> >>> > return x(x)(y); }); }) (function(x){ return f (function(y){ return 
>>> >>> > x(x)(y); }); }); };
>>> >>> > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * 
>>> >>> > f(x - 1)); }; };
>>> >>> > console.log(Y(Fact)(5));
>>> >>> >
>>> >>> > reference: 
>>> >>> > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points,
>>> >>> >  
>>> >>> > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
>>> >>>
>>> >>> I have updated the patch for the latest code:
>>> >>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
>>> >>>
>>> >>> The SEGV on test_alot.vim seems fixed.
>>> >>>
>>> >>>
>>> >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> 
>>> >>> > x(x)(y)})}))}
>>> >>>
>>> >>> This still causes errors. Not sure why. Simpler example would be better.
>>> >>
>>> >> I have updated the patch:
>>> >> https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default
>>> >
>>> > What happens in case of
>>> >
>>> >     function Foo(arg)
>>> >         let d = {}
>>> >         let d.f = {-> d}
>>> >         return d.f
>>> >     endfunction
>>> >     let i = 0
>>> >     while i < 1000000 | call Foo() | endwhile
>>> >
>>> > ? Specifically I suspect memory leak here because lambdas now are
>>> > (implicit) containers, but you did not touch GC.
>>>
>>> Forgot `let i += 1`. Though it should still be interruptible by
>>> `<C-c>`, so `while 1` may even be better for a quick test: if
>>> everything is fine, memory usage will drop after `<C-c>`, but may
>>> increase before (AFAIR, by default full GC which checks for cycles is
>>> run at main loop when waiting for characters). If not, it will not.
>>
>> I have slightly updated the patch:
>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/162e04a587ce7e0b6b4ce46afe092cc4a5ab21e0/lambda-update.patch?fileviewer=file-view-default
>>
>> Some tests based on mattn's patch are added. (Not all yet.)
>>
>>
>>     function! Foo()
>>         let d = {}
>>         let d.f = {-> d}
>>         "let d.f = d
>>         return d.f
>>     endfunction
>>     let i = 0 | while i < 1000000 | call Foo() | let i+= 1 | endwhile
>>
>> While running this loop, memory usage increases, but it decreases after 
>> ending
>> the loop.  This is almost the same when the line "let d.f = d" is used 
>> instead
>> of the lambda expression.  However more tests might be needed to check that
>> there is no memory leakage.
>
> I was wrong regarding the consequences and why you should alter the
> GC: it is not memory leak because cycle is not GC’d. It is *crash*
> because Vim does not know that dictionary is referenced:
>
> ```VimL
> function F()
>     let d = {}
>     return {-> d}
> endfunction
> let L = F()
> call garbagecollect(1)
> call feedkeys(":echo L()\n", 'n')
> ```
>
> Save to `test.vim` and run as `vim -u NONE -i NONE -N -S test.vim`.
> When I use it in Vim with optimizations it crashes immediately:
>
> ```
> #0  0x00007f85da75b947 in kill () from /lib64/libc.so.6
> #1  0x0000000000598928 in mch_exit ()
> #2  0x00000000006c8f87 in getout ()
> #3  0x000000000059695e in deathtrap ()
> #4  <signal handler called>
> #5  0x00007f85da7aa5ba in strlen () from /lib64/libc.so.6
> #6  0x0000000000474173 in string_quote ()
> #7  0x00000000004582ac in dict2string ()
> #8  0x0000000000476aa5 in echo_string_core ()
> #9  0x000000000047d253 in ex_echo ()
> #10 0x00000000004c13cb in do_one_cmd ()
> #11 0x00000000004c51fa in do_cmdline ()
> #12 0x000000000055f545 in nv_colon ()
> #13 0x000000000056cb48 in normal_cmd ()
> #14 0x00000000006c8b65 in main_loop ()
> #15 0x000000000043c21c in main ()
> ```
>
> When not it crashes and hangs either immediately or when I press :, if
> I comment garbagecollect() call, but then type it myself and exit, I
> get
>
> ```
> #0  0x0000000000950a60 in ?? ()
> #1  0x0000000000594f3f in vim_regexec_both (rmp=0x942860,
> line=0x94ebd0 <incomplete sequence \354\224>, col=0, nl=0) at
> regexp.c:8122
> #2  0x0000000000594ed9 in vim_regexec_prog (prog=0x93eb20
> <clip_exclude_prog>, ignore_case=0, line=0x94ebd0 <incomplete sequence
> \354\224>, col=0) at regexp.c:8166
> #3  0x00000000005837b8 in x_connect_to_server () at os_unix.c:1674
> #4  0x000000000057d3e9 in get_x11_windis () at os_unix.c:1767
> #5  0x000000000057d26f in mch_settitle (title=0x983c20 "\340P\230",
> icon=0x0) at os_unix.c:2150
> #6  0x000000000057d971 in mch_restore_title (which=3) at os_unix.c:2228
> #7  0x000000000057eb2c in mch_exit (r=1) at os_unix.c:3279
> #8  0x00000000006a8544 in getout (exitval=1) at main.c:1493
> #9  0x000000000052c7cb in preserve_exit () at misc1.c:9494
> #10 0x00000000005847bd in deathtrap (sigarg=11) at os_unix.c:1164
> #11 <signal handler called>
> #12 0x00007fa18d008d5a in malloc_consolidate () from /lib64/libc.so.6
> #13 0x00007fa18d009a70 in _int_free () from /lib64/libc.so.6
> #14 0x00000000005312ee in vim_free (x=0x968660) at misc2.c:1698
> #15 0x00000000005d4c73 in free_screenlines () at screen.c:8833
> #16 0x000000000053126f in free_all_mem () at misc2.c:1231
> #17 0x000000000057eba6 in mch_exit (r=0) at os_unix.c:3330
> #18 0x00000000006a8544 in getout (exitval=0) at main.c:1493
> #19 0x00000000004b76c1 in ex_quit_all (eap=0x7ffda0419aa8) at ex_docmd.c:7249
> #20 0x00000000004a8b47 in do_one_cmd (cmdlinep=0x7ffda041a208,
> sourcing=0, cstack=0x7ffda0419d50, fgetline=0x4c83e0 <getexline>,
> cookie=0x0) at ex_docmd.c:2925
> #21 0x00000000004a4a70 in do_cmdline (cmdline=0x0, fgetline=0x4c83e0
> <getexline>, cookie=0x0, flags=0) at ex_docmd.c:1110
> #22 0x000000000054e548 in nv_colon (cap=0x7ffda041a348) at normal.c:5323
> #23 0x0000000000545222 in normal_cmd (oap=0x7ffda041a3e8, toplevel=1)
> at normal.c:1149
> #24 0x00000000006a8ed4 in main_loop (cmdwin=0, noexmode=0) at main.c:1308
> #25 0x00000000006a5509 in main (argc=8, argv=0x7ffda041a738) at main.c:874
> ```
>
> When hanging bt is
>
> ```
> #0  0x00007f5203cd092b in __lll_lock_wait_private () from /lib64/libc.so.6
> #1  0x00007f5203c54766 in malloc () from /lib64/libc.so.6
> #2  0x0000000000530b5e in lalloc (size=14560, message=1) at misc2.c:920
> #3  0x00000000005bd796 in nfa_regmatch (prog=0x950a70, start=0x950c50,
> submatch=0x942568, m=0x942378) at ./regexp_nfa.c:5547
> #4  0x00000000005bd1d6 in nfa_regtry (prog=0x950a70, col=0, tm=0x0) at
> ./regexp_nfa.c:6967
> #5  0x00000000005bcce0 in nfa_regexec_both (line=0x94ebd0
> "konsole-256color", startcol=0, tm=0x0) at ./regexp_nfa.c:7159
> #6  0x00000000005a4fab in nfa_regexec_nl (rmp=0x942860, line=0x94ebd0
> "konsole-256color", col=0, line_lbr=0) at ./regexp_nfa.c:7318
> #7  0x0000000000594f3f in vim_regexec_both (rmp=0x942860,
> line=0x94ebd0 "konsole-256color", col=0, nl=0) at regexp.c:8122
> #8  0x0000000000594ed9 in vim_regexec_prog (prog=0x93eb20
> <clip_exclude_prog>, ignore_case=0, line=0x94ebd0 "konsole-256color",
> col=0) at regexp.c:8166
> #9  0x00000000005837b8 in x_connect_to_server () at os_unix.c:1674
> #10 0x000000000057d3e9 in get_x11_windis () at os_unix.c:1767
> #11 0x000000000057d26f in mch_settitle (title=0x983c20 "[Нет имени] -
> VIM", icon=0x0) at os_unix.c:2150
> #12 0x000000000057d971 in mch_restore_title (which=3) at os_unix.c:2228
> #13 0x000000000057eb2c in mch_exit (r=1) at os_unix.c:3279
> #14 0x00000000006a8544 in getout (exitval=1) at main.c:1493
> #15 0x000000000052c7cb in preserve_exit () at misc1.c:9494
> #16 0x00000000005847bd in deathtrap (sigarg=11) at os_unix.c:1164
> #17 <signal handler called>
> #18 0x00007f5203c53184 in _int_malloc () from /lib64/libc.so.6
> #19 0x00007f5203c54778 in malloc () from /lib64/libc.so.6
> #20 0x0000000000530b5e in lalloc (size=29, message=1) at misc2.c:920
> #21 0x0000000000530af8 in alloc (size=29) at misc2.c:818
> #22 0x0000000000642c53 in call_user_func (fp=0x9b02b0, argcount=0,
> argvars=0x7ffd62dee650, rettv=0x7ffd62deee60, firstline=1, lastline=1,
> selfdict=0x0) at userfunc.c:897
> #23 0x0000000000641ac3 in call_func (funcname=0x9b03f0 "<lambda>1",
> len=9, rettv=0x7ffd62deee60, argcount_in=0, argvars_in=0x7ffd62dee650,
> firstline=1, lastline=1, doesrange=0x7ffd62dee8f4, evaluate=1,
> partial=0x0, selfdict_in=0x0)
>     at userfunc.c:1347
> #24 0x00000000006414da in get_func_tv (name=0x9b03f0 "<lambda>1",
> len=9, rettv=0x7ffd62deee60, arg=0x7ffd62deee70, firstline=1,
> lastline=1, doesrange=0x7ffd62dee8f4, evaluate=1, partial=0x0,
> selfdict=0x0) at userfunc.c:514
> #25 0x0000000000471f66 in eval7 (arg=0x7ffd62deee70,
> rettv=0x7ffd62deee60, evaluate=1, want_string=0) at eval.c:4344
> #26 0x00000000004715bf in eval6 (arg=0x7ffd62deee70,
> rettv=0x7ffd62deee60, evaluate=1, want_string=0) at eval.c:3978
> #27 0x0000000000471185 in eval5 (arg=0x7ffd62deee70,
> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3794
> #28 0x00000000004704db in eval4 (arg=0x7ffd62deee70,
> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3493
> #29 0x00000000004702ea in eval3 (arg=0x7ffd62deee70,
> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3410
> #30 0x000000000046608a in eval2 (arg=0x7ffd62deee70,
> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3342
> #31 0x0000000000461b13 in eval1 (arg=0x7ffd62deee70,
> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3270
> #32 0x000000000046aec6 in ex_echo (eap=0x7ffd62def0e8) at eval.c:8166
> #33 0x00000000004a8b47 in do_one_cmd (cmdlinep=0x7ffd62def848,
> sourcing=0, cstack=0x7ffd62def390, fgetline=0x4c83e0 <getexline>,
> cookie=0x0) at ex_docmd.c:2925
> #34 0x00000000004a4a70 in do_cmdline (cmdline=0x0, fgetline=0x4c83e0
> <getexline>, cookie=0x0, flags=0) at ex_docmd.c:1110
> #35 0x000000000054e548 in nv_colon (cap=0x7ffd62def988) at normal.c:5323
> #36 0x0000000000545222 in normal_cmd (oap=0x7ffd62defa28, toplevel=1)
> at normal.c:1149
> #37 0x00000000006a8ed4 in main_loop (cmdwin=0, noexmode=0) at main.c:1308
> #38 0x00000000006a5509 in main (argc=8, argv=0x7ffd62defd78) at main.c:874
> ```

Last two backtraces are from 4c2524dd2403 plus your patch.

>
>>
>>
>>> > Also you should not omit using dict_alloc(). `copy_vars()` looks like
>>> > something that should be in dict.c. Also it looks like something that
>>> > is already implemented: looks much like extend(), so you probably just
>>> > need to employ `dict_extend()`. Probably modifying it, but I doubt
>>
>> I didn't notice the function dict_extend().
>>
>>> > that `copyitem = FALSE` is valid, wanting to see whether your example
>>> > works with `let Bar = Foo("test: using allocated string")`.
>>
>> l: and a: dictionaries are handled differently in the function
>> call_user_func().
>>
>>
>>> > And, I guess, Bram will reject this because you copy the whole l: and
>>> > a: dictionaries.
>>
>> Not all l: and d: dictionaries are copied. Only used variables are copied,
>> but they are copied twice.
>>
>> 1. When parsing a lambda, check all used l: and a: variables and copy them to
>>    dictionaries in ufunc_T structure.
>> 2. When executing the lambda, the all l: and a: variables in ufunc_T are
>>    copied to l: and a: dictionaries in funccall_T structure.
>>
>> Mattn's implementation was storing only the references to l: and a: (but even
>> they are not used). Not sure which is better.
>>
>> 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.

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