summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2010-01-31 12:35:19 +0100
committerAndy Wingo <wingo@pobox.com>2010-02-26 11:56:02 +0100
commite10cf6b9c7e54c79db4de74584f1b0b65847d4fc (patch)
tree3df9ed5f6b52af3b0ffd5605e2f8834705bb589c
parentd296431516dbf14535fc6eaba551fede19c09772 (diff)
deprecate lazy-catch
* libguile/deprecated.h: * libguile/deprecated.c (scm_internal_lazy_catch, scm_lazy_catch): Deprecate, and print out a nasty warning that people should change to with-throw-handler. * libguile/throw.h: * libguile/throw.c (scm_c_with_throw_handler): Deprecate the use of the lazy_catch_p argument, printing out a nasty warning if someone actually passes 1 as that argument. The combination of the pre-unwind and post-unwind handlers should be sufficient. * test-suite/tests/exceptions.test: Remove lazy-catch tests, as they are deprecated. Two of them fail: * throw/catch: effect of lazy-catch unwinding on throw to another key * throw/catch: repeat of previous test but with lazy-catch Hopefully people are not depending on this behavior, and the warning is sufficiently nasty for people to switch. We will see. * test-suite/tests/eval.test ("promises"): Use with-throw-handler instead of lazy-catch. * doc/ref/api-debug.texi: * doc/ref/api-control.texi: Update to remove references to lazy-catch, folding in the useful bits to with-throw-handler.
-rw-r--r--doc/ref/api-control.texi198
-rw-r--r--doc/ref/api-debug.texi15
-rw-r--r--libguile/deprecated.c50
-rw-r--r--libguile/deprecated.h10
-rw-r--r--libguile/throw.c83
-rw-r--r--libguile/throw.h7
-rw-r--r--test-suite/tests/eval.test30
-rw-r--r--test-suite/tests/exceptions.test153
8 files changed, 169 insertions, 377 deletions
diff --git a/doc/ref/api-control.texi b/doc/ref/api-control.texi
index c76bdfe0c..0e84d8948 100644
--- a/doc/ref/api-control.texi
+++ b/doc/ref/api-control.texi
@@ -1,6 +1,6 @@
@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@@ -606,8 +606,7 @@ more conveniently.
@menu
* Exception Terminology:: Different ways to say the same thing.
* Catch:: Setting up to catch exceptions.
-* Throw Handlers:: Adding extra handling to a throw.
-* Lazy Catch:: Catch without unwinding the stack.
+* Throw Handlers:: Handling exceptions before unwinding the stack.
* Throw:: Throwing an exception.
* Exception Implementation:: How Guile implements exceptions.
@end menu
@@ -800,17 +799,53 @@ Operations}).
@subsubsection Throw Handlers
It's sometimes useful to be able to intercept an exception that is being
-thrown, but without changing where in the dynamic context that exception
-will eventually be caught. This could be to clean up some related state
-or to pass information about the exception to a debugger, for example.
-The @code{with-throw-handler} procedure provides a way to do this.
+thrown before the stack is unwound. This could be to clean up some
+related state, to print a backtrace, or to pass information about the
+exception to a debugger, for example. The @code{with-throw-handler}
+procedure provides a way to do this.
@deffn {Scheme Procedure} with-throw-handler key thunk handler
@deffnx {C Function} scm_with_throw_handler (key, thunk, handler)
Add @var{handler} to the dynamic context as a throw handler
for key @var{key}, then invoke @var{thunk}.
+
+This behaves exactly like @code{catch}, except that it does not unwind
+the stack before invoking @var{handler}. If the @var{handler} procedure
+returns normally, Guile rethrows the same exception again to the next
+innermost catch or throw handler. @var{handler} may exit nonlocally, of
+course, via an explicit throw or via invoking a continuation.
@end deffn
+Typically @var{handler} is used to display a backtrace of the stack at
+the point where the corresponding @code{throw} occurred, or to save off
+this information for possible display later.
+
+Not unwinding the stack means that throwing an exception that is handled
+via a throw handler is equivalent to calling the throw handler handler
+inline instead of each @code{throw}, and then omitting the surrounding
+@code{with-throw-handler}. In other words,
+
+@lisp
+(with-throw-handler 'key
+ (lambda () @dots{} (throw 'key args @dots{}) @dots{})
+ handler)
+@end lisp
+
+@noindent
+is mostly equivalent to
+
+@lisp
+((lambda () @dots{} (handler 'key args @dots{}) @dots{}))
+@end lisp
+
+In particular, the dynamic context when @var{handler} is invoked is that
+of the site where @code{throw} is called. The examples are not quite
+equivalent, because the body of a @code{with-throw-handler} is not in
+tail position with respect to the @code{with-throw-handler}, and if
+@var{handler} exits normally, Guile arranges to rethrow the error, but
+hopefully the intention is clear. (For an introduction to what is meant
+by dynamic context, @xref{Dynamic Wind}.)
+
@deftypefn {C Function} SCM scm_c_with_throw_handler (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data, int lazy_catch_p)
The above @code{scm_with_throw_handler} takes Scheme procedures as body
(thunk) and handler arguments. @code{scm_c_with_throw_handler} is an
@@ -838,141 +873,13 @@ everything that a @code{catch} would do until the point where
then it rethrows to the next innermost @code{catch} or throw handler
instead.
+Note also that since the dynamic context is not unwound, if a
+@code{with-throw-handler} handler throws to a key that does not match
+the @code{with-throw-handler} expression's @var{key}, the new throw may
+be handled by a @code{catch} or throw handler that is @emph{closer} to
+the throw than the first @code{with-throw-handler}.
-@node Lazy Catch
-@subsubsection Catch Without Unwinding
-
-Before version 1.8, Guile's closest equivalent to
-@code{with-throw-handler} was @code{lazy-catch}. From version 1.8
-onwards we recommend using @code{with-throw-handler} because its
-behaviour is more useful than that of @code{lazy-catch}, but
-@code{lazy-catch} is still supported as well.
-
-A @dfn{lazy catch} is used in the same way as a normal @code{catch},
-with @var{key}, @var{thunk} and @var{handler} arguments specifying the
-exception type, normal case code and handler procedure, but differs in
-one important respect: the handler procedure is executed without
-unwinding the call stack from the context of the @code{throw} expression
-that caused the handler to be invoked.
-
-@deffn {Scheme Procedure} lazy-catch key thunk handler
-@deffnx {C Function} scm_lazy_catch (key, thunk, handler)
-This behaves exactly like @code{catch}, except that it does
-not unwind the stack before invoking @var{handler}.
-If the @var{handler} procedure returns normally, Guile
-rethrows the same exception again to the next innermost catch,
-lazy-catch or throw handler. If the @var{handler} exits
-non-locally, that exit determines the continuation.
-@end deffn
-
-@deftypefn {C Function} SCM scm_internal_lazy_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
-The above @code{scm_lazy_catch} takes Scheme procedures as body and
-handler arguments. @code{scm_internal_lazy_catch} is an equivalent
-taking C functions. See @code{scm_internal_catch} (@pxref{Catch}) for
-a description of the parameters, the behaviour however of course
-follows @code{lazy-catch}.
-@end deftypefn
-
-Typically @var{handler} is used to display a backtrace of the stack at
-the point where the corresponding @code{throw} occurred, or to save off
-this information for possible display later.
-
-Not unwinding the stack means that throwing an exception that is caught
-by a @code{lazy-catch} is @emph{almost} equivalent to calling the
-@code{lazy-catch}'s handler inline instead of each @code{throw}, and
-then omitting the surrounding @code{lazy-catch}. In other words,
-
-@lisp
-(lazy-catch 'key
- (lambda () @dots{} (throw 'key args @dots{}) @dots{})
- handler)
-@end lisp
-
-@noindent
-is @emph{almost} equivalent to
-
-@lisp
-((lambda () @dots{} (handler 'key args @dots{}) @dots{}))
-@end lisp
-
-@noindent
-But why only @emph{almost}? The difference is that with
-@code{lazy-catch} (as with normal @code{catch}), the dynamic context is
-unwound back to just outside the @code{lazy-catch} expression before
-invoking the handler. (For an introduction to what is meant by dynamic
-context, @xref{Dynamic Wind}.)
-
-Then, when the handler @emph{itself} throws an exception, that exception
-must be caught by some kind of @code{catch} (including perhaps another
-@code{lazy-catch}) higher up the call stack.
-
-The dynamic context also includes @code{with-fluids} blocks
-(@pxref{Fluids and Dynamic States}),
-so the effect of unwinding the dynamic context can also be seen in fluid
-variable values. This is illustrated by the following code, in which
-the normal case thunk uses @code{with-fluids} to temporarily change the
-value of a fluid:
-
-@lisp
-(define f (make-fluid))
-(fluid-set! f "top level value")
-
-(define (handler . args)
- (cons (fluid-ref f) args))
-
-(lazy-catch 'foo
- (lambda ()
- (with-fluids ((f "local value"))
- (throw 'foo)))
- handler)
-@result{}
-("top level value" foo)
-
-((lambda ()
- (with-fluids ((f "local value"))
- (handler 'foo))))
-@result{}
-("local value" foo)
-@end lisp
-
-@noindent
-In the @code{lazy-catch} version, the unwinding of dynamic context
-restores @code{f} to its value outside the @code{with-fluids} block
-before the handler is invoked, so the handler's @code{(fluid-ref f)}
-returns the external value.
-
-@code{lazy-catch} is useful because it permits the implementation of
-debuggers and other reflective programming tools that need to access the
-state of the call stack at the exact point where an exception or an
-error is thrown. For an example of this, see REFFIXME:stack-catch.
-
-It should be obvious from the above that @code{lazy-catch} is very
-similar to @code{with-throw-handler}. In fact Guile implements
-@code{lazy-catch} in exactly the same way as @code{with-throw-handler},
-except with a flag set to say ``where there are slight differences
-between what @code{with-throw-handler} and @code{lazy-catch} would do,
-do what @code{lazy-catch} has always done''. There are two such
-differences:
-
-@enumerate
-@item
-@code{with-throw-handler} handlers execute in the full dynamic context
-of the originating @code{throw} call. @code{lazy-catch} handlers
-execute in the dynamic context of the @code{lazy-catch} expression,
-excepting only that the stack has not yet been unwound from the point of
-the @code{throw} call.
-
-@item
-If a @code{with-throw-handler} handler throws to a key that does not
-match the @code{with-throw-handler} expression's @var{key}, the new
-throw may be handled by a @code{catch} or throw handler that is _closer_
-to the throw than the first @code{with-throw-handler}. If a
-@code{lazy-catch} handler throws, it will always be handled by a
-@code{catch} or throw handler that is higher up the dynamic context than
-the first @code{lazy-catch}.
-@end enumerate
-
-Here is an example to illustrate the second difference:
+Here is an example to illustrate this behavior:
@lisp
(catch 'a
@@ -990,14 +897,7 @@ Here is an example to illustrate the second difference:
@noindent
This code will call @code{inner-handler} and then continue with the
-continuation of the inner @code{catch}. If the
-@code{with-throw-handler} was changed to @code{lazy-catch}, however, the
-code would call @code{outer-handler} and then continue with the
-continuation of the outer @code{catch}.
-
-Modulo these two differences, any statements in the previous and
-following subsections about throw handlers apply to lazy catches as
-well.
+continuation of the inner @code{catch}.
@node Throw
diff --git a/doc/ref/api-debug.texi b/doc/ref/api-debug.texi
index c29bfdf12..3c9ec1137 100644
--- a/doc/ref/api-debug.texi
+++ b/doc/ref/api-debug.texi
@@ -1,6 +1,6 @@
@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2010
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@@ -400,13 +400,12 @@ equivalent in C. In Scheme, this means you need something like this:
@end lisp
@noindent
-The @code{catch} here can also be @code{lazy-catch} or
-@code{with-throw-handler}; see @ref{Throw Handlers} and @ref{Lazy Catch}
-for the details of how these differ from @code{catch}. The @code{#t}
-means that the catch is applicable to all kinds of error; if you want to
-restrict your catch to just one kind of error, you can put the symbol
-for that kind of error instead of @code{#t}. The equivalent to this in
-C would be something like this:
+The @code{catch} here can also be @code{with-throw-handler}; see @ref{Throw
+Handlers} for information on the when you might want to use
+@code{with-throw-handler} instead of @code{catch}. The @code{#t} means that the
+catch is applicable to all kinds of error; if you want to restrict your catch to
+just one kind of error, you can put the symbol for that kind of error instead of
+@code{#t}. The equivalent to this in C would be something like this:
@lisp
SCM my_body_proc (void *body_data)
diff --git a/libguile/deprecated.c b/libguile/deprecated.c
index 54f0055b3..95f6f4662 100644
--- a/libguile/deprecated.c
+++ b/libguile/deprecated.c
@@ -1816,6 +1816,56 @@ scm_i_subr_p (SCM x)
}
+
+SCM
+scm_internal_lazy_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
+{
+ scm_c_issue_deprecation_warning
+ ("`scm_internal_lazy_catch' is no longer supported. Instead this call will\n"
+ "dispatch to `scm_c_with_throw_handler'. Your handler will be invoked from\n"
+ "within the dynamic context of the corresponding `throw'.\n"
+ "\nTHIS COULD CHANGE YOUR PROGRAM'S BEHAVIOR.\n\n"
+ "Please modify your program to use `scm_c_with_throw_handler' directly,\n"
+ "and adapt it (if necessary) to expect to be within the dynamic context\n"
+ "of the throw.");
+ return scm_c_with_throw_handler (tag, body, body_data, handler, handler_data, 0);
+}
+
+SCM_DEFINE (scm_lazy_catch, "lazy-catch", 3, 0, 0,
+ (SCM key, SCM thunk, SCM handler),
+ "This behaves exactly like @code{catch}, except that it does\n"
+ "not unwind the stack before invoking @var{handler}.\n"
+ "If the @var{handler} procedure returns normally, Guile\n"
+ "rethrows the same exception again to the next innermost catch,\n"
+ "lazy-catch or throw handler. If the @var{handler} exits\n"
+ "non-locally, that exit determines the continuation.")
+#define FUNC_NAME s_scm_lazy_catch
+{
+ struct scm_body_thunk_data c;
+
+ SCM_ASSERT (scm_is_symbol (key) || scm_is_eq (key, SCM_BOOL_T),
+ key, SCM_ARG1, FUNC_NAME);
+
+ c.tag = key;
+ c.body_proc = thunk;
+
+ scm_c_issue_deprecation_warning
+ ("`lazy-catch' is no longer supported. Instead this call will dispatch\n"
+ "to `with-throw-handler'. Your handler will be invoked from within the\n"
+ "dynamic context of the corresponding `throw'.\n"
+ "\nTHIS COULD CHANGE YOUR PROGRAM'S BEHAVIOR.\n\n"
+ "Please modify your program to use `with-throw-handler' directly, and\n"
+ "adapt it (if necessary) to expect to be within the dynamic context of\n"
+ "the throw.");
+
+ return scm_c_with_throw_handler (key,
+ scm_body_thunk, &c,
+ scm_handle_by_proc, &handler, 0);
+}
+#undef FUNC_NAME
+
+
+
void
scm_i_init_deprecated ()
{
diff --git a/libguile/deprecated.h b/libguile/deprecated.h
index 9832cfbb0..7f26f3fa0 100644
--- a/libguile/deprecated.h
+++ b/libguile/deprecated.h
@@ -611,6 +611,16 @@ SCM_DEPRECATED int scm_i_subr_p (SCM x);
+/* Deprecated 2010-01-31, use with-throw-handler instead */
+SCM_DEPRECATED SCM scm_lazy_catch (SCM tag, SCM thunk, SCM handler);
+SCM_DEPRECATED SCM scm_internal_lazy_catch (SCM tag,
+ scm_t_catch_body body,
+ void *body_data,
+ scm_t_catch_handler handler,
+ void *handler_data);
+
+
+
void scm_i_init_deprecated (void);
#endif
diff --git a/libguile/throw.c b/libguile/throw.c
index fd08e6e70..22d1c4f13 100644
--- a/libguile/throw.c
+++ b/libguile/throw.c
@@ -30,6 +30,7 @@
#include "libguile/alist.h"
#include "libguile/eval.h"
#include "libguile/eq.h"
+#include "libguile/deprecation.h"
#include "libguile/dynwind.h"
#include "libguile/backtrace.h"
#include "libguile/debug.h"
@@ -93,12 +94,11 @@ struct jmp_buf_and_retval /* use only on the stack, in scm_catch */
SCM retval;
};
-/* These are the structures we use to store pre-unwind handling (aka
- "lazy") information for a regular catch, and put on the wind list
- for a "lazy" catch. They store the pre-unwind handler function to
- call, and the data pointer to pass through to it. It's not a
- Scheme closure, but it is a function with data, so the term
- "closure" is appropriate in its broader sense.
+/* These are the structures we use to store pre-unwind handling information for
+ a regular catch, and put on the wind list for a with-throw-handler. They
+ store the pre-unwind handler function to call, and the data pointer to pass
+ through to it. It's not a Scheme closure, but it is a function with data, so
+ the term "closure" is appropriate in its broader sense.
(We don't need anything like this to run the normal (post-unwind)
catch handler, because the same C frame runs both the body and the
@@ -108,7 +108,6 @@ struct pre_unwind_data {
scm_t_catch_handler handler;
void *handler_data;
int running;
- int lazy_catch_p;
};
@@ -187,7 +186,6 @@ scm_c_catch (SCM tag,
pre_unwind.handler = pre_unwind_handler;
pre_unwind.handler_data = pre_unwind_handler_data;
pre_unwind.running = 0;
- pre_unwind.lazy_catch_p = 0;
SCM_SETJBPREUNWIND(jmpbuf, &pre_unwind);
if (SCM_I_SETJMP (jbr.buf))
@@ -303,9 +301,18 @@ scm_c_with_throw_handler (SCM tag,
c.handler = handler;
c.handler_data = handler_data;
c.running = 0;
- c.lazy_catch_p = lazy_catch_p;
pre_unwind = make_pre_unwind_data (&c);
+ if (lazy_catch_p)
+ scm_c_issue_deprecation_warning
+ ("The LAZY_CATCH_P argument to `scm_c_with_throw_handler' is no longer.\n"
+ "supported. Instead the handler will be invoked from within the dynamic\n"
+ "context of the corresponding `throw'.\n"
+ "\nTHIS COULD CHANGE YOUR PROGRAM'S BEHAVIOR.\n\n"
+ "Please modify your program to pass 0 as the LAZY_CATCH_P argument,\n"
+ "and adapt it (if necessary) to expect to be within the dynamic context\n"
+ "of the throw.");
+
SCM_CRITICAL_SECTION_START;
scm_i_set_dynwinds (scm_acons (tag, pre_unwind, scm_i_dynwinds ()));
SCM_CRITICAL_SECTION_END;
@@ -319,15 +326,6 @@ scm_c_with_throw_handler (SCM tag,
return answer;
}
-/* Exactly like scm_internal_catch, except:
- - It does not unwind the stack (this is the major difference).
- - The handler is not allowed to return. */
-SCM
-scm_internal_lazy_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
-{
- return scm_c_with_throw_handler (tag, body, body_data, handler, handler_data, 1);
-}
-
/* scm_internal_stack_catch
Use this one if you want debugging information to be stored in
@@ -354,7 +352,7 @@ static SCM
cwss_body (void *data)
{
struct cwss_data *d = data;
- return scm_internal_lazy_catch (d->tag, d->body, d->data, ss_handler, NULL);
+ return scm_c_with_throw_handler (d->tag, d->body, d->data, ss_handler, NULL, 0);
}
SCM
@@ -566,7 +564,7 @@ scm_handle_by_throw (void *handler_data SCM_UNUSED, SCM tag, SCM args)
-/* the Scheme-visible CATCH, WITH-THROW-HANDLER and LAZY-CATCH functions */
+/* the Scheme-visible CATCH and WITH-THROW-HANDLER functions */
SCM_DEFINE (scm_catch_with_pre_unwind_handler, "catch", 3, 1, 0,
(SCM key, SCM thunk, SCM handler, SCM pre_unwind_handler),
@@ -664,37 +662,6 @@ SCM_DEFINE (scm_with_throw_handler, "with-throw-handler", 3, 0, 0,
}
#undef FUNC_NAME
-SCM_DEFINE (scm_lazy_catch, "lazy-catch", 3, 0, 0,
- (SCM key, SCM thunk, SCM handler),
- "This behaves exactly like @code{catch}, except that it does\n"
- "not unwind the stack before invoking @var{handler}.\n"
- "If the @var{handler} procedure returns normally, Guile\n"
- "rethrows the same exception again to the next innermost catch,\n"
- "lazy-catch or throw handler. If the @var{handler} exits\n"
- "non-locally, that exit determines the continuation.")
-#define FUNC_NAME s_scm_lazy_catch
-{
- struct scm_body_thunk_data c;
-
- SCM_ASSERT (scm_is_symbol (key) || scm_is_eq (key, SCM_BOOL_T),
- key, SCM_ARG1, FUNC_NAME);
-
- c.tag = key;
- c.body_proc = thunk;
-
- /* scm_internal_lazy_catch takes care of all the mechanics of
- setting up a lazy catch key; we tell it to call scm_body_thunk to
- run the body, and scm_handle_by_proc to deal with any throws to
- this catch. The former receives a pointer to c, telling it how
- to behave. The latter receives a pointer to HANDLER, so it knows
- who to call. */
- return scm_internal_lazy_catch (key,
- scm_body_thunk, &c,
- scm_handle_by_proc, &handler);
-}
-#undef FUNC_NAME
-
-
/* throwing */
@@ -815,19 +782,7 @@ scm_ithrow (SCM key, SCM args, int noreturn SCM_UNUSED)
{
struct pre_unwind_data *c =
(struct pre_unwind_data *) SCM_SMOB_DATA_1 (jmpbuf);
- SCM handle, answer;
-
- /* For old-style lazy-catch behaviour, we unwind the dynamic
- context before invoking the handler. */
- if (c->lazy_catch_p)
- {
- scm_dowinds (wind_goal, (scm_ilength (scm_i_dynwinds ())
- - scm_ilength (wind_goal)));
- SCM_CRITICAL_SECTION_START;
- handle = scm_i_dynwinds ();
- scm_i_set_dynwinds (SCM_CDR (handle));
- SCM_CRITICAL_SECTION_END;
- }
+ SCM answer;
/* Call the handler, with framing to set the pre-unwind
structure's running field while the handler is running, so we
diff --git a/libguile/throw.h b/libguile/throw.h
index 1ed6ba6b1..d14cbf839 100644
--- a/libguile/throw.h
+++ b/libguile/throw.h
@@ -52,12 +52,6 @@ SCM_API SCM scm_internal_catch (SCM tag,
scm_t_catch_handler handler,
void *handler_data);
-SCM_API SCM scm_internal_lazy_catch (SCM tag,
- scm_t_catch_body body,
- void *body_data,
- scm_t_catch_handler handler,
- void *handler_data);
-
SCM_API SCM scm_internal_stack_catch (SCM tag,
scm_t_catch_body body,
void *body_data,
@@ -91,7 +85,6 @@ SCM_API int scm_exit_status (SCM args);
SCM_API SCM scm_catch_with_pre_unwind_handler (SCM tag, SCM thunk, SCM handler, SCM lazy_handler);
SCM_API SCM scm_catch (SCM tag, SCM thunk, SCM handler);
SCM_API SCM scm_with_throw_handler (SCM tag, SCM thunk, SCM handler);
-SCM_API SCM scm_lazy_catch (SCM tag, SCM thunk, SCM handler);
SCM_API SCM scm_ithrow (SCM key, SCM args, int noreturn);
SCM_API SCM scm_throw (SCM key, SCM args);
diff --git a/test-suite/tests/eval.test b/test-suite/tests/eval.test
index c253b2d09..fd5d75087 100644
--- a/test-suite/tests/eval.test
+++ b/test-suite/tests/eval.test
@@ -1,5 +1,5 @@
;;;; eval.test --- tests guile's evaluator -*- scheme -*-
-;;;; Copyright (C) 2000, 2001, 2006, 2007, 2009 Free Software Foundation, Inc.
+;;;; Copyright (C) 2000, 2001, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
@@ -306,21 +306,19 @@
exception:wrong-type-arg
(+ (delay (* 3 7)) 13))
- ;; Tests that require the debugging evaluator...
- (with-debugging-evaluator
-
- (pass-if "unmemoizing a promise"
- (display-backtrace
- (let ((stack #f))
- (false-if-exception (lazy-catch #t
- (lambda ()
- (let ((f (lambda (g) (delay (g)))))
- (force (f error))))
- (lambda _
- (set! stack (make-stack #t)))))
- stack)
- (%make-void-port "w"))
- #t))))
+ (pass-if "unmemoizing a promise"
+ (display-backtrace
+ (let ((stack #f))
+ (false-if-exception
+ (with-throw-handler #t
+ (lambda ()
+ (let ((f (lambda (g) (delay (g)))))
+ (force (f error))))
+ (lambda _
+ (set! stack (make-stack #t)))))
+ stack)
+ (%make-void-port "w"))
+ #t)))
;;;
diff --git a/test-suite/tests/exceptions.test b/test-suite/tests/exceptions.test
index c2ec5f48d..bcaa282e5 100644
--- a/test-suite/tests/exceptions.test
+++ b/test-suite/tests/exceptions.test
@@ -1,5 +1,5 @@
;;;; exceptions.test --- tests for Guile's exception handling -*- scheme -*-
-;;;; Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
+;;;; Copyright (C) 2001, 2003, 2004, 2006, 2010 Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
@@ -75,9 +75,9 @@
(lambda () (throw 'a))
(lambda (x y . rest) #f))))
- (with-test-prefix "with lazy handler"
+ (with-test-prefix "with pre-unwind handler"
- (pass-if "lazy fluid state"
+ (pass-if "pre-unwind fluid state"
(equal? '(inner outer arg)
(let ((fluid-parm (make-fluid))
(inner-val #f))
@@ -102,32 +102,34 @@
(lambda (key . args)
(push 2))))
- (throw-test "catch and lazy catch"
+ (throw-test "catch and with-throw-handler"
'(1 2 3 4)
(catch 'a
(lambda ()
(push 1)
- (lazy-catch 'a
- (lambda ()
- (push 2)
- (throw 'a))
- (lambda (key . args)
- (push 3))))
+ (with-throw-handler
+ 'a
+ (lambda ()
+ (push 2)
+ (throw 'a))
+ (lambda (key . args)
+ (push 3))))
(lambda (key . args)
(push 4))))
- (throw-test "catch with rethrowing lazy catch handler"
+ (throw-test "catch with rethrowing throw-handler"
'(1 2 3 4)
(catch 'a
(lambda ()
(push 1)
- (lazy-catch 'a
- (lambda ()
- (push 2)
- (throw 'a))
- (lambda (key . args)
- (push 3)
- (apply throw key args))))
+ (with-throw-handler
+ 'a
+ (lambda ()
+ (push 2)
+ (throw 'a))
+ (lambda (key . args)
+ (push 3)
+ (apply throw key args))))
(lambda (key . args)
(push 4))))
@@ -183,27 +185,6 @@
(lambda (key . args)
(push 4))))
- (throw-test "effect of lazy-catch unwinding on throw to another key"
- '(1 2 3 5 7)
- (catch 'a
- (lambda ()
- (push 1)
- (lazy-catch 'b
- (lambda ()
- (push 2)
- (catch 'a
- (lambda ()
- (push 3)
- (throw 'b))
- (lambda (key . args)
- (push 4))))
- (lambda (key . args)
- (push 5)
- (throw 'a)))
- (push 6))
- (lambda (key . args)
- (push 7))))
-
(throw-test "effect of with-throw-handler not-unwinding on throw to another key"
'(1 2 3 5 4 6)
(catch 'a
@@ -225,27 +206,6 @@
(lambda (key . args)
(push 7))))
- (throw-test "lazy-catch chaining"
- '(1 2 3 4 6 8)
- (catch 'a
- (lambda ()
- (push 1)
- (lazy-catch 'a
- (lambda ()
- (push 2)
- (lazy-catch 'a
- (lambda ()
- (push 3)
- (throw 'a))
- (lambda (key . args)
- (push 4)))
- (push 5))
- (lambda (key . args)
- (push 6)))
- (push 7))
- (lambda (key . args)
- (push 8))))
-
(throw-test "with-throw-handler chaining"
'(1 2 3 4 6 8)
(catch 'a
@@ -267,48 +227,6 @@
(lambda (key . args)
(push 8))))
- (throw-test "with-throw-handler inside lazy-catch"
- '(1 2 3 4 6 8)
- (catch 'a
- (lambda ()
- (push 1)
- (lazy-catch 'a
- (lambda ()
- (push 2)
- (with-throw-handler 'a
- (lambda ()
- (push 3)
- (throw 'a))
- (lambda (key . args)
- (push 4)))
- (push 5))
- (lambda (key . args)
- (push 6)))
- (push 7))
- (lambda (key . args)
- (push 8))))
-
- (throw-test "lazy-catch inside with-throw-handler"
- '(1 2 3 4 6 8)
- (catch 'a
- (lambda ()
- (push 1)
- (with-throw-handler 'a
- (lambda ()
- (push 2)
- (lazy-catch 'a
- (lambda ()
- (push 3)
- (throw 'a))
- (lambda (key . args)
- (push 4)))
- (push 5))
- (lambda (key . args)
- (push 6)))
- (push 7))
- (lambda (key . args)
- (push 8))))
-
(throw-test "throw handlers throwing to each other recursively"
'(1 2 3 4 8 6 10 12)
(catch #t
@@ -340,37 +258,6 @@
(lambda (key . args)
(push 12))))
- (throw-test "repeat of previous test but with lazy-catch"
- '(1 2 3 4 8 12)
- (catch #t
- (lambda ()
- (push 1)
- (lazy-catch 'a
- (lambda ()
- (push 2)
- (lazy-catch 'b
- (lambda ()
- (push 3)
- (lazy-catch 'c
- (lambda ()
- (push 4)
- (throw 'b)
- (push 5))
- (lambda (key . args)
- (push 6)
- (throw 'a)))
- (push 7))
- (lambda (key . args)
- (push 8)
- (throw 'c)))
- (push 9))
- (lambda (key . args)
- (push 10)
- (throw 'b)))
- (push 11))
- (lambda (key . args)
- (push 12))))
-
(throw-test "throw handler throwing to lexically inside catch"
'(1 2 7 5 4 6 9)
(with-throw-handler 'a