Object c_AwaitAllWaitHandle::ti_frommap(const Variant& dependencies) { if (LIKELY(dependencies.isObject())) { auto obj = dependencies.getObjectData(); if (LIKELY(obj->isCollection() && isMapCollection(obj->collectionType()))) { assertx(collections::isType(obj->getVMClass(), CollectionType::Map, CollectionType::ImmMap)); return FromMap(static_cast<BaseMap*>(obj)); } } failMap(); }
Object c_AwaitAllWaitHandle::ti_frommap(const Variant& dependencies) { if (LIKELY(dependencies.isObject())) { auto obj = dependencies.getObjectData(); if (LIKELY(obj->isCollection() && isMapCollection(obj->collectionType()))) { assert(obj->instanceof(c_Map::classof()) || obj->instanceof(c_ImmMap::classof())); return FromMap(static_cast<BaseMap*>(obj)); } } failMap(); }
Object c_AwaitAllWaitHandle::ti_fromvector(const Variant& dependencies) { if (LIKELY(dependencies.isObject())) { auto obj = dependencies.getObjectData(); if (LIKELY(obj->isCollection() && isVectorCollection(obj->collectionType()))) { assertx(collections::isType(obj->getVMClass(), CollectionType::Vector, CollectionType::ImmVector)); return FromVector(static_cast<BaseVector*>(obj)); } } failVector(); }
Object c_AwaitAllWaitHandle::ti_fromvector(const Variant& dependencies) { if (LIKELY(dependencies.isObject())) { auto obj = dependencies.getObjectData(); if (LIKELY(obj->isCollection() && isVectorCollection(obj->collectionType()))) { assert(obj->instanceof(c_Vector::classof()) || obj->instanceof(c_ImmVector::classof())); return FromVector(static_cast<BaseVector*>(obj)); } } failVector(); }
Object HHVM_STATIC_METHOD(AwaitAllWaitHandle, fromMap, const Variant& dependencies) { if (LIKELY(dependencies.isObject())) { auto obj = dependencies.getObjectData(); if (LIKELY(obj->isCollection() && isMapCollection(obj->collectionType()))) { assertx(collections::isType(obj->getVMClass(), CollectionType::Map, CollectionType::ImmMap)); return c_AwaitAllWaitHandle::Create<false>([=](auto fn) { MixedArray::IterateV(static_cast<BaseMap*>(obj)->arrayData(), fn); }); } } failMap(); }
void deepCopy(TypedValue* tv) { switch (tv->m_type) { DT_UNCOUNTED_CASE: case KindOfString: case KindOfResource: case KindOfRef: case KindOfClass: return; case KindOfArray: { auto arr = deepCopyArray(tv->m_data.parr); decRefArr(tv->m_data.parr); tv->m_data.parr = arr; return; } case KindOfObject: { auto obj = tv->m_data.pobj; if (!obj->isCollection()) return; const auto copyVector = [](BaseVector* vec) { Object o = Object::attach(vec); vec->mutate(); assertx(vec->canMutateBuffer()); auto sz = vec->m_size; for (size_t i = 0; i < sz; ++i) { deepCopy(&vec->m_data[i]); } return o.detach(); }; const auto copyMap = [](BaseMap* mp) { Object o = Object::attach(mp); mp->mutate(); auto used = mp->posLimit(); for (uint32_t i = 0; i < used; ++i) { if (mp->isTombstone(i)) continue; auto* e = &mp->data()[i]; deepCopy(&e->data); } return o.detach(); }; switch (obj->collectionType()) { case CollectionType::Pair: { auto pair = c_Pair::Clone(static_cast<c_Pair*>(obj)); Object o = Object::attach(pair); deepCopy(&pair->elm0); deepCopy(&pair->elm1); obj = o.detach(); break; } case CollectionType::Vector: obj = copyVector(c_Vector::Clone(static_cast<c_Vector*>(obj))); break; case CollectionType::ImmVector: obj = copyVector(c_ImmVector::Clone(static_cast<c_ImmVector*>(obj))); break; case CollectionType::Map: obj = copyMap(c_Map::Clone(static_cast<c_Map*>(obj))); break; case CollectionType::ImmMap: obj = copyMap(c_ImmMap::Clone(static_cast<c_ImmMap*>(obj))); break; case CollectionType::Set: obj = c_Set::Clone(static_cast<c_Set*>(obj)); break; case CollectionType::ImmSet: obj = c_ImmSet::Clone(static_cast<c_ImmSet*>(obj)); break; default: assertx(false); } decRefObj(tv->m_data.pobj); tv->m_data.pobj = obj; return; } } not_reached(); }
void deepCopy(TypedValue* tv) { switch (tv->m_type) { DT_UNCOUNTED_CASE: case KindOfString: case KindOfResource: case KindOfRef: case KindOfKeyset: return; case KindOfVec: { auto arr = deepCopyVecArray(tv->m_data.parr); decRefArr(tv->m_data.parr); tv->m_data.parr = arr; return; } case KindOfDict: { auto arr = deepCopyDict(tv->m_data.parr); decRefArr(tv->m_data.parr); tv->m_data.parr = arr; return; } case KindOfArray: { auto arr = deepCopyArray(tv->m_data.parr); decRefArr(tv->m_data.parr); tv->m_data.parr = arr; return; } case KindOfObject: { auto obj = tv->m_data.pobj; if (!obj->isCollection()) return; const auto copyVector = [](BaseVector* vec) { if (vec->size() > 0 && vec->arrayData()->isRefCounted()) { vec->mutate(); auto elm = vec->data(); auto end = vec->data() + vec->size(); do { deepCopy(elm); } while (++elm < end); } return vec; }; const auto copyMap = [](BaseMap* mp) { if (mp->size() > 0 && mp->arrayData()->isRefCounted()) { mp->mutate(); auto used = mp->posLimit(); for (uint32_t i = 0; i < used; ++i) { if (mp->isTombstone(i)) continue; auto* e = &mp->data()[i]; deepCopy(&e->data); } } return mp; }; switch (obj->collectionType()) { case CollectionType::Pair: { auto pair = c_Pair::Clone(static_cast<c_Pair*>(obj)); Object o = Object::attach(pair); deepCopy(&pair->elm0); deepCopy(&pair->elm1); obj = o.detach(); break; } case CollectionType::Vector: obj = copyVector(c_Vector::Clone(static_cast<c_Vector*>(obj))); break; case CollectionType::ImmVector: obj = copyVector(c_ImmVector::Clone(static_cast<c_ImmVector*>(obj))); break; case CollectionType::Map: obj = copyMap(c_Map::Clone(static_cast<c_Map*>(obj))); break; case CollectionType::ImmMap: obj = copyMap(c_ImmMap::Clone(static_cast<c_ImmMap*>(obj))); break; case CollectionType::Set: obj = c_Set::Clone(static_cast<c_Set*>(obj)); break; case CollectionType::ImmSet: obj = c_ImmSet::Clone(static_cast<c_ImmSet*>(obj)); break; default: assertx(false); } assert(obj != tv->m_data.pobj || tv->m_data.pobj->hasMultipleRefs()); decRefObj(tv->m_data.pobj); tv->m_data.pobj = obj; return; } } not_reached(); }