1 /* Copyright (C) 1995,1996 Free Software Foundation, Inc.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
39 * If you do not wish that, delete this exception notice.
46 /* Everybody has an init function. */
51 #include "backtrace.h"
54 #include "continuations.h"
55 #ifdef DEBUG_EXTENSIONS
76 #include "mbstrings.h"
89 #include "sequences.h"
100 #include "strports.h"
106 #include "variable.h"
123 scm_start_stack (base
, in
, out
, err
)
130 struct scm_port_table
* pt
;
132 root
= scm_permanent_object (scm_make_root (SCM_UNDEFINED
));
133 scm_set_root (SCM_ROOT_STATE (root
));
135 scm_stack_base
= base
;
137 /* Create standard ports from stdio files, if requested to do so.
142 scm_def_inp
= SCM_BOOL_F
;
146 SCM_NEWCELL (scm_def_inp
);
147 pt
= scm_add_to_port_table (scm_def_inp
);
148 SCM_CAR (scm_def_inp
) = (scm_tc16_fport
| SCM_OPN
| SCM_RDNG
);
149 SCM_SETPTAB_ENTRY (scm_def_inp
, pt
);
150 SCM_SETSTREAM (scm_def_inp
, (SCM
)in
);
151 if (isatty (fileno (in
)))
153 scm_setbuf0 (scm_def_inp
); /* turn off stdin buffering */
154 SCM_CAR (scm_def_inp
) |= SCM_BUF0
;
156 scm_set_port_revealed_x (scm_def_inp
, SCM_MAKINUM (1));
161 scm_def_outp
= SCM_BOOL_F
;
165 SCM_NEWCELL (scm_def_outp
);
166 pt
= scm_add_to_port_table (scm_def_outp
);
167 SCM_CAR (scm_def_outp
) = (scm_tc16_fport
| SCM_OPN
| SCM_WRTNG
);
168 SCM_SETPTAB_ENTRY (scm_def_outp
, pt
);
169 SCM_SETSTREAM (scm_def_outp
, (SCM
)out
);
170 scm_set_port_revealed_x (scm_def_outp
, SCM_MAKINUM (1));
175 scm_def_errp
= SCM_BOOL_F
;
179 SCM_NEWCELL (scm_def_errp
);
180 pt
= scm_add_to_port_table (scm_def_errp
);
181 SCM_CAR (scm_def_errp
) = (scm_tc16_fport
| SCM_OPN
| SCM_WRTNG
);
182 SCM_SETPTAB_ENTRY (scm_def_errp
, pt
);
183 SCM_SETSTREAM (scm_def_errp
, (SCM
)err
);
184 scm_set_port_revealed_x (scm_def_errp
, SCM_MAKINUM (1));
187 scm_cur_inp
= scm_def_inp
;
188 scm_cur_outp
= scm_def_outp
;
189 scm_cur_errp
= scm_def_errp
;
192 scm_progargs
= SCM_BOOL_F
; /* vestigial */
193 scm_exitval
= SCM_BOOL_F
; /* vestigial */
195 scm_top_level_lookup_thunk_var
= SCM_BOOL_F
;
196 scm_system_transformer
= SCM_BOOL_F
;
198 /* Create an object to hold the root continuation.
200 SCM_NEWCELL (scm_rootcont
);
201 SCM_SETJMPBUF (scm_rootcont
, scm_must_malloc ((long) sizeof (scm_contregs
), "continuation"));
202 SCM_CAR (scm_rootcont
) = scm_tc7_contin
;
203 SCM_SEQ (scm_rootcont
) = 0;
204 /* The root continuation if further initialized by scm_restart_stack. */
206 /* Create the look-aside stack for variables that are shared between
207 * captured continuations.
209 scm_continuation_stack
= scm_make_vector (SCM_MAKINUM (512), SCM_UNDEFINED
, SCM_UNDEFINED
);
210 /* The continuation stack is further initialized by scm_restart_stack. */
212 /* The remainder of stack initialization is factored out to another function so that
213 * if this stack is ever exitted, it can be re-entered using scm_restart_stack.
215 scm_restart_stack (base
);
220 scm_restart_stack (base
)
223 scm_dynwinds
= SCM_EOL
;
224 SCM_DYNENV (scm_rootcont
) = SCM_EOL
;
225 SCM_THROW_VALUE (scm_rootcont
) = SCM_EOL
;
226 #ifdef DEBUG_EXTENSIONS
227 SCM_DFRAME (scm_rootcont
) = scm_last_debug_frame
= 0;
229 SCM_BASE (scm_rootcont
) = base
;
230 scm_continuation_stack_ptr
= SCM_MAKINUM (0);
234 static char remsg
[] = "remove\n#define ", addmsg
[] = "add\n#define ";
237 static void fixconfig
SCM_P ((char *s1
, char *s2
, int s
));
240 fixconfig (s1
, s2
, s
)
247 fputs ("\nin ", stderr
);
248 fputs (s
? "setjump" : "scmfig", stderr
);
249 fputs (".h and recompile scm\n", stderr
);
254 static void check_config
SCM_P ((void));
262 if (HEAP_SEG_SIZE
!= j
)
263 fixconfig ("reduce", "size of HEAP_SEG_SIZE", 0);
266 if (sizeof (float) != sizeof (long))
267 fixconfig (remsg
, "SCM_SINGLES", 0);
268 #endif /* def SCM_SINGLES */
272 if (2 * SCM_BITSPERDIG
/ SCM_CHAR_BIT
> sizeof (long))
273 fixconfig (remsg
, "SCM_BIGDIG", 0);
274 #ifndef SCM_DIGSTOOBIG
275 if (SCM_DIGSPERLONG
* sizeof (SCM_BIGDIG
) > sizeof (long))
276 fixconfig (addmsg
, "SCM_DIGSTOOBIG", 0);
280 #ifdef SCM_STACK_GROWS_UP
281 if (((SCM_STACKITEM
*) & j
- stack_start_ptr
) < 0)
282 fixconfig (remsg
, "SCM_STACK_GROWS_UP", 1);
284 if ((stack_start_ptr
- (SCM_STACKITEM
*) & j
) < 0)
285 fixconfig (addmsg
, "SCM_STACK_GROWS_UP", 1);
293 typedef int setjmp_type
;
295 typedef long setjmp_type
;
300 * argc and argv are made the return values of program-arguments.
302 * in, out, and err, if not NULL, become the standard ports.
303 * If NULL is passed, your "initfunc" should set up the
306 * boot_cmd is a string containing a Scheme expression to evaluate
307 * to get things rolling.
309 * result is returned a string containing a printed result of evaluating
312 * the return value is:
313 * scm_boot_ok - evaluation concluded normally
314 * scm_boot_error - evaluation concluded with a Scheme error
315 * scm_boot_emem - allocation error mallocing *result
316 * scm_boot_ereenter - scm_boot_guile was called re-entrantly, which is
320 static int scm_boot_guile_1
SCM_P ((SCM_STACKITEM
*base
,
322 int argc
, char **argv
,
323 FILE *in
, FILE *out
, FILE *err
,
324 void (*init_func
) (),
328 scm_boot_guile (result
, argc
, argv
, in
, out
, err
, init_func
, boot_cmd
)
335 void (*init_func
) ();
340 return scm_boot_guile_1 (&dummy
, result
, argc
, argv
, in
, out
, err
,
341 init_func
, boot_cmd
);
345 scm_boot_guile_1 (base
, result
, argc
, argv
, in
, out
, err
, init_func
, boot_cmd
)
353 void (*init_func
) ();
356 static int initialized
= 0;
358 setjmp_type setjmp_val
;
361 if (live
) /* This function is not re-entrant. */
363 return scm_boot_ereenter
;
368 scm_ints_disabled
= 1;
373 scm_restart_stack (base
);
377 scm_ports_prehistory ();
378 scm_smob_prehistory ();
379 scm_tables_prehistory ();
380 scm_init_storage (0);
383 scm_init_threads (base
);
385 scm_start_stack (base
, in
, out
, err
);
390 scm_init_arbiters ();
392 scm_init_backtrace ();
395 scm_init_continuations ();
399 scm_init_fdsocket ();
413 /* Excluding this until it's really needed makes the binary
414 * smaller after linking. */
421 scm_init_procprop ();
424 #ifdef DEBUG_EXTENSIONS
427 scm_init_stackchk ();
428 scm_init_struct (); /* Requires struct */
430 scm_init_strports ();
434 scm_init_print (); /* Requires struct */
436 scm_init_sequences ();
439 scm_init_strorder ();
440 scm_init_mbstrings ();
443 scm_init_variable ();
449 #ifdef DEBUG_EXTENSIONS
450 scm_init_debug (); /* Requires macro smobs */
455 scm_progargs
= scm_makfromstrs (argc
, argv
);
456 scm_init_load_path ();
460 scm_block_gc
= 0; /* permit the gc to run */
461 /* ints still disabled */
466 command
= scm_makfrom0str (boot_cmd
);
468 setjmp_val
= setjmp (SCM_JMPBUF (scm_rootcont
));
470 #ifdef STACK_CHECKING
471 scm_stack_checking_enabled_p
= SCM_STACK_CHECKING_P
;
475 SCM last
= SCM_UNDEFINED
;
478 /* Call the initialization function passed in by the user, if
480 if (init_func
) (*init_func
) ();
482 /* Evaluate boot_cmd string. */
487 p
= scm_mkstrport (SCM_MAKINUM (0),
493 form
= scm_read (p
, SCM_BOOL_F
, SCM_BOOL_F
);
494 if (SCM_EOF_VAL
== form
)
496 last
= scm_eval_x (form
);
501 scm_restore_signals ();
502 /* This tick gives any pending
503 * asyncs a chance to run. This must be done after
504 * the call to scm_restore_signals.
508 scm_ints_disabled
= 1; /* Hopefully redundant but just to be sure. */
513 str_answer
= scm_strprint_obj (last
);
514 *result
= (char *)malloc (1 + SCM_LENGTH (str_answer
));
516 stat
= scm_boot_emem
;
519 memcpy (*result
, SCM_CHARS (str_answer
), SCM_LENGTH (str_answer
));
520 (*result
)[SCM_LENGTH (str_answer
)] = 0;
527 /* This is reached if an unhandled throw terminated Scheme.
528 * Such an occurence should be extremely unlikely -- it indicates
529 * a programming error in the boot code.
531 * Details of the bogus exception are stored in scm_exitval even
532 * though that isn't currently reflected in the return value.
536 scm_restore_signals ();
537 /* This tick gives any pending
538 * asyncs a chance to run. This must be done after
539 * the call to scm_restore_signals.
541 * Note that an unhandled exception during signal handling
542 * will put as back at the call to scm_restore_signals immediately
543 * preceeding. A sufficiently bogus signal handler could
544 * conceivably cause an infinite loop here.
548 scm_ints_disabled
= 1; /* Hopefully redundant but just to be sure. */
553 str_answer
= scm_strprint_obj (scm_exitval
);
554 *result
= (char *)malloc (1 + SCM_LENGTH (str_answer
));
556 stat
= scm_boot_emem
;
559 memcpy (*result
, SCM_CHARS (str_answer
), SCM_LENGTH (str_answer
));
560 (*result
)[SCM_LENGTH (str_answer
)] = 0;
561 stat
= scm_boot_error
;