diff --git a/docs/bootstrap-inventory.md b/docs/bootstrap-inventory.md index b937e8914..1d9bd0e4f 100644 --- a/docs/bootstrap-inventory.md +++ b/docs/bootstrap-inventory.md @@ -8,11 +8,11 @@ Regenerate: `php script/bootstrap-inventory.php` | Metric | Count | |--------|------:| -| PHP files on vm.php path | 4311 | -| Phase A inventory files (M2 ratio SSOT) | 4311 | +| PHP files on vm.php path | 4312 | +| Phase A inventory files (M2 ratio SSOT) | 4312 | | Phase A ratio-deferred paths | 0 | | Source constructs flagged (blockers) | 0 | -| Source constructs flagged (warnings) | 11621 | +| Source constructs flagged (warnings) | 11622 | ## Compiler CFG gaps (`lib/Compiler.php`) @@ -56,6 +56,7 @@ Rank live CFG gaps across inventory files: `php script/bootstrap-inventory-triag | `ext/bcmath/bcscale.php` | 0 | 1 | | `ext/bcmath/bcsqrt.php` | 0 | 1 | | `ext/bcmath/bcsub.php` | 0 | 1 | +| `ext/brotli/BrotliExtensionPolicy.php` | 0 | 1 | | `ext/brotli/BrotliJitHelper.php` | 0 | 1 | | `ext/brotli/JitBrotli.php` | 0 | 1 | | `ext/brotli/Module.php` | 0 | 3 | @@ -4438,6 +4439,11 @@ Rank live CFG gaps across inventory files: `php script/bootstrap-inventory-triag **Warnings** (review for bootstrap subset): - 1 class method(s) +### `ext/brotli/BrotliExtensionPolicy.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) + ### `ext/brotli/BrotliJitHelper.php` **Warnings** (review for bootstrap subset): @@ -4451,8 +4457,8 @@ Rank live CFG gaps across inventory files: `php script/bootstrap-inventory-triag ### `ext/brotli/Module.php` **Warnings** (review for bootstrap subset): -- new brotli_compress (line 21) -- new brotli_uncompress (line 22) +- new brotli_compress (line 24) +- new brotli_uncompress (line 25) - 1 class method(s) ### `ext/brotli/VmBrotliNative.php` @@ -5786,48 +5792,48 @@ Rank live CFG gaps across inventory files: `php script/bootstrap-inventory-triag - new DomNodeState (line 2414) - new DOMException (line 2561) - new DOMException (line 2575) -- new Variable (line 2589) -- new DOMException (line 2603) -- new DOMException (line 2606) -- new DOMException (line 2614) -- new DOMException (line 2640) -- new DOMException (line 2653) -- new DOMException (line 2839) -- new DOMException (line 3036) -- new DOMException (line 3040) -- new DOMException (line 3129) -- new DOMException (line 3133) -- new DOMException (line 3191) -- new DOMException (line 3208) -- new DOMException (line 3237) -- new DOMException (line 3278) -- new DOMException (line 3303) -- new DOMException (line 3789) -- new Variable (line 3813) -- new DOMException (line 4036) -- new DOMException (line 4117) -- new DOMException (line 4159) -- new ObjectEntry (line 4244) -- new DomNodeState (line 4248) -- new Variable (line 4255) -- new ObjectEntry (line 4455) -- new DomNodeState (line 4459) -- new Variable (line 4466) -- new ObjectEntry (line 4486) -- new DomNodeState (line 4489) -- new Variable (line 4497) -- new DOMException (line 4699) -- new DOMException (line 4706) -- new DOMException (line 4713) -- new DOMException (line 4717) -- new DOMException (line 4720) -- new DOMException (line 4729) -- new Variable (line 5477) -- new Variable (line 5490) -- new DOMException (line 5572) -- new DOMException (line 5583) -- new DOMException (line 5649) -- new DOMException (line 5657) +- new Variable (line 2591) +- new DOMException (line 2605) +- new DOMException (line 2608) +- new DOMException (line 2616) +- new DOMException (line 2642) +- new DOMException (line 2655) +- new DOMException (line 2841) +- new DOMException (line 3038) +- new DOMException (line 3042) +- new DOMException (line 3131) +- new DOMException (line 3135) +- new DOMException (line 3193) +- new DOMException (line 3210) +- new DOMException (line 3239) +- new DOMException (line 3280) +- new DOMException (line 3305) +- new DOMException (line 3791) +- new Variable (line 3815) +- new DOMException (line 4038) +- new DOMException (line 4119) +- new DOMException (line 4161) +- new ObjectEntry (line 4246) +- new DomNodeState (line 4250) +- new Variable (line 4257) +- new ObjectEntry (line 4457) +- new DomNodeState (line 4461) +- new Variable (line 4468) +- new ObjectEntry (line 4488) +- new DomNodeState (line 4491) +- new Variable (line 4499) +- new DOMException (line 4701) +- new DOMException (line 4708) +- new DOMException (line 4715) +- new DOMException (line 4719) +- new DOMException (line 4722) +- new DOMException (line 4731) +- new Variable (line 5481) +- new Variable (line 5494) +- new DOMException (line 5576) +- new DOMException (line 5587) +- new DOMException (line 5653) +- new DOMException (line 5661) - 277 class method(s) - 2 closure(s) @@ -22569,45 +22575,45 @@ Rank live CFG gaps across inventory files: `php script/bootstrap-inventory-triag - new OpCode (line 37435) - new OpCode (line 37467) - new OpCode (line 37529) -- new Operand\Temporary (line 39209) -- new Operand\Temporary (line 39702) -- new Operand\Temporary (line 39888) -- new Operand\Temporary (line 39920) -- new Operand\Temporary (line 40016) -- new Operand\Temporary (line 40138) -- new OpCode (line 40140) -- new OpCode (line 41518) -- new Operand\Temporary (line 41976) -- new OpCode (line 42500) -- new Operand\Literal (line 42799) -- new Variable (line 42801) -- new OpCode (line 42847) -- new OpCode (line 43062) -- new OpCode (line 43072) -- new OpCode (line 43075) -- new Operand\Temporary (line 43102) -- new Operand\Temporary (line 43139) -- new OpCode (line 43141) -- new OpCode (line 43152) -- new Operand\Temporary (line 43155) -- new OpCode (line 43157) +- new Operand\Temporary (line 39217) +- new Operand\Temporary (line 39710) +- new Operand\Temporary (line 39896) +- new Operand\Temporary (line 39928) +- new Operand\Temporary (line 40024) +- new Operand\Temporary (line 40146) +- new OpCode (line 40148) +- new OpCode (line 41526) +- new Operand\Temporary (line 41984) +- new OpCode (line 42508) +- new Operand\Literal (line 42807) +- new Variable (line 42809) +- new OpCode (line 42855) +- new OpCode (line 43070) +- new OpCode (line 43080) +- new OpCode (line 43083) +- new Operand\Temporary (line 43110) +- new Operand\Temporary (line 43147) +- new OpCode (line 43149) +- new OpCode (line 43160) +- new Operand\Temporary (line 43163) - new OpCode (line 43165) - new OpCode (line 43173) - new OpCode (line 43181) -- new OpCode (line 43184) -- new OpCode (line 43212) -- new OpCode (line 43235) -- new OpCode (line 43252) -- new OpCode (line 43259) -- new Operand\Literal (line 43938) -- new OpCode (line 45063) -- new Literal (line 45095) -- new OpCode (line 45194) -- new Variable (line 45201) -- new Temporary (line 45203) +- new OpCode (line 43189) +- new OpCode (line 43192) +- new OpCode (line 43220) +- new OpCode (line 43243) +- new OpCode (line 43260) +- new OpCode (line 43267) +- new Operand\Literal (line 43946) +- new OpCode (line 45075) +- new Literal (line 45107) - new OpCode (line 45206) -- new CompileFatal (line 45541) -- new CompileFatal (line 45796) +- new Variable (line 45213) +- new Temporary (line 45215) +- new OpCode (line 45218) +- new CompileFatal (line 45553) +- new CompileFatal (line 45808) - 962 class method(s) - 47 closure(s) @@ -22960,7 +22966,7 @@ Rank live CFG gaps across inventory files: `php script/bootstrap-inventory-triag ### `lib/CompilerVersion.php` **Warnings** (review for bootstrap subset): -- 166 class method(s) +- 167 class method(s) ### `lib/CurlyBraceOffsetRejector.php` diff --git a/docs/bootstrap-profile.json b/docs/bootstrap-profile.json index e25ba963a..769b3f739 100644 --- a/docs/bootstrap-profile.json +++ b/docs/bootstrap-profile.json @@ -43,6 +43,7 @@ "ext/bcmath/bcscale.php", "ext/bcmath/bcsqrt.php", "ext/bcmath/bcsub.php", + "ext/brotli/BrotliExtensionPolicy.php", "ext/brotli/BrotliJitHelper.php", "ext/brotli/JitBrotli.php", "ext/brotli/Module.php", @@ -245,6 +246,8 @@ "ext/dom/NodeReplaceChild.php", "ext/dom/NodeReplaceChildren.php", "ext/dom/NodeReplaceWith.php", + "ext/dom/TextIsElementContentWhitespace.php", + "ext/dom/TextIsWhitespaceInElementContent.php", "ext/dom/TextSplitText.php", "ext/dom/TokenListAdd.php", "ext/dom/TokenListContains.php", @@ -4543,9 +4546,9 @@ "test/bootstrap-aot/lib_opcode/main.php" ], "totals": { - "inventory_files": 4309, + "inventory_files": 4312, "excluded": 0, - "eligible": 4309, + "eligible": 4312, "aot_lint_targets": 113, "aot_link_targets": 100, "aot_link_lib_targets": 1 diff --git a/docs/bootstrap-selfhost.md b/docs/bootstrap-selfhost.md index 607f90a2d..dec287aed 100644 --- a/docs/bootstrap-selfhost.md +++ b/docs/bootstrap-selfhost.md @@ -2,7 +2,7 @@ **Gen-0 without Zend:** `BOOTSTRAP_M5_NO_ZEND=1 make bootstrap-selfhost-link` installs `prelinked/bootstrap-gen0/bin-compile-aot` and links `compiler_minimal` without `php bin/compile.php` ([#3053](https://github.com/PurHur/php-compiler/issues/3053)). **M5 lib spine compile:** `BOOTSTRAP_NO_ZEND_FALLBACK=1 make bootstrap-selfhost-lib-spine-smoke` (default in link script) refuses host `php bin/compile.php` on the spine emit path ([#8716](https://github.com/PurHur/php-compiler/issues/8716)). **Contributor workflow:** [bootstrap-dev-workflow.md](bootstrap-dev-workflow.md) (tiered gen-1+ path, spine checklist, CI). -**Project north star:** The **compiler fully compiles itself** — native AOT from `lib/` (no `vendor/` at cold boot), then compiles PHP and rebuilds the next compiler revision without Zend. **M2 spine:** **4311** / **4311** Phase A inventory (`php script/bootstrap-spine-count.php`; `check-selfhost-spine-coverage-sync.php`). **M5 daily gate:** `make north-star5-verify-fast` (~1–2 min) ✅; **`--strict`** (~1h) pre-merge only. Committed `prelinked/bootstrap-gen0/` sidecars + vendor **3/3** cold boot. **Hot loop:** VM driver execute probe ~**20ms**; full spine relink only with `BOOTSTRAP_VM_DRIVER_EXECUTE_PROBE_FULL_LINK=1` ([#2201](https://github.com/PurHur/php-compiler/issues/2201)). **Living tracker:** [#1492](https://github.com/PurHur/php-compiler/issues/1492) (was [#1056](https://github.com/PurHur/php-compiler/issues/1056)) · **re-root doc:** [self-host-target.md](self-host-target.md) · **generation ladder:** [bootstrap-generations.md](bootstrap-generations.md) · **M5 fast path:** [bootstrap-m5-fast-path.md](bootstrap-m5-fast-path.md) · public status: [development-status § North star](https://purhur.github.io/php-compiler/development-status.html#north-star-self-host). Parent tracking: [#78](https://github.com/PurHur/php-compiler/issues/78) (roadmap), [#212](https://github.com/PurHur/php-compiler/issues/212) (closed umbrella). +**Project north star:** The **compiler fully compiles itself** — native AOT from `lib/` (no `vendor/` at cold boot), then compiles PHP and rebuilds the next compiler revision without Zend. **M2 spine:** **4312** / **4312** Phase A inventory (`php script/bootstrap-spine-count.php`; `check-selfhost-spine-coverage-sync.php`). **M5 daily gate:** `make north-star5-verify-fast` (~1–2 min) ✅; **`--strict`** (~1h) pre-merge only. Committed `prelinked/bootstrap-gen0/` sidecars + vendor **3/3** cold boot. **Hot loop:** VM driver execute probe ~**20ms**; full spine relink only with `BOOTSTRAP_VM_DRIVER_EXECUTE_PROBE_FULL_LINK=1` ([#2201](https://github.com/PurHur/php-compiler/issues/2201)). **Living tracker:** [#1492](https://github.com/PurHur/php-compiler/issues/1492) (was [#1056](https://github.com/PurHur/php-compiler/issues/1056)) · **re-root doc:** [self-host-target.md](self-host-target.md) · **generation ladder:** [bootstrap-generations.md](bootstrap-generations.md) · **M5 fast path:** [bootstrap-m5-fast-path.md](bootstrap-m5-fast-path.md) · public status: [development-status § North star](https://purhur.github.io/php-compiler/development-status.html#north-star-self-host). Parent tracking: [#78](https://github.com/PurHur/php-compiler/issues/78) (roadmap), [#212](https://github.com/PurHur/php-compiler/issues/212) (closed umbrella). ## Current gates diff --git a/docs/pages/development-status.md b/docs/pages/development-status.md index 78559ab9a..5801365de 100644 --- a/docs/pages/development-status.md +++ b/docs/pages/development-status.md @@ -15,7 +15,7 @@ permalink: /development-status.html | **North star** | Compiler compiles itself without Zend ([#1492](https://github.com/PurHur/php-compiler/issues/1492)) | | **v1.1.0 theme** | M5 fast-path stability; enum/property hooks; `preg_match` JIT; `spl_autoload*`; php-in-PHP JIT helpers ([#78](https://github.com/PurHur/php-compiler/issues/78)) | | **Wave 3** | Language **12/12** · Stdlib **13/13** on master ([#1380](https://github.com/PurHur/php-compiler/issues/1380)) | -| **Spine SSOT** | `php script/bootstrap-spine-count.php` → **4311** / **4311** | +| **Spine SSOT** | `php script/bootstrap-spine-count.php` → **4312** / **4312** | | **Builtin matrix** | **852** functions ([`docs/capabilities.md`](https://github.com/PurHur/php-compiler/blob/master/docs/capabilities.md)) | | **Try it** | [`docs/GETTING-STARTED.md`](https://github.com/PurHur/php-compiler/blob/master/docs/GETTING-STARTED.md) | @@ -50,7 +50,7 @@ permalink: /development-status.html ### Still open (high signal) - **MCJIT execute** — `bin/jit.php -r` SIGSEGV ([#98](https://github.com/PurHur/php-compiler/issues/98)) -- **Literal spine ratio** — **4311/4311** ✅ (Jul 2026) +- **Literal spine ratio** — **4312/4312** ✅ (Jul 2026) - **Compile-spine stub retirement** — shrink `PHP_COMPILER_SELFHOST_AOT` on M3 allowlist ([#1402](https://github.com/PurHur/php-compiler/issues/1402)) - **007-ThrowsWeb AOT execute** — invalid POST segfault at runtime (link OK; slice `EXAMPLES_AOT_SMOKE_ONLY=007`) - **LLVM 14+ upgrade** — experimental `script/install-llvm14.sh` ([#174](https://github.com/PurHur/php-compiler/issues/174)) @@ -62,7 +62,7 @@ permalink: /development-status.html - **`phpc` CLI** — `run`, `serve`, `build`, `deploy`, `lint`, `test`, `init`, `doctor` - **Examples 000–009** — VM and AOT link/execute for the curated web subset - **Self-host M0** — `compiler_minimal bundle OK` ✅ -- **Self-host M2** — spine **4311/4311** ✅; native link + lint ✅ +- **Self-host M2** — spine **4312/4312** ✅; native link + lint ✅ - **Self-host M3** — HelloWorld strict `emit_path=native` ✅ ([#1493](https://github.com/PurHur/php-compiler/issues/1493)); inventory argv `bin/compile.php` ✅ ([#3024](https://github.com/PurHur/php-compiler/issues/3024) closed); compile-smoke strict native ✅ ([#1937](https://github.com/PurHur/php-compiler/issues/1937)) - **Self-host M4** — `make bootstrap-loop-probe` full ladder ✅; gen-2→gen-3 full-spine recompile ✅ - **Self-host M5** — vendor prelink **3/3** ✅; **`make north-star5-verify-fast`** daily ✅; `--strict` pre-merge; gen-0 refreshed; VM probe ~**20ms** @@ -92,7 +92,7 @@ See [`docs/bootstrap-selfhost.md`](https://github.com/PurHur/php-compiler/blob/m |-----------|--------| | **M0** — Small `lib/` bundle runs | ✅ | | **M1** — Compiler-shaped bundle + compile-smoke | ✅ | -| **M2** — Spine toward full inventory | ✅ **4311** / **4311** | +| **M2** — Spine toward full inventory | ✅ **4312** / **4312** | | **M3** — Native compiles PHP (no Zend emit) | ✅ Smoke + inventory argv driver strict native | | **M4** — Bootstrap loop (next revision) | ✅ `bootstrap-loop-probe` full ladder | | **M5** — Full self-host, no `vendor/` cold boot | ✅ Presenter strict + compiled-only empty `build/` cold boot ([#3053](https://github.com/PurHur/php-compiler/issues/3053)) | diff --git a/docs/roadmap-wave3.md b/docs/roadmap-wave3.md index 6fd093b25..97e7a2bdb 100644 --- a/docs/roadmap-wave3.md +++ b/docs/roadmap-wave3.md @@ -19,7 +19,7 @@ Regenerate capability truth: `php script/capability-matrix.php`, `php script/cap Related merges outside this wave: `goto` ([#1228](https://github.com/PurHur/php-compiler/issues/1228) / [#1333](https://github.com/PurHur/php-compiler/pull/1333)), anonymous classes ([#1233](https://github.com/PurHur/php-compiler/issues/1233) / [#1386](https://github.com/PurHur/php-compiler/pull/1386)). -**M2 spine:** **4311** / **4311** (`php script/bootstrap-spine-count.php`) — full Phase A inventory in `compiler_lib_spine_smoke`; coverage sync ✅ (`check-selfhost-spine-coverage-sync.php`). Native spine **link** + **lint** ✅ ([#2134](https://github.com/PurHur/php-compiler/issues/2134), [#8559](https://github.com/PurHur/php-compiler/issues/8559)). **M5 daily gate:** `make north-star5-verify-fast` + VM probe ~20ms ([#2201](https://github.com/PurHur/php-compiler/issues/2201)); `--strict` pre-merge only. M4 gen-2→gen-3 recompile ✅. Target doc: [self-host-target.md](self-host-target.md) +**M2 spine:** **4312** / **4312** (`php script/bootstrap-spine-count.php`) — full Phase A inventory in `compiler_lib_spine_smoke`; coverage sync ✅ (`check-selfhost-spine-coverage-sync.php`). Native spine **link** + **lint** ✅ ([#2134](https://github.com/PurHur/php-compiler/issues/2134), [#8559](https://github.com/PurHur/php-compiler/issues/8559)). **M5 daily gate:** `make north-star5-verify-fast` + VM probe ~20ms ([#2201](https://github.com/PurHur/php-compiler/issues/2201)); `--strict` pre-merge only. M4 gen-2→gen-3 recompile ✅. Target doc: [self-host-target.md](self-host-target.md) ## Language (#1354–#1366) diff --git a/docs/self-host-target.md b/docs/self-host-target.md index b9bc19c04..85aa059df 100644 --- a/docs/self-host-target.md +++ b/docs/self-host-target.md @@ -79,7 +79,7 @@ That is **M5**. Everything below is the honest path from today’s bootstrap to | Indicator | Formula | Jun 2026 | |-----------|---------|----------| -| **M2 spine progress** | `require_once` units in `compiler_lib_spine_smoke` ÷ Phase A inventory file count | **4311** / **4311** (`php script/bootstrap-spine-count.php`) | +| **M2 spine progress** | `require_once` units in `compiler_lib_spine_smoke` ÷ Phase A inventory file count | **4312** / **4312** (`php script/bootstrap-spine-count.php`) | | **Public “Self-host” row** | Same M2 ratio until M3–M5 gates add weight ([`development-status.md`](pages/development-status.md)) | **~97%** | | **M5 vendor prelink** | `object_ok` packages ÷ 3 | **3 / 3** (cfg, types, llvm) | | **Composite (internal)** | Milestone weights in table above (M0–M1 = 100%, M2 = spine %, M3–M5 = gate %) | **~90%** | diff --git a/ext/brotli/BrotliExtensionPolicy.php b/ext/brotli/BrotliExtensionPolicy.php new file mode 100644 index 000000000..e7b45d1c8 --- /dev/null +++ b/ext/brotli/BrotliExtensionPolicy.php @@ -0,0 +1,21 @@ +='); } + /** + * ext/brotli via pure PHP {@see \PHPCompiler\ext\brotli\VmBrotliNative} — withheld on reference profile (#17563). + * + * Gated on stable 8.4.0 / {@see languageProfileVersion()} so 8.4.0-dev reference profile matches Zend 8.2 + * phantom gate (host ext-brotli absent). Enable forward profile via `PHP_COMPILER_PROFILE=8.4`. + */ + public static function supportsBrotli(): bool + { + return version_compare(self::languageProfileVersion(), '8.4.0', '>='); + } + /** * ext/sqlite3 exception surface — withheld on reference profile (#17106, #17194). * diff --git a/test/compliance/JITTest.php b/test/compliance/JITTest.php index 94d6f99c5..9711144f7 100755 --- a/test/compliance/JITTest.php +++ b/test/compliance/JITTest.php @@ -571,6 +571,15 @@ public static function providePHPTests(): \Generator && str_contains($name, 'bz2_phantom')) { continue; } + if (!CompilerVersion::supportsBrotli() + && (str_contains($name, 'brotli') || str_contains($name, 'brotli_')) + && !str_contains($name, 'brotli_phantom')) { + continue; + } + if (CompilerVersion::supportsBrotli() + && str_contains($name, 'brotli_phantom')) { + continue; + } if (!CompilerVersion::supportsBcmath() && (str_contains($name, 'bcadd') || str_contains($name, 'bcsub') diff --git a/test/compliance/VMTest.php b/test/compliance/VMTest.php index 58ecc138b..f443ef801 100755 --- a/test/compliance/VMTest.php +++ b/test/compliance/VMTest.php @@ -467,6 +467,15 @@ public static function providePHPTests(): \Generator && str_contains($name, 'bz2_phantom')) { continue; } + if (!CompilerVersion::supportsBrotli() + && (str_contains($name, 'brotli') || str_contains($name, 'brotli_')) + && !str_contains($name, 'brotli_phantom')) { + continue; + } + if (CompilerVersion::supportsBrotli() + && str_contains($name, 'brotli_phantom')) { + continue; + } if (!CompilerVersion::supportsBcmath() && (str_contains($name, 'bcadd') || str_contains($name, 'bcsub') diff --git a/test/compliance/cases/stdlib/brotli_phantom.phpt b/test/compliance/cases/stdlib/brotli_phantom.phpt new file mode 100644 index 000000000..14ba75fae --- /dev/null +++ b/test/compliance/cases/stdlib/brotli_phantom.phpt @@ -0,0 +1,14 @@ +--TEST-- +stdlib brotli — not advertised on reference profile (#17563, ext/brotli) +--FILE-- +assertFalse(CompilerVersion::supportsBrotli()); + } + + public function testSupportsBrotliTrueOnForwardProfile(): void + { + $prev = getenv('PHP_COMPILER_PROFILE'); + putenv('PHP_COMPILER_PROFILE=8.4'); + try { + $this->assertTrue(CompilerVersion::supportsBrotli()); + } finally { + if (false === $prev) { + putenv('PHP_COMPILER_PROFILE'); + } else { + putenv('PHP_COMPILER_PROFILE='.$prev); + } + } + } + public function testSupportsNextafterFalseOnReferenceProfile(): void { $this->assertFalse(CompilerVersion::supportsNextafter());