diff --git a/Makefile b/Makefile index 59044625..dbe5a751 100755 --- a/Makefile +++ b/Makefile @@ -112,3 +112,7 @@ test-docker: docker-build-22 .PHONY: test-docker-quick test-docker-quick: docker run --rm -v $(shell pwd):/compiler -w /compiler $(LOCAL_DEV_IMAGE) php vendor/bin/phpunit --exclude-group llvm + +.PHONY: bootstrap-inventory +bootstrap-inventory: + php script/bootstrap-inventory.php diff --git a/docs/bootstrap-inventory.md b/docs/bootstrap-inventory.md new file mode 100644 index 00000000..f8c4d2f3 --- /dev/null +++ b/docs/bootstrap-inventory.md @@ -0,0 +1,1462 @@ +# Bootstrap inventory (vm.php path) + +Auto-generated by `script/bootstrap-inventory.php`. Tracks **Phase A** of [#212](https://github.com/PurHur/php-compiler/issues/212) (self-host bootstrap). + +Regenerate: `php script/bootstrap-inventory.php` + +## Summary + +| Metric | Count | +|--------|------:| +| PHP files on vm.php path | 188 | +| Source constructs flagged (blockers) | 10 | +| Source constructs flagged (warnings) | 501 | + +## Compiler CFG gaps (`lib/Compiler.php`) + +These `LogicException` messages indicate CFG ops or expressions not yet lowered: + +- `Unsupported class type: ` +- `Unsupported class body element: ` +- `Unknown Op Type: ` +- `Unknown Stmt Type: ` +- `Unknown BinaryOp Type: ` +- `Unknown CastOp Type: ` +- `Unknown UnaryOp Type: ` +- `Unsupported expression: ` +- `Unknown Literal Operand Type: ` +- `Unknown Operand Type: ` +- `Unknown Terminal Type: ` + +## Files + +| File | Blockers | Warnings | +|------|----------|----------| +| `bin/vm.php` | 0 | 1 | +| `ext/standard/JitBin2hex.php` | 0 | 1 | +| `ext/standard/JitEnv.php` | 0 | 1 | +| `ext/standard/JitExplode.php` | 0 | 1 | +| `ext/standard/JitHeader.php` | 0 | 1 | +| `ext/standard/JitHtmlspecialchars.php` | 0 | 1 | +| `ext/standard/JitImplode.php` | 0 | 1 | +| `ext/standard/JitNumberFormat.php` | 0 | 1 | +| `ext/standard/JitPath.php` | 0 | 1 | +| `ext/standard/JitRealpath.php` | 0 | 1 | +| `ext/standard/JitStrPad.php` | 0 | 1 | +| `ext/standard/JitStrRepeat.php` | 0 | 1 | +| `ext/standard/JitStringConcat.php` | 0 | 1 | +| `ext/standard/JitStringIndex.php` | 0 | 1 | +| `ext/standard/JitStrpos.php` | 0 | 1 | +| `ext/standard/JitUrlencode.php` | 0 | 1 | +| `ext/standard/Module.php` | 0 | 93 | +| `ext/standard/VmFs.php` | 0 | 3 | +| `ext/standard/VmNumberFormat.php` | 0 | 1 | +| `ext/standard/VmString.php` | 0 | 2 | +| `ext/standard/abs.php` | 0 | 1 | +| `ext/standard/array_combine.php` | 0 | 3 | +| `ext/standard/array_count.php` | 0 | 1 | +| `ext/standard/array_fill.php` | 0 | 3 | +| `ext/standard/array_flip.php` | 0 | 3 | +| `ext/standard/array_key_exists.php` | 0 | 1 | +| `ext/standard/array_keys.php` | 0 | 1 | +| `ext/standard/array_merge.php` | 0 | 1 | +| `ext/standard/array_pop.php` | 0 | 1 | +| `ext/standard/array_push.php` | 0 | 2 | +| `ext/standard/array_reverse.php` | 0 | 1 | +| `ext/standard/array_search.php` | 0 | 1 | +| `ext/standard/array_shift.php` | 0 | 1 | +| `ext/standard/array_slice.php` | 0 | 1 | +| `ext/standard/array_sum.php` | 0 | 1 | +| `ext/standard/array_unique.php` | 0 | 4 | +| `ext/standard/array_values.php` | 0 | 1 | +| `ext/standard/basename.php` | 0 | 1 | +| `ext/standard/bin2hex.php` | 0 | 1 | +| `ext/standard/bindec.php` | 0 | 1 | +| `ext/standard/boolval.php` | 0 | 1 | +| `ext/standard/ceil.php` | 0 | 1 | +| `ext/standard/chr.php` | 0 | 1 | +| `ext/standard/cos.php` | 0 | 1 | +| `ext/standard/decbin.php` | 0 | 1 | +| `ext/standard/dechex.php` | 0 | 1 | +| `ext/standard/decoct.php` | 0 | 1 | +| `ext/standard/deg2rad.php` | 0 | 1 | +| `ext/standard/dirname.php` | 0 | 1 | +| `ext/standard/exp.php` | 0 | 1 | +| `ext/standard/explode.php` | 0 | 3 | +| `ext/standard/floatval.php` | 0 | 1 | +| `ext/standard/floor.php` | 0 | 1 | +| `ext/standard/fmod.php` | 0 | 1 | +| `ext/standard/getenv_.php` | 0 | 1 | +| `ext/standard/gettype.php` | 0 | 1 | +| `ext/standard/glob_.php` | 0 | 1 | +| `ext/standard/header_.php` | 0 | 1 | +| `ext/standard/hexdec.php` | 0 | 1 | +| `ext/standard/htmlspecialchars.php` | 0 | 1 | +| `ext/standard/implode.php` | 0 | 1 | +| `ext/standard/in_array.php` | 0 | 1 | +| `ext/standard/int_max.php` | 0 | 1 | +| `ext/standard/int_min.php` | 0 | 1 | +| `ext/standard/intdiv.php` | 0 | 2 | +| `ext/standard/intval.php` | 0 | 1 | +| `ext/standard/is_finite.php` | 0 | 1 | +| `ext/standard/is_infinite.php` | 0 | 1 | +| `ext/standard/is_nan.php` | 0 | 1 | +| `ext/standard/is_numeric.php` | 0 | 1 | +| `ext/standard/is_scalar.php` | 0 | 1 | +| `ext/standard/lcfirst.php` | 0 | 1 | +| `ext/standard/log.php` | 0 | 1 | +| `ext/standard/nl2br.php` | 0 | 1 | +| `ext/standard/number_format.php` | 0 | 1 | +| `ext/standard/octdec.php` | 0 | 1 | +| `ext/standard/ord.php` | 0 | 1 | +| `ext/standard/parse_url.php` | 0 | 3 | +| `ext/standard/pi.php` | 0 | 1 | +| `ext/standard/pow.php` | 0 | 1 | +| `ext/standard/putenv_.php` | 0 | 1 | +| `ext/standard/rad2deg.php` | 0 | 1 | +| `ext/standard/range.php` | 0 | 4 | +| `ext/standard/rawurlencode.php` | 0 | 1 | +| `ext/standard/realpath.php` | 0 | 1 | +| `ext/standard/round.php` | 0 | 1 | +| `ext/standard/scandir.php` | 0 | 1 | +| `ext/standard/sin.php` | 0 | 1 | +| `ext/standard/sort_.php` | 0 | 3 | +| `ext/standard/sqrt.php` | 0 | 1 | +| `ext/standard/str_contains.php` | 0 | 1 | +| `ext/standard/str_ends_with.php` | 0 | 1 | +| `ext/standard/str_pad.php` | 0 | 1 | +| `ext/standard/str_repeat.php` | 0 | 1 | +| `ext/standard/str_replace.php` | 0 | 1 | +| `ext/standard/str_split.php` | 0 | 3 | +| `ext/standard/str_starts_with.php` | 0 | 1 | +| `ext/standard/strcmp.php` | 0 | 1 | +| `ext/standard/string_ltrim.php` | 0 | 1 | +| `ext/standard/string_rtrim.php` | 0 | 1 | +| `ext/standard/string_trim.php` | 0 | 1 | +| `ext/standard/strncmp.php` | 0 | 1 | +| `ext/standard/strpos.php` | 0 | 1 | +| `ext/standard/strrev.php` | 0 | 1 | +| `ext/standard/strtolower.php` | 0 | 1 | +| `ext/standard/strtoupper.php` | 0 | 1 | +| `ext/standard/strval.php` | 0 | 1 | +| `ext/standard/substr.php` | 0 | 1 | +| `ext/standard/tan.php` | 0 | 1 | +| `ext/standard/ucfirst.php` | 0 | 1 | +| `ext/standard/urlencode.php` | 0 | 1 | +| `ext/types/Module.php` | 0 | 13 | +| `ext/types/is_type.php` | 0 | 1 | +| `ext/types/mb_strlen.php` | 0 | 1 | +| `ext/types/strlen.php` | 0 | 1 | +| `lib/AOT/Linker.php` | 8 | 1 | +| `lib/Block.php` | 0 | 4 | +| `lib/Compiler.php` | 0 | 56 | +| `lib/Frame.php` | 0 | 1 | +| `lib/Func.php` | 0 | 1 | +| `lib/Func/Internal.php` | 0 | 2 | +| `lib/Func/JIT.php` | 0 | 2 | +| `lib/Func/PHP.php` | 0 | 1 | +| `lib/Handler.php` | 0 | 1 | +| `lib/JIT.php` | 0 | 10 | +| `lib/JIT/Analyzer.php` | 0 | 1 | +| `lib/JIT/ArrayBuiltinHelper.php` | 0 | 5 | +| `lib/JIT/BasicBlockHelper.php` | 0 | 1 | +| `lib/JIT/Builtin.php` | 0 | 1 | +| `lib/JIT/Builtin/ErrorHandler.php` | 0 | 1 | +| `lib/JIT/Builtin/Internal.php` | 0 | 1 | +| `lib/JIT/Builtin/MemoryManager.php` | 0 | 3 | +| `lib/JIT/Builtin/MemoryManager/Native.php` | 0 | 1 | +| `lib/JIT/Builtin/MemoryManager/PHP.php` | 0 | 1 | +| `lib/JIT/Builtin/Output.php` | 0 | 1 | +| `lib/JIT/Builtin/Refcount.php` | 0 | 1 | +| `lib/JIT/Builtin/StringGetenv.php` | 0 | 1 | +| `lib/JIT/Builtin/StringHtmlspecialchars.php` | 0 | 1 | +| `lib/JIT/Builtin/StringUrlencode.php` | 0 | 1 | +| `lib/JIT/Builtin/Type.php` | 0 | 4 | +| `lib/JIT/Builtin/Type/HashTable.php` | 0 | 2 | +| `lib/JIT/Builtin/Type/MaskedArray.php` | 0 | 1 | +| `lib/JIT/Builtin/Type/NativeArray.php` | 0 | 1 | +| `lib/JIT/Builtin/Type/Object_.php` | 0 | 2 | +| `lib/JIT/Builtin/Type/String_.php` | 0 | 1 | +| `lib/JIT/Builtin/Type/Value.php` | 0 | 4 | +| `lib/JIT/Builtin/VarArg.php` | 0 | 1 | +| `lib/JIT/Call.php` | 0 | 1 | +| `lib/JIT/Call/Native.php` | 0 | 1 | +| `lib/JIT/Call/Vararg.php` | 0 | 2 | +| `lib/JIT/Context.php` | 0 | 15 | +| `lib/JIT/HashTableHelper.php` | 0 | 1 | +| `lib/JIT/Helper.php` | 0 | 7 | +| `lib/JIT/IssetHelper.php` | 0 | 1 | +| `lib/JIT/JitNativeString.php` | 0 | 5 | +| `lib/JIT/JitValueBox.php` | 0 | 1 | +| `lib/JIT/JitValueCompare.php` | 0 | 1 | +| `lib/JIT/OperandName.php` | 0 | 1 | +| `lib/JIT/Result.php` | 0 | 3 | +| `lib/JIT/StringOffsetHelper.php` | 0 | 1 | +| `lib/JIT/SuperglobalInit.php` | 0 | 3 | +| `lib/JIT/ValueEchoHelper.php` | 0 | 1 | +| `lib/JIT/Variable.php` | 0 | 18 | +| `lib/Module.php` | 0 | 1 | +| `lib/ModuleAbstract.php` | 0 | 1 | +| `lib/OpCode.php` | 0 | 1 | +| `lib/Printer.php` | 0 | 1 | +| `lib/Runtime.php` | 0 | 21 | +| `lib/VM.php` | 0 | 7 | +| `lib/VM/ClassEntry.php` | 0 | 1 | +| `lib/VM/ClassProperty.php` | 0 | 1 | +| `lib/VM/Context.php` | 0 | 10 | +| `lib/VM/HashTable.php` | 2 | 20 | +| `lib/VM/ObjectEntry.php` | 0 | 1 | +| `lib/VM/Optimizer.php` | 0 | 1 | +| `lib/VM/Optimizer/AssignOp.php` | 0 | 1 | +| `lib/VM/Refcount.php` | 0 | 1 | +| `lib/VM/Variable.php` | 0 | 4 | +| `lib/Web/DevServer.php` | 0 | 1 | +| `lib/Web/ProjectManifest.php` | 0 | 1 | +| `lib/Web/Superglobals.php` | 0 | 5 | +| `src/macro_functions.php` | 0 | 1 | + +## Per-file construct flags + +### `bin/vm.php` + +**Warnings** (review for bootstrap subset): +- new Runtime (line 17) + +### `ext/standard/JitBin2hex.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitEnv.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitExplode.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitHeader.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitHtmlspecialchars.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitImplode.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitNumberFormat.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitPath.php` + +**Warnings** (review for bootstrap subset): +- 9 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitRealpath.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitStrPad.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitStrRepeat.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitStringConcat.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitStringIndex.php` + +**Warnings** (review for bootstrap subset): +- 5 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitStrpos.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/JitUrlencode.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/Module.php` + +**Warnings** (review for bootstrap subset): +- new str_repeat (line 22) +- new decbin (line 23) +- new abs (line 24) +- new ceil (line 25) +- new floor (line 26) +- new round (line 27) +- new number_format (line 28) +- new sqrt (line 29) +- new pi (line 30) +- new deg2rad (line 31) +- new rad2deg (line 32) +- new log (line 33) +- new exp (line 34) +- new sin (line 35) +- new cos (line 36) +- new tan (line 37) +- new is_nan (line 38) +- new is_finite (line 39) +- new is_infinite (line 40) +- new pow (line 41) +- new fmod (line 42) +- new intval (line 43) +- new floatval (line 44) +- new boolval (line 45) +- new gettype (line 46) +- new strval (line 47) +- new int_min (line 48) +- new int_max (line 49) +- new intdiv (line 50) +- new ord (line 51) +- new chr (line 52) +- new strcmp (line 53) +- new dechex (line 54) +- new hexdec (line 55) +- new decoct (line 56) +- new octdec (line 57) +- new bindec (line 58) +- new is_numeric (line 59) +- new is_scalar (line 60) +- new lcfirst (line 61) +- new ucfirst (line 62) +- new strtolower (line 63) +- new strtoupper (line 64) +- new string_trim (line 65) +- new string_ltrim (line 66) +- new string_rtrim (line 67) +- new substr (line 68) +- new strrev (line 69) +- new strpos (line 70) +- new str_contains (line 71) +- new str_starts_with (line 72) +- new str_ends_with (line 73) +- new strncmp (line 74) +- new array_count (line 75) +- new array_count (line 76) +- new array_key_exists (line 77) +- new in_array (line 78) +- new array_push (line 79) +- new array_pop (line 80) +- new array_shift (line 81) +- new sort_ (line 82) +- new array_values (line 83) +- new array_keys (line 84) +- new array_merge (line 85) +- new array_slice (line 86) +- new explode (line 87) +- new implode (line 88) +- new str_replace (line 89) +- new nl2br (line 90) +- new array_reverse (line 91) +- new array_search (line 92) +- new array_sum (line 93) +- new array_flip (line 94) +- new array_unique (line 95) +- new array_fill (line 96) +- new array_combine (line 97) +- new range (line 98) +- new bin2hex (line 99) +- new str_pad (line 100) +- new str_split (line 101) +- new htmlspecialchars (line 102) +- new header_ (line 103) +- new urlencode (line 104) +- new rawurlencode (line 105) +- new parse_url (line 106) +- new dirname (line 107) +- new basename (line 108) +- new realpath (line 109) +- new getenv_ (line 110) +- new putenv_ (line 111) +- new scandir (line 112) +- new glob_ (line 113) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/VmFs.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 18) +- new Variable (line 20) +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/VmNumberFormat.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/VmString.php` + +**Warnings** (review for bootstrap subset): +- 40 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler +- 1 closure(s) + +### `ext/standard/abs.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_combine.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 53) +- new Variable (line 57) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_count.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_fill.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 47) +- new Variable (line 50) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_flip.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 39) +- new Variable (line 45) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_key_exists.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_keys.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_merge.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_pop.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_push.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 39) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_reverse.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_search.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_shift.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_slice.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_sum.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_unique.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 39) +- new Variable (line 52) +- new Variable (line 55) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/array_values.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/basename.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/bin2hex.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/bindec.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/boolval.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/ceil.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/chr.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/cos.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/decbin.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/dechex.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/decoct.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/deg2rad.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/dirname.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/exp.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/explode.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 38) +- new Variable (line 40) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/floatval.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/floor.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/fmod.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/getenv_.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/gettype.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/glob_.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/header_.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/hexdec.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/htmlspecialchars.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/implode.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/in_array.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/int_max.php` + +**Warnings** (review for bootstrap subset): +- 5 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/int_min.php` + +**Warnings** (review for bootstrap subset): +- 5 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/intdiv.php` + +**Warnings** (review for bootstrap subset): +- new DivisionByZeroError (line 38) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/intval.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/is_finite.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/is_infinite.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/is_nan.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/is_numeric.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/is_scalar.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/lcfirst.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/log.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/nl2br.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/number_format.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/octdec.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/ord.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/parse_url.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 42) +- new Variable (line 44) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/pi.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/pow.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/putenv_.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/rad2deg.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/range.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 57) +- new Variable (line 61) +- new Variable (line 68) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/rawurlencode.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/realpath.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/round.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/scandir.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/sin.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/sort_.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 53) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler +- 1 closure(s) + +### `ext/standard/sqrt.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/str_contains.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/str_ends_with.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/str_pad.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/str_repeat.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/str_replace.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/str_split.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 49) +- new Variable (line 51) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/str_starts_with.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/strcmp.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/string_ltrim.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/string_rtrim.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/string_trim.php` + +**Warnings** (review for bootstrap subset): +- 5 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/strncmp.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/strpos.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/strrev.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/strtolower.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/strtoupper.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/strval.php` + +**Warnings** (review for bootstrap subset): +- 5 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/substr.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/tan.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/ucfirst.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/standard/urlencode.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/types/Module.php` + +**Warnings** (review for bootstrap subset): +- new strlen (line 22) +- new mb_strlen (line 23) +- new is_type (line 24) +- new is_type (line 25) +- new is_type (line 26) +- new is_type (line 27) +- new is_type (line 28) +- new is_type (line 29) +- new is_type (line 30) +- new is_type (line 31) +- new is_type (line 32) +- new is_type (line 33) +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/types/is_type.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/types/mb_strlen.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `ext/types/strlen.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/AOT/Linker.php` + +**Blockers** (likely prevent AOT bootstrap compile): +- shell_exec() (line 121) +- shell_exec() (line 142) +- shell_exec() (line 176) +- shell_exec() (line 180) +- shell_exec() (line 223) +- shell_exec() (line 233) +- shell_exec() (line 289) +- exec() (line 295) + +**Warnings** (review for bootstrap subset): +- 11 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Block.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 152) +- new Frame (line 170) +- new Variable (line 189) +- 9 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Compiler.php` + +**Warnings** (review for bootstrap subset): +- new Func\PHP (line 41) +- new Block (line 46) +- new OpCode (line 100) +- new Block (line 109) +- new OpCode (line 119) +- new Variable (line 134) +- new Operand\Temporary (line 135) +- new OpCode (line 157) +- new Operand\Literal (line 168) +- new OpCode (line 170) +- new OpCode (line 185) +- new OpCode (line 193) +- new OpCode (line 213) +- new OpCode (line 218) +- new OpCode (line 251) +- new OpCode (line 260) +- new OpCode (line 353) +- new OpCode (line 360) +- new OpCode (line 374) +- new OpCode (line 380) +- new OpCode (line 395) +- new OpCode (line 401) +- new OpCode (line 412) +- new OpCode (line 420) +- new OpCode (line 426) +- new OpCode (line 432) +- new OpCode (line 437) +- new OpCode (line 444) +- new OpCode (line 451) +- new OpCode (line 457) +- new OpCode (line 462) +- new OpCode (line 469) +- new OpCode (line 476) +- new OpCode (line 481) +- new OpCode (line 486) +- new OpCode (line 495) +- new OpCode (line 500) +- new OpCode (line 507) +- new OpCode (line 516) +- new OpCode (line 535) +- new Block (line 551) +- new Block (line 554) +- new OpCode (line 557) +- new OpCode (line 563) +- new OpCode (line 577) +- new Block (line 584) +- new OpCode (line 587) +- new OpCode (line 597) +- new Operand\Temporary (line 607) +- new Variable (line 615) +- new Operand\Temporary (line 617) +- new Variable (line 678) +- new OpCode (line 708) +- new OpCode (line 714) +- new OpCode (line 718) +- 25 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Frame.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Func.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Func/Internal.php` + +**Warnings** (review for bootstrap subset): +- new Frame (line 33) +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Func/JIT.php` + +**Warnings** (review for bootstrap subset): +- new Frame (line 31) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Func/PHP.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Handler.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 139) +- new JIT\Call\Vararg (line 146) +- new JIT\Call\Native (line 149) +- new ext\standard\boolval (line 249) +- new Variable (line 413) +- new Variable (line 712) +- new Operand\Literal (line 782) +- new Operand\Literal (line 786) +- new Operand\Literal (line 790) +- 11 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Analyzer.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/ArrayBuiltinHelper.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 277) +- new Variable (line 279) +- new Variable (line 643) +- new Variable (line 651) +- 22 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/BasicBlockHelper.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/ErrorHandler.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/Internal.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/MemoryManager.php` + +**Warnings** (review for bootstrap subset): +- new MemoryManager\Native (line 24) +- new MemoryManager\PHP (line 26) +- 6 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/MemoryManager/Native.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/MemoryManager/PHP.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/Output.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/Refcount.php` + +**Warnings** (review for bootstrap subset): +- 11 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/StringGetenv.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/StringHtmlspecialchars.php` + +**Warnings** (review for bootstrap subset): +- 5 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/StringUrlencode.php` + +**Warnings** (review for bootstrap subset): +- 8 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/Type.php` + +**Warnings** (review for bootstrap subset): +- new Type\String_ (line 21) +- new Type\Value (line 23) +- new Type\HashTable (line 24) +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/Type/HashTable.php` + +**Warnings** (review for bootstrap subset): +- 29 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler +- 1 closure(s) + +### `lib/JIT/Builtin/Type/MaskedArray.php` + +**Warnings** (review for bootstrap subset): +- 8 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/Type/NativeArray.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/Type/Object_.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 352) +- 12 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/Type/String_.php` + +**Warnings** (review for bootstrap subset): +- 13 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/Type/Value.php` + +**Warnings** (review for bootstrap subset): +- new StdClass (line 457) +- new StdClass (line 1010) +- new StdClass (line 1931) +- 12 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Builtin/VarArg.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Call.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Call/Native.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Call/Vararg.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler +- 1 closure(s) + +### `lib/JIT/Context.php` + +**Warnings** (review for bootstrap subset): +- new Scope (line 75) +- new Analyzer (line 93) +- new Helper (line 94) +- new Builtin\Refcount (line 96) +- new Builtin\Output (line 98) +- new Builtin\Type (line 99) +- new Builtin\Internal (line 100) +- new Builtin\VarArg (line 101) +- new Builtin\ErrorHandler (line 102) +- new Scope (line 117) +- new Result (line 208) +- new Variable (line 284) +- new Variable (line 494) +- new Variable (line 526) +- 32 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/HashTableHelper.php` + +**Warnings** (review for bootstrap subset): +- 9 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Helper.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 48) +- new Variable (line 50) +- new Variable (line 52) +- new Variable (line 635) +- new Variable (line 637) +- new Variable (line 639) +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/IssetHelper.php` + +**Warnings** (review for bootstrap subset): +- 8 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/JitNativeString.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 22) +- new Variable (line 33) +- new Variable (line 40) +- new Variable (line 62) +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/JitValueBox.php` + +**Warnings** (review for bootstrap subset): +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/JitValueCompare.php` + +**Warnings** (review for bootstrap subset): +- 6 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/OperandName.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Result.php` + +**Warnings** (review for bootstrap subset): +- new Func\JIT (line 41) +- new Func\JIT (line 49) +- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/StringOffsetHelper.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/SuperglobalInit.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 113) +- new VMVariable (line 137) +- 7 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/ValueEchoHelper.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/JIT/Variable.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 173) +- new Variable (line 190) +- new Variable (line 217) +- new Variable (line 231) +- new self (line 246) +- new self (line 253) +- new self (line 266) +- new self (line 273) +- new self (line 286) +- new self (line 293) +- new Variable (line 374) +- new Variable (line 394) +- new Variable (line 413) +- new Variable (line 430) +- new Variable (line 448) +- new Variable (line 461) +- new Variable (line 473) +- 15 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Module.php` + +**Warnings** (review for bootstrap subset): +- 6 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/ModuleAbstract.php` + +**Warnings** (review for bootstrap subset): +- 8 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/OpCode.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Printer.php` + +**Warnings** (review for bootstrap subset): +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Runtime.php` + +**Warnings** (review for bootstrap subset): +- new NodeTraverser (line 49) +- new NodeVisitor\NameResolver (line 51) +- new Parser (line 53) +- new ParserFactory (line 54) +- new Traverser (line 58) +- new Visitor\Simplifier (line 59) +- new Visitor\DeadBlockEliminator (line 60) +- new Traverser (line 61) +- new Visitor\PhiResolver (line 62) +- new LivenessDetector (line 63) +- new Optimizer\AssignOp (line 64) +- new TypeReconstructor (line 66) +- new Compiler (line 67) +- new VMContext (line 69) +- new VM (line 70) +- new ext\types\Module (line 85) +- new ext\standard\Module (line 86) +- new JIT (line 91) +- new JITContext (line 105) +- new State (line 130) +- 14 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 64) +- new Variable (line 69) +- new Func\PHP (line 210) +- new ClassEntry (line 260) +- new ObjectEntry (line 272) +- new VM\ClassProperty (line 362) +- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM/ClassEntry.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM/ClassProperty.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM/Context.php` + +**Warnings** (review for bootstrap subset): +- new Variable (line 36) +- new Variable (line 38) +- new Variable (line 42) +- new Variable (line 46) +- new Variable (line 50) +- new Variable (line 71) +- new HashTable (line 72) +- new RunStackEntry (line 99) +- new RunStackEntry (line 101) +- 8 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM/HashTable.php` + +**Blockers** (likely prevent AOT bootstrap compile): +- generator yield (line 62) +- generator yield (line 86) + +**Warnings** (review for bootstrap subset): +- new Refcount (line 46) +- new Variable (line 76) +- new Variable (line 102) +- new Variable (line 159) +- new Variable (line 184) +- new self (line 233) +- new Variable (line 235) +- new self (line 248) +- new Variable (line 254) +- new Variable (line 279) +- new Variable (line 307) +- new self (line 325) +- new Variable (line 327) +- new self (line 349) +- new Variable (line 360) +- new HashTableBucket (line 563) +- new Variable (line 563) +- new HashTableBucket (line 574) +- new Variable (line 574) +- 38 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM/ObjectEntry.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM/Optimizer.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM/Optimizer/AssignOp.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM/Refcount.php` + +**Warnings** (review for bootstrap subset): +- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/VM/Variable.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 89) +- new HashTable (line 102) +- new HashTable (line 106) +- 39 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Web/DevServer.php` + +**Warnings** (review for bootstrap subset): +- 14 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Web/ProjectManifest.php` + +**Warnings** (review for bootstrap subset): +- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `lib/Web/Superglobals.php` + +**Warnings** (review for bootstrap subset): +- new HashTable (line 257) +- new Variable (line 258) +- new Variable (line 277) +- new Variable (line 327) +- 15 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler + +### `src/macro_functions.php` + +**Warnings** (review for bootstrap subset): +- new Token (line 62) + diff --git a/script/bootstrap-inventory.php b/script/bootstrap-inventory.php new file mode 100644 index 00000000..da18b481 --- /dev/null +++ b/script/bootstrap-inventory.php @@ -0,0 +1,285 @@ +#!/usr/bin/env php + */ + public array $blockers = []; + + /** @var list */ + public array $warnings = []; + + private int $classMethodCount = 0; + + private int $closureCount = 0; + + public function enterNode(Node $node) + { + if ($node instanceof Node\Stmt\Try_) { + $this->blockers[] = 'try/catch (line '.$node->getLine().')'; + } elseif ($node instanceof Node\Expr\Yield_ || $node instanceof Node\Expr\YieldFrom) { + $this->blockers[] = 'generator yield (line '.$node->getLine().')'; + } elseif ($node instanceof Node\Stmt\ClassMethod && $node->name->toString() !== '__construct') { + ++$this->classMethodCount; + } elseif ($node instanceof Node\Stmt\Enum_) { + $this->blockers[] = 'enum (line '.$node->getLine().')'; + } elseif ($node instanceof Node\Stmt\Trait_) { + $this->warnings[] = 'trait '.$node->name.' (line '.$node->getLine().')'; + } elseif ($node instanceof Node\Expr\Closure || $node instanceof Node\Expr\ArrowFunction) { + ++$this->closureCount; + } elseif ($node instanceof Node\Expr\New_ && $node->class instanceof Node\Name) { + $name = $node->class->toString(); + if (!str_starts_with($name, 'PHPCompiler\\') + && !str_starts_with($name, 'PHPCfg\\') + && !str_starts_with($name, 'PHPTypes\\') + && !str_starts_with($name, 'PhpParser\\') + && !str_starts_with($name, 'PHPLLVM\\') + && !in_array($name, ['LogicException', 'RuntimeException', 'InvalidArgumentException', 'TypeError', 'ReflectionClass', 'SplObjectStorage'], true) + ) { + $this->warnings[] = 'new '.$name.' (line '.$node->getLine().')'; + } + } elseif ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { + $fn = $node->name->toString(); + if (in_array($fn, ['eval', 'create_function', 'shell_exec', 'exec', 'passthru'], true)) { + $this->blockers[] = $fn.'() (line '.$node->getLine().')'; + } + } + } + + public function beforeTraverse(array $nodes) + { + $this->classMethodCount = 0; + $this->closureCount = 0; + } + + public function afterTraverse(array $nodes) + { + if ($this->classMethodCount > 0) { + $this->warnings[] = $this->classMethodCount.' class method(s) — PHPCfg Op\\Stmt\\ClassMethod not lowered in Compiler'; + } + if ($this->closureCount > 0) { + $this->warnings[] = $this->closureCount.' closure(s)'; + } + } +} + +/** + * @return list + */ +function bootstrapExtractCompilerBlockers(string $compilerFile): array +{ + $source = (string) file_get_contents($compilerFile); + $blockers = []; + if (preg_match_all('/throw new \\\\LogicException\([\'"]([^\'"]+)[\'"]/', $source, $m)) { + foreach ($m[1] as $msg) { + if (stripos($msg, 'unknown') !== false || stripos($msg, 'unsupported') !== false) { + $blockers[] = $msg; + } + } + } + + return array_values(array_unique($blockers)); +} + +/** + * @return array{blockers: list, warnings: list} + */ +function bootstrapScanConstructs(string $file): array +{ + $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); + $code = (string) file_get_contents($file); + try { + $ast = $parser->parse($code); + } catch (Throwable $e) { + return [ + 'blockers' => ['parse error: '.$e->getMessage()], + 'warnings' => [], + ]; + } + if (!is_array($ast)) { + return ['blockers' => [], 'warnings' => []]; + } + + $visitor = new BootstrapConstructVisitor(); + $traverser = new NodeTraverser(); + $traverser->addVisitor($visitor); + $traverser->traverse($ast); + + return [ + 'blockers' => $visitor->blockers, + 'warnings' => $visitor->warnings, + ]; +} + +/** + * @param array $report + */ +function bootstrapRenderMarkdown(array $report): string +{ + $lines = []; + $lines[] = '# Bootstrap inventory (vm.php path)'; + $lines[] = ''; + $lines[] = 'Auto-generated by `script/bootstrap-inventory.php`. Tracks **Phase A** of [#212](https://github.com/PurHur/php-compiler/issues/212) (self-host bootstrap).'; + $lines[] = ''; + $lines[] = 'Regenerate: `php script/bootstrap-inventory.php`'; + $lines[] = ''; + $lines[] = '## Summary'; + $lines[] = ''; + $lines[] = '| Metric | Count |'; + $lines[] = '|--------|------:|'; + $lines[] = '| PHP files on vm.php path | '.$report['totals']['files'].' |'; + $lines[] = '| Source constructs flagged (blockers) | '.$report['totals']['blockers'].' |'; + $lines[] = '| Source constructs flagged (warnings) | '.$report['totals']['warnings'].' |'; + $lines[] = ''; + $lines[] = '## Compiler CFG gaps (`lib/Compiler.php`)'; + $lines[] = ''; + $lines[] = 'These `LogicException` messages indicate CFG ops or expressions not yet lowered:'; + $lines[] = ''; + foreach ($report['compiler_blockers'] as $msg) { + $lines[] = '- `'.$msg.'`'; + } + $lines[] = ''; + $lines[] = '## Files'; + $lines[] = ''; + $lines[] = '| File | Blockers | Warnings |'; + $lines[] = '|------|----------|----------|'; + foreach ($report['files'] as $rel => $info) { + $b = count($info['blockers']); + $w = count($info['warnings']); + if ($b === 0 && $w === 0) { + continue; + } + $lines[] = '| `'.$rel.'` | '.$b.' | '.$w.' |'; + } + $lines[] = ''; + $lines[] = '## Per-file construct flags'; + $lines[] = ''; + foreach ($report['files'] as $rel => $info) { + if ($info['blockers'] === [] && $info['warnings'] === []) { + continue; + } + $lines[] = '### `'.$rel.'`'; + $lines[] = ''; + if ($info['blockers'] !== []) { + $lines[] = '**Blockers** (likely prevent AOT bootstrap compile):'; + foreach ($info['blockers'] as $item) { + $lines[] = '- '.$item; + } + $lines[] = ''; + } + if ($info['warnings'] !== []) { + $lines[] = '**Warnings** (review for bootstrap subset):'; + foreach ($info['warnings'] as $item) { + $lines[] = '- '.$item; + } + $lines[] = ''; + } + } + + return implode("\n", $lines)."\n"; +} + +$check = in_array('--check', $argv, true); +$jsonOut = in_array('--json', $argv, true); +$outFile = $root.'/docs/bootstrap-inventory.md'; + +$entryFiles = [ + 'bin/vm.php', + 'src/cli.php', + 'src/tokenizer-compat.php', + 'src/yay-php8-compat.php', + 'src/llvm-env.php', + 'src/macro_functions.php', +]; + +$compilerBlockers = bootstrapExtractCompilerBlockers($root.'/lib/Compiler.php'); + +$files = []; +foreach ($entryFiles as $rel) { + $path = $root.'/'.$rel; + if (is_file($path)) { + $files[$path] = true; + } +} +foreach (['lib', 'ext', 'src'] as $dir) { + $base = $root.'/'.$dir; + if (!is_dir($base)) { + continue; + } + $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($base)); + foreach ($it as $file) { + if ($file->isFile() && str_ends_with($file->getPathname(), '.php')) { + $files[$file->getPathname()] = true; + } + } +} + +ksort($files, SORT_STRING); + +$fileReports = []; +$totals = ['files' => 0, 'blockers' => 0, 'warnings' => 0]; +foreach (array_keys($files) as $path) { + if (!is_file($path) || !str_ends_with($path, '.php')) { + continue; + } + $rel = substr($path, strlen($root) + 1); + $constructs = bootstrapScanConstructs($path); + $fileReports[$rel] = $constructs; + ++$totals['files']; + $totals['blockers'] += count($constructs['blockers']); + $totals['warnings'] += count($constructs['warnings']); +} + +$report = [ + 'entry' => 'bin/vm.php', + 'compiler_blockers' => $compilerBlockers, + 'totals' => $totals, + 'files' => $fileReports, +]; + +if ($jsonOut) { + echo json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)."\n"; + exit(0); +} + +$markdown = bootstrapRenderMarkdown($report); +if ($check) { + if (!is_file($outFile)) { + fwrite(STDERR, "Missing {$outFile}; run: php script/bootstrap-inventory.php\n"); + exit(1); + } + $committed = (string) file_get_contents($outFile); + if ($committed !== $markdown) { + fwrite(STDERR, "Stale {$outFile}; run: php script/bootstrap-inventory.php\n"); + exit(1); + } + exit(0); +} + +if (!is_dir(dirname($outFile))) { + mkdir(dirname($outFile), 0775, true); +} +file_put_contents($outFile, $markdown); +fwrite(STDOUT, "Wrote {$outFile} ({$totals['files']} files, {$totals['blockers']} blockers)\n"); diff --git a/script/ci-local.sh b/script/ci-local.sh index 7d75fda7..d54238d2 100755 --- a/script/ci-local.sh +++ b/script/ci-local.sh @@ -25,6 +25,7 @@ if [[ -x script/apply-patches.sh ]]; then fi "$PHP_BIN" "${PHP_OPTS[@]}" script/capability-matrix.php --check +"$PHP_BIN" "${PHP_OPTS[@]}" script/bootstrap-inventory.php --check LLVM_DIR="$(cd "$(dirname "$0")/.." && pwd)/.llvm" if [[ -f "$LLVM_DIR/libLLVM-9.so.1" ]]; then diff --git a/test/unit/BootstrapInventoryTest.php b/test/unit/BootstrapInventoryTest.php new file mode 100644 index 00000000..94cbbf17 --- /dev/null +++ b/test/unit/BootstrapInventoryTest.php @@ -0,0 +1,37 @@ +/dev/null'; + $json = shell_exec($cmd); + $this->assertIsString($json); + $report = json_decode($json, true); + $this->assertIsArray($report); + $this->assertSame('bin/vm.php', $report['entry']); + $this->assertGreaterThan(100, $report['totals']['files']); + $this->assertArrayHasKey('lib/Runtime.php', $report['files']); + $this->assertArrayHasKey('lib/Compiler.php', $report['files']); + } + + public function testInventoryDocIsFresh(): void + { + $root = dirname(__DIR__, 2); + $doc = $root.'/docs/bootstrap-inventory.md'; + $this->assertFileExists($doc); + $cmd = escapeshellarg(PHP_BINARY).' '.escapeshellarg($root.'/script/bootstrap-inventory.php').' --check 2>&1'; + exec($cmd, $out, $code); + $this->assertSame(0, $code, implode("\n", $out)); + } +}