diff options
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 71 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass_p.h | 7 |
2 files changed, 45 insertions, 33 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index e734347e3e..da14ca48d3 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -132,10 +132,10 @@ InternalClass::InternalClass(ExecutionEngine *engine) , vtable(nullptr) , prototype(nullptr) , parent(nullptr) - , m_sealed(nullptr) - , m_frozen(nullptr) , size(0) , extensible(true) + , isSealed(false) + , isFrozen(false) { id = engine->newInternalClassId(); } @@ -149,12 +149,13 @@ InternalClass::InternalClass(QV4::InternalClass *other) , propertyTable(other->propertyTable) , nameMap(other->nameMap) , propertyData(other->propertyData) - , m_sealed(nullptr) - , m_frozen(nullptr) , size(other->size) , extensible(other->extensible) + , isSealed(other->isSealed) + , isFrozen(other->isFrozen) , isUsedAsProto(other->isUsedAsProto) { + Q_ASSERT(!isFrozen); id = engine->newInternalClassId(); } @@ -430,8 +431,8 @@ uint InternalClass::find(const String *string) InternalClass *InternalClass::sealed() { - if (m_sealed) - return m_sealed; + if (isSealed) + return this; bool alreadySealed = !extensible; for (uint i = 0; i < size; ++i) { @@ -445,29 +446,38 @@ InternalClass *InternalClass::sealed() } if (alreadySealed) { - m_sealed = this; + isSealed = true; return this; } - m_sealed = engine->newClass(this); + Transition temp = { { nullptr }, nullptr, InternalClassTransition::Sealed }; + Transition &t = lookupOrInsertTransition(temp); + + if (t.lookup) { + Q_ASSERT(t.lookup && t.lookup->isSealed); + return t.lookup; + } + + InternalClass *s = engine->newClass(this); for (uint i = 0; i < size; ++i) { PropertyAttributes attrs = propertyData.at(i); if (attrs.isEmpty()) continue; attrs.setConfigurable(false); - m_sealed->propertyData.set(i, attrs); + s->propertyData.set(i, attrs); } - m_sealed->extensible = false; + s->extensible = false; + s->isSealed = true; - m_sealed->m_sealed = m_sealed; - return m_sealed; + t.lookup = s; + return s; } InternalClass *InternalClass::frozen() { - if (m_frozen) - return m_frozen; + if (isFrozen) + return this; bool alreadyFrozen = !extensible; for (uint i = 0; i < size; ++i) { @@ -481,12 +491,20 @@ InternalClass *InternalClass::frozen() } if (alreadyFrozen) { - m_frozen = this; - m_sealed = this; + isSealed = true; + isFrozen = true; return this; } - m_frozen = engine->newClass(this); + Transition temp = { { nullptr }, nullptr, InternalClassTransition::Frozen }; + Transition &t = lookupOrInsertTransition(temp); + + if (t.lookup) { + Q_ASSERT(t.lookup && t.lookup->isSealed && t.lookup->isFrozen); + return t.lookup; + } + + InternalClass *f = engine->newClass(this); for (uint i = 0; i < size; ++i) { PropertyAttributes attrs = propertyData.at(i); @@ -495,13 +513,14 @@ InternalClass *InternalClass::frozen() if (attrs.isData()) attrs.setWritable(false); attrs.setConfigurable(false); - m_frozen->propertyData.set(i, attrs); + f->propertyData.set(i, attrs); } - m_frozen->extensible = false; + f->extensible = false; + f->isSealed = true; + f->isFrozen = true; - m_frozen->m_frozen = m_frozen; - m_frozen->m_sealed = m_frozen; - return m_frozen; + t.lookup = f; + return f; } InternalClass *InternalClass::propertiesFrozen() const @@ -548,10 +567,6 @@ void InternalClass::destroyAll() destroyStack.pop_back(); Q_ASSERT(next->engine); next->engine = nullptr; - if (next->m_sealed && next->m_sealed != next) - destroyStack.push_back(next->m_sealed); - if (next->m_frozen && next->m_frozen != next) - destroyStack.push_back(next->m_frozen); for (size_t i = 0; i < next->transitions.size(); ++i) { Q_ASSERT(next->transitions.at(i).lookup); @@ -600,10 +615,6 @@ void InternalClass::markObjects(InternalClass *ic, MarkStack *stack) Q_ASSERT(t.lookup); markObjects(t.lookup, stack); } - if (ic->m_frozen) - markObjects(ic->m_frozen, stack); - if (ic->m_sealed) - markObjects(ic->m_sealed, stack); } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index 168ed6c950..7533253873 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -248,6 +248,8 @@ struct InternalClassTransition VTableChange = 0x200, PrototypeChange = 0x201, ProtoClass = 0x202, + Sealed = 0x203, + Frozen = 0x204, RemoveMember = -1 }; @@ -273,11 +275,10 @@ struct InternalClass { std::vector<Transition> transitions; InternalClassTransition &lookupOrInsertTransition(const InternalClassTransition &t); - InternalClass *m_sealed; - InternalClass *m_frozen; - uint size; bool extensible; + bool isSealed; + bool isFrozen; bool isUsedAsProto = false; Q_REQUIRED_RESULT InternalClass *nonExtensible(); |