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();
}
Exemple #6
0
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();
}
Exemple #7
0
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();
}