diff --git a/hphp/compiler/analysis/emitter.cpp b/hphp/compiler/analysis/emitter.cpp index b9bbb51e6..7482c8891 100644 --- a/hphp/compiler/analysis/emitter.cpp +++ b/hphp/compiler/analysis/emitter.cpp @@ -7076,7 +7076,7 @@ static Unit* emitHHBCNativeClassUnit(const HhbcExtClassInfo* builtinClasses, Entry e; e.name = const_cast(it->first); e.info = it->second; - e.ci = ClassInfo::FindClassInterfaceOrTrait(e.name); + e.ci = ClassInfo::FindSystemClassInterfaceOrTrait(e.name); assert(e.ci); StringData* parentName = StringData::GetStaticString(e.ci->getParentClass().get()); diff --git a/hphp/runtime/base/class_info.cpp b/hphp/runtime/base/class_info.cpp index b462498fa..6f99d94a1 100644 --- a/hphp/runtime/base/class_info.cpp +++ b/hphp/runtime/base/class_info.cpp @@ -193,19 +193,6 @@ Array ClassInfo::GetClassLike(unsigned mask, unsigned value) { return ret; } -const ClassInfo::ConstantInfo *ClassInfo::FindConstant(CStrRef name) { - assert(!name.isNull()); - assert(s_loaded); - const ConstantInfo *info; - info = s_systemFuncs->getConstantInfo(name); - if (info) return info; - if (s_hook) { - info = s_hook->findConstant(name); - if (info) return info; - } - return nullptr; -} - ClassInfo::ConstantInfo::ConstantInfo() : valueLen(0), callback(nullptr), deferred(true) { } @@ -354,24 +341,6 @@ bool ClassInfo::GetClassMethods(MethodVec &ret, const ClassInfo *classInfo) { return true; } -void ClassInfo::GetClassProperties(PropertyMap &props, CStrRef classname) { - if (!classname.empty()) { - const ClassInfo *classInfo = FindClass(classname); - if (classInfo) { - classInfo->getAllProperties(props); - } - } -} - -void ClassInfo::GetClassProperties(PropertyVec &props, CStrRef classname) { - if (!classname.empty()) { - const ClassInfo *classInfo = FindClass(classname); - if (classInfo) { - classInfo->getAllProperties(props); - } - } -} - void ClassInfo::GetClassSymbolNames(CArrRef names, bool interface, bool trait, std::vector &classes, std::vector *clsMethods, @@ -497,70 +466,6 @@ const ClassInfo *ClassInfo::getParentClassInfo() const { return FindClass(parentName); } -void ClassInfo::getAllParentsVec(ClassVec &parents) const { - CStrRef parent = getParentClass(); - if (!parent.empty()) { - parents.push_back(parent); - const ClassInfo *info = FindClass(parent); - if (info) info->getAllParentsVec(parents); - } -} - -void ClassInfo::getAllInterfacesVec(InterfaceVec &interfaces) const { - CStrRef parent = getParentClass(); - if (!parent.empty()) { - const ClassInfo *info = FindClass(parent); - if (info) info->getAllInterfacesVec(interfaces); - } - - const InterfaceVec &ifs = getInterfacesVec(); - for (unsigned int i = 0; i < ifs.size(); i++) { - CStrRef intf = ifs[i]; - interfaces.push_back(intf); - const ClassInfo *info = FindInterface(intf); - if (info) info->getAllInterfacesVec(interfaces); - } -} - -bool ClassInfo::derivesFrom(CStrRef name, bool considerInterface) const { - assert(!name.isNull()); - return derivesFromImpl(name, considerInterface); -} - -bool ClassInfo::derivesFromImpl(CStrRef name, bool considerInterface) const { - if (name->isame(getParentClass().get())) { - return true; - } - - const ClassInfo *parent = getParentClassInfo(); - if (parent && parent->derivesFromImpl(name, considerInterface)) { - return true; - } - - if (considerInterface) { - const InterfaceSet &interfaces = getInterfaces(); - for (InterfaceSet::const_iterator iter = interfaces.begin(); - iter != interfaces.end(); ++iter) { - if (name->isame(iter->get())) { - return true; - } - const ClassInfo *parent = FindInterface(*iter); - if (parent && parent->derivesFromImpl(name, considerInterface)) { - return true; - } - } - } - return false; -} - -bool ClassInfo::IsSubClass(CStrRef className1, CStrRef className2, - bool considerInterface) { - const ClassInfo *clsInfo1 = ClassInfo::FindClass(className1); - if (!clsInfo1) return false; - - return clsInfo1->derivesFrom(className2, considerInterface); -} - ClassInfo::MethodInfo *ClassInfo::getMethodInfo(CStrRef name) const { assert(!name.isNull()); @@ -603,133 +508,6 @@ const { return nullptr; } -// internal function className::methodName or callObject->methodName -bool ClassInfo::HasAccess(CStrRef className, CStrRef methodName, - bool staticCall, bool hasCallObject) { - // It has to be either a static call or a call with an object. - assert(staticCall || hasCallObject); - const ClassInfo *clsInfo = ClassInfo::FindClass(className); - if (!clsInfo) return false; - ClassInfo *defClass; - ClassInfo::MethodInfo *methodInfo = - clsInfo->hasMethod(methodName, defClass); - if (!methodInfo) return false; - if (methodInfo->attribute & ClassInfo::IsPublic) return true; - VM::Class* ctx = g_vmContext->getContextClass(); - if (!ctx) { - return false; - } - const ClassInfo *ctxClass = ClassInfo::FindClass(ctx->nameRef()); - bool hasObject = hasCallObject || g_vmContext->getThis(); - if (ctxClass) { - return ctxClass->checkAccess(defClass, methodInfo, staticCall, hasObject); - } - return false; -} - -bool ClassInfo::checkAccess(ClassInfo *defClass, - MethodInfo *methodInfo, - bool staticCall, - bool hasObject) const { - assert(defClass && methodInfo); - if ((m_name->isame(defClass->m_name.get()))) { - if (methodInfo->attribute & ClassInfo::IsStatic) return true; - return hasObject; - } - - if (methodInfo->attribute & ClassInfo::IsStatic) { - if (methodInfo->attribute & ClassInfo::IsPublic) return true; - if (methodInfo->attribute & ClassInfo::IsProtected) { - return derivesFrom(defClass->m_name, false) || - defClass->derivesFrom(m_name, false); - } - return false; - } - if (!hasObject && !staticCall) return false; - if (methodInfo->attribute & ClassInfo::IsPublic) return true; - if (methodInfo->attribute & ClassInfo::IsProtected) { - return derivesFrom(defClass->m_name, false) || - defClass->derivesFrom(m_name, false); - } - return false; -} - -void ClassInfo::getAllProperties(PropertyMap &props) const { - const PropertyMap &properties = getProperties(); - props.insert(properties.begin(), properties.end()); - - CStrRef parentClass = getParentClass(); - if (!parentClass.empty()) { - GetClassProperties(props, parentClass); - } -} - -void ClassInfo::getAllProperties(PropertyVec &props) const { - const PropertyVec &properties = getPropertiesVec(); - props.insert(props.end(), properties.begin(), properties.end()); - - CStrRef parentClass = getParentClass(); - if (!parentClass.empty()) { - GetClassProperties(props, parentClass); - } -} - -void ClassInfo::filterProperties(Array &props, Attribute toRemove) const { - const PropertyVec &properties = getPropertiesVec(); - for (unsigned i = 0; i < properties.size(); i++) { - if (properties[i]->attribute & toRemove) { - props.remove(properties[i]->name, true); - } - } - const ClassInfo *parent = getParentClassInfo(); - if (parent) { - parent->filterProperties(props, toRemove); - } -} - -ClassInfo::PropertyInfo *ClassInfo::getPropertyInfo(CStrRef name) const { - assert(!name.isNull()); - const PropertyMap &properties = getProperties(); - PropertyMap::const_iterator iter = properties.find(name); - if (iter != properties.end()) { - return iter->second; - } - return nullptr; -} - -bool ClassInfo::hasProperty(CStrRef name) const { - assert(!name.isNull()); - const PropertyMap &properties = getProperties(); - return properties.find(name) != properties.end(); -} - -ClassInfo::ConstantInfo *ClassInfo::getConstantInfo(CStrRef name) const { - assert(!name.isNull()); - const ConstantMap &constants = getConstants(); - ConstantMap::const_iterator iter = constants.find(name); - if (iter != constants.end()) { - return iter->second; - } - return nullptr; -} - -bool ClassInfo::hasConstant(CStrRef name) const { - assert(!name.isNull()); - const ConstantMap &constants = getConstants(); - return constants.find(name) != constants.end(); -} - -bool ClassInfo::PropertyInfo::isVisible(const ClassInfo *context) const { - if ((attribute & ClassInfo::IsPublic) || context == owner) return true; - if (!context) return false; - if (attribute & ClassInfo::IsProtected) { - return owner->derivesFrom(context->getName(), false) || - context->derivesFrom(owner->getName(), false); - } - assert(attribute & ClassInfo::IsPrivate); - return false; -} - /////////////////////////////////////////////////////////////////////////////// // load functions @@ -1042,14 +820,5 @@ ClassInfo::MethodInfo::~MethodInfo() { } } -void ClassInfo::GetArray(const ObjectData *obj, - Array &props, GetArrayKind kind) { - obj->o_getArray(props, !(kind & GetArrayPrivate)); -} - -void ClassInfo::SetArray(ObjectData *obj, CArrRef props) { - obj->o_setArray(props); -} - /////////////////////////////////////////////////////////////////////////////// } diff --git a/hphp/runtime/base/class_info.h b/hphp/runtime/base/class_info.h index 608e5bdce..4bc8d9f77 100644 --- a/hphp/runtime/base/class_info.h +++ b/hphp/runtime/base/class_info.h @@ -84,13 +84,6 @@ public: NeedsActRec = (1u << 31),// x x }; - enum GetArrayKind { - GetArrayNone = 0, - GetArrayPrivate = 1, - GetArrayPublic = 2, - GetArrayAll = GetArrayPrivate|GetArrayPublic - }; - class ConstantInfo { public: ConstantInfo(); @@ -170,7 +163,6 @@ public: DataType type; const char *docComment; const ClassInfo *owner; - bool isVisible(const ClassInfo *context) const; }; typedef StringIMap ClassMap; @@ -215,10 +207,6 @@ public: */ static Array GetClasses() { return GetClassLike(IsInterface|IsTrait, 0); } - static bool HasClassInterfaceOrTrait(CStrRef name) { - return FindClassInterfaceOrTrait(name); - } - /** * Locate one class. */ @@ -269,11 +257,6 @@ public: */ static const ClassInfo *FindSystemClassInterfaceOrTrait(CStrRef name); - /** - * Locate one constant (excluding dynamic and redeclared constants) - */ - static const ConstantInfo *FindConstant(CStrRef name); - /** * Get all statically known constants */ @@ -293,13 +276,6 @@ public: static bool GetClassMethods(MethodVec &ret, CStrRef classname, int type = 0); static bool GetClassMethods(MethodVec &ret, const ClassInfo *classInfo); - /** - * Return all properties a class has, including the ones on base classes and - * the ones that were implicitly defined. - */ - static void GetClassProperties(PropertyMap &props, CStrRef classname); - static void GetClassProperties(PropertyVec &props, CStrRef classname); - /** * Read user attributes in from the class map. */ @@ -321,13 +297,6 @@ public: std::vector *clsProperties, std::vector *clsConstants); - static void GetArray(const ObjectData *obj, - Array &props, GetArrayKind kind); - static void GetArray(const ObjectData *obj, - Array &props, bool pubOnly) { - GetArray(obj, props, pubOnly ? GetArrayPublic : GetArrayAll); - } - static void SetArray(ObjectData *obj, CArrRef props); static void SetHook(ClassInfoHook *hook) { s_hook = hook; } static Variant GetVariant(DataType type, const void *addr) { @@ -379,10 +348,6 @@ public: virtual const TraitSet &getTraits() const = 0; virtual const TraitVec &getTraitsVec() const = 0; virtual const TraitAliasVec &getTraitAliasesVec() const = 0; - bool derivesFrom(CStrRef name, bool considerInterface) const; - - void getAllParentsVec(ClassVec &parents) const; // recursive - void getAllInterfacesVec(InterfaceVec &interfaces) const; // recursive /** * Method functions. @@ -393,30 +358,18 @@ public: MethodInfo *hasMethod(CStrRef name, ClassInfo *&classInfo, bool interfaces = false) const; - static bool HasAccess(CStrRef className, CStrRef methodName, - bool staticCall, bool hasCallObject); - static bool IsSubClass(CStrRef className1, CStrRef className2, - bool considerInterface); /** * Property functions. */ virtual const PropertyMap &getProperties() const = 0; // non-recursively virtual const PropertyVec &getPropertiesVec() const = 0; // non-recursively - void getAllProperties(PropertyMap &props) const; // recursively - void getAllProperties(PropertyVec &props) const; // recursively - // Remove properties with the given attribute from the array, recursively. - void filterProperties(Array &props, Attribute toRemove) const; - PropertyInfo *getPropertyInfo(CStrRef name) const; - bool hasProperty(CStrRef name) const; /** * Constant functions. */ virtual const ConstantMap &getConstants() const = 0; virtual const ConstantVec &getConstantsVec() const = 0; - ConstantInfo *getConstantInfo(CStrRef name) const; - bool hasConstant(CStrRef name) const; virtual const UserAttributeVec &getUserAttributeVec() const = 0; @@ -437,10 +390,6 @@ protected: int m_line2; const char *m_docComment; - bool derivesFromImpl(CStrRef name, bool considerInterface) const; - bool checkAccess(ClassInfo *defClass, MethodInfo *methodInfo, - bool staticCall, bool hasObject) const; - private: static ClassMap s_class_like; // all classes, interfaces and traits static Array GetClassLike(unsigned mask, unsigned value); diff --git a/hphp/runtime/base/object_data.cpp b/hphp/runtime/base/object_data.cpp index e8fc4b704..cebdc13b6 100644 --- a/hphp/runtime/base/object_data.cpp +++ b/hphp/runtime/base/object_data.cpp @@ -386,7 +386,7 @@ Object ObjectData::FromArray(ArrayData *properties) { Array ObjectData::o_toArray() const { Array ret(ArrayData::Create()); - ClassInfo::GetArray(this, ret, ClassInfo::GetArrayAll); + o_getArray(ret, false); return ret; } diff --git a/hphp/runtime/base/shared/immutable_obj.cpp b/hphp/runtime/base/shared/immutable_obj.cpp index 2ccb15f8e..092f1df06 100644 --- a/hphp/runtime/base/shared/immutable_obj.cpp +++ b/hphp/runtime/base/shared/immutable_obj.cpp @@ -34,7 +34,7 @@ ImmutableObj::ImmutableObj(ObjectData *obj) { assert(!obj->instanceof(SystemLib::s_SerializableClass)); m_cls = obj->o_getClassName()->copy(true); Array props; - ClassInfo::GetArray(obj, props, ClassInfo::GetArrayAll); + obj->o_getArray(props, false); m_propCount = 0; if (props.empty()) { m_props = nullptr; @@ -73,7 +73,7 @@ Object ImmutableObj::getObject() { true); } Array v = ai.create(); - ClassInfo::SetArray(obj.get(), v); + obj->o_setArray(v); obj->t___wakeup(); return obj; } diff --git a/hphp/runtime/base/variable_serializer.cpp b/hphp/runtime/base/variable_serializer.cpp index d6c1248fd..0e46f3b69 100644 --- a/hphp/runtime/base/variable_serializer.cpp +++ b/hphp/runtime/base/variable_serializer.cpp @@ -392,7 +392,7 @@ void VariableSerializer::write(CObjRef v) { collectionSerialize(v.get(), this); } else { Array props(ArrayData::Create()); - ClassInfo::GetArray(v.get(), props, ClassInfo::GetArrayPublic); + v->o_getArray(props, true); setObjectInfo(v->o_getClassName(), v->o_getId(), 'O'); props.serialize(this); } diff --git a/hphp/runtime/ext/ext_mysql.cpp b/hphp/runtime/ext/ext_mysql.cpp index b63281890..94c4a07de 100644 --- a/hphp/runtime/ext/ext_mysql.cpp +++ b/hphp/runtime/ext/ext_mysql.cpp @@ -1589,7 +1589,7 @@ Variant f_mysql_fetch_object(CVarRef result, Variant properties = php_mysql_fetch_hash(result, MYSQL_ASSOC); if (!same(properties, false)) { Object obj = create_object(class_name, params); - ClassInfo::SetArray(obj.get(), properties); + obj->o_setArray(properties); return obj; } diff --git a/hphp/runtime/ext/ext_spl.cpp b/hphp/runtime/ext/ext_spl.cpp index 26141ba22..2ab7335fe 100644 --- a/hphp/runtime/ext/ext_spl.cpp +++ b/hphp/runtime/ext/ext_spl.cpp @@ -140,82 +140,64 @@ Variant f_hphp_get_this() { } Variant f_class_implements(CVarRef obj, bool autoload /* = true */) { - String clsname; + VM::Class* cls; if (obj.isString()) { - clsname = obj.toString(); + cls = VM::Unit::getClass(obj.getStringData(), autoload); + if (!cls) { + return false; + } } else if (obj.isObject()) { - clsname = obj.toObject()->o_getClassName(); + cls = obj.getObjectData()->getVMClass(); } else { return false; } - - const ClassInfo *info = ClassInfo::FindClassInterfaceOrTrait(clsname); - if (info == NULL) { - if (!autoload) return false; - AutoloadHandler::s_instance->invokeHandler(clsname); - return f_class_implements(clsname, false); - } - Array ret(Array::Create()); - ClassInfo::InterfaceVec ifs; - info->getAllInterfacesVec(ifs); - for (unsigned int i = 0; i < ifs.size(); i++) { - ret.set(ifs[i], ifs[i]); + for (auto& elem : cls->allInterfaces()) { + // For the case where cls is an interface, we don't want to + // include cls in the array we return + if (elem == cls) continue; + ret.set(elem->nameRef(), elem->nameRef()); } - return ret; } Variant f_class_parents(CVarRef obj, bool autoload /* = true */) { - String clsname; + VM::Class* cls; if (obj.isString()) { - clsname = obj.toString(); + cls = VM::Unit::getClass(obj.getStringData(), autoload); + if (!cls) { + return false; + } } else if (obj.isObject()) { - clsname = obj.toObject()->o_getClassName(); + cls = obj.getObjectData()->getVMClass(); } else { return false; } - - const ClassInfo *info = ClassInfo::FindClassInterfaceOrTrait(clsname); - if (info == NULL) { - if (!autoload) return false; - AutoloadHandler::s_instance->invokeHandler(clsname); - return f_class_parents(clsname, false); - } - Array ret(Array::Create()); - ClassInfo::ClassVec parents; - info->getAllParentsVec(parents); - for (unsigned int i = 0; i < parents.size(); i++) { - ret.set(parents[i], parents[i]); + for (cls = cls->parent(); cls; cls = cls->parent()) { + auto& clsName = cls->nameRef(); + ret.set(clsName, clsName); } - return ret; } Variant f_class_uses(CVarRef obj, bool autoload /* = true */) { - String clsname; + VM::Class* cls; if (obj.isString()) { - clsname = obj.toString(); + cls = VM::Unit::getClass(obj.getStringData(), autoload); + if (!cls) { + return false; + } } else if (obj.isObject()) { - clsname = obj.toObject()->o_getClassName(); + cls = obj.getObjectData()->getVMClass(); } else { return false; } - - const ClassInfo *info = ClassInfo::FindClassInterfaceOrTrait(clsname); - if (!info) { - if (!autoload) return false; - AutoloadHandler::s_instance->invokeHandler(clsname); - return f_class_uses(clsname, false); - } - Array ret(Array::Create()); - const ClassInfo::TraitVec &traits = info->getTraitsVec(); - for (unsigned int i = 0; i < traits.size(); i++) { - ret.set(traits[i], traits[i]); + for (auto& elem : cls->usedTraits()) { + auto& traitName = elem.get()->nameRef(); + ret.set(traitName, traitName); } - return ret; } diff --git a/hphp/runtime/vm/funcdict.h b/hphp/runtime/vm/funcdict.h index a5cacafe9..803d8a8bb 100644 --- a/hphp/runtime/vm/funcdict.h +++ b/hphp/runtime/vm/funcdict.h @@ -45,8 +45,6 @@ private: bool rename(const StringData* old, const StringData* n3w); bool isFunctionRenameable(const StringData* name); void addRenameableFunctions(ArrayData* arr); - - //Array getUserFunctions(); }; }