Permalink
Browse files

Properly handle exceptions generated from LEAVE, including those that…

… re-enter the associated block.
  • Loading branch information...
sorear committed Aug 6, 2011
1 parent 7e257a0 commit 1ce800eb813c915a055f707c598e3eb550152470
Showing with 19 additions and 4 deletions.
  1. +18 −4 lib/Kernel.cs
  2. +1 −0 t/spectest.data
View
@@ -4153,8 +4153,24 @@ class ExitRunloopException : Exception {
}
public static void RunCore(ref Frame cur) {
+ // TimToady says that any exception thrown (but not internally
+ // caught) during CATCH or LEAVE processing becomes the new
+ // exception
+ Exception handle = null;
for(;;) {
try {
+ if (handle is ResumeUnwindException) {
+ ResumeUnwindException rue =
+ (ResumeUnwindException) handle;
+ cur = Kernel.Unwind(cur, rue.type, rue.to_frame,
+ rue.to_ip, rue.to_data, null, null,
+ rue.p6backtrace);
+ }
+ else if (handle != null) {
+ cur = Kernel.Die(cur, handle.ToString());
+ }
+ handle = null;
+
if (TraceCount != 0) {
for(;;) {
if (--TraceCount == 0)
@@ -4169,11 +4185,8 @@ class ExitRunloopException : Exception {
if (ere.payload != null)
throw ere.payload;
return;
- } catch (ResumeUnwindException rue) {
- cur = Kernel.Unwind(cur, rue.type, rue.to_frame, rue.to_ip,
- rue.to_data, null, null, rue.p6backtrace);
} catch (Exception ex) {
- cur = Kernel.Die(cur, ex.ToString());
+ handle = ex;
}
}
}
@@ -4576,6 +4589,7 @@ class LastFrameNode {
} else {
// TODO: catch generated exceptions and add to @!
csr.caller.resultSlot = Kernel.NilP.mo.typeVar;
+ Kernel.SetTopFrame(csr);
csr = csr.Return();
}
}
View
@@ -64,6 +64,7 @@ S04-blocks-and-statements/temp.t
S04-declarations/multiple.t
S04-declarations/my.t
S04-declarations/state.t
+S04-exceptions/control_across_runloop.t
S04-phasers/enter-leave.t
S04-phasers/keep-undo.t
S04-phasers/pre-post.t

0 comments on commit 1ce800e

Please sign in to comment.