From f60fc06fc0f9d9f9f60904bad8f7b8906f2b9ca6 Mon Sep 17 00:00:00 2001 From: Alex Malyshev Date: Mon, 14 Apr 2014 21:10:27 -0700 Subject: [PATCH] Fix order of key/val setting for IterNext helpers The correct ordering is to set the value first, then the key. (if it exists) After combing runtime/base/array-iterator.cpp, I found a few instances where we had this flipped. Reviewed By: @jdelong Differential Revision: D1275430 --- hphp/runtime/base/array-iterator.cpp | 6 +++--- hphp/test/slow/eval_order/1501.php | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/hphp/runtime/base/array-iterator.cpp b/hphp/runtime/base/array-iterator.cpp index f7a993f48fe..8288d08b236 100644 --- a/hphp/runtime/base/array-iterator.cpp +++ b/hphp/runtime/base/array-iterator.cpp @@ -1255,13 +1255,13 @@ int64_t new_iter_array_key(Iter* dest, static_cast(IterNextIndex::ArrayPacked) << 16 | itypeU32; assert(aiter.m_itype == ArrayIter::TypeArray); assert(aiter.m_nextHelperIdx == IterNextIndex::ArrayPacked); - keyOut->m_type = KindOfInt64; - keyOut->m_data.num = 0; if (WithRef) { tvDupWithRef(*packedData(ad), *valOut); } else { cellDup(*tvToCell(packedData(ad)), *valOut); } + keyOut->m_type = KindOfInt64; + keyOut->m_data.num = 0; return 1; } @@ -1766,12 +1766,12 @@ int64_t iter_next_packed_impl(Iter* it, } tvDecRefOnly(valOut); iter.setPos(pos); + cellDup(*tvToCell(packedData(ad) + pos), *valOut); if (HasKey) { tvDecRefOnly(keyOut); keyOut->m_data.num = pos; keyOut->m_type = KindOfInt64; } - cellDup(*tvToCell(packedData(ad) + pos), *valOut); return 1; } diff --git a/hphp/test/slow/eval_order/1501.php b/hphp/test/slow/eval_order/1501.php index 97ebade6a00..a25aa635dc6 100644 --- a/hphp/test/slow/eval_order/1501.php +++ b/hphp/test/slow/eval_order/1501.php @@ -1,6 +1,10 @@ $x) { - var_dump($x); - } +function main() { + $a = array(123); + foreach ($a as $x => $x) { + var_dump($x); + } +} + +main(); -- 2.11.4.GIT