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
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ test-harness:
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
.PHONY: bootstrap-inventory bootstrap-profile bootstrap-aot-lint
bootstrap-inventory:
php script/bootstrap-inventory.php
bootstrap-profile: bootstrap-inventory
php script/bootstrap-profile.php
bootstrap-aot-lint: bootstrap-profile
php script/bootstrap-aot-lint.php
281 changes: 281 additions & 0 deletions docs/bootstrap-profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
{
"phase": "B",
"issue": 212,
"entry": "bin/vm.php",
"unsupported_constructs": [
"try/catch",
"generator yield",
"enum",
"eval()",
"create_function()",
"shell_exec()",
"exec()",
"passthru()"
],
"compiler_cfg_gaps": [
"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: "
],
"excluded_files": [
"lib/AOT/Linker.php",
"lib/VM/HashTable.php"
],
"eligible_files": [
"bin/vm.php",
"ext/standard/JitBin2hex.php",
"ext/standard/JitDate.php",
"ext/standard/JitEnv.php",
"ext/standard/JitExplode.php",
"ext/standard/JitHeader.php",
"ext/standard/JitHex2bin.php",
"ext/standard/JitHtmlspecialchars.php",
"ext/standard/JitHttpResponseCode.php",
"ext/standard/JitImplode.php",
"ext/standard/JitNl2br.php",
"ext/standard/JitNumberFormat.php",
"ext/standard/JitParseUrl.php",
"ext/standard/JitPath.php",
"ext/standard/JitRandomBytes.php",
"ext/standard/JitRealpath.php",
"ext/standard/JitRequestBody.php",
"ext/standard/JitStrPad.php",
"ext/standard/JitStrRepeat.php",
"ext/standard/JitStrReplace.php",
"ext/standard/JitStrSplit.php",
"ext/standard/JitStringConcat.php",
"ext/standard/JitStringIndex.php",
"ext/standard/JitStripTags.php",
"ext/standard/JitStrpos.php",
"ext/standard/JitUrlencode.php",
"ext/standard/Module.php",
"ext/standard/VmDate.php",
"ext/standard/VmExit.php",
"ext/standard/VmFs.php",
"ext/standard/VmNumberFormat.php",
"ext/standard/VmScope.php",
"ext/standard/VmString.php",
"ext/standard/abs.php",
"ext/standard/array_combine.php",
"ext/standard/array_count.php",
"ext/standard/array_fill.php",
"ext/standard/array_flip.php",
"ext/standard/array_key_exists.php",
"ext/standard/array_keys.php",
"ext/standard/array_merge.php",
"ext/standard/array_pop.php",
"ext/standard/array_push.php",
"ext/standard/array_reverse.php",
"ext/standard/array_search.php",
"ext/standard/array_shift.php",
"ext/standard/array_slice.php",
"ext/standard/array_sum.php",
"ext/standard/array_unique.php",
"ext/standard/array_values.php",
"ext/standard/basename.php",
"ext/standard/bin2hex.php",
"ext/standard/bindec.php",
"ext/standard/boolval.php",
"ext/standard/ceil.php",
"ext/standard/chr.php",
"ext/standard/compact_.php",
"ext/standard/cos.php",
"ext/standard/date.php",
"ext/standard/decbin.php",
"ext/standard/dechex.php",
"ext/standard/decoct.php",
"ext/standard/deg2rad.php",
"ext/standard/dirname.php",
"ext/standard/exp.php",
"ext/standard/explode.php",
"ext/standard/extract_.php",
"ext/standard/file_get_contents.php",
"ext/standard/floatval.php",
"ext/standard/floor.php",
"ext/standard/fmod.php",
"ext/standard/getallheaders_.php",
"ext/standard/getenv_.php",
"ext/standard/gettype.php",
"ext/standard/glob_.php",
"ext/standard/gmdate.php",
"ext/standard/header_.php",
"ext/standard/header_list.php",
"ext/standard/header_remove.php",
"ext/standard/hex2bin.php",
"ext/standard/hexdec.php",
"ext/standard/htmlspecialchars.php",
"ext/standard/http_response_code.php",
"ext/standard/implode.php",
"ext/standard/in_array.php",
"ext/standard/int_max.php",
"ext/standard/int_min.php",
"ext/standard/intdiv.php",
"ext/standard/intval.php",
"ext/standard/is_finite.php",
"ext/standard/is_infinite.php",
"ext/standard/is_nan.php",
"ext/standard/is_numeric.php",
"ext/standard/is_scalar.php",
"ext/standard/lcfirst.php",
"ext/standard/log.php",
"ext/standard/nl2br.php",
"ext/standard/number_format.php",
"ext/standard/octdec.php",
"ext/standard/ord.php",
"ext/standard/parse_url.php",
"ext/standard/pi.php",
"ext/standard/pow.php",
"ext/standard/putenv_.php",
"ext/standard/rad2deg.php",
"ext/standard/random_bytes.php",
"ext/standard/range.php",
"ext/standard/rawurldecode.php",
"ext/standard/rawurlencode.php",
"ext/standard/realpath.php",
"ext/standard/round.php",
"ext/standard/scandir.php",
"ext/standard/sin.php",
"ext/standard/sort_.php",
"ext/standard/sqrt.php",
"ext/standard/str_contains.php",
"ext/standard/str_ends_with.php",
"ext/standard/str_pad.php",
"ext/standard/str_repeat.php",
"ext/standard/str_replace.php",
"ext/standard/str_split.php",
"ext/standard/str_starts_with.php",
"ext/standard/strcmp.php",
"ext/standard/string_ltrim.php",
"ext/standard/string_rtrim.php",
"ext/standard/string_trim.php",
"ext/standard/strip_tags.php",
"ext/standard/stripos.php",
"ext/standard/strncmp.php",
"ext/standard/strpos.php",
"ext/standard/strrev.php",
"ext/standard/strtolower.php",
"ext/standard/strtoupper.php",
"ext/standard/strval.php",
"ext/standard/substr.php",
"ext/standard/tan.php",
"ext/standard/time.php",
"ext/standard/ucfirst.php",
"ext/standard/ucwords.php",
"ext/standard/urldecode.php",
"ext/standard/urlencode.php",
"ext/standard/var_dump.php",
"ext/types/Module.php",
"ext/types/is_type.php",
"ext/types/mb_strlen.php",
"ext/types/strlen.php",
"lib/Block.php",
"lib/Cli/PhpcInit.php",
"lib/Compiler.php",
"lib/Doctor.php",
"lib/Frame.php",
"lib/Func.php",
"lib/Func/Internal.php",
"lib/Func/JIT.php",
"lib/Func/PHP.php",
"lib/Handler.php",
"lib/JIT.php",
"lib/JIT/Analyzer.php",
"lib/JIT/ArrayBuiltinHelper.php",
"lib/JIT/BasicBlockHelper.php",
"lib/JIT/Builtin.php",
"lib/JIT/Builtin/ErrorHandler.php",
"lib/JIT/Builtin/HttpResponseCode.php",
"lib/JIT/Builtin/Internal.php",
"lib/JIT/Builtin/MemoryManager.php",
"lib/JIT/Builtin/MemoryManager/Native.php",
"lib/JIT/Builtin/MemoryManager/PHP.php",
"lib/JIT/Builtin/Output.php",
"lib/JIT/Builtin/Refcount.php",
"lib/JIT/Builtin/ScriptExit.php",
"lib/JIT/Builtin/StringDateTime.php",
"lib/JIT/Builtin/StringGetenv.php",
"lib/JIT/Builtin/StringHtmlspecialchars.php",
"lib/JIT/Builtin/StringNl2br.php",
"lib/JIT/Builtin/StringRandomBytes.php",
"lib/JIT/Builtin/StringUcwords.php",
"lib/JIT/Builtin/StringUrldecode.php",
"lib/JIT/Builtin/StringUrlencode.php",
"lib/JIT/Builtin/Type.php",
"lib/JIT/Builtin/Type/HashTable.php",
"lib/JIT/Builtin/Type/MaskedArray.php",
"lib/JIT/Builtin/Type/NativeArray.php",
"lib/JIT/Builtin/Type/Object_.php",
"lib/JIT/Builtin/Type/String_.php",
"lib/JIT/Builtin/Type/Value.php",
"lib/JIT/Builtin/VarArg.php",
"lib/JIT/Call.php",
"lib/JIT/Call/Native.php",
"lib/JIT/Call/Vararg.php",
"lib/JIT/CoalesceHelper.php",
"lib/JIT/Context.php",
"lib/JIT/HashTableHelper.php",
"lib/JIT/Helper.php",
"lib/JIT/IssetHelper.php",
"lib/JIT/JitNativeString.php",
"lib/JIT/JitValueBox.php",
"lib/JIT/JitValueCompare.php",
"lib/JIT/NullsafeHelper.php",
"lib/JIT/OperandName.php",
"lib/JIT/Result.php",
"lib/JIT/Scope.php",
"lib/JIT/StringOffsetHelper.php",
"lib/JIT/SuperglobalInit.php",
"lib/JIT/ValueEchoHelper.php",
"lib/JIT/Variable.php",
"lib/Lint/IncrementDetector.php",
"lib/Lint/Issue.php",
"lib/Lint/LintCompiler.php",
"lib/Lint/Linter.php",
"lib/Lint/ListDestructuringDetector.php",
"lib/Lint/SwitchDetector.php",
"lib/Lint/UnsupportedRegistry.php",
"lib/Module.php",
"lib/ModuleAbstract.php",
"lib/OpCode.php",
"lib/Printer.php",
"lib/Runtime.php",
"lib/VM.php",
"lib/VM/ClassEntry.php",
"lib/VM/ClassProperty.php",
"lib/VM/Context.php",
"lib/VM/ErrorReporter.php",
"lib/VM/ObjectEntry.php",
"lib/VM/Optimizer.php",
"lib/VM/Optimizer/AssignOp.php",
"lib/VM/Refcount.php",
"lib/VM/ScriptExit.php",
"lib/VM/Variable.php",
"lib/Web/DevServer.php",
"lib/Web/ProjectManifest.php",
"lib/Web/ResponseContext.php",
"lib/Web/Superglobals.php",
"src/cli.php",
"src/llvm-env.php",
"src/macro_functions.php",
"src/tokenizer-compat.php",
"src/yay-php8-compat.php"
],
"aot_lint_targets": [
"examples/000-HelloWorld/example.php",
"test/bootstrap-aot/echo_hello.php"
],
"totals": {
"inventory_files": 239,
"excluded": 2,
"eligible": 237,
"aot_lint_targets": 2
}
}
94 changes: 94 additions & 0 deletions script/bootstrap-aot-lint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env php
<?php

