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
4 changes: 4 additions & 0 deletions lib/JIT/BootstrapCompileSmokeM3Emit.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
require_once __DIR__.'/RuntimeEmitTuInit.php';

use PHPCompiler\ext\standard\JitStringSearch;
use PHPCompiler\JIT\Builtin\StringFileGetContents;
use PHPCompiler\JIT\Builtin\StringGetenv;
use PHPLLVM\Builder;
use PHPLLVM\Value;
Expand Down Expand Up @@ -435,6 +436,9 @@ private static function emitSourceReadOrFail(
$i64 = $context->getTypeFromString('int64');
$strPtr = $context->getTypeFromString('__string__*');

// Lazy ensureFull (#35089 / peer #34578): Context no longer NestedJITs
// __compiler_file_get_contents during full standalone init (#15604 / #32122).
StringFileGetContents::ensureLinked($context);
$code = $context->builder->call(
$context->lookupFunction('__compiler_file_get_contents'),
$sourceFile
Expand Down
15 changes: 8 additions & 7 deletions lib/JIT/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -2498,19 +2498,20 @@ private function ensureFullStandaloneBodies(): void
// (#10173). Full standalone must not emit fn-static table ABI during init —
// leftover Context NestedJIT vs Runtime ABI drift mints phpc_fn_static_*.1
// (#31894 / #32122).
Builtin\StringUtf8Latin1::ensureStandaloneBodies($this);
Builtin\RewriteVarsRuntime::ensureStandaloneBodies($this);
Builtin\DefineRuntime::ensureStandaloneBodies($this);
// StringUtf8Latin1 / RewriteVars / Define / Strspn / FileGetContents / Readfile
// always-on removed (#35089): JitUtf8Latin1 / JitDefine / SpnJitLowering /
// JitParseStrUserScriptCstrKernel / JitFileGetContents / readfile.php /
// RewriteVarsRuntime::emit* / BootstrapCompileSmokeM3Emit already ensureLinked
// before lookup (peer ensureMinimal #34578 / Type #34474 / #34423). Full
// standalone must not NestedJIT those ABIs during init — leftover Context
// NestedJIT vs Runtime ABI drift mints utf8_*.1 / define.1 /
// file_get_contents.1 / readfile.1 / strspn.1 (#31894 / #32122).
Builtin\SuperglobalRefreshRuntime::ensureStandaloneBodies($this);
// SuperglobalName always-on removed (#35035): JitSuperglobalName / JIT.php
// StringSuperglobalName::ensureLinked before lookup (peer ensureMinimal #34812 /
// #33235). Full standalone must not NestedJIT is_superglobal_name during init —
// leftover Context NestedJIT vs Runtime ABI drift mints is_superglobal_name.1
// (#31894 / #32122).
Builtin\StringStrspn::ensureStandaloneBodies($this);
// BootstrapCompileSmokeM3Emit / inventory argv {main} calls __compiler_file_get_contents (#15604).
Builtin\StringFileGetContents::ensureStandaloneBodies($this);
Builtin\StringReadfile::ensureStandaloneBodies($this);
// TokenGetAll / Highlight / Hebrev / Hebrevc always-on removed (#35035): each
// ensureStandaloneBodies is a no-op — helper LLVM compiles on first lowering
// (TokenGetAll::helperFunction / JitHighlight / JitHebrev). Do not re-add eager
Expand Down
85 changes: 85 additions & 0 deletions test/unit/ContextFullStandaloneLazyStdlibRuntimeShrinkTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

namespace PHPCompiler\Test\Unit;

use PHPUnit\Framework\TestCase;

/**
* Drop Context::ensureFullStandaloneBodies always-on NestedJIT of Utf8Latin1 /
* RewriteVars / Define / Strspn / FileGetContents / Readfile (#35089 / peers #34578 / #35086).
*
* Full standalone must not NestedJIT those ABIs during init (#32122 .1 mint class).
* Call sites already ensureLinked before lookup.
*/
final class ContextFullStandaloneLazyStdlibRuntimeShrinkTest extends TestCase
{
public function testEnsureFullDropsEagerStdlibNestedJit(): void
{
$context = (string) file_get_contents(__DIR__.'/../../lib/JIT/Context.php');
$this->assertStringContainsString('#35089', $context);
$fullPos = strpos($context, 'private function ensureFullStandaloneBodies');
$this->assertNotFalse($fullPos);
$fullEnd = strpos($context, 'public function compileToFile', $fullPos);
$this->assertNotFalse($fullEnd);
$fullBody = substr($context, $fullPos, $fullEnd - $fullPos);

foreach ([
'StringUtf8Latin1::ensureStandaloneBodies($this)',
'RewriteVarsRuntime::ensureStandaloneBodies($this)',
'DefineRuntime::ensureStandaloneBodies($this)',
'StringStrspn::ensureStandaloneBodies($this)',
'StringFileGetContents::ensureStandaloneBodies($this)',
'StringReadfile::ensureStandaloneBodies($this)',
] as $forbidden) {
$this->assertStringNotContainsString(
$forbidden,
$fullBody,
'ensureFullStandaloneBodies must not eagerly '.$forbidden.' (#35089)'
);
}

// Still links echo / argv / refresh used by standalone main.
$this->assertStringContainsString('ValueEchoRuntime::ensureLinked($this)', $fullBody);
$this->assertStringContainsString('CliArgvRuntime::ensureStandaloneBodies($this)', $fullBody);
$this->assertStringContainsString('SuperglobalRefreshRuntime::ensureStandaloneBodies($this)', $fullBody);
}

public function testCallSitesStillEnsureBeforeLookup(): void
{
$checks = [
'ext/standard/JitUtf8Latin1.php' => 'StringUtf8Latin1::ensureLinked',
'ext/standard/JitDefine.php' => 'DefineRuntime::ensureLinked',
'ext/standard/JitFileGetContents.php' => 'StringFileGetContents::ensureLinked',
'ext/standard/readfile.php' => 'StringReadfile::ensureLinked',
'ext/standard/SpnJitLowering.php' => 'StringStrspn::ensureLinked',
'lib/JIT/Builtin/RewriteVarsRuntime.php' => 'self::ensureLinked($context)',
'lib/JIT/BootstrapCompileSmokeM3Emit.php' => 'StringFileGetContents::ensureLinked',
];
foreach ($checks as $rel => $needle) {
$path = __DIR__.'/../../'.$rel;
$this->assertFileExists($path, $rel);
$source = (string) file_get_contents($path);
$this->assertStringContainsString($needle, $source, $rel.' must ensure lazily (#35089)');
}
}

public function testNoNewRuntimeCForFullStdlibLazy(): void
{
$runtimeDir = dirname(__DIR__, 2).'/lib/AOT/runtime';
foreach ([
'file_get_contents.c',
'readfile.c',
'utf8_latin1.c',
'define_runtime.c',
'strspn.c',
'rewrite_vars.c',
] as $name) {
$this->assertFileDoesNotExist(
$runtimeDir.'/'.$name,
"must not add {$name} for #35089 — PHP JIT bridges only"
);
}
}
}
Loading