summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-12-20 18:56:14 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-12-20 18:56:14 -0800
commit43b3c4a7879e73ef370e696ee7531175857ae554 (patch)
treec50c970a1b58712146eea4c5b17e92509fa9b483
parent1c9044fb047cadde7e4efa2b110f6a6a80962d1a (diff)
downloadtxr-43b3c4a7879e73ef370e696ee7531175857ae554.tar.gz
txr-43b3c4a7879e73ef370e696ee7531175857ae554.tar.bz2
txr-43b3c4a7879e73ef370e696ee7531175857ae554.zip
Bug #35137
* unwind.c (uw_unwind_to_exit_point): When jumping to a catch frame, do not mark it invisible. * unwind.h (uw_catch): Flip the matches to nil so that this catch frame can no longer be identified as an unwind point by uw_throw, and thus will not be re-entered for the purposes of handling an exception. It remains visible for the purposes of running the clean up code. (uw_unwind): Prior to executing cleanup forms, flip the visibility to 0. This means that the frame will no longer be re-entered for any reason.
-rw-r--r--ChangeLog16
-rw-r--r--unwind.c9
-rw-r--r--unwind.h10
3 files changed, 24 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index f486688c..c7941624 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
2011-12-20 Kaz Kylheku <kaz@kylheku.com>
+ Bug #35137
+
+ * unwind.c (uw_unwind_to_exit_point): When jumping to a catch frame,
+ do not mark it invisible.
+
+ * unwind.h (uw_catch): Flip the matches to nil so that this catch
+ frame can no longer be identified as an unwind point by uw_throw,
+ and thus will not be re-entered for the purposes of handling
+ an exception. It remains visible for the purposes of running the
+ clean up code.
+ (uw_unwind): Prior to executing cleanup forms, flip the visibility
+ to 0. This means that the frame will no longer be re-entered
+ for any reason.
+
+2011-12-20 Kaz Kylheku <kaz@kylheku.com>
+
Streamlining exception handling macros a little bit.
* eval.c (op_unwind_protect): Use uw_simple_catch_begin,
diff --git a/unwind.c b/unwind.c
index 7abd4e97..03ae0104 100644
--- a/unwind.c
+++ b/unwind.c
@@ -65,11 +65,6 @@ static void uw_unwind_to_exit_point(void)
uw_stack->ca.sym = nil;
uw_stack->ca.exception = nil;
uw_stack->ca.cont = uw_exit_point;
- /* This catch frame is no longer
- visible. If the unwind section
- throws something, it cannot
- be caught in the same frame. */
- uw_stack->ca.visible = 0;
/* 1 means unwind only. */
longjmp(uw_stack->ca.jb, 1);
abort();
@@ -94,10 +89,6 @@ static void uw_unwind_to_exit_point(void)
case UW_ENV: /* env frame cannot be exit point */
abort();
case UW_CATCH:
- /* Catch frame is no longer visible.
- If a catch or unwind throw something,
- it cannot go back to the same catch. */
- uw_stack->ca.visible = 0;
/* 2 means actual catch, not just unwind */
longjmp(uw_stack->ca.jb, 2);
default:
diff --git a/unwind.h b/unwind.h
index 98b965e7..03e43982 100644
--- a/unwind.h
+++ b/unwind.h
@@ -155,11 +155,17 @@ noreturn val type_mismatch(val, ...);
break; \
case 2: \
EXCVAR = uw_catch.ca.exception; \
- SYMVAR = uw_catch.ca.sym;
+ SYMVAR = uw_catch.ca.sym; \
+ /* prevent looping */ \
+ uw_catch.ca.matches = nil;
#define uw_unwind \
+ /* suppress unused label warning */ \
+ goto uw_unwind_label; \
uw_unwind_label: \
- case 1:
+ case 1: \
+ /* prevent looping */ \
+ uw_catch.ca.visible = 0;
#define uw_catch_end \
break; \