parent
a31c84ed7f
commit
0eba3b72f9
4 changed files with 147 additions and 0 deletions
@ -0,0 +1,18 @@ |
||||
<?php |
||||
|
||||
function splRuntimeDirectCalls(Iterator $iterator, object $object, string $constantName): array |
||||
{ |
||||
return [ |
||||
iterator_count($iterator), |
||||
iterator_to_array($iterator), |
||||
iterator_to_array($iterator, false), |
||||
spl_object_hash($object), |
||||
spl_object_id($object), |
||||
constant($constantName), |
||||
]; |
||||
} |
||||
|
||||
function splRuntimeDynamicConstant(mixed $constantName): mixed |
||||
{ |
||||
return constant($constantName); |
||||
} |
||||
@ -0,0 +1,30 @@ |
||||
<?php |
||||
|
||||
use TypePhp\CompilerTest; |
||||
|
||||
final class SplRuntimeOptimizerTest extends BaseTest |
||||
{ |
||||
public function testCallsUseDirectPhpxWrappersWhenArgumentTypesAreSafe(): void |
||||
{ |
||||
global $translator; |
||||
|
||||
$compiler = CompilerTest::create(TYPEPHP_ROOT_PATH); |
||||
$translator = $compiler; |
||||
$source = TYPEPHP_ROOT_PATH . '/phpunit/code/spl-runtime-direct-calls.php'; |
||||
$compiler->addFiles([$source]); |
||||
$compiler->prepareFile($source); |
||||
$generated = $compiler->convertFile($source); |
||||
$code = file_get_contents($generated); |
||||
|
||||
self::assertIsString($code); |
||||
self::assertSame(1, substr_count($code, 'php::fn::iterator_count(')); |
||||
self::assertSame(2, substr_count($code, 'php::fn::iterator_to_array(')); |
||||
self::assertSame(1, substr_count($code, 'php::fn::spl_object_hash(')); |
||||
self::assertSame(1, substr_count($code, 'php::fn::spl_object_id(')); |
||||
self::assertSame(1, substr_count($code, 'php::fn::constant(')); |
||||
|
||||
// A mixed name must retain Zend's runtime parameter validation rather |
||||
// than being coerced into the String ABI used by the direct wrapper. |
||||
self::assertStringContainsString('php::call(', $code); |
||||
} |
||||
} |
||||
@ -0,0 +1,60 @@ |
||||
--TEST-- |
||||
SPL iterator, object identity, and constant functions use direct wrappers |
||||
--FILE-- |
||||
<?php |
||||
|
||||
function makeIterator(): Iterator |
||||
{ |
||||
return new ArrayIterator(['name' => 'phpx', 4 => 42]); |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
var_dump(iterator_count(makeIterator())); |
||||
var_dump(iterator_to_array(makeIterator())); |
||||
var_dump(iterator_to_array(makeIterator(), false)); |
||||
|
||||
$object = new stdClass(); |
||||
var_dump(spl_object_id($object) > 0); |
||||
var_dump(strlen(spl_object_hash($object)) === 32); |
||||
var_dump(spl_object_id($object) === spl_object_id($object)); |
||||
|
||||
define('TYPEPHP_RUNTIME_FAST_CONSTANT', ['ok' => true]); |
||||
var_dump(constant('TYPEPHP_RUNTIME_FAST_CONSTANT')); |
||||
|
||||
try { |
||||
iterator_count(42); |
||||
} catch (TypeError $error) { |
||||
echo $error->getMessage(), "\n"; |
||||
} |
||||
|
||||
try { |
||||
spl_object_hash('invalid'); |
||||
} catch (TypeError $error) { |
||||
echo $error->getMessage(), "\n"; |
||||
} |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
int(2) |
||||
array(2) { |
||||
["name"]=> |
||||
string(4) "phpx" |
||||
[4]=> |
||||
int(42) |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
string(4) "phpx" |
||||
[1]=> |
||||
int(42) |
||||
} |
||||
bool(true) |
||||
bool(true) |
||||
bool(true) |
||||
array(1) { |
||||
["ok"]=> |
||||
bool(true) |
||||
} |
||||
iterator_count(): Argument #1 ($iterator) must be of type Traversable|array, int given |
||||
spl_object_hash(): Argument #1 ($object) must be of type object, string given |
||||
Loading…
Reference in new issue