Compiler implementation
Factor handbook » The implementation » Optimizing compiler

Prev:Calling the optimizing compiler


The compiler vocabulary, in addition to providing the user-visible words of the compiler, implements the main compilation loop.

Once compiled, a word is added to the assoc stored in the compiled variable. When compilation is complete, this assoc is passed to modify-code-heap.

The compile-word word performs the actual task of compiling an individual word. The process proceeds as follows:
The frontend word calls build-tree. If this fails, the error is passed to deoptimize. The logic for ignoring certain compile errors generated for inline words and macros is located here. If the error is not ignorable, it is added to the global compiler-errors assoc (see Compiler errors).
If the word contains a breakpoint, compilation ends here. Otherwise, all remaining steps execute until machine code is generated. Any further errors thrown by the compiler are not reported as compile errors, but instead are ordinary exceptions. This is because they indicate bugs in the compiler, not errors in user code.
The frontend word then calls optimize-tree. This produces the final optimized tree IR, and this stage of the compiler is complete.
The backend word calls build-cfg followed by optimize-cfg and a few other stages. Finally, it calls generate.

If compilation fails, the word is stored in the compiled assoc with a value of f. This causes the VM to compile the word with the non-optimizing compiler.

Calling modify-code-heap is handled not by the compiler vocabulary, but rather compiler.units. The optimizing compiler merely provides an implementation of the recompile generic word.