aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4internalclass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4internalclass.cpp')
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp100
1 files changed, 88 insertions, 12 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index c890dc0550..b22d3073b9 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -137,14 +137,83 @@ void PropertyHash::detach(bool grow, int classSize)
d = dd;
}
+
+SharedInternalClassDataPrivate<PropertyKey>::SharedInternalClassDataPrivate(const SharedInternalClassDataPrivate<PropertyKey> &other)
+ : refcount(1),
+ engine(other.engine),
+ data(nullptr)
+{
+ if (other.alloc()) {
+ int s = other.size();
+ data = MemberData::allocate(engine, other.alloc(), other.data);
+ setSize(s);
+ }
+}
+
+SharedInternalClassDataPrivate<PropertyKey>::SharedInternalClassDataPrivate(const SharedInternalClassDataPrivate<PropertyKey> &other,
+ uint pos, PropertyKey value)
+ : refcount(1),
+ engine(other.engine)
+{
+ data = MemberData::allocate(engine, other.alloc(), nullptr);
+ memcpy(data, other.data, sizeof(Heap::MemberData) - sizeof(Value) + pos*sizeof(Value));
+ data->values.size = pos + 1;
+ data->values.set(engine, pos, Value::fromReturnedValue(value.id()));
+}
+
+void SharedInternalClassDataPrivate<PropertyKey>::grow()
+{
+ uint a = alloc() * 2;
+ int s = size();
+ data = MemberData::allocate(engine, a, data);
+ setSize(s);
+ Q_ASSERT(alloc() >= a);
+}
+
+uint SharedInternalClassDataPrivate<PropertyKey>::alloc() const
+{
+ return data ? data->values.alloc : 0;
+}
+
+uint SharedInternalClassDataPrivate<PropertyKey>::size() const
+{
+ return data ? data->values.size : 0;
+}
+
+void SharedInternalClassDataPrivate<PropertyKey>::setSize(uint s)
+{
+ Q_ASSERT(data && s <= alloc());
+ data->values.size = s;
+}
+
+PropertyKey SharedInternalClassDataPrivate<PropertyKey>::at(uint i)
+{
+ Q_ASSERT(data && i < size());
+ return PropertyKey::fromId(data->values.values[i].rawValue());
+}
+
+void SharedInternalClassDataPrivate<PropertyKey>::set(uint i, PropertyKey t)
+{
+ Q_ASSERT(data && i < size());
+ data->values.values[i].rawValueRef() = t.id();
+}
+
+void SharedInternalClassDataPrivate<PropertyKey>::mark(MarkStack *s)
+{
+ if (data)
+ data->mark(s);
+}
+
+
+
namespace Heap {
void InternalClass::init(ExecutionEngine *engine)
{
Base::init();
new (&propertyTable) PropertyHash();
- new (&nameMap) SharedInternalClassData<PropertyKey>();
- new (&propertyData) SharedInternalClassData<PropertyAttributes>();
+ new (&nameMap) SharedInternalClassData<PropertyKey>(engine);
+ new (&propertyData) SharedInternalClassData<PropertyAttributes>(engine);
new (&transitions) std::vector<Transition>();
this->engine = engine;
@@ -204,6 +273,11 @@ void InternalClass::destroy()
Base::destroy();
}
+QString InternalClass::keyAt(uint index) const
+{
+ return nameMap.at(index).toQString();
+}
+
static void insertHoleIntoPropertyData(QV4::Object *object, int idx)
{
Heap::Object *o = object->d();
@@ -288,8 +362,8 @@ Heap::InternalClass *InternalClass::changeMember(PropertyKey identifier, Propert
if (data.isAccessor() != propertyData.at(idx).isAccessor()) {
// this changes the layout of the class, so we need to rebuild the data
newClass->propertyTable = PropertyHash();
- newClass->nameMap = SharedInternalClassData<PropertyKey>();
- newClass->propertyData = SharedInternalClassData<PropertyAttributes>();
+ newClass->nameMap = SharedInternalClassData<PropertyKey>(engine);
+ newClass->propertyData = SharedInternalClassData<PropertyAttributes>(engine);
newClass->size = 0;
for (uint i = 0; i < size; ++i) {
PropertyKey identifier = nameMap.at(i);
@@ -423,7 +497,9 @@ Heap::InternalClass *InternalClass::addMemberImpl(PropertyKey identifier, Proper
return t.lookup;
// create a new class and add it to the tree
- Heap::InternalClass *newClass = engine->newClass(this);
+ Scope scope(engine);
+ Scoped<QV4::InternalClass> ic(scope, engine->newClass(this));
+ InternalClass *newClass = ic->d();
PropertyHash::Entry e = { identifier, newClass->size };
newClass->propertyTable.addEntry(e, newClass->size);
@@ -504,7 +580,9 @@ Heap::InternalClass *InternalClass::sealed()
return t.lookup;
}
- Heap::InternalClass *s = engine->newClass(this);
+ Scope scope(engine);
+ Scoped<QV4::InternalClass> ic(scope, engine->newClass(this));
+ Heap::InternalClass *s = ic->d();
for (uint i = 0; i < size; ++i) {
PropertyAttributes attrs = propertyData.at(i);
@@ -550,7 +628,9 @@ Heap::InternalClass *InternalClass::frozen()
return t.lookup;
}
- Heap::InternalClass *f = engine->newClass(this);
+ Scope scope(engine);
+ Scoped<QV4::InternalClass> ic(scope, engine->newClass(this));
+ Heap::InternalClass *f = ic->d();
for (uint i = 0; i < size; ++i) {
PropertyAttributes attrs = propertyData.at(i);
@@ -631,11 +711,7 @@ void InternalClass::markObjects(Heap::Base *b, MarkStack *stack)
if (ic->parent)
ic->parent->mark(stack);
- for (uint i = 0; i < ic->size; ++i) {
- PropertyKey id = ic->nameMap.at(i);
- if (Heap::Base *b = id.asStringOrSymbol())
- b->mark(stack);
- }
+ ic->nameMap.mark(stack);
}
}