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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ composer install
| `PHP_COMPILER_LLVM_PATH` | Path to LLVM 9 `clang`, `ld`, and `libLLVM-9.so.1` (default: repo `.llvm/` after install) |
| `PHP_COMPILER_SKIP_SERVE_TESTS` | Skip `ServeTest` / `ServeAotTest` (set on GitHub Actions; use in sandboxes that cannot bind TCP) |
| `PHP_COMPILER_RUN_SERVE_TESTS` | Force HTTP serve integration tests even when loopback bind probe fails |
| `PHP_COMPILER_ALLOW_JIT_SKIP` | Do not fail `ci-local.sh` when LLVM is present but JIT compliance tests are 100% skipped (broken dev env only) |

`script/ci-local.sh` sets LLVM paths automatically when `.llvm/libLLVM-9.so.1` exists. It probes `127.0.0.1` bind capability and runs `@group serve` tests when allowed. **GitHub Actions** sets `PHP_COMPILER_SKIP_SERVE_TESTS=1` because hosted runners often block listeners; **local and Docker CI** (`make test-docker`, `./script/docker-ci-local.sh`) must run those tests — do not export the skip variable there.

Expand Down
20 changes: 13 additions & 7 deletions docs/bootstrap-inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ Regenerate: `php script/bootstrap-inventory.php`

| Metric | Count |
|--------|------:|
| PHP files on vm.php path | 192 |
| PHP files on vm.php path | 193 |
| Source constructs flagged (blockers) | 10 |
| Source constructs flagged (warnings) | 514 |
| Source constructs flagged (warnings) | 515 |

## Compiler CFG gaps (`lib/Compiler.php`)

Expand Down Expand Up @@ -44,6 +44,7 @@ These `LogicException` messages indicate CFG ops or expressions not yet lowered:
| `ext/standard/JitRealpath.php` | 0 | 1 |
| `ext/standard/JitStrPad.php` | 0 | 1 |
| `ext/standard/JitStrRepeat.php` | 0 | 1 |
| `ext/standard/JitStrReplace.php` | 0 | 1 |
| `ext/standard/JitStringConcat.php` | 0 | 1 |
| `ext/standard/JitStringIndex.php` | 0 | 1 |
| `ext/standard/JitStrpos.php` | 0 | 1 |
Expand Down Expand Up @@ -281,6 +282,11 @@ These `LogicException` messages indicate CFG ops or expressions not yet lowered:
**Warnings** (review for bootstrap subset):
- 1 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler

### `ext/standard/JitStrReplace.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):
Expand Down Expand Up @@ -809,7 +815,7 @@ These `LogicException` messages indicate CFG ops or expressions not yet lowered:
### `ext/standard/str_replace.php`

**Warnings** (review for bootstrap subset):
- 2 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler
- 3 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler

### `ext/standard/str_split.php`

Expand Down Expand Up @@ -1048,10 +1054,10 @@ These `LogicException` messages indicate CFG ops or expressions not yet lowered:
- 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)
- new Variable (line 718)
- new Operand\Literal (line 788)
- new Operand\Literal (line 792)
- new Operand\Literal (line 796)
- 11 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler

### `lib/JIT/Analyzer.php`
Expand Down
69 changes: 69 additions & 0 deletions script/check-jit-compliance-ran.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env php
<?php

declare(strict_types=1);

/**
* Fail CI when LLVM is present but JIT compliance (JITTest) ran zero tests.
*
* @see https://github.com/PurHur/php-compiler/issues/250
* @see https://github.com/PurHur/php-compiler/issues/98
*/
if ($argc < 2) {
fwrite(STDERR, "Usage: {$argv[0]} <junit-xml> [llvm-dir]\n");
exit(2);
}

$junitPath = $argv[1];
$llvmDir = $argv[2] ?? getenv('PHP_COMPILER_LLVM_PATH') ?: '';

if (!is_file($junitPath)) {
fwrite(STDERR, "JIT compliance guard: JUnit log not found: {$junitPath}\n");
exit(1);
}

$xml = @simplexml_load_file($junitPath);
if (false === $xml) {
fwrite(STDERR, "JIT compliance guard: could not parse JUnit XML: {$junitPath}\n");
exit(1);
}

$total = 0;
$skipped = 0;
$executed = 0;

/** @var \SimpleXMLElement $testcase */
foreach ($xml->xpath('//testcase') ?: [] as $testcase) {
$classname = (string) ($testcase['classname'] ?? '');
$file = (string) ($testcase['file'] ?? '');
if (!str_contains($classname, 'JITTest') && !str_contains($file, 'JITTest.php')) {
continue;
}
++$total;
if (isset($testcase->skipped)) {
++$skipped;
} else {
++$executed;
}
}

if (0 === $total) {
fwrite(STDERR, "JIT compliance guard: no JITTest cases in {$junitPath}\n");
fwrite(STDERR, " Ensure @group llvm includes test/compliance/JITTest.php.\n");
exit(1);
}

if (0 === $executed) {
fwrite(STDERR, "JIT compliance guard FAILED: LLVM is present but all {$total} JIT tests were skipped.\n");
if ('' !== $llvmDir) {
fwrite(STDERR, " LLVM dir: {$llvmDir}\n");
}
fwrite(STDERR, " Fix: export PHP_COMPILER_LLVM_PATH to a tree containing libLLVM-9.so.1\n");
fwrite(STDERR, " and prepend that directory to LD_LIBRARY_PATH and PATH.\n");
fwrite(STDERR, " Docker: use /opt/llvm9 (image #237) — avoid a broken host .llvm/ bind-mount override.\n");
fwrite(STDERR, " Override (broken dev env only): PHP_COMPILER_ALLOW_JIT_SKIP=1\n");
exit(1);
}

fwrite(STDOUT, "JIT compliance guard OK: {$executed} of {$total} JIT tests executed ({$skipped} skipped).\n");
exit(0);
9 changes: 8 additions & 1 deletion script/ci-local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,12 @@ fi

if [[ -f "$LLVM_DIR/libLLVM-9.so.1" ]]; then
echo "PHPUnit: JIT, AOT (web fixtures + examples, ExamplesCompileTest AOT lint)..."
"$PHP_BIN" "${PHP_OPTS[@]}" vendor/bin/phpunit --group llvm --exclude-group serve "$@"
LLVM_JUNIT="$(mktemp "${TMPDIR:-/tmp}/llvm-junit.XXXXXX.xml")"
"$PHP_BIN" "${PHP_OPTS[@]}" vendor/bin/phpunit --group llvm --exclude-group serve --log-junit "$LLVM_JUNIT" "$@"
if [[ -n "${PHP_COMPILER_ALLOW_JIT_SKIP:-}" ]]; then
echo "JIT compliance guard skipped (PHP_COMPILER_ALLOW_JIT_SKIP is set)."
else
"$PHP_BIN" "${PHP_OPTS[@]}" script/check-jit-compliance-ran.php "$LLVM_JUNIT" "$LLVM_DIR"
fi
rm -f "$LLVM_JUNIT"
fi
Loading