On Thu, Sep 25, 2014 at 11:50 PM, Stas Malyshev <smalys...@sugarcrm.com>
wrote:

> Hi!
>
> > It was on design. list() was intended to support plain arrays only.
>
> I'm not sure I'm getting this point - why list($a, $b) = $foo is not
> just translated as $a = $foo[0], $b = $foo[1], etc.? Is it hard to make
> it work that way?
>

That's exactly what list() does. The only catch is that $foo here is reused
multiple times and mustn't be freed in the meantime (for the cases where
$foo is some complex expression resulting in an VAR or TMP_VAR operand).
That's what the ZEND_FETCH_ADD_LOCK flags for FETCH_DIM_R does - it does
$foo[0] without freeing $foo.

However back when list() was introduced FETCH_DIM_R didn't support CONST or
TMP_VAR operands, so instead these two used a separate FETCH_DIM_TMP_VAR
opcode, which supports only arrays and not strings or objects. Support for
CONST|TMP in FETCH_DIM_R was only added in PHP 5.5 as part of constant
string/array dereferencing.

Long story short, because FETCH_DIM_R now supports CONST and TMP_VAR
operands, we can always use it and FETCH_DIM_TMP_VAR can be dropped -
that's all that has to be done in order to always support strings and
objects in list(). (I've linked a patch for this previously, see
https://github.com/nikic/php-src/compare/stringOffsetsInList).

If I understood it correctly, then Dmitry's alternative is to add support
for CV and VAR operands to FETCH_DIM_TMP_VAR and always use that for
list(). This avoids having to check the ZEND_FETCH_ADD_LOCK flag in
FETCH_DIM_R. However I don't think that this optimization is related to
whether or not we support strings and objects. We can have a separate
opcode only for list() in either case, no matter which choice is made here.

Nikita

Reply via email to