diff options
author | Andy Wingo <wingo@pobox.com> | 2010-01-31 12:35:19 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2010-02-26 11:56:02 +0100 |
commit | e10cf6b9c7e54c79db4de74584f1b0b65847d4fc (patch) | |
tree | 3df9ed5f6b52af3b0ffd5605e2f8834705bb589c /libguile/throw.c | |
parent | d296431516dbf14535fc6eaba551fede19c09772 (diff) | |
download | guile-e10cf6b9c7e54c79db4de74584f1b0b65847d4fc.tar.gz |
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.
Diffstat (limited to 'libguile/throw.c')
-rw-r--r-- | libguile/throw.c | 83 |
1 files changed, 19 insertions, 64 deletions
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 |