How the TypePHP Compiler Achieves Self-Hosting: Bootstrap Pipeline and Two-Phase Compilation
The TypePHP compiler achieves full self-hosting by using a pure-PHP bootstrap script to load its own source modules, then executing a two-phase prepare-and-convert pipeline that compiles its PHP source into a native binary capable of replacing the original bootstrap script.
The swoole/typephp repository implements a rare feat in compiler construction: a production-quality AOT (Ahead-of-Time) compiler written entirely in PHP that compiles itself into native machine code. This self-hosting architecture eliminates dependency on external compiler toolchains during the build process, allowing TypePHP to bootstrap from pure PHP source to optimized native binary.
The Bootstrap Entry Point
Self-hosting begins with the executable script at bin/tpc.php. This entry point loads the compiler's runtime environment by requiring a specific sequence of PHP modules:
require __DIR__ . '/bootstrap.php';
require TYPEPHP_ROOT_PATH . '/src/polyfills.php';
require TYPEPHP_ROOT_PATH . '/src/gen_stub.php';
require TYPEPHP_ROOT_PATH . '/src/compiler.php';
The constant TYPEPHP_PHP_SCRIPT_ENTRY distinguishes this PHP-hosted execution from the already-compiled binary version. When present, the runtime interprets the source rather than executing native code, establishing the foundation for the self-hosting loop.
Two-Phase Compilation Pipeline
The main() function in src/compiler.php orchestrates the transformation through two distinct phases that ensure deterministic output.
Prepare Phase: Symbol Model Construction
During prepare, the compiler parses every PHP file in the target source tree—including its own source when self-hosting—and constructs a complete symbol model without allocating runtime IDs. This phase performs semantic analysis and type inference across the entire codebase before any code generation occurs.
Convert Phase: AST Lowering to C++17
The convert phase transforms the prepared Abstract Syntax Tree (AST) into C++17 source code. TypePHP then invokes the native compiler (Clang) to generate the final binary. As implemented in the source, this pipeline follows the sequence: PHP source → parse → lower → native compiler → binary.
The Self-Hosting Mechanism
TypePHP achieves self-hosting by treating its own source code as a standard compilation target. When you invoke the compiler without the --compiler flag, it executes the same main() function used for any project build.
Compiling the Compiler Itself
To create the self-hosted binary, run the bootstrap script against its own entry point:
# Bootstrap phase: compile the compiler using PHP interpreter
php bin/tpc.php bin/tpc.php -O2 -j 8
This command produces a native binary ./tpc that contains the compiled version of the compiler. The resulting binary can then compile other PHP projects without requiring the PHP runtime:
# Self-hosted phase: use the native binary
./tpc examples/yield.php -O3 -r -- --help
Deterministic Build Guarantees
Because TypePHP uses identical two-phase logic for both bootstrapping and self-hosted compilation, the binary produced from PHP source remains deterministic. The compiler applies the same symbol resolution and code generation paths to its own source as it does to user projects, preventing "bootstrap drift" where the compiled compiler diverges from its source representation.
Native Type Assignment for Cross-Runtime Consistency
A critical technical requirement for self-hosting is ensuring that PHP variables maintain consistent behavior across both interpreted and compiled execution contexts. In src/CompilerBase.php, the compiler assigns each PHP local variable a fixed C++ type during the conversion phase. The source code explicitly notes: "The self-hosted compiler assigns one fixed C++ type to each PHP local variable."
This deterministic typing ensures that when the compiler runs as PHP source (during bootstrap) versus as compiled C++ (after self-hosting), variable semantics remain identical. Without this guarantee, the compiler might produce different outputs when interpreting its own source versus executing its compiled form, breaking the self-hosting invariant.
Summary
- Pure PHP Bootstrap: The
bin/tpc.phpscript loads compiler modules viarequirestatements, establishing the entry point for self-hosting. - Two-Phase Pipeline: The
main()function insrc/compiler.phpexecutes prepare (symbol model) and convert (C++ generation) phases deterministically. - Self-Compilation: TypePHP compiles its own source tree using the same pipeline as user projects, producing the
./tpcnative binary. - Type Consistency: Fixed C++ type assignment in
CompilerBase.phpensures identical behavior between interpreted and compiled execution. - Deterministic Output: Identical compilation paths for bootstrap and self-hosted builds prevent divergence between source and binary.
Frequently Asked Questions
What does "self-hosting" mean for the TypePHP compiler?
Self-hosting means the TypePHP compiler is written entirely in PHP and can compile its own source code into a native executable. As stated in the repository README, "the tpc compiler binary is built by compiling the compiler's own PHP source code with TypePHP." This creates a feedback loop where the compiler builds itself through successive recompilations.
How does the bootstrap process work without a pre-existing binary?
The bootstrap relies on the PHP interpreter to execute bin/tpc.php, which loads the compiler's source modules from src/compiler.php and related files. This interpreted execution compiles the TypePHP source into a native binary, after which the system no longer requires the PHP interpreter for compilation tasks.
Why is deterministic typing crucial for TypePHP's self-hosting?
Deterministic typing ensures that each PHP variable receives exactly one fixed C++ type during compilation, regardless of whether the compiler is running as interpreted PHP (during bootstrap) or as compiled C++ (after self-hosting). This prevents semantic differences that would cause the compiled compiler to generate different code than the interpreted version, which would break the self-hosting guarantee.
Can the self-hosted TypePHP compiler compile any PHP project?
Yes, the self-hosted binary uses the same main() function and two-phase pipeline as the bootstrap version. Once built, the native ./tpc binary can compile any compatible PHP project using the command ./tpc <source> [options], offering the same optimization levels and code generation capabilities as the bootstrap process.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →