On Wed, Feb 22, 2006 at 09:52:34PM -0500, Bob Rogers wrote:
Content-Description: message body text
>    The good news is that the attached patch makes this work.  The bad
> news is that it also breaks PGE, albeit in a small way.  Six of the
> "<after>" tests (mostly, but not exclusively, involving "<!after>") in
> t/compilers/pge/p6rules/builtins.t seem to go into an infinite loop.  I
> have been unable to figure this out, so I'm hoping it will be easy for
> someone who understands PGE.  (Maybe there's something in PGE that
> assumes that returning from a sub restores the state of the user stack?)

Okay, looking at a debug trace further it appears that the user
stack is indeed not behaving the way PGE expects it to.  This
could be from a shortcoming in my understanding of how things
will work, so the detailed explanation of PGE's expectations
is below.

PGE does not expect that a sub will restore the state of the user
stack, but it does expect that *coroutines* get their own copy of
the user stack, and that calling/returning from a coroutine will 
not affect the current user stack.  This expectation comes from 
two sources-- first, it's claimed at the bottom of page 165 in 
"Perl 6 and Parrot Essentials", and the docs/pmc/subs.pmc file 
says that coroutines get a COW copy of the user stack.

As I said, I'll be the first to admit that my understanding of
how the user stack is supposed to work may be incorrect.  

Based on the trace I just looked at, it appears that a save opcode 
executed inside a coroutine -- the coroutine generated to handle
the <after c> subrule -- is indeed affecting the results of a
restore in the caller and causing an infinite loop.  In particular,
I'm seeing the following sequence...

    save I1                 I1=1
    ...
    (invoke coroutine)
    ...
    save I1                 I1=0
    ...
    (yield from coroutine back to caller)
    ...
    restore I1              
    inc I1                  I1=0       ( should be I1=1 ?)

So, with this patch applied, user stacks in coroutines don't
appear to be working the way I would expect them to.  

Any clarification from others would be very helpful here.

On somewhat related note, I'm probably going to eliminate PGE's 
use of the user stack altogether and replacing it with an Array 
object that is used as a stack via push/pop opcodes.  Leo has 
commented that this may be faster than the save/restore ops, and 
it will also make it much easier for PGE to implement <cut>,
<commit>, and other related ops, since it can instantly erase
parts of the backtracking state by clearing the array.  

However, I'd still like to be sure I understand how the user
stack works in coroutines, so any answers or guidance on this
would be greatly appreciated.

Hope this helps,

Pm

Reply via email to