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()"); } }
ArrayData* APCLocalArray::loadElems() const { auto count = m_arr->size(); ArrayData* elems; if (m_arr->isPacked()) { PackedArrayInit ai(count); for (uint i = 0; i < count; i++) { ai.append(GetValueRef(this, i)); } elems = ai.create(); } else { ArrayInit ai(count, ArrayInit::Mixed{}); for (uint i = 0; i < count; i++) { ai.add(getKey(i), GetValueRef(this, i), true); } elems = ai.create(); } if (elems->isStatic()) { elems = elems->copy(); } return elems; }
ArrayData* SharedVariant::loadElems(const SharedArray &array) { assert(is(KindOfArray)); auto count = arrSize(); ArrayData* elems; if (isPacked()) { PackedArrayInit ai(count); for (uint i = 0; i < count; i++) { ai.append(array.getValueRef(i)); } elems = ai.create(); } else { ArrayInit ai(count); for (uint i = 0; i < count; i++) { ai.add(m_data.array->getKeyIndex(i)->toLocal(), array.getValueRef(i), true); } elems = ai.create(); } if (elems->isStatic()) elems = elems->copy(); return elems; }
ArrayData* SharedVariant::loadElems(const SharedMap &sharedMap) { assert(is(KindOfArray)); auto count = arrSize(); ArrayData* elems; if (getIsVector()) { VectorInit ai(count); for (uint i = 0; i < count; i++) { ai.add(sharedMap.getValueRef(i)); } elems = ai.create(); } else { ArrayInit ai(count); for (uint i = 0; i < count; i++) { ai.add(m_data.map->getKeyIndex(i)->toLocal(), sharedMap.getValueRef(i), true); } elems = ai.create(); } if (elems->isStatic()) elems = elems->copy(); return elems; }
ArrayData* APCLocalArray::loadElems() const { auto count = m_arr->size(); ArrayData* elems; if (m_arr->isPacked()) { PackedArrayInit ai(count); for (uint32_t i = 0; i < count; i++) { ai.append(RvalAtPos(this, i).tv()); } elems = ai.create(); } else { ArrayInit ai(count, ArrayInit::Mixed{}); for (uint32_t i = 0; i < count; i++) { ai.add(getKey(i), RvalAtPos(this, i).tv(), true); } elems = ai.create(); } if (elems->isStatic()) { elems = elems->copy(); } assert(elems->hasExactlyOneRef()); return elems; }
ArrayData* SharedVariant::loadElems(const SharedMap &sharedMap, bool mapInit /* = false */) { assert(is(KindOfArray)); uint count = arrSize(); bool isVector = getIsVector(); ArrayInit ai = mapInit ? ArrayInit(count, ArrayInit::mapInit) : isVector ? ArrayInit(count, ArrayInit::vectorInit) : ArrayInit(count); if (isVector) { for (uint i = 0; i < count; i++) { ai.set(sharedMap.getValueRef(i)); } } else { for (uint i = 0; i < count; i++) { ai.add(m_data.map->getKeyIndex(i)->toLocal(), sharedMap.getValueRef(i), true); } } ArrayData* elems = ai.create(); if (elems->isStatic()) elems = elems->copy(); return elems; }
ArrayData* SharedMap::loadElems(bool mapInit /* = false */) const { uint count = size(); bool isVec = isVector(); auto ai = mapInit ? ArrayInit(count, ArrayInit::mapInit) : isVec ? ArrayInit(count, ArrayInit::vectorInit) : ArrayInit(count); if (isVec) { for (uint i = 0; i < count; i++) { ai.set(getValueRef(i)); } } else { for (uint i = 0; i < count; i++) { ai.add(m_map->getKey(i), getValueRef(i), true); } } ArrayData* elems = ai.create(); if (elems->isStatic()) elems = elems->copy(); return elems; }