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

PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to