void c_MutableArrayIterator::t___construct(VRefParam array) { INSTANCE_METHOD_INJECTION_BUILTIN(MutableArrayIterator, MutableArrayIterator::__construct); if (m_valid) { MIterCtx& mi = marr(); mi.~MIterCtx(); m_valid = false; } Variant var(strongBind(array)); TypedValue* tv = (TypedValue*)(&var); ASSERT(tv->m_type == KindOfRef); if (tv->m_data.ptv->m_type == KindOfArray) { ArrayData* ad = tv->m_data.ptv->m_data.parr; if (ad->getCount() > 1) { ArrayData* copy = ad->copy(); copy->incRefCount(); ad->decRefCount(); // count > 1 to begin with; don't need release ad = tv->m_data.ptv->m_data.parr = copy; } MIterCtx& mi = marr(); (void) new (&mi) MIterCtx(tv->m_data.pref); m_valid = mi.m_mArray->advance(); if (!m_valid) mi.~MIterCtx(); } else if (tv->m_data.ptv->m_type == KindOfObject) { CStrRef ctxStr = hhvm ? g_vmContext->getContextClassName(true) : FrameInjection::GetClassName(true); bool isIterator; Object obj = tv->m_data.ptv->m_data.pobj->iterableObject(isIterator); if (isIterator) { raise_error("An iterator cannot be used with foreach by reference"); } Array iterArray = obj->o_toIterArray(ctxStr, true); ArrayData* ad = iterArray.getArrayData(); if (ad->getCount() > 1) { ArrayData* copy = ad->copy(); copy->incRefCount(); ad->decRefCount(); // count > 1 to begin with; don't need release ad = copy; } MIterCtx& mi = marr(); (void) new (&mi) MIterCtx(ad); m_valid = mi.m_mArray->advance(); if (!m_valid) mi.~MIterCtx(); } else { raise_warning("Invalid argument supplied for foreach()"); } }