コード例 #1
0
ファイル: ext_std_closure.cpp プロジェクト: neuroidss/hhvm
static Array HHVM_METHOD(Closure, __debugInfo) {
  auto closure = c_Closure::fromObject(this_);

  Array ret = Array::Create();

  // Serialize 'use' parameters.
  if (auto useVars = closure->getUseVars()) {
    Array use;

    auto cls = this_->getVMClass();
    auto propsInfo = cls->declProperties();
    auto nProps = cls->numDeclProperties();
    for (size_t i = 0; i < nProps; ++i) {
      auto value = &useVars[i];
      use.setWithRef(Variant(StrNR(propsInfo[i].name)), tvAsCVarRef(value));
    }

    if (!use.empty()) {
      ret.set(s_static, use);
    }
  }

  auto const func = closure->getInvokeFunc();

  // Serialize function parameters.
  if (auto nParams = func->numParams()) {
   Array params;

   auto lNames = func->localNames();
   for (int i = 0; i < nParams; ++i) {
      auto str = String::attach(
        StringData::Make(s_varprefix.get(), lNames[i])
      );

      bool optional = func->params()[i].phpCode;
      if (auto mi = func->methInfo()) {
        optional = optional || mi->parameters[i]->valueText;
      }

      params.set(str, optional ? s_optional : s_required);
    }

    ret.set(s_parameter, params);
  }

  // Serialize 'this' object.
  if (closure->hasThis()) {
    ret.set(s_this, Object(closure->getThis()));
  }

  return ret;
}
コード例 #2
0
ファイル: apc-object.cpp プロジェクト: smcshaner/hhvm
APCHandle::Pair APCObject::Construct(ObjectData* objectData) {
  // This function assumes the object and object/array down the tree have no
  // internal references and do not implement the serializable interface.
  assert(!objectData->instanceof(SystemLib::s_SerializableClass));

  auto cls = objectData->getVMClass();
  auto clsOrName = make_class(cls);
  if (clsOrName.right()) return ConstructSlow(objectData, clsOrName);

  // We have a persistent Class. Build an array of APCHandle* to mirror the
  // declared properties in the object.
  auto const propInfo = cls->declProperties();
  auto const hasDynProps = objectData->hasDynProps();
  auto const numRealProps = propInfo.size();
  auto const numApcProps = numRealProps + hasDynProps;
  auto size = sizeof(APCObject) + sizeof(APCHandle*) * numApcProps;
  auto const apcObj = new (malloc_huge(size)) APCObject(clsOrName, numApcProps);
  apcObj->m_persistent = 1;

  // Set a few more flags for faster fetching: whether or not the object has a
  // wakeup method, and whether or not we can use a fast path that avoids
  // default-initializing properties before setting them to their APC values.
  if (!cls->lookupMethod(s___wakeup.get())) apcObj->m_no_wakeup = 1;
  if (!cls->instanceCtor()) {
    apcObj->m_fast_init = 1;
  }

  auto const apcPropVec = apcObj->persistentProps();
  auto const objPropVec = objectData->propVec();
  const TypedValueAux* propInit = nullptr;

  for (unsigned i = 0; i < numRealProps; ++i) {
    auto const attrs = propInfo[i].attrs;
    assert((attrs & AttrStatic) == 0);

    const TypedValue* objProp;
    if (attrs & AttrBuiltin) {
      // Special properties like the Memoize cache should be set to their
      // default value, not the current value.
      if (propInit == nullptr) {
        propInit = cls->pinitVec().empty() ? &cls->declPropInit()[0]
                                           : &(*cls->getPropData())[0];
      }

      objProp = propInit + i;
    } else {
      objProp = objPropVec + i;
    }

    auto val = APCHandle::Create(tvAsCVarRef(objProp), false,
                                 APCHandleLevel::Inner, true);
    size += val.size;
    apcPropVec[i] = val.handle;
  }

  if (UNLIKELY(hasDynProps)) {
    auto val = APCHandle::Create(objectData->dynPropArray(), false,
                                 APCHandleLevel::Inner, true);
    size += val.size;
    apcPropVec[numRealProps] = val.handle;
  }

  return {apcObj->getHandle(), size};
}