[ Note to p6c: This thread is about the proposed and only partially
  specified ".begin_eh"/".end_eh" directives that would specify exception
  handling as a static property of a range of opcodes in a subroutine,
  rather than the current dynamic approach of C<push_handler> etc.  I'm
  including p6c in case Lisp isn't the only language with potential issues
  here.  See also docs/pdds/clip/pdd23_exceptions.pod.]

On Mon, Jun 12, 2006 at 08:24:55PM -0400, Bob Rogers wrote:
>    From: Chip Salzenberg <[EMAIL PROTECTED]>
>    Date: Mon, 12 Jun 2006 06:54:24 -0700
> 
>    On Sun, Jun 11, 2006 at 11:52:14AM -0400, Bob Rogers wrote:
>    >    I notice the following paragraph, vintage late May, in
>    > pdd23_exceptions.pod:
>    > 
>    >  A C<.begin_eh> directive marks the beginning of a span of
>    >  opcodes which the programmer expects to throw an exception.  If
>    >  an exception occurs in the execution of the given opcode span,
>    >  Parrot will transfer control to I<LABEL>.
>    > 
>    > I assume this means that you intend to replace the current methodology
>    > of searching for an Exception_Handler object on the control stack when
>    > an error is thrown with a search through sub metadata.
> 
>    That's the plan.  The upside is that on the non-exceptional case, nothing 
> at
>    all needs to be done.  I just couldn't see the value in making the VM
>    allocate and free memory blocks on the control stack, over and over, when
>    no exceptions are occurring.
> 
> Yes, that's nice.  The downside, though, is that you have to do more
> work when it's time to throw, but I agree that this is likely to happen
> less often, at least for most error-handling situations.  (There's also
> a load-time cost, I imagine, but it can't be very large.)

I think we're seeing the same thing.

>    Unfortunately, this is a step backwards from my perspective, as it is
> already problematic to use Parrot as it exists now to implement ANSI
> Common Lisp error signalling semantics, and any approach based on
> metadata (being static) will make it more so.  However, I can still
> implement ANSI semantics using dynamic binding, C<pushaction>, and
> continuations that respect both (which they currently do not), though
> the result won't interoperate with error handling in the rest of Parrot.

{{ Please read the rest of the message before answering this paragraph.
   It may be moot. }}
OK, maybe I don't understand CL or your implmentation strategy, but: Aren't
you planning on -compiling- the CL to PIR?  When the form that does
exception handling is compiled to PIR, why can't you translate it to (among
other things) a .eh block?

Separately, what do you mean by "respecting" pushaction in the continuation
implementation?

>    > How do you envision this interacting with C<pushaction>, e.g.?  
> Currently,
>    > it is straightforward for find_exception_handler to DTRT WRT other 
> control
>    > stack entries.  Would the metadata also contain information about
>    > C<pushaction> and such?
> 
>    I hadn't decided either way about C<pushaction>.  Seems to me that either
>    way will work though.  Could you spell out a little more of what you see
>    as being bad (or harder)?
> 
> Actions are dynamic state that must nest properly with respect to error
> handlers.  So you have to know how many actions to pop & invoke when
> unwinding the stack before invoking a given error handler.  So it seems
> to me that you would also have to lexicalize actions in order to give
> find_exception_handler a clue.

Ah, well, that's fine then.  In fact we are going to lexicalize actions, in
the form of an optional I<FINALLY_LABEL> on .begin_eh:

   .begin_eh [ I<CATCH_LABEL> ] [ , I<FINALLY_LABEL> ]

A 'finally' label gets called on the way out of an exception block whether
or not the departure was the result of an exception.  To handle the non-
exception case, I imagine PIR will just emit "call my_finally" when it
encounters the ".end_eh" directive.

On the other hand, since static exception blocks haven't been implemented
yet, it's not too late to ditch the whole change as a bad job, if that's
the right decision for Lisp and other languages.  Lispers are people too.  :-)

> But you can't lexicalize actions completely without removing the ability
> to invoke a closure as a cleanup action!

Not at all.  It just makes you emit the call instruction yourself.  For
example:

.sub example
    .local pmc my_cleanup
    my_cleanup = <insert expression here that would have been pushaction'd>
    .begin_eh ,my_finally

    # body of subroutine here

    .end_eh
    .return ()

  my_finally:
    call my_cleanup
    ret
.end

The implications of throwing an exception from a 'finally' label need to be
specified clearly, of course.  But once that's done, making sure that
exception handling code calls all the right 'finally' labels in the right
order is a Simple Matter Of Programming.

> Dynamic bindings in particular require runtime dynamic state (namely, the
> saved values), so there still needs to be something on the control stack
> to capture it.

I think the 'finally' feature is pretty much what you need for this.
-- 
Chip Salzenberg <[EMAIL PROTECTED]>

Reply via email to