[ 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]>