[reply redirected to ffi@haskell.org] John Meacham <john@repetae.net> writes:
I may be missing something obvious here, but from the current FFI spec it appears that it is impossible to create libraries in haskell which are meant to be called from c code without running into undefined behavior. The problem is in the definition of hs_init() and hs_exit() . now, it is acceptable to have hs_init and hs_exit called in the initialization and finalization of your library, but the problem arrises when you link against more than one library which is implemented in haskell, suddenly whichever library is initialized secondly segfaults! (or whatever undefined behaviour means.). programs could suddenly stop working when a library is changed from a c implementation to a haskell one, which seems to be a bad thing.
Hmmm, I see what you mean.
proposed fix: allow nested calls to hs_init, hs_exit, a counter is incremented when hs_init is called more than once, and decremented on hs_exit. only the last call to hs_exit will actually do whatever needs to be done.
The hs_init function takes arguments - what if each call to hs_init specifies a different set of arguments? How about: hs_set_hs_argv (int argc, char *argv[]); hs_set_prog_argv (int argc, char *argv[]); hs_init (); hs_exit (); Where: hs_set_hs_argv sets command line parameters for the Haskell runtime system It can be called at most once and that call must be before the first call to hs_init Warning! The flags are not remotely portable between different Haskell runtimes. hs_set_prog_argv sets arguments seen by getProgName and getArgs It can be called at most once and that call must be before the first call to hs_init hs_init initializes the Haskell runtime It can be called multiple times and must be called before the first call to any function exported by the Haskell code. hs_exit finalizes the Haskell runtime hs_init and hs_exit are required to satisfy the usual bracketing rules: 1) At any time, the number of calls that have been made to hs_exit must be no more than the number of calls that have been made to hs_init. 2) If the number of calls to hs_exit is equal to the number of calls to hs_init, then no further calls to hs_init may be made. By the way, the name 'hs_exit' is a little confusing - I expected it to have an ExitCode argument. 'hs_fini' would better match its actual purpose.
note that this cannot be implemented by the programmer himself since there might be several third party libraries also implemented in haskell which an app wishes to link against.
You can implement the modified API (or your modified semantics) quite readily as a little library which you link against your program. All you have to do is tweak the names a little (e.g., s/hs/HS/) to avoid name clashes. -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/