declare(strict_types=1);

/**
* Bootstrap AOT lint gate (issue #212 Phase B).
*
* Runs bin/compile.php -l on each path in docs/bootstrap-profile.json aot_lint_targets.
* Requires LLVM 9 (same as @group aot tests). Exits 2 when LLVM is missing (skip in CI).
*
* Usage:
* php script/bootstrap-aot-lint.php
* php script/bootstrap-aot-lint.php --verbose
*/

$root = dirname(__DIR__);
require $root.'/vendor/autoload.php';
require __DIR__.'/bootstrap-lib.php';

$verbose = in_array('--verbose', $argv, true);
$profileFile = $root.'/docs/bootstrap-profile.json';

if (!is_file($profileFile)) {
fwrite(STDERR, "Missing {$profileFile}; run: php script/bootstrap-profile.php\n");
exit(1);
}

/** @var array<string, mixed> $profile */
$profile = json_decode((string) file_get_contents($profileFile), true);
if (!is_array($profile) || !isset($profile['aot_lint_targets']) || !is_array($profile['aot_lint_targets'])) {
fwrite(STDERR, "Invalid bootstrap profile: {$profileFile}\n");
exit(1);
}

$llvmDir = bootstrapResolveLlvmDir($root);
if (null === $llvmDir) {
fwrite(STDERR, "bootstrap-aot-lint: LLVM 9 not found (skip)\n");
exit(2);
}

