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. */
53 #include "continuations.h"
54 #ifdef DEBUG_EXTENSIONS
75 #include "mbstrings.h"
88 #include "sequences.h"
104 #include "variable.h"
121 scm_start_stack (base
, in
, out
, err
)
127 struct scm_port_table
* pt
;
129 scm_stack_base
= base
;
131 /* Create standard ports from stdio files, if requested to do so.
136 scm_def_inp
= SCM_BOOL_F
;
140 SCM_NEWCELL (scm_def_inp
);
141 pt
= scm_add_to_port_table (scm_def_inp
);
142 SCM_CAR (scm_def_inp
) = (scm_tc16_fport
| SCM_OPN
| SCM_RDNG
);
143 SCM_SETPTAB_ENTRY (scm_def_inp
, pt
);
144 SCM_SETSTREAM (scm_def_inp
, (SCM
)in
);
145 if (isatty (fileno (in
)))
147 scm_setbuf0 (scm_def_inp
); /* turn off stdin buffering */
148 SCM_CAR (scm_def_inp
) |= SCM_BUF0
;
150 scm_set_port_revealed_x (scm_def_inp
, SCM_MAKINUM (1));
155 scm_def_outp
= SCM_BOOL_F
;
159 SCM_NEWCELL (scm_def_outp
);
160 pt
= scm_add_to_port_table (scm_def_outp
);
161 SCM_CAR (scm_def_outp
) = (scm_tc16_fport
| SCM_OPN
| SCM_WRTNG
);
162 SCM_SETPTAB_ENTRY (scm_def_outp
, pt
);
163 SCM_SETSTREAM (scm_def_outp
, (SCM
)out
);
164 scm_set_port_revealed_x (scm_def_outp
, SCM_MAKINUM (1));
169 scm_def_errp
= SCM_BOOL_F
;
173 SCM_NEWCELL (scm_def_errp
);
174 pt
= scm_add_to_port_table (scm_def_errp
);
175 SCM_CAR (scm_def_errp
) = (scm_tc16_fport
| SCM_OPN
| SCM_WRTNG
);
176 SCM_SETPTAB_ENTRY (scm_def_errp
, pt
);
177 SCM_SETSTREAM (scm_def_errp
, (SCM
)err
);
178 scm_set_port_revealed_x (scm_def_errp
, SCM_MAKINUM (1));
181 scm_cur_inp
= scm_def_inp
;
182 scm_cur_outp
= scm_def_outp
;
183 scm_cur_errp
= scm_def_errp
;
186 scm_progargs
= SCM_BOOL_F
; /* vestigial */
187 scm_exitval
= SCM_BOOL_F
; /* vestigial */
189 scm_top_level_lookup_thunk_var
= SCM_BOOL_F
;
190 scm_system_transformer
= SCM_BOOL_F
;
192 /* Create an object to hold the root continuation.
194 SCM_NEWCELL (scm_rootcont
);
195 SCM_SETJMPBUF (scm_rootcont
, scm_must_malloc ((long) sizeof (regs
), "continuation"));
196 SCM_CAR (scm_rootcont
) = scm_tc7_contin
;
197 /* The root continuation if further initialized by scm_restart_stack. */
199 /* Create the look-aside stack for variables that are shared between
200 * captured continuations.
202 scm_continuation_stack
= scm_make_vector (SCM_MAKINUM (512), SCM_UNDEFINED
, SCM_UNDEFINED
);
203 /* The continuation stack is further initialized by scm_restart_stack. */
205 /* The remainder of stack initialization is factored out to another function so that
206 * if this stack is ever exitted, it can be re-entered using scm_restart_stack.
208 scm_restart_stack (base
);
213 scm_restart_stack (base
)
216 scm_dynwinds
= SCM_EOL
;
217 SCM_DYNENV (scm_rootcont
) = SCM_EOL
;
218 SCM_THROW_VALUE (scm_rootcont
) = SCM_EOL
;
219 #ifdef DEBUG_EXTENSIONS
220 SCM_DFRAME (scm_rootcont
) = last_debug_info_frame
= 0;
222 SCM_BASE (scm_rootcont
) = base
;
223 scm_continuation_stack_ptr
= SCM_MAKINUM (0);
227 static char remsg
[] = "remove\n#define ", addmsg
[] = "add\n#define ";
231 fixconfig (char *s1
, char *s2
, int s
)
234 fixconfig (s1
, s2
, s
)
242 fputs ("\nin ", stderr
);
243 fputs (s
? "setjump" : "scmfig", stderr
);
244 fputs (".h and recompile scm\n", stderr
);
256 if (HEAP_SEG_SIZE
!= j
)
257 fixconfig ("reduce", "size of HEAP_SEG_SIZE", 0);
260 if (sizeof (float) != sizeof (long))
261 fixconfig (remsg
, "SCM_SINGLES", 0);
262 #endif /* def SCM_SINGLES */
266 if (2 * SCM_BITSPERDIG
/ SCM_CHAR_BIT
> sizeof (long))
267 fixconfig (remsg
, "SCM_BIGDIG", 0);
268 #ifndef SCM_DIGSTOOBIG
269 if (SCM_DIGSPERLONG
* sizeof (SCM_BIGDIG
) > sizeof (long))
270 fixconfig (addmsg
, "SCM_DIGSTOOBIG", 0);
274 #ifdef SCM_STACK_GROWS_UP
275 if (((SCM_STACKITEM
*) & j
- stack_start_ptr
) < 0)
276 fixconfig (remsg
, "SCM_STACK_GROWS_UP", 1);
278 if ((stack_start_ptr
- (SCM_STACKITEM
*) & j
) < 0)
279 fixconfig (addmsg
, "SCM_STACK_GROWS_UP", 1);
287 typedef int setjmp_type
;
289 typedef long setjmp_type
;
294 * argc and argv are made the return values of program-arguments.
296 * in, out, and err, if not NULL, become the standard ports.
297 * If NULL is passed, your "initfunc" should set up the
300 * boot_cmd is a string containing a Scheme expression to evaluate
301 * to get things rolling.
303 * result is returned a string containing a printed result of evaluating
306 * the return value is:
307 * scm_boot_ok - evaluation concluded normally
308 * scm_boot_error - evaluation concluded with a Scheme error
309 * scm_boot_emem - allocation error mallocing *result
310 * scm_boot_ereenter - scm_boot_guile was called re-entrantly, which is
315 scm_boot_guile (result
, argc
, argv
, in
, out
, err
, init_func
, boot_cmd
)
322 void (*init_func
) ();
325 static int initialized
= 0;
328 setjmp_type setjmp_val
;
331 if (live
) /* This function is not re-entrant. */
333 return scm_boot_ereenter
;
338 scm_ints_disabled
= 1;
343 scm_restart_stack (&i
);
347 scm_ports_prehistory ();
348 scm_smob_prehistory ();
349 scm_tables_prehistory ();
350 scm_init_storage (0);
351 scm_start_stack (&i
, in
, out
, err
);
356 scm_init_arbiters ();
360 scm_init_continuations ();
361 #ifdef DEBUG_EXTENSIONS
367 scm_init_fdsocket ();
381 /* Excluding this until it's really needed makes the binary
382 * smaller after linking. */
389 scm_init_procprop ();
392 #ifdef DEBUG_EXTENSIONS
395 scm_init_stackchk ();
396 scm_init_strports ();
403 scm_init_sequences ();
406 scm_init_strorder ();
407 scm_init_mbstrings ();
410 scm_init_variable ();
419 scm_progargs
= scm_makfromstrs (argc
, argv
);
420 scm_init_load_path ();
424 scm_block_gc
= 0; /* permit the gc to run */
425 /* ints still disabled */
430 command
= scm_makfrom0str (boot_cmd
);
432 setjmp_val
= setjmp (SCM_JMPBUF (scm_rootcont
));
434 #ifdef STACK_CHECKING
435 scm_stack_checking_enabled_p
= SCM_STACK_CHECKING_P
;
439 SCM last
= SCM_UNDEFINED
;
442 /* Call the initialization function passed in by the user, if
444 if (init_func
) (*init_func
) ();
446 /* Evaluate boot_cmd string. */
451 p
= scm_mkstrport (SCM_MAKINUM (0),
457 form
= scm_read (p
, SCM_BOOL_F
, SCM_BOOL_F
);
458 if (SCM_EOF_VAL
== form
)
460 last
= scm_eval_x (form
);
465 scm_restore_signals ();
466 /* This tick gives any pending
467 * asyncs a chance to run. This must be done after
468 * the call to scm_restore_signals.
472 scm_ints_disabled
= 1; /* Hopefully redundant but just to be sure. */
477 str_answer
= scm_strprint_obj (last
);
478 *result
= (char *)malloc (1 + SCM_LENGTH (str_answer
));
480 stat
= scm_boot_emem
;
483 memcpy (*result
, SCM_CHARS (str_answer
), SCM_LENGTH (str_answer
));
484 (*result
)[SCM_LENGTH (str_answer
)] = 0;
491 /* This is reached if an unhandled throw terminated Scheme.
492 * Such an occurence should be extremely unlikely -- it indicates
493 * a programming error in the boot code.
495 * Details of the bogus exception are stored in scm_exitval even
496 * though that isn't currently reflected in the return value.
500 scm_restore_signals ();
501 /* This tick gives any pending
502 * asyncs a chance to run. This must be done after
503 * the call to scm_restore_signals.
505 * Note that an unhandled exception during signal handling
506 * will put as back at the call to scm_restore_signals immediately
507 * preceeding. A sufficiently bogus signal handler could
508 * conceivably cause an infinite loop here.
512 scm_ints_disabled
= 1; /* Hopefully redundant but just to be sure. */
517 str_answer
= scm_strprint_obj (scm_exitval
);
518 *result
= (char *)malloc (1 + SCM_LENGTH (str_answer
));
520 stat
= scm_boot_emem
;
523 memcpy (*result
, SCM_CHARS (str_answer
), SCM_LENGTH (str_answer
));
524 (*result
)[SCM_LENGTH (str_answer
)] = 0;
525 stat
= scm_boot_error
;