Dan Sugalski <[EMAIL PROTECTED]> wrote:

> The 'invoke the current return continuation' op apparently got lost
> in the blowup. That needs to go in.

Its in and named C<returncc> since yesterday "return with current
continuation".

> I'd like pushing exception handlers to remain simple -- the current
> system is almost OK. What I'd like it to change to is:

>      push_eh label

Shouldn't that be:

   push_eh handler, label

> This is more restrictive than passing in a generic invokable object
> as the exception handler, but given that all the exception handling
> schemes in all our languages of interest do lexically scoped
> exceptions I think we're better off with the restriction.

Good.

> ...Allowing
> random invokables as exception handlers feels like it's likely to
> have some subtle security or consistency problems associated with it,
> though I can't give a good example at the moment.

Yep, it smells like that.

> Throwing exceptions should be:

>     throw language, subsystem, severity, code, object

Allowing just one additional object doesn't properly support Python,
which has two optional expressions for the C<raise> statement and Python
attaches a traceback object to the exception.

OTOH (again from Python's view) raising just a C<StopIteration> or a
C<KeyErrror> ought to be fast as its used heavily.

And Python has an hierarchy of exception *objects*, with inheritance. So
I think that for maximum flexibility we should just have exception
objects, with some mandatory attributes (the exception class might
already provide enough information) and additional information the HLL
might stuff in.

How will Perl6 do it?

> And I'm definitely unsure what types language and subsystem should
> be.

C<language> - I presume - is defining the HLL that emitted the code,
where the exception occured. I think this information has to be in the
interpreter context as we should eventually be able to execute mixed
languages code. So C<language> should probably end up in the traceback
object, passed along with the exception.

BTW - how do we set C<language>?

>      pushmark 12
>      .
>      . random code here
>      .
>      popmark 12

> where everything put on the control stack after the "pushmark
> identifier" is popped off by the corresponding "popmark identifier".
> Marks can nest, and it's the code's responsibility to not reuse
> labels. popmark will *not* cross routine boundaries, so the control
> stack will never be cleared out past the point where it was when the
> sub/method/whatever was entered.

This is intended for cleanup of a bunch of pushed handlers inside one
routine?

> Now, with this, there's one other thing we need to talk about, and
> that's scope exit actions. We promised this a number of years back
> (and now I feel very old) and need to deliver on them. A scope exit
> action is put in place on the control stack with:

>     pushaction Psub

> and when the action is popped off the stack because of a popmark,
> walking the stack back looking for exception handlers, a popaction
> op, or returning from a subroutine the sub is invoked with a *single*
> integer parameter that indicates whether the action is being called
> as part of a normal or exception-based stack unwind. (a status of 0
> means the action was caused by normal code, a 1 because the action
> was popped off as parrot walked backwards looking for an exception
> handler)

> If folks want to argue that the action should get the exception
> information if called as part of an exception unwind I'm OK with
> that. Go for it, I'm unsure of that one.

Python has "try ... finally". It preserves (possibly) existing
exceptions around the finally block. But if in the "finally" clause
another exception occurs (or a "return" of "break" is executed), the
saved exception is lost.
This could mean that the exception object is needed, e.g. to nullify it
in that case.

> .... So, parrot will automatically clear out
> the control stack and invoke any actions on it if:

>     *) the current return continuation is invoked with the return op
>     *) a tail call is made with either the tailcall or tailmethodcall ops

How does the latter look like for recursive tail calls?

> So. Simple, right? Make sense to everyone?

Yep. A lot.

A final question: classifying the exception in the handler is still up
to the HLL, I presume?

And one remark WRT internally thrown exceptions: in case of a
MemoryError exception (Python speak), we are not allowed to use any more
resources, so we probably need to preconstruct a few needed items for
such a case.

leo

Reply via email to