From: "James Keenan via RT" <[EMAIL PROTECTED]>
   Date: Sun, 16 Mar 2008 10:46:15 -0700

   On Sun Mar 16 10:02:32 2008, rgrjr wrote:

   > I think it ought to happen, though I think Allison just wanted a ticket
   > for updating existing PDDs, and not for a whole new PDD.  I asked
   > Allison for a clarification on 11-Mar in Will's "[oops; continuation
   > 0xb6926320 of type 22 is trying to jump from runloop 15008 to runloop
   > 1]" thread, and had been waiting for that.
   > 
   >    But I do agree that it ought to be a separate ticket.  The underlying
   > issue is still with us, but has outgrown the original ticket.
   > 

   Okay.  I will now close this ticket.  For more granular tracking, I
   recommend that a separate RT be opened for each existing PDD which needs
   updating.

   Thank you very much.
   kid51

OK, I've finished the writeup for one or more new tickets; please advise
on whether this is on target, and how to file it.  My personal
recommendation is for a single design/documentation ticket, the
satisfaction of which will generate a number of implementation tickets.

   FWIW, the issue seems much less scary for having written it up.  It
probably also helps that I've let go of the notion that we can ever
remove all continuation barriers; it's a big job, and I still can't
think of a compelling use case for needing to do so.

                                        -- Bob

   In between instructions, all Parrot control and data state is
captured in Parrot runtime data structures.  During the execution of an
instruction, some state may be kept temporarily in the C calling stack.
If the C code happens to enter an inferior runloop, e.g. to run a vtable
method, and that code creates a continuation, this continuation has no
way to capture the extra C program state for the partially-executed
instruction.  If such a continuation were used to resume the inferior
runloop after returning to the main one [1], the resumed PIR would
execute normally, but when it returned, the latter half of the partial
instruction would be skipped.  This is a relatively obscure case, but
would likely result in a serious failure if the partial instruction was
expected to set registers.

   Coroutines are similarly affected, though it seems strange to want to
yield or resume a coroutine from within a vtable method.  On the other
hand, a coroutine can be thought of as just an application of
continuations, so users have a right to expect this to work.

   The continuation barrier issue is separable into a handful of
subproblems, and could be addressed in stages.  The topic of this issue,
therefore, is to research and document the desired long-term solution to
the overall problem, in such PDDs as are appropriate, before starting
down the garden path.

   As a guideline, here is an outline of the subproblems:

   1.  Currently, it is not even possible to jump from the current
inferior runloop to another currently-executing runloop.  (The
destination runloop in this case belongs to an outer dynamic scope, so
this is equivalent to transfer of control to a still-active outer frame
in a stack-based implementation.)  This "outward continuation" case is
commonly encountered in error handling and control structure
implementations.  The current implementation just runs the new PIR code
in the current runloop (after printing a warning), which is almost
certainly the wrong thing.  In order to fix it, it is only necessary to
record a separate longjmp address for each runloop, storing it in a
place where Continuation:invoke can use it (after testing that it is
still valid!).  The original runloop (plus any intervening runloops)
would need to be marked as invalid, as their portion of the C stack is
being unwound.  Languages without continuations or coroutines would need
nothing more, so fixing at least this much would help in most cases.

   2.  Attempts to re-enter a non-existent runloop could be made to work
transparently for operations which have limited side effects and return
the same result when re-run.  For example, most get_integer or
store_pmc_indexed_int implementations should fit that description (but
obviously not push_pmc).  To do this, the code that sets up the inferior
runloop can create a return continuation that *restarts* the interrupted
instruction.  If the return continuation is invoked when its runloop
still exists, then that runloop exits normally; otherwise, we stay in
the same runloop and return to the instruction that got us into that
mess in the first place.

   3.  Bugs will then be reported for instructions that cannot be
restarted this way.  It may be possible to fix at least some of them by
reordering vtable method calls so that the ones that are expected to
have nontrivial side effects are done last.  In any case, such bugs
should be relatively rare.

   4.  That leaves a hard-core residue of cases that cannot be fixed
without rewriting to eliminate the inferior runloop.  At a minimum, this
requires adding support for calling a C "continuation" when the PIR
returns, and rewriting the C in explicit continuation-passing style,
which is a major job.  This job could conceivably be made easier by
implementing a higher-level unification of C functions, PIR subs, and
instruction C code [2]; that's an even bigger job, but has other
benefits.

Notes:

[1]  Not currently possible, but assume that subproblem 1 has been
     addressed.

[2]  Such as Leo's Cfunc.pod proposal made in
     http://groups.google.com/group/perl.perl6.internals/msg/09b910b34f6d27f4;
     see
     
http://groups.google.com/group/perl.perl6.internals/browse_thread/thread/9693de802d3178f3/f298d47bf4df7948
     for the complete thread.

Reply via email to