diff options
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 26 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4objectproto.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 15 |
5 files changed, 32 insertions, 23 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index 8c44d65426..2115ee09a0 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -116,6 +116,7 @@ InternalClass::InternalClass(ExecutionEngine *engine) , m_sealed(0) , m_frozen(0) , size(0) + , extensible(true) { } @@ -130,7 +131,9 @@ InternalClass::InternalClass(const QV4::InternalClass &other) , m_sealed(0) , m_frozen(0) , size(other.size) + , extensible(other.extensible) { + Q_ASSERT(extensible); } void InternalClass::changeMember(Object *object, String *string, PropertyAttributes data, uint *index) @@ -228,6 +231,27 @@ InternalClass *InternalClass::changeVTable(const ManagedVTable *vt) return newClass; } +InternalClass *InternalClass::nonExtensible() +{ + if (!extensible) + return this; + + Transition temp; + temp.vtable = 0; + temp.lookup = 0; + temp.flags = Transition::NotExtensible; + + Transition &t = lookupOrInsertTransition(temp); + if (t.lookup) + return t.lookup; + + InternalClass *newClass = engine->newClass(*this); + newClass->extensible = false; + + t.lookup = newClass; + return newClass; +} + void InternalClass::addMember(Object *object, String *string, PropertyAttributes data, uint *index) { data.resolve(); @@ -357,6 +381,7 @@ InternalClass *InternalClass::sealed() attrs.setConfigurable(false); m_sealed = m_sealed->addMember(nameMap.at(i), attrs); } + m_sealed = m_sealed->nonExtensible(); m_sealed->m_sealed = m_sealed; return m_sealed; @@ -377,6 +402,7 @@ InternalClass *InternalClass::frozen() attrs.setConfigurable(false); m_frozen = m_frozen->addMember(nameMap.at(i), attrs); } + m_frozen = m_frozen->nonExtensible(); m_frozen->m_frozen = m_frozen; m_frozen->m_sealed = m_frozen; diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index 5973ca2c7c..b92bee3fac 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -197,7 +197,8 @@ struct InternalClassTransition int flags; enum { // range 0-0xff is reserved for attribute changes - VTableChange = 0x100 + VTableChange = 0x100, + NotExtensible = 0x200 }; bool operator==(const InternalClassTransition &other) const @@ -223,9 +224,11 @@ struct InternalClass : public QQmlJS::Managed { InternalClass *m_frozen; uint size; + bool extensible; static InternalClass *create(ExecutionEngine *engine, const ManagedVTable *vtable); InternalClass *changeVTable(const ManagedVTable *vt); + InternalClass *nonExtensible(); static void addMember(Object *object, String *string, PropertyAttributes data, uint *index); InternalClass *addMember(String *string, PropertyAttributes data, uint *index = 0); InternalClass *addMember(Identifier *identifier, PropertyAttributes data, uint *index = 0); diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index a38750dd07..298779906b 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -140,8 +140,7 @@ struct Q_QML_EXPORT Object: Managed { inline ExecutionEngine *engine() const { return internalClass()->engine; } - bool isExtensible() const { return d()->extensible; } - void setExtensible(bool b) { d()->extensible = b; } + bool isExtensible() const { return d()->internalClass->extensible; } // Array handling diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 34a9b9cb64..445d4f7a68 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -244,8 +244,6 @@ ReturnedValue ObjectPrototype::method_seal(CallContext *ctx) if (!o) return ctx->engine()->throwTypeError(); - o->setExtensible(false); - o->setInternalClass(o->internalClass()->sealed()); if (o->arrayData()) { @@ -269,8 +267,6 @@ ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx) if (ArgumentsObject::isNonStrictArgumentsObject(o)) Scoped<ArgumentsObject>(scope, o)->fullyCreate(); - o->setExtensible(false); - o->setInternalClass(o->internalClass()->frozen()); if (o->arrayData()) { @@ -292,7 +288,7 @@ ReturnedValue ObjectPrototype::method_preventExtensions(CallContext *ctx) if (!o) return ctx->engine()->throwTypeError(); - o->setExtensible(false); + o->setInternalClass(o->internalClass()->nonExtensible()); return o.asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 31db8a21c5..526cb01ac4 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -50,7 +50,6 @@ struct Q_QML_EXPORT Base { Base() {} Base(InternalClass *internal) : internalClass(internal) - , extensible(1) { Q_ASSERT(inUse() && !isMarked()); // #### @@ -60,20 +59,6 @@ struct Q_QML_EXPORT Base { InternalClass *internalClass; quintptr mm_data; }; - struct { - uchar _markBit : 1; - uchar _inUse : 1; - uchar extensible : 1; // used by Object - uchar _needsActivation : 1; // used by FunctionObject - uchar _strictMode : 1; // used by FunctionObject - uchar _bindingKeyFlag : 1; - uchar _hasAccessorProperty : 1; - uchar _unused : 1; - mutable uchar _subtype; - uchar _unused2; - uchar _unused3; - - }; void setVTable(const ManagedVTable *vt); inline ReturnedValue asReturnedValue() const; |