コード例 #1
0
ファイル: ext_std_closure.cpp プロジェクト: fredemmott/hhvm
void c_Closure::init(int numArgs, ActRec* ar, TypedValue* sp) {
  auto const cls = getVMClass();
  auto const invokeFunc = getInvokeFunc();

  if (invokeFunc->cls()) {
    setThisOrClass(ar->getThisOrClass());
    if (invokeFunc->isStatic()) {
      if (!hasClass()) {
        setClass(getThisUnchecked()->getVMClass());
      }
    } else if (!hasClass()) {
      getThisUnchecked()->incRefCount();
    }
  } else {
    hdr()->ctx = nullptr;
  }

  /*
   * Copy the use vars to instance variables, and initialize any
   * instance properties that are for static locals to KindOfUninit.
   */
  auto const numDeclProperties = cls->numDeclProperties();
  assertx(numDeclProperties - numArgs == getInvokeFunc()->numStaticLocals());
  auto beforeCurUseVar = sp + numArgs;
  auto curProperty = getUseVars();
  int i = 0;
  assertx(numArgs <= numDeclProperties);
  for (; i < numArgs; i++) {
    // teleport the references in here so we don't incref
    tvCopy(*--beforeCurUseVar, *curProperty++);
  }
  for (; i < numDeclProperties; ++i) {
    tvWriteUninit(*curProperty++);
  }
}
コード例 #2
0
ファイル: runtime.cpp プロジェクト: StetHD/hhvm
int init_closure(ActRec* ar, TypedValue* sp) {
  auto closure = c_Closure::fromObject(ar->getThis());

  // Swap in the $this or late bound class or null if it is ony from a plain
  // function or pseudomain
  ar->setThisOrClassAllowNull(closure->getThisOrClass());

  if (ar->hasThis()) {
    ar->getThis()->incRefCount();
  }

  // Put in the correct context
  ar->m_func = closure->getInvokeFunc();

  // The closure is the first local.
  // Similar to tvWriteObject() but we don't incref because it used to be $this
  // and now it is a local, so they cancel out
  TypedValue* firstLocal = --sp;
  firstLocal->m_type = KindOfObject;
  firstLocal->m_data.pobj = closure;

  // Copy in all the use vars
  TypedValue* prop = closure->getUseVars();
  int n = closure->getNumUseVars();
  for (int i=0; i < n; i++) {
    tvDup(*prop++, *--sp);
  }

  return n + 1;
}
コード例 #3
0
ファイル: ext_closure.cpp プロジェクト: nadanomics/hhvm
void c_Closure::init(int numArgs, ActRec* ar, TypedValue* sp) {
  auto const invokeFunc = getVMClass()->lookupMethod(s_uuinvoke.get());

  m_ctx = ar->m_this;
  if (ar->hasThis()) {
    if (invokeFunc->isStatic()) {
      // Only set the class for static closures.
      setClass(ar->getThis()->getVMClass());
    } else {
      ar->getThis()->incRefCount();
    }
  }

  /*
   * Copy the use vars to instance variables, and initialize any
   * instance properties that are for static locals to KindOfUninit.
   */
  auto const numDeclProperties = getVMClass()->numDeclProperties();
  assert(numDeclProperties - numArgs == getInvokeFunc()->numStaticLocals());
  TypedValue* beforeCurUseVar = sp + numArgs;
  TypedValue* curProperty = propVec();
  int i = 0;
  assert(numArgs <= numDeclProperties);
  for (; i < numArgs; i++) {
    // teleport the references in here so we don't incref
    tvCopy(*--beforeCurUseVar, *curProperty++);
  }
  for (; i < numDeclProperties; ++i) {
    tvWriteUninit(curProperty++);
  }
}
コード例 #4
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;
}
コード例 #5
0
ファイル: ext_closure.cpp プロジェクト: nadanomics/hhvm
Array c_Closure::t___debuginfo() {
  Array ret = Array::Create();

  // Serialize 'use' parameters.
  if (auto propValues = propVec()) {
    Array use;

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

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

  auto const func = getInvokeFunc();

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

   for (int i = 0; i < func->numParams(); ++i) {
      auto str = String::attach(
        StringData::Make(s_varprefix.get(), func->localNames()[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 (hasThis()) {
    ret.set(s_this, Object(getThis()));
  }

  return ret;
}