Patrick R. Michaud wrote:
What I'm trying to do is to test the ability to resume after
exceptions thrown by C<foo>. The C<main> sub above sets up
a handler to catch exceptions, then calls C<foo>. The handler
simply resumes any exception that is caught. The C<foo> sub
prints 'ok 1', throws an exception, prints 'ok 2', throws another
exception, and prints 'ok 3'.
I can resume the first exception but not the second:
$ ./parrot x.pir
ok 1
ok 2
No exception handler and no message
current instr.: 'foo' pc 46 (x.pir:20)
called from Sub 'main' pc 29 (x.pir:10)
$
Suggestions and corrections to my code welcomed.
The old exception system deleted a handler as soon as it was retrieved
for an exception. For backward-compatibility, the new exception system
replicates that mis-feature. The problem is, if you end up throwing an
exception in the middle of handling another one, and didn't mark the
handler somehow, you can easily get an infinite loop of thrown
exceptions (when the handler gets some data it didn't expect from the
second exception, and so throws another exception).
In an ideal world:
a) every exception handler would first check the type of the exception
it was passed, and rethrow any exceptions it can't handle.
b) exception handlers would only be deleted by 'pop_eh', and otherwise
would simply pass out of scope after leaving the context where they were
defined.
Since (a) has to be in place before (b) can work, it was delayed.
(And I just changed the name of the 'retcont' attribute to 'resume', to
make it a little clearer.)
Allison