-
-
Notifications
You must be signed in to change notification settings - Fork 44
Standard Driver
Unlike most languages, the Felix compiler generates libraries, not programs. There is one mandatory logical entry point, one standard optional entry point, a set of user defined C entry points, and an optional Python3 module entry point.
The Felix compiler gathers all global data into a single C struct which is called the thread frame. The initialisation process first constructs an object of this type, then calls the initialisation entry point passing a pointer to it as well as some other fixed data. The initialisation procedure create a closure bound to the thread frame, which when executed executes the top level user code, so as to initialise the library by completing the initialisation of the thread frame.
A library may contain a procedure with the special name flx_main
.
If present, the standard driver executes it after initialising the library.
It is provided to ensure there is a mechanism to ensure the sequencing
of operations, since the order of initialisation of components of the
thread frame is not fully determinate.
The client programmer can also provide any number of additional exported
entry points. Wrappers with extern "C"
visibility and conforming
to C ABI rules are generated.
In addition, if any python functions are exported, they are collected
into a standard Python3 module, which is given the extern "C"
name
required so the library can be loaded by CPython.
In order to pretend that a Felix generated library is a program, most programmers simply rely on the library initialisation code. Felix provides two linkage models.
With dynamic linkage, a shared library or DLL is built from the user
Felix code. In order to pretend this library is a program, two fixed
executables are provided, flx_run
and flx_arun
.
The main difference is flx_arun
can do asynchronous I/O, whereas
flx_run
is deliberately restricted to disable it. The driver
constructs an environment for Felix and then dynamically loads the
library, initialises it, and runs the flx_main
entry point if it exists.
The semantics of static linkage are similar. Felix generates an object file rather than a shared library, and statically links it to a the driver using a compiler generated bridging stub. The bridging stub maps the fix entry point names the driver object uses to those specific to the library being used.