Hazelnut's Architecture

ImgArchitecture The Hazelnut project is splitted into three main roles:

  • the Loader which loads and contains a kernel description
  • the Builder bootstraps the environment and generates the objects based on a seed
  • the serializer writes the objects into an Smalltalk image File

The key point is that replacing any of those components, may lead to change the kind of bootstrap it is creating: different behavioral models, different image formats.

The loader and builder components are an exclusive part of the Hazelnut project, while the serializer we are currently using is a project by itself.

The Loader

In the stable version 2.0 of Hazelnut the Loader is an object that creates a Seed object. A seed is a description of the kernel that will be generated. It does know how which behavior definitions -such as classes, methods and traits- should be created, and how to assemble and initialize them.

In Hazelnut the loader role is mainly played by a Seed class like in:

 seed := PharoSeed new.
 seed fromDirectoryNamed: 'PharoKernel/source'.
 seed processInitializer: [ :env | (env at: #HazelZygote) freshProcessQuitting ].
 seed buildSeed.

This example seed knows how to generate a seed for a Pharo image, loads the source code definitions from source code files, and is told which will be the new process the image will have.

PharoSeed loads the sourcecode and parses it using a PetitParser to build the behavior definitions.

Once built the seed, we have to build the kernel using...

The Builder

The builder loads the definitions in the seed and generates the real objects that will end up in the kernel:

builder := HazelKernelBuilder new.
builder kernelSpec: seed.
builder buildKernel.

The current builder's internal process is the following:

buildKernel
    self
        declareGlobalVariables;
        buildBehaviors;
        installMethods;
        configureBehaviors;
        initializeImage

Current implementation takes the method source definitions and compiles them using the Opal Compiler.

The Serializer

The serializer takes the bootstrapped graph of objects and serializes them into an image file. Nowadays the component fulfilling this role is the project ImageWriter which is a replacement of the old SystemTracer with the objective of having a better model and understand the image format easily.

ImageWriter right now supports the writing of any graph from a given root, which allows someone to write an image from any object graph, without the need of writing the complete environment.

The part of the execution for the writer that really matters is the following:

writer := HzImageWriter new.
writer format: HzCogImageFormat new.
"a seed may apply some substitutions while writing"
seed appySubstitutionsOn: writer forEnvironment: builder bootstrapEnvironment.
writer imageFileName: 'kernel'.
writer writeImage: builder bootstrapEnvironment.