The janet
binary is a combined REPL and runtime. The runtime includes a compiler that compiles Janet code on the fly before executing that code.
The janet
binary is built from two C source files: an amalgamated file (janet.c
) and a shell client (shell.c
). These files can be compiled by any compatible C compiler.
The amalgamated file, janet.c
, is not included in Janet's repository but is generated during the 'bootstrapping' phase of the Janet build process. The generation of the amalgamation involves two steps:
-
The bodies of the relevant C source files are literally copied into the amalgmated file.
-
The core functions that are written in Janet (and are in
src/boot/boot.janet
) are marshaled into a byte array by the bootstrapper and that byte array is also copied into the amalgamated file.
Both of these steps are performed by the bootstrapper.
The bootstrapper is the compiled form of src/boot/boot.c
. When you compile Janet from source, the bootstrapper is first compiled from boot.c
.
The bootstrapper contains a main()
function that performs the following steps when it is executed:
- initialises the Janet virtual machine
- runs a number of tests
- reads the
boot.janet
file into a string - executes the Janet code in
src/boot/boot.janet
using thejanet_dobytes()
function
Looking at boot.janet
, we can see that file accomplishes multiple things.
-
It creates the core environment. It does this by evaluating the function definitions and bindings that begin the file and comprise most of its contents.
-
It reads in the C source files that are used in the amalgamation and outputs them into
janet.c
. -
It marshalls the core environment into a byte array and then outputs this byte array into a variable called
janet_core_image
that is defined injanet.c
.
The shell client, src/mainclient/shell.c
, is included in the Janet repository. It primarily consists of functions that are relevant for the REPL. However, it also includes the main
function used in the janet
binary.
The shell client's main
function initalises the Janet virtual machine, loads the core environment (using janet_core_env()
) and then runs the cli-main
function together with the arguments passed to the shell client. Since the cli-main
function is defined in boot.janet
, it is part of the core environent.
The core environment is loaded by the C function janet_core_env()
. This function is defined in janet/src/core/corelib.c
and loads the environment by unmarshalling the byte array in the janet_core_image
variable using Janet's janet_unmarshal
function.
When a user runs the janet
binary, the core environment is loaded. As a result, the larger the core environment (i.e. the more functions and bindings in janet/src/boot/boot.janet
), the longer the startup time.
The links here are all to the versions of the files current at the time of writing (8ede16dc269d67d60609b495c404b3586569cf18).