Object HHVM_STATIC_METHOD(AwaitAllWaitHandle, fromVec,
                          const Array& dependencies) {
  auto ad = dependencies.get();
  assertx(ad);
  assertx(ad->isVecArray());
  if (!ad->size()) return Object{returnEmpty()};
  return c_AwaitAllWaitHandle::FromPackedArray(ad);
}
예제 #2
0
Object HHVM_STATIC_METHOD(AwaitAllWaitHandle, fromVec,
                          const Array& dependencies) {
  auto ad = dependencies.get();
  assertx(ad);
  assertx(ad->isVecArray());
  if (!ad->size()) return Object{returnEmpty()};
  return c_AwaitAllWaitHandle::Create<false>([=](auto fn) {
    PackedArray::IterateV(ad, fn);
  });
}
예제 #3
0
void APCTypedValue::deleteUncounted() {
  assert(m_handle.isUncounted());
  auto kind = m_handle.kind();
  assert(kind == APCKind::UncountedString ||
         kind == APCKind::UncountedArray ||
         kind == APCKind::UncountedVec ||
         kind == APCKind::UncountedDict ||
         kind == APCKind::UncountedKeyset);
  if (kind == APCKind::UncountedString) {
    m_data.str->destructUncounted();
  } else if (kind == APCKind::UncountedArray) {
    assert(m_data.arr->isPHPArray());
    if (m_data.arr->hasPackedLayout()) {
      auto arr = m_data.arr;
      this->~APCTypedValue();
      PackedArray::ReleaseUncounted(arr, sizeof(APCTypedValue));
      return;  // Uncounted PackedArray frees the joint allocation.
    } else {
      auto arr = m_data.arr;
      this->~APCTypedValue();
      MixedArray::ReleaseUncounted(arr, sizeof(APCTypedValue));
      return;  // Uncounted MixedArray frees the joint allocation.
    }
  } else if (kind == APCKind::UncountedVec) {
    auto vec = m_data.vec;
    assert(vec->isVecArray());
    this->~APCTypedValue();
    PackedArray::ReleaseUncounted(vec, sizeof(APCTypedValue));
    return;
  } else if (kind == APCKind::UncountedDict) {
    auto dict = m_data.dict;
    assert(dict->isDict());
    this->~APCTypedValue();
    MixedArray::ReleaseUncounted(dict, sizeof(APCTypedValue));
    return;
  } else if (kind == APCKind::UncountedKeyset) {
    auto keyset = m_data.keyset;
    assert(keyset->isKeyset());
    this->~APCTypedValue();
    SetArray::ReleaseUncounted(keyset, sizeof(APCTypedValue));
    return;
  }

  delete this;
}
예제 #4
0
APCHandle::Pair APCHandle::Create(const Variant& source,
                                  bool serialized,
                                  APCHandleLevel level,
                                  bool unserializeObj) {

  auto type = source.getType(); // this gets rid of the ref, if it was one
  switch (type) {
    case KindOfUninit: {
      auto value = APCTypedValue::tvUninit();
      return {value->getHandle(), sizeof(APCTypedValue)};
    }
    case KindOfNull: {
      auto value = APCTypedValue::tvNull();
      return {value->getHandle(), sizeof(APCTypedValue)};
    }
    case KindOfBoolean: {
      auto value = source.getBoolean() ? APCTypedValue::tvTrue()
                                       : APCTypedValue::tvFalse();
      return {value->getHandle(), sizeof(APCTypedValue)};
    }
    case KindOfInt64: {
      auto value = new APCTypedValue(source.getInt64());
      return {value->getHandle(), sizeof(APCTypedValue)};
    }
    case KindOfDouble: {
      auto value = new APCTypedValue(source.getDouble());
      return {value->getHandle(), sizeof(APCTypedValue)};
    }
    case KindOfPersistentString:
    case KindOfString: {
      StringData* s = source.getStringData();
      if (serialized) {
        // It is priming, and there might not be the right class definitions
        // for unserialization.
        return APCString::MakeSerializedObject(apc_reserialize(String{s}));
      }
      if (s->isStatic()) {
        auto value = new APCTypedValue(APCTypedValue::StaticStr{}, s);
        return APCHandle::Pair{value->getHandle(), sizeof(APCTypedValue)};
      }
      auto const st = lookupStaticString(s);
      if (st) {
        auto value = new APCTypedValue(APCTypedValue::StaticStr{}, st);
        return {value->getHandle(), sizeof(APCTypedValue)};
      }
      if (apcExtension::UseUncounted) {
        auto st = StringData::MakeUncounted(s->slice());
        auto value = new APCTypedValue(APCTypedValue::UncountedStr{}, st);
        return {value->getHandle(), st->size() + sizeof(APCTypedValue)};
      }
      return APCString::MakeSharedString(s);
    }

    case KindOfPersistentVec:
    case KindOfVec: {
      auto ad = source.getArrayData();
      assert(ad->isVecArray());
      if (ad->isStatic()) {
        auto value = new APCTypedValue(APCTypedValue::StaticVec{}, ad);
        return {value->getHandle(), sizeof(APCTypedValue)};
      }

      return APCArray::MakeSharedVec(ad, level, unserializeObj);
    }

    case KindOfPersistentDict:
    case KindOfDict: {
      auto ad = source.getArrayData();
      assert(ad->isDict());
      if (ad->isStatic()) {
        auto value = new APCTypedValue(APCTypedValue::StaticDict{}, ad);
        return {value->getHandle(), sizeof(APCTypedValue)};
      }

      return APCArray::MakeSharedDict(ad, level, unserializeObj);
    }

    case KindOfPersistentKeyset:
    case KindOfKeyset: {
      auto ad = source.getArrayData();
      assert(ad->isKeyset());
      if (ad->isStatic()) {
        auto value = new APCTypedValue(APCTypedValue::StaticKeyset{}, ad);
        return {value->getHandle(), sizeof(APCTypedValue)};
      }

      return APCArray::MakeSharedKeyset(ad, level, unserializeObj);
    }

    case KindOfPersistentArray:
    case KindOfArray: {
      auto ad = source.getArrayData();
      assert(ad->isPHPArray());
      if (ad->isStatic()) {
        auto value = new APCTypedValue(APCTypedValue::StaticArr{}, ad);
        return {value->getHandle(), sizeof(APCTypedValue)};
      }

      return APCArray::MakeSharedArray(ad, level, unserializeObj);
    }

    case KindOfObject:
      if (source.getObjectData()->isCollection()) {
        return APCCollection::Make(source.getObjectData(),
                                   level,
                                   unserializeObj);
      }
      return unserializeObj ? APCObject::Construct(source.getObjectData()) :
             APCString::MakeSerializedObject(apc_serialize(source));

    case KindOfResource:
      // TODO Task #2661075: Here and elsewhere in the runtime, we convert
      // Resources to the empty array during various serialization operations,
      // which does not match Zend behavior. We should fix this.
      return APCArray::MakeSharedEmptyArray();

    case KindOfRef:
    case KindOfClass:
      return {nullptr, 0};
  }
  not_reached();
}
예제 #5
0
Variant APCHandle::toLocal() const {
  switch (m_kind) {
    case APCKind::Uninit:
    case APCKind::Null:
      return init_null(); // shortcut.. no point to forward
    case APCKind::Bool:
      return APCTypedValue::fromHandle(this)->getBoolean();
    case APCKind::Int:
      return APCTypedValue::fromHandle(this)->getInt64();
    case APCKind::Double:
      return APCTypedValue::fromHandle(this)->getDouble();
    case APCKind::StaticString:
    case APCKind::UncountedString:
      return Variant{APCTypedValue::fromHandle(this)->getStringData(),
                     Variant::PersistentStrInit{}};
    case APCKind::SharedString:
      return Variant::attach(
        StringData::MakeProxy(APCString::fromHandle(this))
      );
    case APCKind::StaticArray:
    case APCKind::UncountedArray:
      return Variant{APCTypedValue::fromHandle(this)->getArrayData(),
                     KindOfPersistentArray,
                     Variant::PersistentArrInit{}};
    case APCKind::StaticVec:
    case APCKind::UncountedVec:
      return Variant{APCTypedValue::fromHandle(this)->getVecData(),
                     KindOfPersistentVec,
                     Variant::PersistentArrInit{}};
    case APCKind::StaticDict:
    case APCKind::UncountedDict:
      return Variant{APCTypedValue::fromHandle(this)->getDictData(),
                     KindOfPersistentDict,
                     Variant::PersistentArrInit{}};
    case APCKind::StaticKeyset:
    case APCKind::UncountedKeyset:
      return Variant{APCTypedValue::fromHandle(this)->getKeysetData(),
                     KindOfPersistentKeyset,
                     Variant::PersistentArrInit{}};
    case APCKind::SerializedArray: {
      auto const serArr = APCString::fromHandle(this)->getStringData();
      auto const v = apc_unserialize(serArr->data(), serArr->size());
      assert(v.isPHPArray());
      return v;
    }
    case APCKind::SerializedVec: {
      auto const serVec = APCString::fromHandle(this)->getStringData();
      auto const v = apc_unserialize(serVec->data(), serVec->size());
      assert(v.isVecArray());
      return v;
    }
    case APCKind::SerializedDict: {
      auto const serDict = APCString::fromHandle(this)->getStringData();
      auto const v = apc_unserialize(serDict->data(), serDict->size());
      assert(v.isDict());
      return v;
    }
    case APCKind::SerializedKeyset: {
      auto const serKeyset = APCString::fromHandle(this)->getStringData();
      auto const v = apc_unserialize(serKeyset->data(), serKeyset->size());
      assert(v.isKeyset());
      return v;
    }
    case APCKind::SharedArray:
    case APCKind::SharedPackedArray:
      return Variant::attach(
        APCLocalArray::Make(APCArray::fromHandle(this))->asArrayData()
      );
    case APCKind::SharedVec:
      return Variant::attach(
        APCArray::fromHandle(this)->toLocalVec()
      );
    case APCKind::SharedDict:
      return Variant::attach(
        APCArray::fromHandle(this)->toLocalDict()
      );
    case APCKind::SharedKeyset:
      return Variant::attach(
        APCArray::fromHandle(this)->toLocalKeyset()
      );
    case APCKind::SerializedObject: {
      auto const serObj = APCString::fromHandle(this)->getStringData();
      return apc_unserialize(serObj->data(), serObj->size());
    }
    case APCKind::SharedCollection:
      return APCCollection::fromHandle(this)->createObject();
    case APCKind::SharedObject:
      return APCObject::MakeLocalObject(this);
  }
  not_reached();
}