At 9:59 AM +0100 11/19/04, Leopold Toetsch wrote:
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".

Hrm. The name's not right, since there's no current continuation involved. (At least we shouldn't be passing in the current continuation on return -- instead the return continuation that was in effect when the code we're returning to was active should be the return 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

Nope. The only thing that push_eh (or whatever we name it) needs is the address of the code to jump to if an exception's thrown. The exception pushing code should take care of building whatever structure's needed to call into it. (Though other than making a return continuation and changing the address to the address used in the push_eh instruction I'm not sure we need to do anything else)



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.

Hrm. Well, the traceback object could just be the interpreter structure at the time of the the exception. That'd be cheap enough to pass in. I'm fine with adding that as a second PMC parameter.


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

Yeah. That's partly the reason for the non-PMC parameters. The other reason for them is that we may be throwing an exception at a point where it's not possible to actually create a PMC. We can always stuff in constant strings and integers, though.


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.

Python code can always pass in an exception object in the PMC parameter slot -- that's fine. Perl 5 throws plain strings or arbitrary PMCs as exceptional things, and the internals may throw exceptions with non-pmc parameters if for some reason a PMC couldn't be created.


> 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.

Yep.

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.

Possibly, but C code may well be throwing exceptions too, but still want to attach a language to it.


BTW - how do we set C<language>?

In general, I'd figured it was an attribute placed at compile-time on a sub PMC.


> 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?

Yep.

> 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.

I think that the python compiler will be able to manage things sufficiently to make this work out OK without us doing anything else. (Well, other than passing in the interpreter struct for traceback)


> .... 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?

The same as non-recursive calls -- we clear out the stack and use the return continuation we were passed in as the return continuation for the sub we're calling. That it's the current sub's just a detail. :)


 > 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?

Yeah. We provide the information, but past that it's other people's problem.

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.

Yeah, that was the reason for the non-pmc parameters. That way we can pass on at least a minimal amount of information and possibly do something with it.
--
Dan


--------------------------------------it's like this-------------------
Dan Sugalski                          even samurai
[EMAIL PROTECTED]                         have teddy bears and even
                                      teddy bears get drunk

Reply via email to