diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-08-29 13:24:38 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-02 17:27:36 +0200 |
commit | 3ad8b0f0e8193bb7b62ffee6b33588ef6b51459c (patch) | |
tree | a4c05097b9787efcb2749ed2d40590b1beb2d360 /src/qml | |
parent | 6c69cdb1af58dfb584615aa60d4f69b359b312cc (diff) |
Add the object's prototype to the InternalClass structure
Change-Id: Ifa97d3354a7a7afadf70f9ba540716bd5b1eef44
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 28 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass_p.h | 11 |
3 files changed, 39 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index a8a169f486..08093ca24c 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -714,6 +714,8 @@ void ExecutionEngine::markObjects() if (m_qmlExtensions) m_qmlExtensions->markObjects(); + emptyClass->markObjects(); + for (QSet<CompiledData::CompilationUnit*>::ConstIterator it = compilationUnits.constBegin(), end = compilationUnits.constEnd(); it != end; ++it) (*it)->markObjects(); diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index f4edc99545..50803db73d 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -126,6 +126,7 @@ uint PropertyHash::lookup(const Identifier *identifier) const InternalClass::InternalClass(const QV4::InternalClass &other) : engine(other.engine) + , prototype(other.prototype) , propertyTable(other.propertyTable) , nameMap(other.nameMap) , propertyData(other.propertyData) @@ -163,6 +164,25 @@ InternalClass *InternalClass::changeMember(String *string, PropertyAttributes da } +InternalClass *InternalClass::changePrototype(Object *proto) +{ + if (prototype == proto) + return this; + + Transition t; + t.prototype = proto; + t.flags = Transition::ProtoChange; + + QHash<Transition, InternalClass *>::const_iterator tit = transitions.constFind(t); + if (tit != transitions.constEnd()) + return tit.value(); + + // create a new class and add it to the tree + InternalClass *newClass = engine->newClass(*this); + newClass->prototype = proto; + return newClass; +} + InternalClass *InternalClass::addMember(String *string, PropertyAttributes data, uint *index) { // qDebug() << "InternalClass::addMember()" << string->toQString() << size << hex << (uint)data.m_all << data.type(); @@ -293,4 +313,12 @@ void InternalClass::destroy() transitions.clear(); } +void InternalClass::markObjects() +{ + prototype->mark(); + for (QHash<Transition, InternalClass *>::ConstIterator it = transitions.begin(), end = transitions.end(); + it != end; ++it) + it.value()->markObjects(); +} + QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index fc6c5352b1..1fba947a37 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -108,8 +108,12 @@ inline PropertyHash::~PropertyHash() struct InternalClassTransition { - Identifier *id; + union { + Identifier *id; + Object *prototype; + }; int flags; + enum { ProtoChange = 0x100 }; bool operator==(const InternalClassTransition &other) const { return id == other.id && flags == other.flags; } @@ -118,6 +122,7 @@ uint qHash(const QV4::InternalClassTransition &t, uint = 0); struct InternalClass { ExecutionEngine *engine; + Object *prototype; PropertyHash propertyTable; // id to valueIndex QVector<String *> nameMap; @@ -131,6 +136,7 @@ struct InternalClass { uint size; + InternalClass *changePrototype(Object *proto); InternalClass *addMember(String *string, PropertyAttributes data, uint *index = 0); InternalClass *changeMember(String *string, PropertyAttributes data, uint *index = 0); void removeMember(Object *object, Identifier *id); @@ -140,10 +146,11 @@ struct InternalClass { InternalClass *frozen(); void destroy(); + void markObjects(); private: friend struct ExecutionEngine; - InternalClass(ExecutionEngine *engine) : engine(engine), m_sealed(0), m_frozen(0), size(0) {} + InternalClass(ExecutionEngine *engine) : engine(engine), prototype(0), m_sealed(0), m_frozen(0), size(0) {} InternalClass(const InternalClass &other); }; |