Allow early initialization of classes if they don't have any [sp]init methods
We were being too conservative in determining whether to use the static property cache when accessing a property from outside the class. In fact we'd never use it in that case, because we required that the class not need initialization (and any class with static properties needs initialization!). We can relax this restriction to just enforce that the class not define sinit or pinit methods -- scalar properties are fine.
Esse commit está contido em:
@@ -2197,6 +2197,7 @@ void Class::setInitializers() {
|
||||
|
||||
m_needInitialization = (m_pinitVec.size() > 0 ||
|
||||
m_staticProperties.size() > 0);
|
||||
m_hasInitMethods = (m_pinitVec.size() > 0 || m_sinitVec.size() > 0);
|
||||
|
||||
// The __init__ method defined in the Exception class gets special treatment
|
||||
static StringData* sd__init__ = StringData::GetStaticString("__init__");
|
||||
|
||||
@@ -721,6 +721,7 @@ public:
|
||||
|
||||
bool hasDeepInitProps() const { return m_hasDeepInitProps; }
|
||||
bool needInitialization() const { return m_needInitialization; }
|
||||
bool hasInitMethods() const { return m_hasInitMethods; }
|
||||
bool callsCustomInstanceInit() const { return m_callsCustomInstanceInit; }
|
||||
const InterfaceMap& allInterfaces() const { return m_interfaces; }
|
||||
const std::vector<ClassPtr>& usedTraits() const {
|
||||
@@ -966,11 +967,14 @@ private:
|
||||
InitVec m_pinitVec;
|
||||
InitVec m_sinitVec;
|
||||
const ClassInfo* m_clsInfo;
|
||||
unsigned m_needInitialization : 1; // any __[ps]init() methods?
|
||||
unsigned m_needInitialization : 1; // requires initialization,
|
||||
// due to [ps]init or simply
|
||||
// having static members
|
||||
unsigned m_hasInitMethods : 1; // any __[ps]init() methods?
|
||||
unsigned m_callsCustomInstanceInit : 1; // should we always call __init__
|
||||
// on new instances?
|
||||
unsigned m_hasDeepInitProps : 1;
|
||||
unsigned m_attrCopy : 29; // cache of m_preClass->attrs().
|
||||
unsigned m_attrCopy : 28; // cache of m_preClass->attrs().
|
||||
int m_ODAttrs;
|
||||
|
||||
int m_builtinPropSize;
|
||||
|
||||
@@ -223,7 +223,7 @@ bool canUseSPropCache(SSATmp* clsTmp,
|
||||
// initialized yet. getSProp() below will trigger initialization,
|
||||
// but that's only valid to do earlier if it doesn't require any
|
||||
// property initializer ([sp]init methods).
|
||||
if (cls->needInitialization()) return false;
|
||||
if (cls->hasInitMethods()) return false;
|
||||
|
||||
bool visible, accessible;
|
||||
cls->getSProp(const_cast<Class*>(ctx), propName, visible, accessible);
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário