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
)
128 struct scm_port_table
* pt
;
130 root
= scm_permanent_object (scm_make_root (SCM_UNDEFINED
));
131 scm_set_root (SCM_ROOT_STATE (root
));
133 scm_stack_base
= base
;
135 /* Create standard ports from stdio files, if requested to do so.
140 scm_def_inp
= SCM_BOOL_F
;
144 SCM_NEWCELL (scm_def_inp
);
145 pt
= scm_add_to_port_table (scm_def_inp
);
146 SCM_CAR (scm_def_inp
) = (scm_tc16_fport
| SCM_OPN
| SCM_RDNG
);
147 SCM_SETPTAB_ENTRY (scm_def_inp
, pt
);
148 SCM_SETSTREAM (scm_def_inp
, (SCM
)in
);
149 if (isatty (fileno (in
)))
151 scm_setbuf0 (scm_def_inp
); /* turn off stdin buffering */
152 SCM_CAR (scm_def_inp
) |= SCM_BUF0
;
154 scm_set_port_revealed_x (scm_def_inp
, SCM_MAKINUM (1));
159 scm_def_outp
= SCM_BOOL_F
;
163 SCM_NEWCELL (scm_def_outp
);
164 pt
= scm_add_to_port_table (scm_def_outp
);
165 SCM_CAR (scm_def_outp
) = (scm_tc16_fport
| SCM_OPN
| SCM_WRTNG
);
166 SCM_SETPTAB_ENTRY (scm_def_outp
, pt
);
167 SCM_SETSTREAM (scm_def_outp
, (SCM
)out
);
168 scm_set_port_revealed_x (scm_def_outp
, SCM_MAKINUM (1));
173 scm_def_errp
= SCM_BOOL_F
;
177 SCM_NEWCELL (scm_def_errp
);
178 pt
= scm_add_to_port_table (scm_def_errp
);
179 SCM_CAR (scm_def_errp
) = (scm_tc16_fport
| SCM_OPN
| SCM_WRTNG
);
180 SCM_SETPTAB_ENTRY (scm_def_errp
, pt
);
181 SCM_SETSTREAM (scm_def_errp
, (SCM
)err
);
182 scm_set_port_revealed_x (scm_def_errp
, SCM_MAKINUM (1));
185 scm_cur_inp
= scm_def_inp
;
186 scm_cur_outp
= scm_def_outp
;
187 scm_cur_errp
= scm_def_errp
;
190 scm_progargs
= SCM_BOOL_F
; /* vestigial */
191 scm_exitval
= SCM_BOOL_F
; /* vestigial */
193 scm_top_level_lookup_thunk_var
= SCM_BOOL_F
;
194 scm_system_transformer
= SCM_BOOL_F
;
196 /* Create an object to hold the root continuation.
198 SCM_NEWCELL (scm_rootcont
);
199 SCM_SETJMPBUF (scm_rootcont
, scm_must_malloc ((long) sizeof (regs
), "continuation"));
200 SCM_CAR (scm_rootcont
) = scm_tc7_contin
;
201 /* The root continuation if further initialized by scm_restart_stack. */
203 /* Create the look-aside stack for variables that are shared between
204 * captured continuations.
206 scm_continuation_stack
= scm_make_vector (SCM_MAKINUM (512), SCM_UNDEFINED
, SCM_UNDEFINED
);
207 /* The continuation stack is further initialized by scm_restart_stack. */
209 /* The remainder of stack initialization is factored out to another function so that
210 * if this stack is ever exitted, it can be re-entered using scm_restart_stack.
212 scm_restart_stack (base
);
217 scm_restart_stack (base
)
220 scm_dynwinds
= SCM_EOL
;
221 SCM_DYNENV (scm_rootcont
) = SCM_EOL
;
222 SCM_THROW_VALUE (scm_rootcont
) = SCM_EOL
;
223 #ifdef DEBUG_EXTENSIONS
224 SCM_DFRAME (scm_rootcont
) = last_debug_info_frame
= 0;
226 SCM_BASE (scm_rootcont
) = base
;
227 scm_continuation_stack_ptr
= SCM_MAKINUM (0);
231 static char remsg
[] = "remove\n#define ", addmsg
[] = "add\n#define ";
235 fixconfig (char *s1
, char *s2
, int s
)
238 fixconfig (s1
, s2
, s
)
246 fputs ("\nin ", stderr
);
247 fputs (s
? "setjump" : "scmfig", stderr
);
248 fputs (".h and recompile scm\n", stderr
);
260 if (HEAP_SEG_SIZE
!= j
)
261 fixconfig ("reduce", "size of HEAP_SEG_SIZE", 0);
264 if (sizeof (float) != sizeof (long))
265 fixconfig (remsg
, "SCM_SINGLES", 0);
266 #endif /* def SCM_SINGLES */
270 if (2 * SCM_BITSPERDIG
/ SCM_CHAR_BIT
> sizeof (long))
271 fixconfig (remsg
, "SCM_BIGDIG", 0);
272 #ifndef SCM_DIGSTOOBIG
273 if (SCM_DIGSPERLONG
* sizeof (SCM_BIGDIG
) > sizeof (long))
274 fixconfig (addmsg
, "SCM_DIGSTOOBIG", 0);
278 #ifdef SCM_STACK_GROWS_UP
279 if (((SCM_STACKITEM
*) & j
- stack_start_ptr
) < 0)
280 fixconfig (remsg
, "SCM_STACK_GROWS_UP", 1);
282 if ((stack_start_ptr
- (SCM_STACKITEM
*) & j
) < 0)
283 fixconfig (addmsg
, "SCM_STACK_GROWS_UP", 1);
291 typedef int setjmp_type
;
293 typedef long setjmp_type
;
298 * argc and argv are made the return values of program-arguments.
300 * in, out, and err, if not NULL, become the standard ports.
301 * If NULL is passed, your "initfunc" should set up the
304 * boot_cmd is a string containing a Scheme expression to evaluate
305 * to get things rolling.
307 * result is returned a string containing a printed result of evaluating
310 * the return value is:
311 * scm_boot_ok - evaluation concluded normally
312 * scm_boot_error - evaluation concluded with a Scheme error
313 * scm_boot_emem - allocation error mallocing *result
314 * scm_boot_ereenter - scm_boot_guile was called re-entrantly, which is
319 scm_boot_guile (result
, argc
, argv
, in
, out
, err
, init_func
, boot_cmd
)
326 void (*init_func
) ();
329 static int initialized
= 0;
332 setjmp_type setjmp_val
;
335 if (live
) /* This function is not re-entrant. */
337 return scm_boot_ereenter
;
342 scm_ints_disabled
= 1;
347 scm_restart_stack (&i
);
351 scm_ports_prehistory ();
352 scm_smob_prehistory ();
353 scm_tables_prehistory ();
354 scm_init_storage (0);
359 scm_start_stack (&i
, in
, out
, err
);
364 scm_init_arbiters ();
368 scm_init_continuations ();
369 #ifdef DEBUG_EXTENSIONS
375 scm_init_fdsocket ();
389 /* Excluding this until it's really needed makes the binary
390 * smaller after linking. */
397 scm_init_procprop ();
400 #ifdef DEBUG_EXTENSIONS
403 scm_init_stackchk ();
404 scm_init_strports ();
409 scm_init_print (); /* Requires struct */
411 scm_init_sequences ();
414 scm_init_strorder ();
415 scm_init_mbstrings ();
418 scm_init_variable ();
427 scm_progargs
= scm_makfromstrs (argc
, argv
);
428 scm_init_load_path ();
432 scm_block_gc
= 0; /* permit the gc to run */
433 /* ints still disabled */
438 command
= scm_makfrom0str (boot_cmd
);
440 setjmp_val
= setjmp (SCM_JMPBUF (scm_rootcont
));
442 #ifdef STACK_CHECKING
443 scm_stack_checking_enabled_p
= SCM_STACK_CHECKING_P
;
447 SCM last
= SCM_UNDEFINED
;
450 /* Call the initialization function passed in by the user, if
452 if (init_func
) (*init_func
) ();
454 /* Evaluate boot_cmd string. */
459 p
= scm_mkstrport (SCM_MAKINUM (0),
465 form
= scm_read (p
, SCM_BOOL_F
, SCM_BOOL_F
);
466 if (SCM_EOF_VAL
== form
)
468 last
= scm_eval_x (form
);
473 scm_restore_signals ();
474 /* This tick gives any pending
475 * asyncs a chance to run. This must be done after
476 * the call to scm_restore_signals.
480 scm_ints_disabled
= 1; /* Hopefully redundant but just to be sure. */
485 str_answer
= scm_strprint_obj (last
);
486 *result
= (char *)malloc (1 + SCM_LENGTH (str_answer
));
488 stat
= scm_boot_emem
;
491 memcpy (*result
, SCM_CHARS (str_answer
), SCM_LENGTH (str_answer
));
492 (*result
)[SCM_LENGTH (str_answer
)] = 0;
499 /* This is reached if an unhandled throw terminated Scheme.
500 * Such an occurence should be extremely unlikely -- it indicates
501 * a programming error in the boot code.
503 * Details of the bogus exception are stored in scm_exitval even
504 * though that isn't currently reflected in the return value.
508 scm_restore_signals ();
509 /* This tick gives any pending
510 * asyncs a chance to run. This must be done after
511 * the call to scm_restore_signals.
513 * Note that an unhandled exception during signal handling
514 * will put as back at the call to scm_restore_signals immediately
515 * preceeding. A sufficiently bogus signal handler could
516 * conceivably cause an infinite loop here.
520 scm_ints_disabled
= 1; /* Hopefully redundant but just to be sure. */
525 str_answer
= scm_strprint_obj (scm_exitval
);
526 *result
= (char *)malloc (1 + SCM_LENGTH (str_answer
));
528 stat
= scm_boot_emem
;
531 memcpy (*result
, SCM_CHARS (str_answer
), SCM_LENGTH (str_answer
));
532 (*result
)[SCM_LENGTH (str_answer
)] = 0;
533 stat
= scm_boot_error
;