On 03/01/2018 23:19, Michael Morris wrote:
I'm not familiar with the Zend Engine as I probably should be. I bring the
perspective of an end user. From what you've posted am I correct in stating
that PHP Type Hints / scalar Type Declarations are in truth syntactic sugar
for asserting the type checks.
This is how I've always pictured it, but I've never dug into the
implementation before, so I had a look. (If anyone's curious how I found
it, I started by searching for "callable", because it's a keyword that
should only show up in type hints, then clicked through on LXR to
everything that looked promising.)
It looks like the actual "assertion" is the function
zend_verify_arg_type [1] which calls zend_check_type [2] and formats an
appropriate Error if the type check returns false.
zend_check_type has to do various things depending on the type hint the
user specified, which I'm guessing are classified when the function is
compiled:
* Null values are checked against nullable type markers and null default
values.
* A class name traverses up through the inheritance hierarchy of the
argument until it finds a match or reaches the end [3], while an
interface name has to recursively check all interfaces that might be
indirectly implemented [4]
* The "callable" type hint has to check all sorts of different formats,
and is scope-dependent [5]
* Strict array and scalar type hints are just a comparison of bit fields
* Weak scalar type hints which aren't a direct match end up in
zend_verify_scalar_type_hint to perform coercion if possible [6]
When talking about additional type checks for assignment to properties,
or "locked" local variables, etc, this is the code we're saying needs to
be run more often. For simple types, in strict mode, it's not too bad,
but checking classes, interfaces, and complex pseudotypes like
"callable" seem pretty intensive. This is likely to get more complex
too: proposed additions include union types ("Foo|Bar"), intersection
types ("Foo&Bar"), typed arrays ("int[]"), generics ("Map<int,Foo>"),
and others.
So I guess I'm agreeing with Rasmus and Dan Ackroyd that thinking
there's an easy optimisation here is naive.
For the same reason, I am supportive of the idea of having type checks,
at least those we don't have yet, only enable with an off-by-default INI
setting, treating them like assertions or DbC, not as part of the normal
runtime behaviour.
[1]
https://php-lxr.adamharvey.name/source/xref/master/Zend/zend_execute.c#zend_verify_arg_type
[2]
https://php-lxr.adamharvey.name/source/xref/master/Zend/zend_execute.c#zend_check_type
[3]
https://php-lxr.adamharvey.name/source/xref/master/Zend/zend_operators.c#instanceof_class
[4]
https://php-lxr.adamharvey.name/source/xref/master/Zend/zend_operators.c#instanceof_interface
[5]
https://php-lxr.adamharvey.name/source/xref/master/Zend/zend_API.c#zend_is_callable_impl
[6]
https://php-lxr.adamharvey.name/source/xref/master/Zend/zend_execute.c#zend_verify_scalar_type_hint
--
Rowan Collins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php