summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Shinwell <mshinwell@gmail.com>2017-02-21 11:49:12 +0100
committerMark Shinwell <mshinwell@gmail.com>2017-02-21 11:49:12 +0100
commit766d970e7890d41b63ebf164b38fa5365872ee34 (patch)
tree24d6f9ff6a1968684c400293582c659959a46a20
parentb35b7229ee3695fee3e0b9dc5ca6aa119e420a9e (diff)
downloadocaml-766d970e7890d41b63ebf164b38fa5365872ee34.tar.gz
Add caml_startup_exn
-rw-r--r--Changes2
-rw-r--r--asmrun/startup.c20
-rw-r--r--bytecomp/bytelink.ml7
-rw-r--r--byterun/caml/callback.h1
-rw-r--r--byterun/caml/startup.h6
-rw-r--r--byterun/startup.c18
-rw-r--r--manual/manual/cmds/intf-c.etex12
7 files changed, 54 insertions, 12 deletions
diff --git a/Changes b/Changes
index aa1f959436..9d8f8094e3 100644
--- a/Changes
+++ b/Changes
@@ -44,6 +44,8 @@ Next version (4.05.0):
passed to the new functions are handled by the garbage collector.
(Gabriel Scherer, review by Mark Shinwell, request by Immanuel Litzroth)
+- GPR#953 (was MPR#385): Add caml_startup_exn (Mark Shinwell)
+
- GPR#891: Use -fno-builtin-memcmp when building runtime with gcc.
(Leo White)
diff --git a/asmrun/startup.c b/asmrun/startup.c
index 8f469aedef..70bbc4369d 100644
--- a/asmrun/startup.c
+++ b/asmrun/startup.c
@@ -100,10 +100,9 @@ extern void caml_install_invalid_parameter_handler();
#endif
-void caml_main(char **argv)
+value caml_startup_exn(char **argv)
{
char * exe_name, * proc_self_exe;
- value res;
char tos;
#ifdef WITH_SPACETIME
@@ -140,14 +139,21 @@ void caml_main(char **argv)
caml_sys_init(exe_name, argv);
if (sigsetjmp(caml_termination_jmpbuf.buf, 0)) {
if (caml_termination_hook != NULL) caml_termination_hook(NULL);
- return;
+ return Val_unit;
}
- res = caml_start_program();
- if (Is_exception_result(res))
- caml_fatal_uncaught_exception(Extract_exception(res));
+ return caml_start_program();
}
void caml_startup(char **argv)
{
- caml_main(argv);
+ value res = caml_startup_exn(argv);
+
+ if (Is_exception_result(res)) {
+ caml_fatal_uncaught_exception(Extract_exception(res));
+ }
+}
+
+void caml_main(char **argv)
+{
+ caml_startup(argv);
}
diff --git a/bytecomp/bytelink.ml b/bytecomp/bytelink.ml
index 660c1eaaa2..8f82fc96d0 100644
--- a/bytecomp/bytelink.ml
+++ b/bytecomp/bytelink.ml
@@ -501,6 +501,13 @@ let link_bytecode_as_c ppf tolink outfile =
\n caml_sections, sizeof(caml_sections),\
\n argv);\
\n}\
+\nvalue caml_startup_exn(char ** argv)\
+\n{\
+\n return caml_startup_code_exn(caml_code, sizeof(caml_code),\
+\n caml_data, sizeof(caml_data),\
+\n caml_sections, sizeof(caml_sections),\
+\n argv);\
+\n}\
\n#ifdef __cplusplus\
\n}\
\n#endif\n";
diff --git a/byterun/caml/callback.h b/byterun/caml/callback.h
index 58d3faffa1..147eb71811 100644
--- a/byterun/caml/callback.h
+++ b/byterun/caml/callback.h
@@ -49,6 +49,7 @@ CAMLextern void caml_iterate_named_values(caml_named_action f);
CAMLextern void caml_main (char ** argv);
CAMLextern void caml_startup (char ** argv);
+CAMLextern value caml_startup_exn (char ** argv);
CAMLextern int caml_callback_depth;
diff --git a/byterun/caml/startup.h b/byterun/caml/startup.h
index 3df4206aa4..0c38dac0f1 100644
--- a/byterun/caml/startup.h
+++ b/byterun/caml/startup.h
@@ -29,6 +29,12 @@ CAMLextern void caml_startup_code(
char *section_table, asize_t section_table_size,
char **argv);
+CAMLextern value caml_startup_code_exn(
+ code_t code, asize_t code_size,
+ char *data, asize_t data_size,
+ char *section_table, asize_t section_table_size,
+ char **argv);
+
enum { FILE_NOT_FOUND = -1, BAD_BYTECODE = -2 };
extern int caml_attempt_open(char **name, struct exec_trailer *trail,
diff --git a/byterun/startup.c b/byterun/startup.c
index 219baa70b3..3b388b45fe 100644
--- a/byterun/startup.c
+++ b/byterun/startup.c
@@ -396,13 +396,12 @@ CAMLexport void caml_main(char **argv)
/* Main entry point when code is linked in as initialized data */
-CAMLexport void caml_startup_code(
+CAMLexport value caml_startup_code_exn(
code_t code, asize_t code_size,
char *data, asize_t data_size,
char *section_table, asize_t section_table_size,
char **argv)
{
- value res;
char * cds_file;
char * exe_name;
@@ -461,7 +460,20 @@ CAMLexport void caml_startup_code(
caml_sys_init(exe_name, argv);
/* Execute the program */
caml_debugger(PROGRAM_START);
- res = caml_interprete(caml_start_code, caml_code_size);
+ return caml_interprete(caml_start_code, caml_code_size);
+}
+
+CAMLexport void caml_startup_code(
+ code_t code, asize_t code_size,
+ char *data, asize_t data_size,
+ char *section_table, asize_t section_table_size,
+ char **argv)
+{
+ value res;
+
+ res = caml_startup_code_exn(code, code_size, data, data_size,
+ section_table, section_table_size,
+ argv);
if (Is_exception_result(res)) {
caml_exn_bucket = Extract_exception(res);
if (caml_debugger_in_use) {
diff --git a/manual/manual/cmds/intf-c.etex b/manual/manual/cmds/intf-c.etex
index 461ae824d8..d89430cf79 100644
--- a/manual/manual/cmds/intf-c.etex
+++ b/manual/manual/cmds/intf-c.etex
@@ -1543,6 +1543,13 @@ parameter containing the command-line parameters. Unlike "caml_main",
this "argv" parameter is used only to initialize "Sys.argv", but not
for finding the name of the executable file.
+The "caml_startup" function calls the uncaught exception handler (or
+enters the debugger, if running under ocamldebug) if an exception escapes
+from a top-level module initialiser. Such exceptions may be caught in the
+C code by instead using the "caml_startup_exn" function and testing the result
+using {\tt Is_exception_result} (followed by {\tt Extract_exception} if
+appropriate).
+
The "-output-obj" option can also be used to obtain the C source file.
More interestingly, the same option can also produce directly a shared
library (".so" file, ".dll" under Windows) that contains the OCaml
@@ -1558,7 +1565,8 @@ The native-code compiler "ocamlopt" also supports the "-output-obj"
option, causing it to output a C object file or a shared library
containing the native code for all OCaml modules on the command-line,
as well as the OCaml startup code. Initialization is performed by
-calling "caml_startup" as in the case of the bytecode compiler.
+calling "caml_startup" (or "caml_startup_exn") as in the case of the
+bytecode compiler.
For the final linking phase, in addition to the object file produced
by "-output-obj", you will have to provide the OCaml runtime
@@ -1675,7 +1683,7 @@ runtime library) by "libasmrun.a" (the native-code runtime library).)
Now, we can use the two functions "fib" and "format_result" in any C
program, just like regular C functions. Just remember to call
-"caml_startup" once before.
+"caml_startup" (or "caml_startup_exn") once before.
\begin{verbatim}
/* File main.c -- a sample client for the OCaml functions */