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