コード例 #1
0
ファイル: ext_function.cpp プロジェクト: hashaash/hiphop-php
Array hhvm_get_frame_args(const ActRec* ar) {
  if (ar == NULL) {
    return Array();
  }
  HPHP::VM::ExtraArgs* eArgs = ar->getExtraArgs();
  int numParams = ar->m_func->numParams();
  int numArgs = ar->numArgs();
  HphpArray* retval = NEW(HphpArray)(numArgs);

  TypedValue* local = (TypedValue*)(uintptr_t(ar) - sizeof(TypedValue));
  for (int i = 0; i < numArgs; ++i) {
    if (i < numParams) {
      // This corresponds to one of the function's formal parameters, so it's
      // on the stack.
      retval->nvAppend(local, false);
      --local;
    } else {
      // This is not a formal parameter, so it's in the ExtraArgs.
      ASSERT(eArgs);
      ASSERT(i - numParams < (int)eArgs->numExtraArgs());
      retval->nvAppend(eArgs->getExtraArg(i - numParams), false);
    }
  }

  return Array(retval);
}
コード例 #2
0
RefData* staticLocInitImpl(StringData* name, ActRec* fp, TypedValue val,
                           TargetCache::CacheHandle ch) {
  assert(useTargetCache == (bool)ch);
  HphpArray* map;
  if (useTargetCache) {
    // If we have a cache handle, we know the current func isn't a
    // closure or generator closure so we can directly grab its static
    // locals map.
    const Func* func = fp->m_func;
    assert(!(func->isClosureBody() || func->isGeneratorFromClosure()));
    map = func->getStaticLocals();
  } else {
    map = get_static_locals(fp);
  }

  TypedValue *mapVal = map->nvGet(name);
  if (!mapVal) {
    map->set(name, tvAsCVarRef(&val), false);
    mapVal = map->nvGet(name);
  }
  if (mapVal->m_type != KindOfRef) {
    tvBox(mapVal);
  }
  assert(mapVal->m_type == KindOfRef);
  RefData* ret = mapVal->m_data.pref;
  if (useTargetCache) {
    *TargetCache::handleToPtr<RefData*>(ch) = ret;
  }
  ret->incRefCount();
  return ret;
}
コード例 #3
0
ファイル: runtime.cpp プロジェクト: mambaliu/hiphop-php
bool run_intercept_handler_for_invokefunc(TypedValue* retval,
                                          const Func* f,
                                          CArrRef params,
                                          ObjectData* this_,
                                          StringData* invName,
                                          Variant* ihandler) {
  using namespace HPHP::VM::Transl;
  ASSERT(ihandler);
  ASSERT(retval);
  Variant doneFlag = true;
  Array args = params;
  if (invName) {
    // This is a magic call, so we need to shuffle the args
    HphpArray* magicArgs = NEW(HphpArray)(2);
    magicArgs->append(invName, false);
    magicArgs->append(params, false);
    args = magicArgs;
  }
  Array intArgs =
    CREATE_VECTOR5(f->fullNameRef(), (this_ ? Variant(Object(this_)) : null),
                   args, ihandler->asCArrRef()[1], ref(doneFlag));
  call_intercept_handler<false>(retval, intArgs, NULL, ihandler);
  // $done is true, meaning don't enter the intercepted function.
  return !doneFlag.toBoolean();
}
コード例 #4
0
ファイル: runtime.cpp プロジェクト: mambaliu/hiphop-php
HOT_FUNC
int64 new_iter_array(Iter* dest, ArrayData* ad, TypedValue* valOut) {
  TRACE(2, "%s: I %p, ad %p\n", __func__, dest, ad);
  valOut = tvToCell(valOut);
  if (UNLIKELY(!IsHphpArray(ad))) {
    goto cold;
  }
  {
    HphpArray* arr = (HphpArray*)ad;
    if (LIKELY(arr->getSize() != 0)) {
      if (UNLIKELY(tvWillBeReleased(valOut))) {
        goto cold;
      }
      tvDecRefOnly(valOut);
      // We are transferring ownership of the array to the iterator, therefore
      // we do not need to adjust the refcount.
      (void) new (&dest->arr()) ArrayIter(arr, ArrayIter::noIncNonNull);
      dest->m_itype = Iter::TypeArray;
      HphpArray::Elm* elm = arr->getElm(dest->arr().m_pos);
      getHphpArrayElm(elm, valOut, NULL);
      return 1LL;
    }
    // We did not transfer ownership of the array to an iterator, so we need
    // to decRef the array.
    if (UNLIKELY(arr->getCount() == 1)) {
      goto cold;
    }
    arr->decRefCount();
    return 0LL;
  }
cold:
  return new_iter_array_cold(dest, ad, valOut, NULL);
}
コード例 #5
0
ファイル: ext_class.cpp プロジェクト: Sydney-o9/hiphop-php
Array vm_get_class_vars(CStrRef className) {
  HPHP::VM::Class* cls = HPHP::VM::Unit::lookupClass(className.get());
  if (cls == NULL) {
    raise_error("Unknown class %s", className->data());
  }
  cls->initialize();

  const VM::Class::SProp* sPropInfo = cls->staticProperties();
  const size_t numSProps = cls->numStaticProperties();
  const VM::Class::Prop* propInfo = cls->declProperties();
  const size_t numDeclProps = cls->numDeclProperties();

  // The class' instance property initialization template is in different
  // places, depending on whether it has any request-dependent initializers
  // (i.e. constants)
  const VM::Class::PropInitVec& declPropInitVec = cls->declPropInit();
  const VM::Class::PropInitVec* propVals = !cls->pinitVec().empty()
    ? cls->getPropData() : &declPropInitVec;
  ASSERT(propVals != NULL);
  ASSERT(propVals->size() == numDeclProps);

  // For visibility checks
  CallerFrame cf;
  HPHP::VM::Class* ctx = arGetContextClass(cf());
  const ClassInfo* ctxCI =
    (ctx == NULL ? NULL : g_vmContext->findClassInfo(CStrRef(ctx->nameRef())));
  ClassInfo::PropertyMap propMap;
  g_vmContext->findClassInfo(className)->getAllProperties(propMap);

  HphpArray* ret = NEW(HphpArray)(numDeclProps + numSProps);

  for (size_t i = 0; i < numDeclProps; ++i) {
    StringData* name = const_cast<StringData*>(propInfo[i].m_name);
    // Empty names are used for invisible/private parent properties; skip them
    if (name->size() == 0) continue;
    if (propMap[String(name)]->isVisible(ctxCI)) {
      const TypedValue* value = &((*propVals)[i]);
      ret->nvSet(name, value, false);
    }
  }

  for (size_t i = 0; i < numSProps; ++i) {
    bool vis, access;
    TypedValue* value = cls->getSProp(ctx, sPropInfo[i].m_name, vis, access);
    if (vis) {
      ret->nvSet(const_cast<StringData*>(sPropInfo[i].m_name), value, false);
    }
  }

  return ret;
}
コード例 #6
0
ファイル: memory-profile.cpp プロジェクト: Alienfeel/hhvm
// static
size_t MemoryProfile::getSizeOfArray(ArrayData *arr) {
  size_t size = getSizeOfPtr(arr);
  if (size == 0) { return 0; }
  if (arr->isHphpArray()) {
    // calculate extra size
    HphpArray *ha = static_cast<HphpArray *>(arr);
    size_t hashSize = ha->hashSize();
    size_t maxElms = HphpArray::computeMaxElms(ha->m_tableMask);
    if (maxElms > HphpArray::SmallSize) {
      size += maxElms * sizeof(HphpArray::Elm) + hashSize * sizeof(int32_t);
    }
  }
  return size;
}
コード例 #7
0
ファイル: runtime.cpp プロジェクト: Halfnhav/hiphop-php
// Returned array has refcount one! Caller must not incref.
HphpArray* pack_args_into_array(ActRec* ar, int nargs) {
  HphpArray* argArray = HphpArray::MakeReserve(nargs);
  for (int i = 0; i < nargs; ++i) {
    TypedValue* tv = (TypedValue*)(ar) - (i+1);
    argArray->HphpArray::appendWithRef(tvAsCVarRef(tv), false);
  }
  if (!ar->hasInvName()) {
    // If this is not a magic call, we're done
    return argArray;
  }
  // This is a magic call, so we need to shuffle the args
  HphpArray* magicArgs = HphpArray::MakeReserve(2);
  magicArgs->append(ar->getInvName(), false);
  magicArgs->append(argArray, false);
  return magicArgs;
}
コード例 #8
0
ファイル: event-hook.cpp プロジェクト: XciA/hiphop-php
static Array get_frame_args_with_ref(const ActRec* ar) {
  int numParams = ar->m_func->numParams();
  int numArgs = ar->numArgs();
  HphpArray* retval = ArrayData::Make(numArgs);

  TypedValue* local = (TypedValue*)(uintptr_t(ar) - sizeof(TypedValue));
  for (int i = 0; i < numArgs; ++i) {
    if (i < numParams) {
      // This corresponds to one of the function's formal parameters, so it's
      // on the stack.
      retval->appendWithRef(tvAsCVarRef(local), false);
      --local;
    } else {
      // This is not a formal parameter, so it's in the ExtraArgs.
      retval->appendWithRef(tvAsCVarRef(ar->getExtraArg(i - numParams)), false);
    }
  }

  return Array(retval);
}
コード例 #9
0
ファイル: array_data.cpp プロジェクト: CyaLiven/hiphop-php
HOT_FUNC
void ArrayData::release() {
  if (isHphpArray()) {
    HphpArray* that = static_cast<HphpArray*>(this);
    that->release();
    return;
  }
  if (isSharedMap()) {
    SharedMap* that = static_cast<SharedMap*>(this);
    that->release();
    return;
  }
  if (isArrayShell()) {
    auto that = static_cast<ArrayShell*>(this);
    that->release();
    return;
  }
  assert(m_kind == kNameValueTableWrapper);
  // NameValueTableWrapper: nop.
}
コード例 #10
0
ファイル: ext_class.cpp プロジェクト: CoolCloud/hiphop-php
Array vm_get_class_constants(CStrRef className) {
  HPHP::VM::Class* cls = HPHP::VM::Unit::lookupClass(className.get());
  if (cls == NULL) {
    return NEW(HphpArray)(0);
  }

  size_t numConstants = cls->numConstants();
  HphpArray* retVal = NEW(HphpArray)(numConstants);
  const VM::Class::Const* consts = cls->constants();
  for (size_t i = 0; i < numConstants; i++) {
    // Note: hphpc doesn't include inherited constants in
    // get_class_constants(), so mimic that behavior
    if (consts[i].m_class == cls) {
      StringData* name  = const_cast<StringData*>(consts[i].m_name);
      TypedValue* value = cls->clsCnsGet(consts[i].m_name);
      retVal->nvSet(name, value, false);
    }
  }

  return retVal;
}
コード例 #11
0
ファイル: runtime.cpp プロジェクト: mambaliu/hiphop-php
ArrayData* new_tuple(int n, const TypedValue* values) {
  HphpArray* a = NEW(HphpArray)(n, values);
  a->incRefCount();
  TRACE(2, "newTupleHelper: size %d\n", n);
  return a;
}