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
13 changes: 6 additions & 7 deletions lib/JIT/Builtin/StringParseStr.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use PHPCompiler\JIT\Context;

/**
* JIT link for __compiler_parse_str — PHP helper on embed, LLVM on standalone (#9295).
* JIT link for __compiler_parse_str — ParseStrRuntime PHP on embed and standalone (#9295, #13360).
*/
final class StringParseStr
{
Expand All @@ -16,14 +16,13 @@ public static function ensureLinked(Context $context): void
self::implement($context);
}

public static function implement(Context $context): void
public static function ensureStandaloneBodies(Context $context): void
{
if (Builtin::LOAD_TYPE_STANDALONE === $context->loadType) {
StringParseStrJit::implement($context);

return;
}
self::implement($context);
}

public static function implement(Context $context): void
{
ParseStrRuntime::implement($context);
StringParseStrJit::ensureSubhelpers($context);
}
Expand Down
58 changes: 2 additions & 56 deletions lib/JIT/Builtin/StringParseStrJit.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ final class StringParseStrJit
/** Standalone AOT: bracket/delimited-pair helpers for superglobals_refresh.c (#7302). */
public static function ensureStandaloneBodies(Context $context): void
{
self::implement($context);
self::ensureSubhelpers($context);
}

/** Superglobals/multipart LLVM helpers only — main entry is {@see ParseStrRuntime} (#9295). */
/** Superglobals/multipart LLVM helpers only — main entry is {@see ParseStrRuntime} (#9295, #13360). */
public static function ensureSubhelpers(Context $context): void
{
$restore = self::captureInsertBlock($context);
Expand All @@ -56,26 +56,6 @@ public static function ensureSubhelpers(Context $context): void
self::restoreInsertBlock($context, $restore);
}

public static function implement(Context $context): void
{
$restore = self::captureInsertBlock($context);
self::ensureLibc($context);
self::ensureHashtableHelpers($context);

$probe = $context->module->getNamedFunction('__compiler_parse_str');
if (null !== $probe && $probe->countBasicBlocks() > 0) {
$context->registerFunction('__compiler_parse_str', $probe);
self::restoreInsertBlock($context, $restore);

return;
}

self::ensureSubhelpers($context);
self::implementIfMissing($context, '__compiler_parse_str', self::emitCompilerParseStr(...));

self::restoreInsertBlock($context, $restore);
}

/**
* @param callable(Context, LlvmFunction): void $emit
*/
Expand Down Expand Up @@ -1015,40 +995,6 @@ private static function emitParseDelimitedPairs(Context $context, LlvmFunction $
$context->builder->returnVoid();
}

private static function emitCompilerParseStr(Context $context, LlvmFunction $fn): void
{
$entry = $fn->appendBasicBlock('entry');
$context->builder->positionAtEnd($entry);

$dest = $fn->getParam(0);
$encoded = $fn->getParam(1);
$htPtr = $context->getTypeFromString('__hashtable__*');
$strMap = $context->structFieldMap['__string__'];
$i8p = $context->getTypeFromString('int8*');

$nullDest = $context->builder->icmp(Builder::INT_EQ, $dest, $htPtr->constNull());
$early = $fn->appendBasicBlock('cps_early');
$work = $fn->appendBasicBlock('cps_work');
$context->builder->branchIf($nullDest, $early, $work);

$context->builder->positionAtEnd($early);
$context->builder->returnVoid();

$context->builder->positionAtEnd($work);
$data = $context->builder->structGep($encoded, $strMap['value']);
$body = $context->builder->pointerCast($data, $i8p);
$amp = $context->getTypeFromString('int8')->constInt(38, false);
$zeroI32 = $context->getTypeFromString('int32')->constInt(0, false);
$context->builder->call(
$context->lookupFunction('__phpc_parse_str_parse_delimited_pairs'),
$dest,
$body,
$amp,
$zeroI32
);
$context->builder->returnVoid();
}

private static function strndup(Context $context, Value $src, Value $len): Value
{
$sizeT = $context->getTypeFromString('size_t');
Expand Down
2 changes: 1 addition & 1 deletion lib/JIT/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ private function defineBuiltins(int $loadType): void {
Builtin\CliArgvRuntime::ensureStandaloneBodies($this);
Builtin\StringStripTags::ensureStandaloneBodies($this);
Builtin\StringStrtr::ensureStandaloneBodies($this);
Builtin\StringParseStrJit::ensureStandaloneBodies($this);
Builtin\StringParseStr::ensureStandaloneBodies($this);
Builtin\StringJsonEncode::ensureStandaloneBodies($this);
Builtin\StringJsonDecode::ensureStandaloneBodies($this);
Builtin\StringGetenv::ensureDeferredStubsForInventoryEmit($this);
Expand Down
9 changes: 7 additions & 2 deletions test/unit/ParseStrRuntimeShrinkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,18 @@ public function testParseStrEngineExposesDelimitedParserForSuperglobals(): void
$this->assertStringContainsString('cookiePairDecode', $source);
}

public function testStringParseStrRoutesJitEmbedThroughParseStrRuntime(): void
public function testStringParseStrRoutesAllLoadTypesThroughParseStrRuntime(): void
{
$source = (string) file_get_contents($this->repoRoot.'/lib/JIT/Builtin/StringParseStr.php');
$this->assertStringContainsString('ParseStrRuntime::implement', $source);
$this->assertStringContainsString('StringParseStrJit::ensureSubhelpers', $source);
$this->assertStringContainsString('StringParseStrJit::implement', $source);
$this->assertStringNotContainsString('StringParseStrJit::implement', $source);
$this->assertStringNotContainsString('LOAD_TYPE_STANDALONE', $source);
$this->assertLessThan(35, \substr_count($source, "\n") + 1);

$jit = (string) file_get_contents($this->repoRoot.'/lib/JIT/Builtin/StringParseStrJit.php');
$this->assertStringNotContainsString('emitCompilerParseStr', $jit);
$this->assertStringNotContainsString('function implement(', $jit);
}

public function testParseStrJitHelperDelegatesToParseStrEngine(): void
Expand Down