1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-17 17:20:29 +02:00

* throw.c (scm_internal_catch): Make body funcs and handler funcs

use separate data pointers, to allow them to be designed
independently and reused.
(scm_body_thunk, scm_handle_by_proc, scm_handle_by_message):
Renamed from catch_body, catch_handler, and uncaught_throw; made
generically useful.
(struct scm_catch_body_data): Renamed from catch_body_data; moved
to throw.h.
(scm_catch): Use the above.
(scm_throw): Don't bother printing a message for an uncaught
throw; we establish a default handler in init.
* throw.h (scm_internal_catch): Prototype updated.
(scm_body_thunk, scm_handle_by_proc, scm_handle_by_message): New
decls.
(struct scm_body_thunk_data): New structure, used as data
argument to scm_body_thunk.
* init.c (struct main_func_closure): New structure, packaging up
the data to pass to the user's main function.
(scm_boot_guile): Create one.  Pass it to scm_boot_guile_1.
(scm_boot_guile_1): Pass it through to invoke_main_func.  Use
scm_internal_catch to establish a catch-all handler, using
scm_handle_by_message.  This replaces the special-case code in
scm_throw.
(invoke_main_func): Body function for scm_internal_catch; invoke
the user's main function, using the main_func_closure pointer to
decide what to pass it.
* root.c (struct cwdr_body_data): Remove handler_proc member.
(cwdr): Use scm_handle_by_proc instead of cwdr_handler.
(cwdr_handler): Removed.
This commit is contained in:
Jim Blandy 1996-12-21 04:48:21 +00:00
parent 370312ae6e
commit 816a6f06c8
4 changed files with 151 additions and 105 deletions

View file

@ -261,12 +261,20 @@ typedef int setjmp_type;
typedef long setjmp_type;
#endif
static void scm_boot_guile_1 SCM_P ((SCM_STACKITEM *base,
int argc, char **argv,
void (*main_func) (void *closure,
int argc,
char **argv),
void *closure));
/* All the data needed to invoke the main function. */
struct main_func_closure
{
/* the function to call */
void (*main_func) SCM_P ((void *closure, int argc, char **argv));
void *closure; /* dummy data to pass it */
int argc;
char **argv; /* the argument list it should receive */
};
static void scm_boot_guile_1 SCM_P ((SCM_STACKITEM *base,
struct main_func_closure *closure));
static SCM invoke_main_func SCM_P ((void *body_data, SCM jmpbuf));
/* Fire up the Guile Scheme interpreter.
@ -282,6 +290,12 @@ static void scm_boot_guile_1 SCM_P ((SCM_STACKITEM *base,
call scm_set_program_arguments with the final list, so Scheme code
will know which arguments have been processed.
scm_boot_guile establishes a catch-all catch handler which prints
an error message and exits the process. This means that Guile
exits in a coherent way when system errors occur and the user isn't
prepared to handle it. If the user doesn't like this behavior,
they can establish their own universal catcher to shadow this one.
Why must the caller do all the real work from MAIN_FUNC? The
garbage collector assumes that all local variables of type SCM will
be above scm_boot_guile's stack frame on the stack. If you try to
@ -302,10 +316,17 @@ scm_boot_guile (argc, argv, main_func, closure)
end of the stack, and the address of one of its own local
variables as the other end. */
SCM_STACKITEM dummy;
struct main_func_closure c;
return scm_boot_guile_1 (&dummy, argc, argv, main_func, closure);
c.main_func = main_func;
c.closure = closure;
c.argc = argc;
c.argv = argv;
return scm_boot_guile_1 (&dummy, &c);
}
/* Record here whether SCM_BOOT_GUILE_1 has already been called. This
variable is now here and not inside SCM_BOOT_GUILE_1 so that one
can tweak it. This is necessary for unexec to work. (Hey, "1-live"
@ -314,12 +335,9 @@ scm_boot_guile (argc, argv, main_func, closure)
int scm_boot_guile_1_live = 0;
static void
scm_boot_guile_1 (base, argc, argv, main_func, closure)
scm_boot_guile_1 (base, closure)
SCM_STACKITEM *base;
int argc;
char **argv;
void (*main_func) ();
void *closure;
struct main_func_closure *closure;
{
static int initialized = 0;
/* static int live = 0; */
@ -436,8 +454,9 @@ scm_boot_guile_1 (base, argc, argv, main_func, closure)
{
scm_init_signals ();
scm_set_program_arguments (argc, argv, 0);
(*main_func) (closure, argc, argv);
scm_set_program_arguments (closure->argc, closure->argv, 0);
scm_internal_catch (SCM_BOOL_T, invoke_main_func, closure,
scm_handle_by_message, 0);
}
scm_restore_signals ();
@ -452,3 +471,17 @@ scm_boot_guile_1 (base, argc, argv, main_func, closure)
main_func themselves. */
exit (0);
}
static SCM
invoke_main_func (body_data, jmpbuf)
void *body_data;
SCM jmpbuf;
{
struct main_func_closure *closure = (struct main_func_closure *) body_data;
(*closure->main_func) (closure->closure, closure->argc, closure->argv);
/* never reached */
return SCM_UNDEFINED;
}