summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-12-20 17:42:56 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-12-20 17:42:56 -0800
commit1c9044fb047cadde7e4efa2b110f6a6a80962d1a (patch)
tree48376683f5d2d94dd259ec778e9e771ba020fc47
parentf16d4a0947c00f5256aad67ddca906948a25b4a4 (diff)
downloadtxr-1c9044fb047cadde7e4efa2b110f6a6a80962d1a.tar.gz
txr-1c9044fb047cadde7e4efa2b110f6a6a80962d1a.tar.bz2
txr-1c9044fb047cadde7e4efa2b110f6a6a80962d1a.zip
Streamlining exception handling macros a little bit.
* eval.c (op_unwind_protect): Use uw_simple_catch_begin, and remove the uw_catch (exsym, exvals) clause. Put explicit braces around the unwind code even though it is only one statement. * match.c (do_txeval): Got rid of empty uw_unwind clause. This is not needed any longer. (v_try): Got rid of explicit uw_do_unwind calls. * unwind.h (uw_simple_catch_begin): New macro. (uw_do_unwind): Macro removed. (uw_catch): Added goto uw_unwind_label at the front. This way if the previous clause falls through, control goes to the unwind logic. (uw_unwind): Got rid of initial break. Previous clause should fall through to unwind logic, whether it is the main clause, or one of the catches. (uw_catch_end): Default case aborts, because we don't expect this.
-rw-r--r--ChangeLog24
-rw-r--r--eval.c9
-rw-r--r--match.c4
-rw-r--r--unwind.h15
4 files changed, 39 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index c5851292..f486688c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
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,
+ and remove the uw_catch (exsym, exvals) clause. Put
+ explicit braces around the unwind code even though it
+ is only one statement.
+
+ * match.c (do_txeval): Got rid of empty uw_unwind clause.
+ This is not needed any longer.
+ (v_try): Got rid of explicit uw_do_unwind calls.
+
+ * unwind.h (uw_simple_catch_begin): New macro.
+ (uw_do_unwind): Macro removed.
+ (uw_catch): Added goto uw_unwind_label at the front.
+ This way if the previous clause falls through,
+ control goes to the unwind logic.
+ (uw_unwind): Got rid of initial break. Previous
+ clause should fall through to unwind logic,
+ whether it is the main clause, or one of the catches.
+ (uw_catch_end): Default case aborts, because
+ we don't expect this.
+
+2011-12-20 Kaz Kylheku <kaz@kylheku.com>
+
Critical regression. Hash lookup was crashing on some platforms
due to negative hashing values being reduced modulo table size
to a negative array index.
diff --git a/eval.c b/eval.c
index f67b21af..e7475f9b 100644
--- a/eval.c
+++ b/eval.c
@@ -668,16 +668,13 @@ static val op_unwind_protect(val form, val env)
val cleanup_forms = rest(rest(form));
val result = nil;
- uw_catch_begin(nil, exsym, exvals);
+ uw_simple_catch_begin;
result = eval(prot_form, env, prot_form);
- uw_do_unwind;
-
- uw_catch (exsym, exvals);
-
- uw_unwind
+ uw_unwind {
eval_progn(cleanup_forms, env, cleanup_forms);
+ }
uw_catch_end;
diff --git a/match.c b/match.c
index 09d34dec..4e060df0 100644
--- a/match.c
+++ b/match.c
@@ -1366,6 +1366,8 @@ static val do_txeval(val spec, val form, val bindings, val allow_unbound)
sem_error(spec, lit("~a"), exc, nao);
}
+
+ uw_unwind { }
}
uw_catch_end;
@@ -2748,7 +2750,6 @@ static val v_try(match_files_ctx *c)
uw_catch_begin(catch_syms, exsym, exvals);
result = match_files(mf_spec(*c, try_clause));
- uw_do_unwind;
uw_catch(exsym, exvals) {
{
@@ -2807,7 +2808,6 @@ static val v_try(match_files_ctx *c)
}
}
}
- uw_do_unwind;
}
uw_unwind {
diff --git a/unwind.h b/unwind.h
index 4dea9469..98b965e7 100644
--- a/unwind.h
+++ b/unwind.h
@@ -133,6 +133,13 @@ noreturn val type_mismatch(val, ...);
uw_pop_frame(&uw_env); \
} while (0)
+#define uw_simple_catch_begin \
+ do { \
+ uw_frame_t uw_catch; \
+ uw_push_catch(&uw_catch, nil); \
+ switch (setjmp(uw_catch.ca.jb)) { \
+ case 0:
+
#define uw_catch_begin(MATCHES, SYMVAR, \
EXCVAR) \
obj_t *SYMVAR = nil; \
@@ -143,23 +150,21 @@ noreturn val type_mismatch(val, ...);
switch (setjmp(uw_catch.ca.jb)) { \
case 0:
-#define uw_do_unwind \
- goto uw_unwind_label
-
#define uw_catch(SYMVAR, EXCVAR) \
+ goto uw_unwind_label; \
break; \
case 2: \
EXCVAR = uw_catch.ca.exception; \
SYMVAR = uw_catch.ca.sym;
#define uw_unwind \
- break; \
uw_unwind_label: \
case 1:
#define uw_catch_end \
- default: \
break; \
+ default: \
+ abort(); \
} \
if (uw_catch.ca.cont) \
uw_continue(&uw_catch, \