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