$compileBin = $root.'/bin/compile.php';
if (!is_file($compileBin)) {
fwrite(STDERR, "Missing {$compileBin}\n");
exit(1);
}

$env = bootstrapLlvmProcessEnv($llvmDir);
$phpBin = PHP_BINARY;
$failures = [];

foreach ($profile['aot_lint_targets'] as $rel) {
if (!is_string($rel)) {
continue;
}
$path = $root.'/'.$rel;
if (!is_file($path)) {
$failures[] = "{$rel}: file not found";
continue;
}
$cmd = [$phpBin, $compileBin, '-l', $path];
$descriptorSpec = [
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
];
$proc = proc_open($cmd, $descriptorSpec, $pipes, $root, $env);
if (!is_resource($proc)) {
$failures[] = "{$rel}: proc_open failed";
continue;
}
fclose($pipes[0]);
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$code = proc_close($proc);
if (0 !== $code) {
$detail = trim(($stderr !== false ? $stderr : '')."\n".($stdout !== false ? $stdout : ''));
$failures[] = "{$rel}: exit {$code}".('' !== $detail ? "\n".$detail : '');
continue;
}
if ($verbose) {
fwrite(STDOUT, "OK {$rel}\n");
}
}

if ($failures !== []) {
fwrite(STDERR, "bootstrap-aot-lint failed:\n".implode("\n\n", $failures)."\n");
exit(1);
}

fwrite(STDOUT, 'bootstrap-aot-lint: '.count($profile['aot_lint_targets'])." target(s) OK\n");
exit(0);
Loading
Loading