Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bin/compile.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ function run(string $filename, string $code, array $options): void
if ('' !== $normalized && str_contains($normalized, '/test/bootstrap-aot/')) {
// M3 native emit TU: self-host M3 allowlist (not full bootstrap JIT) (#1937, #1983).
$m3Driver = getenv('PHP_COMPILER_M3_COMPILE_DRIVER');
$m3EmitNative = str_contains($normalized, 'compile_smoke_m3_emit_native_entry.php')
$m3EmitNative = (str_contains($normalized, 'compile_smoke_m3_emit_native_entry.php')
|| str_contains($normalized, 'helloworld_m3_emit_native_entry.php'))
&& ('1' === $m3Driver || 'true' === strtolower((string) $m3Driver));
if ($m3EmitNative) {
putenv('PHP_COMPILER_SELFHOST_AOT=1');
Expand Down
13 changes: 11 additions & 2 deletions bin/phpc.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* phpc lint --all <dir-or-file> [--json]
* phpc init [--profile default|miniwebapp|sessionsweb|apijson|fileupload] [--force] [target-dir]
* phpc test [--fast] [--bootstrap] [--bootstrap-strict] [-- phpunit/ci-local args...]
* phpc doctor [--gates] [--no-lint] [--jit-probe] [--aot-project-probe [dir]] Env probes; --gates adds 005-SessionsWeb ladder (#1903, #1969)
* phpc doctor [--gates] [--selfhost] [--no-lint] [--jit-probe] [--aot-project-probe [dir]] Env probes; --gates MiniWebApp; --selfhost NS2 (#2053)
* phpc validate-manifest [dir] Validate phpc.json schema and paths (issue #263)
*/

Expand Down Expand Up @@ -69,9 +69,10 @@
Scaffold web project (default, miniwebapp, sessionsweb, apijson, or fileupload)
phpc test [--fast] [args...] Run ci-local.sh (full) or ci-fast.sh (no LLVM)
phpc test --bootstrap [--strict] Bootstrap subset (inventory + spine sync; #1961)
phpc doctor [--gates] [--no-lint] [--jit-probe] [--aot-project-probe [dir]]
phpc doctor [--gates] [--selfhost] [--no-lint] [--jit-probe] [--aot-project-probe [dir]]
Probe environment; LLVM/JIT readiness (#717, #746)
--gates MiniWebApp ladder + NS1/NS2 + 005-SessionsWeb (#1969)
--selfhost North Star 2 bootstrap gates only (#2053, #1492)
--jit-probe Run MCJIT smoke (script/jit-runtime-probe.php)
--aot-project-probe [dir] AOT build + execute on 003-MiniWebApp (or dir)
phpc validate-manifest [dir] Validate phpc.json (default: cwd)
Expand Down Expand Up @@ -264,6 +265,7 @@
}
require $repoRoot.'/vendor/autoload.php';
$gates = false;
$selfhost = false;
$noLint = false;
$jitProbe = false;
$aotProjectProbe = false;
Expand All @@ -273,6 +275,10 @@
$gates = true;
continue;
}
if ('--selfhost' === $arg) {
$selfhost = true;
continue;
}
if ('--no-lint' === $arg) {
$noLint = true;
continue;
Expand All @@ -292,6 +298,9 @@
fwrite(STDERR, "phpc doctor: unknown option: {$arg}\n");
exit(1);
}
if ($selfhost) {
exit(\PHPCompiler\Doctor::runSelfhost($repoRoot));
}
if ($gates) {
exit(\PHPCompiler\Doctor::runGates($repoRoot, $noLint));
}
Expand Down
3 changes: 2 additions & 1 deletion docs/bootstrap-m5-fast-path.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Supporting fixes from #1402:
| `Runtime::initVmContext` | **Native** via `RuntimeInitVmContext::emit` (allocate `VM\Context`, set `runtime` + `vmContext`); wired in `compileBlock()`; off deny list (#1494). PHP CFG `new VMContext` still LLVM 9 link crash when combined with ctor spine. |
| `Runtime::loadJit` | `compileRuntimeLoadJitM3Native` + nested `createJit` helpers (#1495) |
| `Runtime::standalone` | Compile-driver link OK (#1402, #1056) |
| `helloworld_compile_smoke` | Deny-listed for link (LLVM 9); smoke uses int+echo (#1514); compile_driver calls stub until link fixed |
| `helloworld_compile_smoke` | Deny-listed for link (LLVM 9); compile_driver bundle keeps stub; runtime emit uses `helloworld_m3_emit_native_entry.php` → `compile_smoke_m3_emit` (#1768) |
| `helloworld_m3_emit_native_entry.php` | Native emit TU (same spine as `compile_smoke_m3_emit_native_entry.php`); probe: `bootstrap-selfhost-helloworld-probe.sh` with `PHP_COMPILER_EMIT_HELPER_LINK=1` |
| `compile_smoke_m3_emit` | Deny-listed for self-host `compile_driver` link (LLVM 9); native emit via `compile_smoke_m3_emit_native_entry.php` + `PHP_COMPILER_SELFHOST_AOT=1` `PHP_COMPILER_M3_COMPILE_DRIVER=1` `PHP_COMPILER_EMIT_HELPER_LINK=1` (#1983, #1937) |
| `Compiler::compile` / `compileFunc` | PHP CFG lowering in emit TU when `PHP_COMPILER_EMIT_HELPER_LINK=1` (link OK; runtime emit still blocked by emit-binary global init segfault — #1937) |
| Native emit runtime | `BOOTSTRAP_M3_RUNTIME_COMPILE=1` + `PHP_COMPILER_M3_EMIT_MINIMAL=1` skips eager `loadJitCompileModuleFuncs` during smoke emit |
Expand Down
3 changes: 2 additions & 1 deletion docs/bootstrap-selfhost.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@
| M2 lib spine VM `-r` smoke | `./script/bootstrap-selfhost-lib-spine-vm-smoke.sh` or `BOOTSTRAP_LIB_SPINE_VM_SMOKE=1 make bootstrap-selfhost-lib-spine-vm-smoke` | ✅ same binary + `PHP_COMPILER_VM_SPINE_SMOKE=1` prints `vm-spine-ok` ([#1846](https://github.com/PurHur/php-compiler/issues/1846); `ci-local.sh` default `BOOTSTRAP_LIB_SPINE_VM_SMOKE_GATE=1` ([#1867](https://github.com/PurHur/php-compiler/issues/1867)); set `0` to skip) |
| M3 HelloWorld self-host probe lint | `php bin/compile.php -l test/selfhost/compiler_helloworld_smoke/main.php` | ✅ `compiler_compile_smoke` spine + `helloworld_compile_smoke` driver (linkable) |
| M3 HelloWorld compile driver lint | `php bin/compile.php -l test/selfhost/compiler_helloworld_smoke/compile_driver.php` | ✅ `Runtime::parseAndCompile` + mode-file dispatch (native link opt-in) |
| M3 HelloWorld self-host probe | `./script/bootstrap-selfhost-helloworld-probe.sh` or `make bootstrap-selfhost-helloworld` | 🚧 **partial** — bundle link ✅; HelloWorld AOT **run** native ✅; **emit uses Zend fallback** until native runtime compile passes ([#1492](https://github.com/PurHur/php-compiler/issues/1492); probe sets `M3_NATIVE_COMPILE=1` / `emit_path=native` only on selfhost compile-driver success; `BOOTSTRAP_M3_HELLOWORLD_STRICT=1` fails without fallback — see [bootstrap-m5-fast-path.md](bootstrap-m5-fast-path.md)) |
| M3 HelloWorld self-host probe | `./script/bootstrap-selfhost-helloworld-probe.sh` or `make bootstrap-selfhost-helloworld` | 🚧 **partial** — bundle link ✅; HelloWorld AOT **run** native ✅; native emit via `helloworld_m3_emit_native_entry.php` blocked at emit-TU runtime init ([#1768](https://github.com/PurHur/php-compiler/issues/1768), [#1937](https://github.com/PurHur/php-compiler/issues/1937)); `emit_path=native` when `compile_smoke_m3_emit: compile OK`; Zend fallback otherwise — see [bootstrap-m5-fast-path.md](bootstrap-m5-fast-path.md) |
| M3 HelloWorld wave gate | `./script/bootstrap-wave-check.sh --with-helloworld` | ✅ opt-in `BOOTSTRAP_M3_HELLOWORLD=1` |
| M3 HelloWorld strict CI gate | `BOOTSTRAP_M3_HELLOWORLD_STRICT_GATE=1 ./script/ci-local.sh` | opt-in ([#1526](https://github.com/PurHur/php-compiler/issues/1526)); runs `bootstrap-selfhost-helloworld-probe.sh` with `BOOTSTRAP_M3_HELLOWORLD_STRICT=1` + compile-driver link (default **off** until `emit_path=native` stable) |
| M4 bootstrap-loop gen-1 link | `./script/bootstrap-loop-gen1-link.sh` or `make bootstrap-loop-gen1-link` | 🚧 **partial** — gen-1 link ✅; gen-2 **Zend** emit until M3 native compile ([#1498](https://github.com/PurHur/php-compiler/issues/1498)) |
| M4 bootstrap-loop probe | `./script/bootstrap-loop-probe.sh` or `make bootstrap-loop-probe` | 🚧 **ladder** — M2 + M3 partial + gen-1/gen-2 slice, then M3 strict; `--dry-run` skips strict ([#1498](https://github.com/PurHur/php-compiler/issues/1498)) |
| M4 bootstrap-loop probe in CI | `BOOTSTRAP_LOOP_PROBE_GATE=1 ./script/ci-fast.sh` or `./script/ci-local.sh` (LLVM tail) | opt-in runs `--dry-run` ladder; default off until M3 strict stable ([#1777](https://github.com/PurHur/php-compiler/issues/1777), [#1929](https://github.com/PurHur/php-compiler/issues/1929)) |
| North Star 2 presenter in fast CI | `./script/ci-fast.sh` (default) or `make north-star2-verify` | ✅ default-on in ci-fast ([#1928](https://github.com/PurHur/php-compiler/issues/1928), [#2051](https://github.com/PurHur/php-compiler/issues/2051)); opt-out `NORTH_STAR2_VERIFY_GATE=0` |
| Self-host gate ladder CLI | `./phpc doctor --selfhost` | ✅ M2/M3/M4 env vars + probe commands only ([#2053](https://github.com/PurHur/php-compiler/issues/2053)) |
| Bootstrap iteration CLI | `./phpc test --bootstrap` or `./script/bootstrap-test-subset.sh` | ✅ inventory `--check` + spine count sync (no LLVM link by default); `BOOTSTRAP_TEST_SUBSET_VM_SMOKE=1` for M2 VM spine smoke; `--strict` / `--bootstrap-strict` runs M3 HelloWorld strict probe ([#1961](https://github.com/PurHur/php-compiler/issues/1961)) |

Regenerate: `make bootstrap-profile` (inventory + profile + optional `bootstrap-aot-lint`). Phase C: `make bootstrap-aot-link` (or `php script/bootstrap-aot-lint.php --link`). Phase D: `make bootstrap-aot-link-lib`. Bundled compiler lint: `./script/bootstrap-selfhost-lint.sh`. Live lowering target: `make bootstrap-selfhost-probe` (or `./script/bootstrap-selfhost-compile-probe.sh`; optional `--update-inventory`).
Expand Down
72 changes: 72 additions & 0 deletions lib/Doctor.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,78 @@ public static function runGates(string $repoRoot, bool $noLint = false): int
return is_int($exit) ? $exit : 1;
}

/**
* North Star 2 self-host gate ladder only (issues #1492, #2053).
*/
public static function runSelfhost(string $repoRoot): int
{
require_once $repoRoot.'/script/bootstrap-spine-count.php';
$counts = bootstrap_spine_counts($repoRoot);
$spine = $counts['spine'];
$inventory = $counts['inventory'];

$llvmInfo = self::resolveLlvmInfo($repoRoot);
$llvmReady = null !== $llvmInfo['dir'];
$llvmDetail = $llvmReady
? 'ready at '.$llvmInfo['dir'].' ('.$llvmInfo['source'].')'
: 'missing — link/probe steps need LLVM 9 (script/install-llvm9.sh)';

$defaults = self::readCiDefaultsEnv($repoRoot);
$ns2Default = $defaults['NORTH_STAR2_VERIFY_GATE'] ?? '1';
$m3HelloStrictDefault = $defaults['BOOTSTRAP_M3_HELLOWORLD_STRICT_GATE'] ?? '0';
$m3SmokeStrictDefault = $defaults['BOOTSTRAP_M3_COMPILE_SMOKE_STRICT_GATE'] ?? '0';
$m3SmokeProbeDefault = $defaults['BOOTSTRAP_M3_COMPILE_SMOKE_PROBE_GATE'] ?? '1';
$spineCountSyncDefault = $defaults['SELFHOST_SPINE_COUNT_SYNC_GATE'] ?? '1';
$spineCoverageDefault = $defaults['SELFHOST_SPINE_COVERAGE_SYNC_GATE'] ?? '1';
$loopProbeDefault = $defaults['BOOTSTRAP_LOOP_PROBE_GATE'] ?? '0';

$inventoryScript = $repoRoot.'/script/bootstrap-inventory.php';
$inventoryOk = is_file($inventoryScript);
$inventoryDetail = $inventoryOk
? 'php script/bootstrap-inventory.php --check'
: 'script/bootstrap-inventory.php missing';

fwrite(STDOUT, "North Star 2 self-host gates (#1492, #1056):\n\n");

fwrite(STDOUT, "1. Inventory\n");
fwrite(STDOUT, " {$inventoryDetail}\n");
fwrite(STDOUT, " php script/bootstrap-spine-count.php → {$spine}/{$inventory}\n\n");

fwrite(STDOUT, "2. M2 spine\n");
fwrite(STDOUT, " SELFHOST_SPINE_COUNT_SYNC_GATE=".(self::gateEnabled('SELFHOST_SPINE_COUNT_SYNC_GATE', $spineCountSyncDefault) ? '1' : '0')." (default {$spineCountSyncDefault})\n");
fwrite(STDOUT, " SELFHOST_SPINE_COVERAGE_SYNC_GATE=".(self::gateEnabled('SELFHOST_SPINE_COVERAGE_SYNC_GATE', $spineCoverageDefault) ? '1' : '0')." (default {$spineCoverageDefault})\n");
fwrite(STDOUT, " BOOTSTRAP_LIB_SPINE_SMOKE=1 make bootstrap-selfhost-lib-spine-smoke\n");
fwrite(STDOUT, " BOOTSTRAP_LIB_SPINE_VM_SMOKE=1 make bootstrap-selfhost-lib-spine-vm-smoke\n\n");

fwrite(STDOUT, "3. M3 emit (partial vs strict)\n");
fwrite(STDOUT, " BOOTSTRAP_M3_HELLOWORLD_STRICT_GATE=".(self::gateEnabled('BOOTSTRAP_M3_HELLOWORLD_STRICT_GATE', $m3HelloStrictDefault) ? '1' : '0')." (default {$m3HelloStrictDefault}) — ci-local LLVM tail\n");
fwrite(STDOUT, " BOOTSTRAP_M3_COMPILE_SMOKE_PROBE_GATE=".(self::gateEnabled('BOOTSTRAP_M3_COMPILE_SMOKE_PROBE_GATE', $m3SmokeProbeDefault) ? '1' : '0')." (default {$m3SmokeProbeDefault})\n");
fwrite(STDOUT, " BOOTSTRAP_M3_COMPILE_SMOKE_STRICT_GATE=".(self::gateEnabled('BOOTSTRAP_M3_COMPILE_SMOKE_STRICT_GATE', $m3SmokeStrictDefault) ? '1' : '0')." (default {$m3SmokeStrictDefault})\n");
fwrite(STDOUT, " BOOTSTRAP_M3_LINK_COMPILE_DRIVER=1 BOOTSTRAP_M3_COMPILE_DRIVER_REAL_LOWERING=1 BOOTSTRAP_M3_RUNTIME_COMPILE=1 ./script/bootstrap-selfhost-helloworld-probe.sh\n");
fwrite(STDOUT, " BOOTSTRAP_M3_HELLOWORLD_STRICT=1 … helloworld-probe.sh (no Zend fallback; #1493)\n");
fwrite(STDOUT, " Emit TU: test/bootstrap-aot/helloworld_m3_emit_native_entry.php (#1768)\n\n");

fwrite(STDOUT, "4. Presenter / fast CI\n");
fwrite(STDOUT, " NORTH_STAR2_VERIFY_GATE=".(self::gateEnabled('NORTH_STAR2_VERIFY_GATE', $ns2Default) ? '1' : '0')." (default {$ns2Default}) — ci-fast\n");
if (is_executable($repoRoot.'/script/north-star2-verify.sh')) {
fwrite(STDOUT, " make north-star2-verify or ./script/north-star2-verify.sh\n");
}
fwrite(STDOUT, " phpc test --bootstrap [--strict]\n");
fwrite(STDOUT, " make bootstrap-wave-check (opt-in --with-helloworld)\n\n");

fwrite(STDOUT, "5. M4 loop\n");
fwrite(STDOUT, " BOOTSTRAP_LOOP_PROBE_GATE=".(self::gateEnabled('BOOTSTRAP_LOOP_PROBE_GATE', $loopProbeDefault) ? '1' : '0')." (default {$loopProbeDefault}) — ./script/bootstrap-loop-probe.sh --dry-run\n\n");

fwrite(STDOUT, "6. LLVM\n");
fwrite(STDOUT, " {$llvmDetail}\n");
if ($llvmReady) {
fwrite(STDOUT, " phpc doctor --jit-probe (MCJIT smoke)\n");
}
fwrite(STDOUT, "\nDocs: docs/bootstrap-selfhost.md · docs/bootstrap-m5-fast-path.md · docs/self-host-target.md\n");

return 0;
}

/**
* North Star 1 presenter commands after the gate ladder (issues #1845, #1857).
*/
Expand Down
Loading