Exemple #1
0
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;
}
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->nvSet(name, &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;
}
Exemple #3
0
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;
}