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:
parent
370312ae6e
commit
816a6f06c8
4 changed files with 151 additions and 105 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue