diff options
author | Simon Marlow <marlowsd@gmail.com> | 2011-04-12 13:49:09 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2011-04-12 15:48:28 +0100 |
commit | a52ff7619e8b7d74a9d933d922eeea49f580bca8 (patch) | |
tree | e748ba2054b76fe41c600c7cac2b015de3c57248 /docs/users_guide/ffi-chap.xml | |
parent | 5463b55b7dadc1e9918edb2d8666bf3ed195bc61 (diff) | |
download | haskell-a52ff7619e8b7d74a9d933d922eeea49f580bca8.tar.gz |
Change the way module initialisation is done (#3252, #4417)
Previously the code generator generated small code fragments labelled
with __stginit_M for each module M, and these performed whatever
initialisation was necessary for that module and recursively invoked
the initialisation functions for imported modules. This appraoch had
drawbacks:
- FFI users had to call hs_add_root() to ensure the correct
initialisation routines were called. This is a non-standard,
and ugly, API.
- unless we were using -split-objs, the __stginit dependencies would
entail linking the whole transitive closure of modules imported,
whether they were actually used or not. In an extreme case (#4387,
#4417), a module from GHC might be imported for use in Template
Haskell or an annotation, and that would force the whole of GHC to
be needlessly linked into the final executable.
So now instead we do our initialisation with C functions marked with
__attribute__((constructor)), which are automatically invoked at
program startup time (or DSO load-time). The C initialisers are
emitted into the stub.c file. This means that every time we compile
with -prof or -hpc, we now get a stub file, but thanks to #3687 that
is now invisible to the user.
There are some refactorings in the RTS (particularly for HPC) to
handle the fact that initialisers now get run earlier than they did
before.
The __stginit symbols are still generated, and the hs_add_root()
function still exists (but does nothing), for backwards compatibility.
Diffstat (limited to 'docs/users_guide/ffi-chap.xml')
-rw-r--r-- | docs/users_guide/ffi-chap.xml | 35 |
1 files changed, 2 insertions, 33 deletions
diff --git a/docs/users_guide/ffi-chap.xml b/docs/users_guide/ffi-chap.xml index 47c0f01ba9..97a237876f 100644 --- a/docs/users_guide/ffi-chap.xml +++ b/docs/users_guide/ffi-chap.xml @@ -245,18 +245,11 @@ extern HsInt foo(HsInt a0);</programlisting> #include "foo_stub.h" #endif -#ifdef __GLASGOW_HASKELL__ -extern void __stginit_Foo ( void ); -#endif - int main(int argc, char *argv[]) { int i; hs_init(&argc, &argv); -#ifdef __GLASGOW_HASKELL__ - hs_add_root(__stginit_Foo); -#endif for (i = 0; i < 5; i++) { printf("%d\n", foo(2500)); @@ -283,26 +276,6 @@ int main(int argc, char *argv[]) (i.e. those arguments between <literal>+RTS...-RTS</literal>).</para> - <para>Next, we call - <function>hs_add_root</function><indexterm><primary><function>hs_add_root</function></primary> - </indexterm>, a GHC-specific interface which is required to - initialise the Haskell modules in the program. The argument - to <function>hs_add_root</function> should be the name of the - initialization function for the "root" module in your program - - in other words, the module which directly or indirectly - imports all the other Haskell modules in the program. In a - standalone Haskell program the root module is normally - <literal>Main</literal>, but when you are using Haskell code - from a library it may not be. If your program has multiple - root modules, then you can call - <function>hs_add_root</function> multiple times, one for each - root. The name of the initialization function for module - <replaceable>M</replaceable> is - <literal>__stginit_<replaceable>M</replaceable></literal>, and - it may be declared as an external function symbol as in the - code above. Note that the symbol name should be transformed - according to the Z-encoding:</para> - <informaltable> <tgroup cols="2" align="left" colsep="1" rowsep="1"> <thead> @@ -380,9 +353,6 @@ int main(int argc, char *argv[]) // Initialize Haskell runtime hs_init(&argc, &argv); - // Tell Haskell about all root modules - hs_add_root(__stginit_Foo); - // do any other initialization here and // return false if there was a problem return HS_BOOL_TRUE; @@ -394,7 +364,7 @@ int main(int argc, char *argv[]) </programlisting> <para>The initialisation routine, <literal>mylib_init</literal>, calls - <literal>hs_init()</literal> and <literal>hs_add_root()</literal> as + <literal>hs_init()</literal> as normal to initialise the Haskell runtime, and the corresponding deinitialisation function <literal>mylib_end()</literal> calls <literal>hs_exit()</literal> to shut down the runtime.</para> @@ -599,8 +569,7 @@ int main(int argc, char *argv[]) invoke <literal>foreign export</literal>ed functions from multiple OS threads concurrently. The runtime system must be initialised as usual by - calling <literal>hs_init()</literal> - and <literal>hs_add_root</literal>, and these calls must + calling <literal>hs_init()</literal>, and this call must complete before invoking any <literal>foreign export</literal>ed functions.</para> </sect3> |