summaryrefslogtreecommitdiff
path: root/libguile/init.c
diff options
context:
space:
mode:
authorMarius Vollmer <mvo@zagadka.de>2005-01-24 23:41:14 +0000
committerMarius Vollmer <mvo@zagadka.de>2005-01-24 23:41:14 +0000
commit76da80e7881947ebcdb647e5ce4be029fece29f2 (patch)
tree9a56249fecf0002eefc25c6a0bfeb53a2b277d7f /libguile/init.c
parenta54a94b39707f47a1f30533bcf7664094d65d073 (diff)
downloadguile-76da80e7881947ebcdb647e5ce4be029fece29f2.tar.gz
Reverted changed from 2005/01/24 19:14:54, which was a commit to the
wrong branch. Sorry.
Diffstat (limited to 'libguile/init.c')
-rw-r--r--libguile/init.c135
1 files changed, 98 insertions, 37 deletions
diff --git a/libguile/init.c b/libguile/init.c
index 4d25299bb..ca964afb3 100644
--- a/libguile/init.c
+++ b/libguile/init.c
@@ -133,6 +133,46 @@
#include <unistd.h>
#endif
+/* Setting up the stack. */
+
+static void
+restart_stack (void *base)
+{
+ scm_dynwinds = SCM_EOL;
+ SCM_DYNENV (scm_rootcont) = SCM_EOL;
+ SCM_THROW_VALUE (scm_rootcont) = SCM_EOL;
+ SCM_DFRAME (scm_rootcont) = scm_last_debug_frame = 0;
+ SCM_BASE (scm_rootcont) = base;
+}
+
+static void
+start_stack (void *base)
+{
+ SCM root;
+
+ root = scm_permanent_object (scm_make_root (SCM_UNDEFINED));
+ scm_set_root (SCM_ROOT_STATE (root));
+ scm_stack_base = base;
+
+ scm_exitval = SCM_BOOL_F; /* vestigial */
+
+ scm_root->fluids = scm_i_make_initial_fluids ();
+
+ /* Create an object to hold the root continuation.
+ */
+ {
+ scm_t_contregs *contregs = scm_gc_malloc (sizeof (scm_t_contregs),
+ "continuation");
+ contregs->num_stack_items = 0;
+ contregs->seq = 0;
+ SCM_NEWSMOB (scm_rootcont, scm_tc16_continuation, contregs);
+ }
+
+ /* The remainder of stack initialization is factored out to another
+ * function so that if this stack is ever exitted, it can be
+ * re-entered using restart_stack. */
+ restart_stack (base);
+}
#if 0
@@ -305,9 +345,11 @@ struct main_func_closure
char **argv; /* the argument list it should receive */
};
+
+static void scm_init_guile_1 (SCM_STACKITEM *base);
static void scm_boot_guile_1 (SCM_STACKITEM *base,
struct main_func_closure *closure);
-static void *invoke_main_func(void *body_data);
+static SCM invoke_main_func(void *body_data);
/* Fire up the Guile Scheme interpreter.
@@ -341,6 +383,10 @@ static void *invoke_main_func(void *body_data);
void
scm_boot_guile (int argc, char ** argv, void (*main_func) (), void *closure)
{
+ /* The garbage collector uses the address of this variable as one
+ 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;
c.main_func = main_func;
@@ -348,47 +394,19 @@ scm_boot_guile (int argc, char ** argv, void (*main_func) (), void *closure)
c.argc = argc;
c.argv = argv;
- scm_with_guile (invoke_main_func, &c);
-}
-
-static void *
-invoke_main_func (void *body_data)
-{
- struct main_func_closure *closure = (struct main_func_closure *) body_data;
-
- scm_set_program_arguments (closure->argc, closure->argv, 0);
- (*closure->main_func) (closure->closure, closure->argc, closure->argv);
-
- scm_restore_signals ();
-
- /* This tick gives any pending
- * asyncs a chance to run. This must be done after
- * the call to scm_restore_signals.
- */
- SCM_ASYNC_TICK;
-
- /* If the caller doesn't want this, they should exit from main_func
- themselves.
- */
- pthread_exit (NULL);
-
- /* never reached */
- return NULL;
+ scm_boot_guile_1 (&dummy, &c);
}
-#if 0
void
scm_init_guile ()
{
- scm_i_init_guile ((SCM_STACKITEM *)scm_get_stack_base ());
+ scm_init_guile_1 ((SCM_STACKITEM *)scm_get_stack_base ());
}
-#endif
-pthread_mutex_t scm_i_init_mutex = PTHREAD_MUTEX_INITIALIZER;
int scm_initialized_p = 0;
-void
-scm_i_init_guile (SCM_STACKITEM *base)
+static void
+scm_init_guile_1 (SCM_STACKITEM *base)
{
if (scm_initialized_p)
return;
@@ -409,7 +427,7 @@ scm_i_init_guile (SCM_STACKITEM *base)
scm_block_gc = 1;
scm_storage_prehistory ();
- scm_threads_prehistory (base);
+ scm_threads_prehistory ();
scm_ports_prehistory ();
scm_smob_prehistory ();
scm_hashtab_prehistory (); /* requires storage_prehistory */
@@ -430,7 +448,8 @@ scm_i_init_guile (SCM_STACKITEM *base)
scm_init_variable (); /* all bindings need variables */
scm_init_continuations ();
scm_init_root (); /* requires continuations */
- scm_init_threads ();
+ scm_init_threads (base);
+ start_stack (base);
scm_init_gsubr ();
scm_init_thread_procs (); /* requires gsubrs */
scm_init_procprop ();
@@ -532,8 +551,6 @@ scm_i_init_guile (SCM_STACKITEM *base)
scm_i_init_deprecated ();
#endif
- scm_init_threads_root_root ();
-
scm_initialized_p = 1;
scm_block_gc = 0; /* permit the gc to run */
@@ -550,6 +567,50 @@ scm_i_init_guile (SCM_STACKITEM *base)
scm_load_startup_files ();
}
+/* 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"
+ is the name of a local radiostation...) */
+
+int scm_boot_guile_1_live = 0;
+
+static void
+scm_boot_guile_1 (SCM_STACKITEM *base, struct main_func_closure *closure)
+{
+ scm_init_guile_1 (base);
+
+ /* This function is not re-entrant. */
+ if (scm_boot_guile_1_live)
+ abort ();
+
+ scm_boot_guile_1_live = 1;
+
+ scm_set_program_arguments (closure->argc, closure->argv, 0);
+ invoke_main_func (closure);
+
+ scm_restore_signals ();
+
+ /* This tick gives any pending
+ * asyncs a chance to run. This must be done after
+ * the call to scm_restore_signals.
+ */
+ SCM_ASYNC_TICK;
+
+ /* If the caller doesn't want this, they should return from
+ main_func themselves. */
+ exit (0);
+}
+
+static SCM
+invoke_main_func (void *body_data)
+{
+ 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;
+}
/*
Local Variables: