aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-08-29 13:24:38 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-02 17:27:36 +0200
commit3ad8b0f0e8193bb7b62ffee6b33588ef6b51459c (patch)
treea4c05097b9787efcb2749ed2d40590b1beb2d360 /src/qml
parent6c69cdb1af58dfb584615aa60d4f69b359b312cc (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.cpp2
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp28
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h11
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);
};