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
3 changes: 2 additions & 1 deletion lib/JIT/Builtin/StringXmlrpc.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
use PHPLLVM\Builder;

/**
* JIT/AOT link for __compiler_xmlrpc_* via Xmlrpc*JitHelper PHP (#19048).
* JIT/AOT link for __compiler_xmlrpc_* via Xmlrpc*JitHelper PHP (#19048, #32902).
*
* Owns module-local ABI decls (getNamedFunction first) — Type always-on shells removed.
* php-src: ext/xmlrpc/xmlrpc.c — PHP_FUNCTION(xmlrpc_encode), xmlrpc_decode
*/
final class StringXmlrpc
Expand Down
25 changes: 8 additions & 17 deletions lib/JIT/Builtin/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -937,23 +937,13 @@ public function register(): void {
// (JitVmHelperLink::ensureBridge / Runtime implement); Type::initialize still
// ensureLinked. Leftover Type empty decls vs Runtime ABI drift mint
// json_encode.1 (#31894 / #32122).
$fntypeXmlrpcEncodeValue = $this->context->context->functionType(
$this->context->getTypeFromString('__string__*'),
false,
$valuePtr
);
$fnXmlrpcEncodeValue = $this->context->module->addFunction(
'__compiler_xmlrpc_encode_value',
$fntypeXmlrpcEncodeValue
);
$this->context->registerFunction('__compiler_xmlrpc_encode_value', $fnXmlrpcEncodeValue);
// __compiler_xmlrpc_encode_array always-on shell removed (#32250): leftover;
// StringXmlrpc ABI is __compiler_xmlrpc_encode_value + __compiler_xmlrpc_decode.
$fnXmlrpcDecode = $this->context->module->addFunction(
'__compiler_xmlrpc_decode',
$this->context->context->functionType($void, false, $strPtr, $valuePtr)
);
$this->context->registerFunction('__compiler_xmlrpc_decode', $fnXmlrpcDecode);
// __compiler_xmlrpc_encode_value / __compiler_xmlrpc_decode always-on shells
// removed (#32902): __compiler_xmlrpc_encode_array already dropped (#32250).
// User-script xmlrpc_encode()/xmlrpc_decode() stay StringXmlrpc /
// ext/xmlrpc/JitXmlrpc. NestedJIT/AOT bridges getNamedFunction first
// (JitVmHelperLink::ensureBridge / decode emit addFunction if absent);
// Type::initialize still ensureLinked. Leftover Type empty decls vs Runtime
// ABI drift mint xmlrpc_encode.1 (#31894 / #32122).
$fntypeSerializeHashtable = $this->context->context->functionType(
$this->context->getTypeFromString('__string__*'),
false,
Expand Down Expand Up @@ -1113,6 +1103,7 @@ public function initialize(): void {
StringHashAlgos::ensureLinked($this->context);
StringJsonEncode::ensureLinked($this->context);
StringJsonDecode::ensureLinked($this->context);
StringXmlrpc::ensureLinked($this->context);
StringQuotPrint::ensureLinked($this->context);
StringUtf8Latin1::ensureLinked($this->context);
StringCslashes::ensureStandaloneBodies($this->context);
Expand Down
2 changes: 1 addition & 1 deletion test/unit/TypeDeadCompilerAbiRuntimeShrinkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function testTypeBuiltinDropsLeftoverAlwaysOnDeadCompilerAbis(): void
}
$this->assertStringContainsString("addFunction('exit'", $type);
$this->assertStringContainsString("addFunction('abort'", $type);
$this->assertStringContainsString("registerFunction('__compiler_xmlrpc_encode_value'", $type);
// __compiler_xmlrpc_encode_value always-on shell removed (#32902); ownership in StringXmlrpc.
$this->assertStringContainsString("registerFunction('__compiler_number_format'", $type);
}

Expand Down
75 changes: 75 additions & 0 deletions test/unit/TypeDeadXmlrpcAbiRuntimeShrinkTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

declare(strict_types=1);

namespace PHPCompiler\Test\Unit;

use PHPUnit\Framework\TestCase;

/**
* Drop leftover always-on xmlrpc ABI shells from Builtin\Type (#32902).
*
* NestedJIT/AOT bridges stay StringXmlrpc / ext/xmlrpc/JitXmlrpc.
* Runtime owners declare module-locally (getNamedFunction first) so leftover
* Type empty decls cannot mint xmlrpc_encode.1 (#31894 / #32122).
*/
final class TypeDeadXmlrpcAbiRuntimeShrinkTest extends TestCase
{
/** @return list<string> */
private function droppedAbis(): array
{
return [
'__compiler_xmlrpc_encode_value',
'__compiler_xmlrpc_decode',
];
}

public function testTypeBuiltinDropsLeftoverAlwaysOnXmlrpcAbis(): void
{
$type = (string) file_get_contents(__DIR__.'/../../lib/JIT/Builtin/Type.php');
$this->assertStringContainsString('#32902', $type);
foreach ($this->droppedAbis() as $sym) {
$this->assertDoesNotMatchRegularExpression(
'/addFunction\(\s*[\'"]'.preg_quote($sym, '/').'[\'"]/',
$type,
"Builtin\\Type must not always-declare {$sym} (#32902)"
);
$this->assertStringNotContainsString(
"registerFunction('{$sym}'",
$type,
"Builtin\\Type must not always-register {$sym} (#32902)"
);
}
$this->assertStringContainsString("addFunction('exit'", $type);
$this->assertStringContainsString("addFunction('abort'", $type);
$this->assertStringContainsString("registerFunction('__compiler_convert_uuencode'", $type);
$this->assertStringContainsString('StringXmlrpc::ensureLinked', $type);
}

public function testRuntimeOwnerDeclaresXmlrpcAbisModuleLocally(): void
{
$owner = (string) file_get_contents(__DIR__.'/../../lib/JIT/Builtin/StringXmlrpc.php');
$this->assertStringContainsString('#32902', $owner);
$this->assertStringContainsString('getNamedFunction', $owner);
foreach ($this->droppedAbis() as $sym) {
$this->assertStringContainsString($sym, $owner, "{$sym} must remain owned by StringXmlrpc (#32902)");
}
$jit = (string) file_get_contents(__DIR__.'/../../ext/xmlrpc/JitXmlrpc.php');
$this->assertStringContainsString('StringXmlrpc::ensureEncodeLinked', $jit);
$this->assertStringContainsString('StringXmlrpc::ensureDecodeLinked', $jit);
}

public function testTypeInitializeStillEnsureLinksXmlrpcRuntime(): void
{
$type = (string) file_get_contents(__DIR__.'/../../lib/JIT/Builtin/Type.php');
$this->assertStringContainsString('StringXmlrpc::ensureLinked($this->context)', $type);
}

public function testNoNewRuntimeCForXmlrpcAbis(): void
{
$this->assertFileDoesNotExist(dirname(__DIR__, 2).'/lib/AOT/runtime/xmlrpc.c');
$this->assertFileDoesNotExist(dirname(__DIR__, 2).'/runtime/xmlrpc.c');
$this->assertFileDoesNotExist(dirname(__DIR__, 2).'/lib/AOT/runtime/xmlrpc_encode.c');
$this->assertFileDoesNotExist(dirname(__DIR__, 2).'/runtime/xmlrpc_encode.c');
}
}
Loading