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; }
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; }