On 06/07/2018 21:57, Nicolas Grekas wrote:

if ((new ReflectionReference($array[$key]))->getRefcount() > 2) {
I just realized that this interface would suffer from a significant
drawback: it would trigger COW when iterating over immutable arrays,
defeating the shared-memory optimization provided by OPcache.

Any implementation of this that acts like a normal function / constructor call is going to suffer from the same problems as debug_zval_dump: passing a variable from one scope to another will change the properties of that variable. If you accept the variable by reference, you'll duplicate the data if it's part of a COW set (which has nothing to do with OpCache by the way, it's been a core part of the engine since at least 5.0); if you accept it by value, you'll duplicate the data if it's part of a reference set. Either way, you're going to change the refcount on the zval, hence the awkward 2 in Bob's example.

Previous discussions of that function concluded that the only "correct" way to implement this would be as a language feature rather than a true function - if the compiler issues a specific OpCode, it can pull the zval straight out of the symbol table, without interfering with it.

Maybe the two concepts could be combined, and the language feature generate a Reflection object? e.g.

$reflection = reflect_variable($var);
if ( $reflection->isReference() ) {
    $types = $reflection->getReferencedTypes();
}



An interface like new ReflectionReference($array, $key) would be free from
the issue. Combined with get_defined_vars() and the (array) operator for
objects, we can inspect any PHP data structure or scope also this way.

Yuck. Even if this solves the issue of supporting both ref and non-ref variables, you still end up having to compensate for the wrong refcount, and the resultant code would be ugly as sin.

Regards,

--
Rowan Collins
[IMSoP]


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

Reply via email to