aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4internalclass.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-05-12 15:04:53 +0200
committerLars Knoll <lars.knoll@qt.io>2017-05-19 06:23:23 +0000
commit0cdea188727e203ecc529ef8e4e8859cca0be232 (patch)
tree88866951fb97d1c7132922b60e052f496cdd4b52 /src/qml/jsruntime/qv4internalclass.cpp
parentcdbc4b83d59e08189d6ece9ccd88a646be155c08 (diff)
Add support for storing the Vtable in the InternalClass
Prepare for moving the vtable pointer into the internalClass. This adds the required infrastructure to InternalClass, so it can store a vtable pointer and properly handles vtable changes. Change-Id: I688fee1647268dd185d0f9636ab5b3390465daca Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4internalclass.cpp')
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp52
1 files changed, 44 insertions, 8 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index f310b6f551..e117da1a04 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -105,6 +105,7 @@ void PropertyHash::addEntry(const PropertyHash::Entry &entry, int classSize)
InternalClass::InternalClass(ExecutionEngine *engine)
: engine(engine)
+ , vtable(0)
, m_sealed(0)
, m_frozen(0)
, size(0)
@@ -116,6 +117,7 @@ InternalClass::InternalClass(ExecutionEngine *engine)
InternalClass::InternalClass(const QV4::InternalClass &other)
: QQmlJS::Managed()
, engine(other.engine)
+ , vtable(other.vtable)
, propertyTable(other.propertyTable)
, nameMap(other.nameMap)
, propertyData(other.propertyData)
@@ -214,13 +216,13 @@ InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttri
if (data == propertyData.at(idx))
return this;
- Transition temp = { identifier, 0, (int)data.flags() };
+ Transition temp = { { identifier }, nullptr, (int)data.flags() };
Transition &t = lookupOrInsertTransition(temp);
if (t.lookup)
return t.lookup;
// create a new class and add it to the tree
- InternalClass *newClass = engine->internalClasses[EngineBase::Class_Empty];
+ InternalClass *newClass = engine->internalClasses[EngineBase::Class_Empty]->changeVTable(vtable);
for (uint i = 0; i < size; ++i) {
if (i == idx) {
newClass = newClass->addMember(nameMap.at(i), data);
@@ -234,12 +236,34 @@ InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttri
return newClass;
}
+InternalClass *InternalClass::changeVTableImpl(const VTable *vt)
+{
+ Q_ASSERT(vtable != vt);
+
+ Transition temp = { { nullptr }, nullptr, Transition::VTableChange };
+ temp.vtable = vt;
+
+ Transition &t = lookupOrInsertTransition(temp);
+ if (t.lookup)
+ return t.lookup;
+
+ // create a new class and add it to the tree
+ InternalClass *newClass;
+ newClass = engine->newClass(*this);
+ newClass->vtable = vt;
+
+ t.lookup = newClass;
+ Q_ASSERT(t.lookup);
+ Q_ASSERT(newClass->vtable);
+ return newClass;
+}
+
InternalClass *InternalClass::nonExtensible()
{
if (!extensible)
return this;
- Transition temp = { Q_NULLPTR, Q_NULLPTR, Transition::NotExtensible};
+ Transition temp = { { nullptr }, nullptr, Transition::NotExtensible};
Transition &t = lookupOrInsertTransition(temp);
if (t.lookup)
return t.lookup;
@@ -287,7 +311,7 @@ InternalClass *InternalClass::addMember(Identifier *identifier, PropertyAttribut
InternalClass *InternalClass::addMemberImpl(Identifier *identifier, PropertyAttributes data, uint *index)
{
- Transition temp = { identifier, 0, (int)data.flags() };
+ Transition temp = { { identifier }, nullptr, (int)data.flags() };
Transition &t = lookupOrInsertTransition(temp);
if (index)
@@ -323,7 +347,7 @@ void InternalClass::removeMember(Object *object, Identifier *id)
uint propIdx = oldClass->propertyTable.lookup(id);
Q_ASSERT(propIdx < oldClass->size);
- Transition temp = { id, 0, -1 };
+ Transition temp = { { id }, nullptr, -1 };
Transition &t = object->internalClass()->lookupOrInsertTransition(temp);
bool accessor = oldClass->propertyData.at(propIdx).isAccessor();
@@ -332,7 +356,7 @@ void InternalClass::removeMember(Object *object, Identifier *id)
object->setInternalClass(t.lookup);
} else {
// create a new class and add it to the tree
- InternalClass *newClass = oldClass->engine->internalClasses[EngineBase::Class_Empty];
+ InternalClass *newClass = oldClass->engine->internalClasses[EngineBase::Class_Empty]->changeVTable(oldClass->vtable);
for (uint i = 0; i < oldClass->size; ++i) {
if (i == propIdx)
continue;
@@ -351,6 +375,18 @@ void InternalClass::removeMember(Object *object, Identifier *id)
Q_ASSERT(t.lookup);
}
+uint QV4::InternalClass::find(const String *string)
+{
+ engine->identifierTable->identifier(string);
+ const Identifier *id = string->d()->identifier;
+
+ uint index = propertyTable.lookup(id);
+ if (index < size)
+ return index;
+
+ return UINT_MAX;
+}
+
uint InternalClass::find(const Identifier *id)
{
uint index = propertyTable.lookup(id);
@@ -365,7 +401,7 @@ InternalClass *InternalClass::sealed()
if (m_sealed)
return m_sealed;
- m_sealed = engine->internalClasses[EngineBase::Class_Empty];
+ m_sealed = engine->internalClasses[EngineBase::Class_Empty]->changeVTable(vtable);
for (uint i = 0; i < size; ++i) {
PropertyAttributes attrs = propertyData.at(i);
if (attrs.isEmpty())
@@ -394,7 +430,7 @@ InternalClass *InternalClass::frozen()
InternalClass *InternalClass::propertiesFrozen() const
{
- InternalClass *frozen = engine->internalClasses[EngineBase::Class_Empty];
+ InternalClass *frozen = engine->internalClasses[EngineBase::Class_Empty]->changeVTable(vtable);
for (uint i = 0; i < size; ++i) {
PropertyAttributes attrs = propertyData.at(i);
if (attrs.isEmpty())