[perl #41583] [PATCH] Tail calls from within vtable functions broken

Will Coleda via RT parrotbug-followup at parrotcode.org
Fri Oct 30 01:07:20 UTC 2009


On Thu Feb 22 09:29:20 2007, bgeron at gmail.com wrote:
> ---
> osname= linux
> osvers= 2.6.18.3
> arch=   i486-linux-gnu-thread-multi
> cc=     cc
> ---
> Flags:
>     category=core
>     severity=medium
>     ack=no
> ---
> Tail calls from within v-table methods are broken, the tail-called sub
> (or method) will not return correct values.
> 
> When method A tailcalls sub B, B's set_returns stores its opcode
> number (and with it, which registers should be returned), but the
> low-level vtable code gets the registers from A's context.
> (Runops_args stores a pointer to A's context just before it is called,
> wrongly assuming A has the final set_returns. Runops_args returns the
> context to a function that then does return value passing on it.)
> 
> Maybe the solution is to store the current context in a new field in
> the interp structure; I don't know, I'm rather bad at C.
> 
> Example:
> This should print 2, but it prints 13.
> 
> -----
> 
> .sub main :main
>     $P1 = newclass "Foo"
>     $P2 = new "Foo"
> 
>     ## Should return 2, but doesn't.
>     $I1 = elements $P2
>     $S1 = $I1
>     say $S1
> .end
> 
> .namespace ["Foo"]
> 
> .sub elements :method :vtable
>     I0 = 13
>     I1 = 2
>     .return identity(I1)
> .end
> 
> .sub identity
>     .param int arg
>     ## arg is I0, taken from the elements context (which is set
>     ## to 13). If we put "I0 = 14" here and don't optimize, we
>     ## return 2. (elements's context's I1)
>     .return (arg)
> .end
> 
> -----
> 
> This happens in svn head.
> 
> Regards,
> Bram Geron.
> 
> ---
> Summary of my parrot 0.4.8 (r16890) configuration:
>   configdate='Sat Feb 10 16:50:38 2007'
>   Platform:
>     osname=linux, archname=i486-linux-gnu-thread-multi
>     jitcapable=1, jitarchname=i386-linux,
>     jitosname=LINUX, jitcpuarch=i386
>     execcapable=1
>     perl=/usr/bin/perl
>   Compiler:
>     cc='cc', ccflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS
> -DDEBIAN  -pipe -I/usr/local/include -D_LARGEFILE_SOURCE
> -D_FILE_OFFSET_BITS=64 -I /usr/include',
>   Linker and Libraries:
>     ld='cc', ldflags=' -L/usr/local/lib',
>     cc_ldflags='',
>     libs='-ldl -lm -lpthread -lcrypt -lrt -lgmp -lreadline -lncurses'
>   Dynamic Linking:
>     share_ext='.so', ld_share_flags='-shared -L/usr/local/lib -fPIC',
>     load_ext='.so', ld_load_flags='-shared -L/usr/local/lib -fPIC'
>   Types:
>     iv=long, intvalsize=4, intsize=4, opcode_t=long, opcode_t_size=4,
>     ptrsize=4, ptr_alignment=1 byteorder=1234,
>     nv=double, numvalsize=8, doublesize=8
> 
> ---
> Environment:
>     HOME    LANG    LANGUAGE    LD_LIBRARY_PATH    LOGDIR    PATH   SHELL

With this code updated to a recent parrot, I can't duplicate this error anymore. I added a test 
in r42168, resolving ticket.

Thanks for the report!

-- 
Will "Coke" Coleda


More information about the parrot-dev mailing list