Skip to content
John Skaller edited this page Dec 7, 2018 · 1 revision

Entry Points

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.

Initialisation Procedure

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.

Optional Mainline

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.

Optional extern C entry points

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.

Optional Python3 module

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.

The Standard Driver

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.

Dynamic Linkage

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.

Static Linkage

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.