1 /**************************************************************************/
2 /* */
3 /* OCaml */
4 /* */
5 /* Xavier Leroy and Damien Doligez, INRIA Rocquencourt */
6 /* */
7 /* Copyright 1996 Institut National de Recherche en Informatique et */
8 /* en Automatique. */
9 /* */
10 /* All rights reserved. This file is distributed under the terms of */
11 /* the GNU Lesser General Public License version 2.1, with the */
12 /* special exception on linking described in the file LICENSE. */
13 /* */
14 /**************************************************************************/
15
16 #define CAML_INTERNALS
17
18 /* Start-up code */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "caml/callback.h"
23 #include "caml/backtrace.h"
24 #include "caml/custom.h"
25 #include "caml/debugger.h"
26 #include "caml/fail.h"
27 #include "caml/freelist.h"
28 #include "caml/gc.h"
29 #include "caml/gc_ctrl.h"
30 #include "caml/intext.h"
31 #include "caml/memory.h"
32 #include "caml/misc.h"
33 #include "caml/mlvalues.h"
34 #include "caml/osdeps.h"
35 #include "caml/printexc.h"
36 #include "caml/stack.h"
37 #include "caml/startup_aux.h"
38 #include "caml/sys.h"
39 #ifdef WITH_SPACETIME
40 #include "caml/spacetime.h"
41 #endif
42 #ifdef HAS_UI
43 #include "caml/ui.h"
44 #endif
45
46 extern int caml_parser_trace;
47 char * caml_code_area_start, * caml_code_area_end;
48 struct ext_table caml_code_fragments_table;
49
50 /* Initialize the atom table and the static data and code area limits. */
51
52 struct segment { char * begin; char * end; };
53
init_static(void)54 static void init_static(void)
55 {
56 extern struct segment caml_data_segments[], caml_code_segments[];
57 int i;
58 struct code_fragment * cf;
59
60 caml_init_atom_table ();
61
62 for (i = 0; caml_data_segments[i].begin != 0; i++) {
63 /* PR#5509: we must include the zero word at end of data segment,
64 because pointers equal to caml_data_segments[i].end are static data. */
65 if (caml_page_table_add(In_static_data,
66 caml_data_segments[i].begin,
67 caml_data_segments[i].end + sizeof(value)) != 0)
68 caml_fatal_error("Fatal error: not enough memory for initial page table");
69 }
70
71 caml_code_area_start = caml_code_segments[0].begin;
72 caml_code_area_end = caml_code_segments[0].end;
73 for (i = 1; caml_code_segments[i].begin != 0; i++) {
74 if (caml_code_segments[i].begin < caml_code_area_start)
75 caml_code_area_start = caml_code_segments[i].begin;
76 if (caml_code_segments[i].end > caml_code_area_end)
77 caml_code_area_end = caml_code_segments[i].end;
78 }
79 /* Register the code in the table of code fragments */
80 cf = caml_stat_alloc(sizeof(struct code_fragment));
81 cf->code_start = caml_code_area_start;
82 cf->code_end = caml_code_area_end;
83 cf->digest_computed = 0;
84 caml_ext_table_init(&caml_code_fragments_table, 8);
85 caml_ext_table_add(&caml_code_fragments_table, cf);
86 }
87
88 /* These are termination hooks used by the systhreads library */
89 struct longjmp_buffer caml_termination_jmpbuf;
90 void (*caml_termination_hook)(void *) = NULL;
91
92 extern value caml_start_program (void);
93 extern void caml_init_ieee_floats (void);
94 extern void caml_init_signals (void);
95
96 #if defined(_MSC_VER) && __STDC_SECURE_LIB__ >= 200411L
97
98 /* PR 4887: avoid crash box of windows runtime on some system calls */
99 extern void caml_install_invalid_parameter_handler();
100
101 #endif
102
caml_startup_exn(char ** argv)103 value caml_startup_exn(char **argv)
104 {
105 char * exe_name, * proc_self_exe;
106 char tos;
107
108 #ifdef WITH_SPACETIME
109 caml_spacetime_initialize();
110 #endif
111 caml_init_frame_descriptors();
112 caml_init_ieee_floats();
113 #if defined(_MSC_VER) && __STDC_SECURE_LIB__ >= 200411L
114 caml_install_invalid_parameter_handler();
115 #endif
116 caml_init_custom_operations();
117 caml_top_of_stack = &tos;
118 #ifdef DEBUG
119 caml_verb_gc = 0x3F;
120 #endif
121 caml_parse_ocamlrunparam();
122 #ifdef DEBUG
123 caml_gc_message (-1, "### OCaml runtime: debug mode ###\n", 0);
124 #endif
125 caml_init_gc (caml_init_minor_heap_wsz, caml_init_heap_wsz,
126 caml_init_heap_chunk_sz, caml_init_percent_free,
127 caml_init_max_percent_free, caml_init_major_window);
128 init_static();
129 caml_init_signals();
130 caml_init_backtrace();
131 caml_debugger_init (); /* force debugger.o stub to be linked */
132 exe_name = argv[0];
133 if (exe_name == NULL) exe_name = "";
134 proc_self_exe = caml_executable_name();
135 if (proc_self_exe != NULL)
136 exe_name = proc_self_exe;
137 else
138 exe_name = caml_search_exe_in_path(exe_name);
139 caml_sys_init(exe_name, argv);
140 if (sigsetjmp(caml_termination_jmpbuf.buf, 0)) {
141 if (caml_termination_hook != NULL) caml_termination_hook(NULL);
142 return Val_unit;
143 }
144 return caml_start_program();
145 }
146
caml_startup(char ** argv)147 void caml_startup(char **argv)
148 {
149 value res = caml_startup_exn(argv);
150
151 if (Is_exception_result(res)) {
152 caml_fatal_uncaught_exception(Extract_exception(res));
153 }
154 }
155
caml_main(char ** argv)156 void caml_main(char **argv)
157 {
158 caml_startup(argv);
159 }
160