[MLton] MLton and shared libraries

Stephen Weeks MLton@mlton.org
Thu, 14 Apr 2005 10:35:43 -0700

> What was is Matthew said, I should look out for?
>  > 1) getting the shared library to initialize the SML heap and
>  > run all the top-level effects (such as allocating and initializing
>  > globals) of the program with exported functions,
> I am a little unsure whether all globals that can't simply be output
> as C literals are initialized in the same way as the reals.

Currently, all the globals (except for reals) are initialized by
running some code.  To turn that into C literals, one would have to
interpret that code at compile time, which seems like a pain.  The
easiest way to solve (1) is to run the SML program (i.e. PrepFarJump
followed by the trampoline).  When one writes a shared library in
MLton, the understanding is that all SML code at the toplevel is run
when the library is initialized.

> The other thing to worry about was:
>  > 2) ensuring that the
>  > suffix of the top-level program does not exit, but instead enters a state
>  > where the program is waiting to service exported function requests.
> to which Weeks added
>  > I hope this can be easily achieved using Thread_returnToC, as it is
>  > done in SML functions exported via _export.  See the "register"
>  > function in basis-library/mlton/thread.sml.
> Is this neccessary if one puts the initizalization part of main()
> into a separate function?

The point here is related to the idea for (1) above.  Right now, the
basis library causes code to be added to the end of every program that
causes the program to call exit() once all the toplevel code has been
executed.  See the call to "setSuffix" in
basis-library/mlton/mlton.sml.  It should be simple enough to add a
boolean compile-time constant, "isSharedLibrary" or somesuch, and to
tweak things so that when isSharedLibrary is true, the suffix returns
to the C initialization code instead of calling exit.

> A tangential question: Is it possible for main() to be called
> several times (perhaps due to multiple threads)? Otherwise the
> if in:
> 	if (gcState.isOriginal) {					\
> 		real_Init();						\
> 		PrepFarJump(mc, ml);					\
> 	} else {							\
> 		/* Return to the saved world */				\
> 		nextFun = *(int*)(gcState.stackTop - WORD_SIZE);	\
> 		cont.nextChunk = nextChunks[nextFun];			\
> 	}								\
> seems unneccesary.

It is not possible for main to be called several times.  The "if
(gcState.isOriginal)" is to distinguish between when the executable is
called with a saved world and when it isn't.