Skip to content

Instantly share code, notes, and snippets.

@pyrmont
Forked from uvtc/Janet-bootstrapping-process.md
Last active March 23, 2021 04:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pyrmont/03b08a4db4a0b6b5600a1f384b834b0d to your computer and use it in GitHub Desktop.
Save pyrmont/03b08a4db4a0b6b5600a1f384b834b0d to your computer and use it in GitHub Desktop.

Building and Running janet

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 Amalgmation

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:

  1. The bodies of the relevant C source files are literally copied into the amalgmated file.

  2. 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

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:

  1. initialises the Janet virtual machine
  2. runs a number of tests
  3. reads the boot.janet file into a string
  4. executes the Janet code in src/boot/boot.janet using the janet_dobytes() function

Looking at boot.janet, we can see that file accomplishes multiple things.

  1. 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.

  2. It reads in the C source files that are used in the amalgamation and outputs them into janet.c.

  3. 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 in janet.c.

The Shell Client

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

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.

@pyrmont
Copy link
Author

pyrmont commented Mar 23, 2021

The links here are all to the versions of the files current at the time of writing (8ede16dc269d67d60609b495c404b3586569cf18).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment