Okay, here's a quick sketch of how exceptions are going to look. First, we're going to treat them as essentially a sort of upwards-only continuation. (Which they really are, so that's fine)
Exceptions are semi-fatal--they are *not* resumable. Too much trouble. Maybe we'll lift that restriction later, though there are issues with it. (Resuming low-level exceptions are a major pain, though it's easier at the parrot level) At the interpreter level, we're throwing exceptions, *all* exceptions, with the system-local exception mechanism. This will be setjmp and longjmp for most everwhere, but if a system's got something better we'll use it. Yeah, this means a certain amount of Macro Hell. I don't much like it, but this is one of the spots where we need it. Exceptions have four parts: Language Severity Class ID Language is the language throwing the exception. (Ruby, Scheme, Perl, Python, Brainf*ck, unlamda, whatever) Severity ranges from informational to "Help the world is ending!" There'll be fields in the interpreter to note at which level exceptions are ignored, and at which level they just throw a message to stderr. Class is stuff like IO, Math, or Internal, which gives a classification of sorts to the exception. ID gives an identifier to the exception. There'll be a name to ID mapping table somewhere. When we set an exception handler, we take a continuation. This means we remember the state of all the stacks (*and* we save off the current register state). This involves walking the stack frames upwards and marking them all COW, but we'll get to that in more detail with continuations. (That'll be another mail message) That exception handler gets pushed onto the control stack. When we get an exception, we unwind the control stack until we get to a handler that can handle the exception. If we find one we invoke the continuation that is responsible for dealing with the exception and let it go from there. The exception handler may, if it chooses, rethrow the exception. Internal/doomed exceptions are somewhat different. We do *not* walk anything. There may be a single internal/doomed exception handler, and all it may do is a bit of last-gasp processing. When it exits the interpreter is destroyed. When throwing an exception, code may also throw an object with it. If so, the object is passed in as a parameter to the exception handler. C code *may*, if it chooses, install a generic exception override, and we'll have a routine for this. Something like: EXCEPTION_OVERRIDE(&exception_frame); EXCEPTION_RELEASE(&exception_frame); but with a bit more thought involved. All it'll do is install a different setjmp destination in the interpreter and later remove it, but it'll take care of the whole linked-list stuff so they'll nest and restore properly. Your code will be 100% responsible for handling *all* exceptions, though it may choose to de-install itself and rethrow. That's OK. Finally, *all* fatal errors will be dealt with by throwing exceptions. The whole "Return 0/NULL on error" thing's too much of a hassle--either we succeed, or we freak out. I'll update the vtable PDD accordingly. This will mean that you may have to do a little more work in those few cases where 'fatal' errors are acceptable, but that should be a tiny minority, so I think this'll be a win. -- Dan --------------------------------------"it's like this"------------------- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even Perl class: stemsystems.com/class teddy bears get drunk