Re: [VOTE] Fix list() behavior inconsistency
| From: | Nikita Popov | Date: | Thu, 25 Sep 2014 22:09:49 +0000 |
| Subject: | Re: [VOTE] Fix list() behavior inconsistency | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-77638@lists.php.net to get a copy of this message | ||
On Thu, Sep 25, 2014 at 11:50 PM, Stas Malyshev <smalyshev@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