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