aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-11-27 08:56:03 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2014-12-17 11:01:10 +0100
commit9d2a5ea28adf8ab35212ca8a71b479bc50960e3d (patch)
treec59e0799ccf55f832f1e2bde02e256ef62ac2d19
parenta58893eeda6bd48f41bdfa19eda147343be5f81e (diff)
Return a Heap::Object in Object::prototype()
Change-Id: Ice0265ae558ba14497421a5bbf25ee9db76adab5 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/qml/jsruntime/qv4context.cpp5
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp149
-rw-r--r--src/qml/jsruntime/qv4managed_p.h9
-rw-r--r--src/qml/jsruntime/qv4object.cpp40
-rw-r--r--src/qml/jsruntime/qv4object_p.h10
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp32
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h8
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp11
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h6
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp3
14 files changed, 142 insertions, 145 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 8b510fd1fc..5b993ab2f8 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -142,7 +142,7 @@ Heap::WithContext::WithContext(ExecutionEngine *engine, QV4::Object *with)
lookups = parent->lookups;
compilationUnit = parent->compilationUnit;
- withObject = with->d();
+ withObject = with ? with->d() : 0;
}
Heap::CatchContext::CatchContext(ExecutionEngine *engine, QV4::String *exceptionVarName, const ValueRef exceptionValue)
@@ -269,7 +269,8 @@ void ExecutionContext::markObjects(Heap::Base *m, ExecutionEngine *engine)
c->function->mark(engine);
} else if (ctx->type == Heap::ExecutionContext::Type_WithContext) {
WithContext::Data *w = static_cast<WithContext::Data *>(ctx);
- w->withObject->mark(engine);
+ if (w->withObject)
+ w->withObject->mark(engine);
} else if (ctx->type == Heap::ExecutionContext::Type_CatchContext) {
CatchContext::Data *c = static_cast<CatchContext::Data *>(ctx);
c->exceptionVarName->mark(engine);
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 160dbe4352..637947d702 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -331,7 +331,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
variantPrototype = memoryManager->alloc<VariantPrototype>(InternalClass::create(this, VariantPrototype::staticVTable()), objectPrototype.asObject());
variantClass = InternalClass::create(this, VariantObject::staticVTable());
- Q_ASSERT(variantPrototype.asObject()->prototype() == objectPrototype.asObject());
+ Q_ASSERT(variantPrototype.asObject()->prototype() == objectPrototype.asObject()->d());
sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype.asObject()));
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index ebdc7be200..62d4eea21c 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -39,67 +39,68 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttributes *attrs)
+ReturnedValue Lookup::lookup(ValueRef thisObject, Object *o, PropertyAttributes *attrs)
{
- ExecutionEngine *engine = obj->engine();
+ ExecutionEngine *engine = o->engine();
Identifier *name = engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]->identifier;
int i = 0;
+ Heap::Object *obj = o->d();
while (i < Size && obj) {
- classList[i] = obj->internalClass();
+ classList[i] = obj->internalClass;
- index = obj->internalClass()->find(name);
+ index = obj->internalClass->find(name);
if (index != UINT_MAX) {
level = i;
- *attrs = obj->internalClass()->propertyData.at(index);
- return !attrs->isAccessor() ? obj->memberData()->data[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
+ *attrs = obj->internalClass->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData->data[index].asReturnedValue() : Object::getValue(thisObject, obj->propertyAt(index), *attrs);
}
- obj = obj->prototype();
+ obj = obj->prototype;
++i;
}
level = Size;
while (obj) {
- index = obj->internalClass()->find(name);
+ index = obj->internalClass->find(name);
if (index != UINT_MAX) {
- *attrs = obj->internalClass()->propertyData.at(index);
- return !attrs->isAccessor() ? obj->memberData()->data[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
+ *attrs = obj->internalClass->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData->data[index].asReturnedValue() : Object::getValue(thisObject, obj->propertyAt(index), *attrs);
}
- obj = obj->prototype();
+ obj = obj->prototype;
}
return Primitive::emptyValue().asReturnedValue();
}
-ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs)
+ReturnedValue Lookup::lookup(Object *thisObject, PropertyAttributes *attrs)
{
- Object *thisObject = obj;
- ExecutionEngine *engine = obj->engine();
+ Heap::Object *obj = thisObject->d();
+ ExecutionEngine *engine = thisObject->engine();
Identifier *name = engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]->identifier;
int i = 0;
while (i < Size && obj) {
- classList[i] = obj->internalClass();
+ classList[i] = obj->internalClass;
- index = obj->internalClass()->find(name);
+ index = obj->internalClass->find(name);
if (index != UINT_MAX) {
level = i;
- *attrs = obj->internalClass()->propertyData.at(index);
- return !attrs->isAccessor() ? obj->memberData()->data[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
+ *attrs = obj->internalClass->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData->data[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
}
- obj = obj->prototype();
+ obj = obj->prototype;
++i;
}
level = Size;
while (obj) {
- index = obj->internalClass()->find(name);
+ index = obj->internalClass->find(name);
if (index != UINT_MAX) {
- *attrs = obj->internalClass()->propertyData.at(index);
- return !attrs->isAccessor() ? obj->memberData()->data[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
+ *attrs = obj->internalClass->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData->data[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
}
- obj = obj->prototype();
+ obj = obj->prototype;
}
return Primitive::emptyValue().asReturnedValue();
}
@@ -350,8 +351,8 @@ ReturnedValue Lookup::getter1(Lookup *l, ExecutionEngine *engine, const ValueRef
// the internal class won't match
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass() &&
- l->classList[1] == o->prototype()->internalClass())
- return o->prototype()->memberData()->data[l->index].asReturnedValue();
+ l->classList[1] == o->prototype()->internalClass)
+ return o->prototype()->memberData->data[l->index].asReturnedValue();
}
return getterTwoClasses(l, engine, object);
}
@@ -363,11 +364,11 @@ ReturnedValue Lookup::getter2(Lookup *l, ExecutionEngine *engine, const ValueRef
// the internal class won't match
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass()) {
- o = o->prototype();
- if (l->classList[1] == o->internalClass()) {
- o = o->prototype();
- if (l->classList[2] == o->internalClass())
- return o->memberData()->data[l->index].asReturnedValue();
+ Heap::Object *p = o->prototype();
+ if (l->classList[1] == p->internalClass) {
+ p = p->prototype;
+ if (l->classList[2] == p->internalClass)
+ return p->memberData->data[l->index].asReturnedValue();
}
}
}
@@ -399,8 +400,8 @@ ReturnedValue Lookup::getter0getter1(Lookup *l, ExecutionEngine *engine, const V
if (l->classList[0] == o->internalClass())
return o->memberData()->data[l->index].asReturnedValue();
if (l->classList[2] == o->internalClass() &&
- l->classList[3] == o->prototype()->internalClass())
- return o->prototype()->memberData()->data[l->index2].asReturnedValue();
+ l->classList[3] == o->prototype()->internalClass)
+ return o->prototype()->memberData->data[l->index2].asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
@@ -413,11 +414,11 @@ ReturnedValue Lookup::getter1getter1(Lookup *l, ExecutionEngine *engine, const V
// the internal class won't match
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass() &&
- l->classList[1] == o->prototype()->internalClass())
- return o->prototype()->memberData()->data[l->index].asReturnedValue();
+ l->classList[1] == o->prototype()->internalClass)
+ return o->prototype()->memberData->data[l->index].asReturnedValue();
if (l->classList[2] == o->internalClass() &&
- l->classList[3] == o->prototype()->internalClass())
- return o->prototype()->memberData()->data[l->index2].asReturnedValue();
+ l->classList[3] == o->prototype()->internalClass)
+ return o->prototype()->memberData->data[l->index2].asReturnedValue();
return getterFallback(l, engine, object);
}
l->getter = getterFallback;
@@ -451,11 +452,11 @@ ReturnedValue Lookup::getterAccessor1(Lookup *l, ExecutionEngine *engine, const
if (object->isManaged()) {
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
- Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass() &&
- l->classList[1] == o->prototype()->internalClass()) {
- Scope scope(o->engine());
- FunctionObject *getter = o->prototype()->propertyAt(l->index)->getter();
+ Heap::Object *o = object->objectValue()->d();
+ if (l->classList[0] == o->internalClass &&
+ l->classList[1] == o->prototype->internalClass) {
+ Scope scope(o->internalClass->engine);
+ FunctionObject *getter = o->prototype->propertyAt(l->index)->getter();
if (!getter)
return Encode::undefined();
@@ -473,13 +474,13 @@ ReturnedValue Lookup::getterAccessor2(Lookup *l, ExecutionEngine *engine, const
if (object->isManaged()) {
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
- Object *o = object->objectValue();
- if (l->classList[0] == o->internalClass()) {
- o = o->prototype();
- if (l->classList[1] == o->internalClass()) {
- o = o->prototype();
- if (l->classList[2] == o->internalClass()) {
- Scope scope(o->engine());
+ Heap::Object *o = object->objectValue()->d();
+ if (l->classList[0] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[1] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[2] == o->internalClass) {
+ Scope scope(o->internalClass->engine);
FunctionObject *getter = o->propertyAt(l->index)->getter();
if (!getter)
return Encode::undefined();
@@ -511,8 +512,8 @@ ReturnedValue Lookup::primitiveGetter1(Lookup *l, ExecutionEngine *engine, const
if (object->type() == l->type) {
Object *o = l->proto;
if (l->classList[0] == o->internalClass() &&
- l->classList[1] == o->prototype()->internalClass())
- return o->prototype()->memberData()->data[l->index].asReturnedValue();
+ l->classList[1] == o->prototype()->internalClass)
+ return o->prototype()->memberData->data[l->index].asReturnedValue();
}
l->getter = getterGeneric;
return getterGeneric(l, engine, object);
@@ -542,7 +543,7 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engin
if (object->type() == l->type) {
Object *o = l->proto;
if (l->classList[0] == o->internalClass() &&
- l->classList[1] == o->prototype()->internalClass()) {
+ l->classList[1] == o->prototype()->internalClass) {
Scope scope(o->engine());
FunctionObject *getter = o->prototype()->propertyAt(l->index)->getter();
if (!getter)
@@ -619,8 +620,8 @@ ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionEngine *engine)
{
Object *o = engine->globalObject();
if (l->classList[0] == o->internalClass() &&
- l->classList[1] == o->prototype()->internalClass())
- return o->prototype()->memberData()->data[l->index].asReturnedValue();
+ l->classList[1] == o->prototype()->internalClass)
+ return o->prototype()->memberData->data[l->index].asReturnedValue();
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, engine);
@@ -628,13 +629,13 @@ ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionEngine *engine)
{
- Object *o = engine->globalObject();
- if (l->classList[0] == o->internalClass()) {
- o = o->prototype();
- if (l->classList[1] == o->internalClass()) {
- o = o->prototype();
- if (l->classList[2] == o->internalClass()) {
- return o->prototype()->memberData()->data[l->index].asReturnedValue();
+ Heap::Object *o = engine->globalObject()->d();
+ if (l->classList[0] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[1] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[2] == o->internalClass) {
+ return o->prototype->memberData->data[l->index].asReturnedValue();
}
}
}
@@ -663,7 +664,7 @@ ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionEngine *engine)
{
Object *o = engine->globalObject();
if (l->classList[0] == o->internalClass() &&
- l->classList[1] == o->prototype()->internalClass()) {
+ l->classList[1] == o->prototype()->internalClass) {
Scope scope(o->engine());
FunctionObject *getter = o->prototype()->propertyAt(l->index)->getter();
if (!getter)
@@ -679,13 +680,13 @@ ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine)
{
- Object *o = engine->globalObject();
- if (l->classList[0] == o->internalClass()) {
- o = o->prototype();
- if (l->classList[1] == o->internalClass()) {
- o = o->prototype();
- if (l->classList[2] == o->internalClass()) {
- Scope scope(o->engine());
+ Heap::Object *o = engine->globalObject()->d();
+ if (l->classList[0] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[1] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[2] == o->internalClass) {
+ Scope scope(o->internalClass->engine);
FunctionObject *getter = o->propertyAt(l->index)->getter();
if (!getter)
return Encode::undefined();
@@ -776,8 +777,8 @@ void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, const ValueRef ob
{
Object *o = static_cast<Object *>(object->asManaged());
if (o && o->internalClass() == l->classList[0]) {
- Object *p = o->prototype();
- if (p && p->internalClass() == l->classList[1]) {
+ Heap::Object *p = o->prototype();
+ if (p && p->internalClass == l->classList[1]) {
if (!o->memberData() || l->index >= o->memberData()->size)
o->ensureMemberIndex(l->index);
o->memberData()->data[l->index] = *value;
@@ -794,10 +795,10 @@ void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, const ValueRef ob
{
Object *o = static_cast<Object *>(object->asManaged());
if (o && o->internalClass() == l->classList[0]) {
- Object *p = o->prototype();
- if (p && p->internalClass() == l->classList[1]) {
- p = p->prototype();
- if (p && p->internalClass() == l->classList[2]) {
+ Heap::Object *p = o->prototype();
+ if (p && p->internalClass == l->classList[1]) {
+ p = p->prototype;
+ if (p && p->internalClass == l->classList[2]) {
if (!o->memberData() || l->index >= o->memberData()->size)
o->ensureMemberIndex(l->index);
o->memberData()->data[l->index] = *value;
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index b67876bc82..e474a432ce 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -68,8 +68,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
static const QV4::ManagedVTable static_vtbl; \
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl; } \
V4_MANAGED_SIZE_TEST \
- const QV4::Heap::DataClass *d() const { return &static_cast<const QV4::Heap::DataClass &>(Managed::data); } \
- QV4::Heap::DataClass *d() { return &static_cast<QV4::Heap::DataClass &>(Managed::data); }
+ QV4::Heap::DataClass *d() const { return &static_cast<QV4::Heap::DataClass &>(const_cast<QV4::Heap::Base &>(Managed::data)); }
#define V4_OBJECT(superClass) \
public: \
@@ -78,8 +77,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
static const QV4::ObjectVTable static_vtbl; \
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
V4_MANAGED_SIZE_TEST \
- const Data *d() const { return &static_cast<const Data &>(Managed::data); } \
- Data *d() { return &static_cast<Data &>(Managed::data); }
+ Data *d() const { return &static_cast<Data &>(const_cast<QV4::Heap::Base &>(Managed::data)); }
#define V4_OBJECT2(DataClass, superClass) \
public: \
@@ -89,8 +87,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
static const QV4::ObjectVTable static_vtbl; \
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
V4_MANAGED_SIZE_TEST \
- const QV4::Heap::DataClass *d() const { return &static_cast<const QV4::Heap::DataClass &>(Managed::data); } \
- QV4::Heap::DataClass *d() { return &static_cast<QV4::Heap::DataClass &>(Managed::data); }
+ QV4::Heap::DataClass *d() const { return &static_cast<QV4::Heap::DataClass &>(const_cast<QV4::Heap::Base &>(Managed::data)); }
#define Q_MANAGED_TYPE(type) \
public: \
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 7ec0c8208c..fea809745f 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -261,16 +261,16 @@ Property *Object::__getPropertyDescriptor__(String *name, PropertyAttributes *at
return __getPropertyDescriptor__(idx, attrs);
- const Object *o = this;
+ const Heap::Object *o = d();
while (o) {
- uint idx = o->internalClass()->find(name);
+ uint idx = o->internalClass->find(name);
if (idx < UINT_MAX) {
if (attrs)
- *attrs = o->internalClass()->propertyData[idx];
+ *attrs = o->internalClass->propertyData[idx];
return const_cast<Property *>(o->propertyAt(idx));
}
- o = o->prototype();
+ o = o->prototype;
}
if (attrs)
*attrs = Attr_Invalid;
@@ -279,23 +279,23 @@ Property *Object::__getPropertyDescriptor__(String *name, PropertyAttributes *at
Property *Object::__getPropertyDescriptor__(uint index, PropertyAttributes *attrs) const
{
- const Object *o = this;
+ const Heap::Object *o = d();
while (o) {
- Property *p = o->arrayData() ? o->arrayData()->getProperty(index) : 0;
+ Property *p = o->arrayData ? o->arrayData->getProperty(index) : 0;
if (p) {
if (attrs)
- *attrs = o->arrayData()->attributes(index);
+ *attrs = o->arrayData->attributes(index);
return p;
}
- if (o->isStringObject()) {
- Property *p = static_cast<const StringObject *>(o)->getIndex(index);
+ if (o->internalClass->vtable->type == Type_StringObject) {
+ Property *p = static_cast<const Heap::StringObject *>(o)->getIndex(index);
if (p) {
if (attrs)
*attrs = (Attr_NotWritable|Attr_NotConfigurable);
return p;
}
}
- o = o->prototype();
+ o = o->prototype;
}
if (attrs)
*attrs = Attr_Invalid;
@@ -308,7 +308,8 @@ bool Object::hasProperty(String *name) const
if (idx != UINT_MAX)
return hasProperty(idx);
- const Object *o = this;
+ Scope scope(engine());
+ ScopedObject o(scope, d());
while (o) {
if (o->hasOwnProperty(name))
return true;
@@ -321,7 +322,8 @@ bool Object::hasProperty(String *name) const
bool Object::hasProperty(uint index) const
{
- const Object *o = this;
+ Scope scope(engine());
+ ScopedObject o(scope, d());
while (o) {
if (o->hasOwnProperty(index))
return true;
@@ -589,7 +591,8 @@ ReturnedValue Object::internalGet(String *name, bool *hasProperty)
name->makeIdentifier();
- Object *o = this;
+ Scope scope(engine());
+ ScopedObject o(scope, this);
while (o) {
uint idx = o->internalClass()->find(name);
if (idx < UINT_MAX) {
@@ -610,7 +613,8 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty)
{
Property *pd = 0;
PropertyAttributes attrs;
- Object *o = this;
+ Scope scope(engine());
+ ScopedObject o(scope, this);
while (o) {
Property *p = o->arrayData() ? o->arrayData()->getProperty(index) : 0;
if (p) {
@@ -619,7 +623,7 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty)
break;
}
if (o->isStringObject()) {
- pd = static_cast<StringObject *>(o)->getIndex(index);
+ pd = static_cast<StringObject *>(o.getPointer())->getIndex(index);
if (pd) {
attrs = (Attr_NotWritable|Attr_NotConfigurable);
break;
@@ -687,7 +691,8 @@ void Object::internalPut(String *name, const ValueRef value)
goto reject;
} else {
// clause 4
- if ((pd = prototype()->__getPropertyDescriptor__(name, &attrs))) {
+ Scope scope(engine());
+ if ((pd = ScopedObject(scope, prototype())->__getPropertyDescriptor__(name, &attrs))) {
if (attrs.isAccessor()) {
if (!pd->setter())
goto reject;
@@ -759,7 +764,8 @@ void Object::internalPutIndexed(uint index, const ValueRef value)
goto reject;
} else {
// clause 4
- if ((pd = prototype()->__getPropertyDescriptor__(index, &attrs))) {
+ Scope scope(engine());
+ if ((pd = ScopedObject(scope, prototype())->__getPropertyDescriptor__(index, &attrs))) {
if (attrs.isAccessor()) {
if (!pd->setter())
goto reject;
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index fed05893ca..ade5383932 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -51,6 +51,9 @@ struct Object : Base {
}
Object(InternalClass *internal, QV4::Object *prototype);
+ const Property *propertyAt(uint index) const { return reinterpret_cast<const Property *>(memberData->data + index); }
+ Property *propertyAt(uint index) { return reinterpret_cast<Property *>(memberData->data + index); }
+
Heap::Object *prototype;
MemberData *memberData;
ArrayData *arrayData;
@@ -71,12 +74,11 @@ struct Q_QML_EXPORT Object: Managed {
Heap::ArrayData *arrayData() const { return d()->arrayData; }
void setArrayData(ArrayData *a) { d()->arrayData = a->d(); }
- const Property *propertyAt(uint index) const { return reinterpret_cast<const Property *>(memberData()->data + index); }
- Property *propertyAt(uint index) { return reinterpret_cast<Property *>(memberData()->data + index); }
+ const Property *propertyAt(uint index) const { return d()->propertyAt(index); }
+ Property *propertyAt(uint index) { return d()->propertyAt(index); }
const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(internalClass()->vtable); }
- // ### GC
- Object *prototype() const { return reinterpret_cast<Object *>(d()->prototype); }
+ Heap::Object *prototype() const { return d()->prototype; }
bool setPrototype(Object *proto);
Property *__getOwnProperty__(String *name, PropertyAttributes *attrs = 0);
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index dfe37dfd53..338f756208 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -38,8 +38,9 @@
using namespace QV4;
-ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, Object *o, uint flags)
- : object(scratch1)
+ObjectIterator::ObjectIterator(ExecutionEngine *e, Value *scratch1, Value *scratch2, Object *o, uint flags)
+ : engine(e)
+ , object(scratch1)
, current(scratch2)
, arrayNode(0)
, arrayIndex(0)
@@ -50,7 +51,8 @@ ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, Object *o, uint
}
ObjectIterator::ObjectIterator(Scope &scope, Object *o, uint flags)
- : object(scope.alloc(1))
+ : engine(scope.engine)
+ , object(scope.alloc(1))
, current(scope.alloc(1))
, arrayNode(0)
, arrayIndex(0)
@@ -60,19 +62,6 @@ ObjectIterator::ObjectIterator(Scope &scope, Object *o, uint flags)
init(o);
}
-ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, uint flags)
- : object(scratch1)
- , current(scratch2)
- , arrayNode(0)
- , arrayIndex(0)
- , memberIndex(0)
- , flags(flags)
-{
- object->m = 0;
- current->m = 0;
- // Caller needs to call init!
-}
-
void ObjectIterator::init(Object *o)
{
object->m = o ? &o->data : 0;
@@ -98,6 +87,8 @@ void ObjectIterator::next(String *&name, uint *index, Property *pd, PropertyAttr
*attrs = PropertyAttributes();
return;
}
+ Scope scope(engine);
+ ScopedObject o(scope);
while (1) {
if (!current->asObject())
@@ -109,7 +100,7 @@ void ObjectIterator::next(String *&name, uint *index, Property *pd, PropertyAttr
break;
// check the property is not already defined earlier in the proto chain
if (current->asObject() != object->asObject()) {
- Object *o = object->asObject();
+ o = object->asObject();
bool shadowed = false;
while (o != current->asObject()) {
if ((!!name && o->hasOwnProperty(name)) ||
@@ -125,10 +116,9 @@ void ObjectIterator::next(String *&name, uint *index, Property *pd, PropertyAttr
return;
}
- if (flags & WithProtoChain) {
- Object *proto = current->objectValue()->prototype();
- current->m = proto ? &proto->data : 0;
- } else
+ if (flags & WithProtoChain)
+ current->m = current->objectValue()->prototype();
+ else
current->m = (Heap::Base *)0;
arrayIndex = 0;
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index 4398ea9b5a..7710543114 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -48,6 +48,7 @@ struct Q_QML_EXPORT ObjectIterator
WithProtoChain = 0x2,
};
+ ExecutionEngine *engine;
Value *object;
Value *current;
SparseArrayNode *arrayNode;
@@ -55,16 +56,13 @@ struct Q_QML_EXPORT ObjectIterator
uint memberIndex;
uint flags;
- ObjectIterator(Value *scratch1, Value *scratch2, Object *o, uint flags);
+ ObjectIterator(ExecutionEngine *e, Value *scratch1, Value *scratch2, Object *o, uint flags);
ObjectIterator(Scope &scope, Object *o, uint flags);
void init(Object *o);
void next(String *&name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
ReturnedValue nextPropertyName(ValueRef value);
ReturnedValue nextPropertyNameAsString(ValueRef value);
ReturnedValue nextPropertyNameAsString();
-private:
- friend struct ForEachIteratorObject;
- ObjectIterator(Value *scratch1, Value *scratch2, uint flags); // Constructor that requires calling init()
};
namespace Heap {
@@ -89,7 +87,7 @@ protected:
inline
Heap::ForEachIteratorObject::ForEachIteratorObject(QV4::ExecutionEngine *engine, QV4::Object *o)
: Heap::Object(engine)
- , it(workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain)
+ , it(engine, workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain)
{
setVTable(QV4::ForEachIteratorObject::staticVTable());
}
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index a4e6b5f49b..aad894bd46 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -552,7 +552,7 @@ ReturnedValue ObjectPrototype::method_set_proto(CallContext *ctx)
Scoped<Object> p(scope, ctx->d()->callData->args[0]);
bool ok = false;
if (!!p) {
- if (o->prototype() == p.getPointer()) {
+ if (o->prototype() == p->d()) {
ok = true;
} else if (o->isExtensible()) {
ok = o->setPrototype(p.getPointer());
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 5d9eb6d55e..b5fbf89e3e 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -303,9 +303,6 @@ ReturnedValue Runtime::deleteName(ExecutionEngine *engine, int nameIndex)
QV4::ReturnedValue Runtime::instanceof(ExecutionEngine *engine, const ValueRef left, const ValueRef right)
{
- // As nothing in this method can call into the memory manager, avoid using a Scope
- // for performance reasons
-
Scope scope(engine);
ScopedFunctionObject f(scope, right->asFunctionObject());
if (!f)
@@ -314,11 +311,11 @@ QV4::ReturnedValue Runtime::instanceof(ExecutionEngine *engine, const ValueRef l
if (f->subtype() == Heap::FunctionObject::BoundFunction)
f = static_cast<BoundFunction *>(f.getPointer())->target();
- Object *v = left->asObject();
+ ScopedObject v(scope, left->asObject());
if (!v)
return Encode(false);
- Object *o = QV4::Value::fromReturnedValue(f->protoProperty()).asObject();
+ ScopedObject o(scope, QV4::Value::fromReturnedValue(f->protoProperty()).asObject());
if (!o)
return engine->throwTypeError();
@@ -327,7 +324,7 @@ QV4::ReturnedValue Runtime::instanceof(ExecutionEngine *engine, const ValueRef l
if (!v)
break;
- else if (o == v)
+ else if (o->d() == v->d())
return Encode(true);
}
@@ -1136,7 +1133,7 @@ QV4::ReturnedValue Runtime::typeofElement(ExecutionEngine *engine, const ValueRe
return Runtime::typeofValue(engine, prop);
}
-void Runtime::pushWithScope(const ValueRef o, NoThrowEngine *engine)
+void Runtime::pushWithScope(const ValueRef o, ExecutionEngine *engine)
{
Scope scope(engine);
ScopedObject obj(scope, o->toObject(engine));
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index ee3aeb2392..4d70a66156 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -125,7 +125,7 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
// exceptions & scopes
static void throwException(ExecutionEngine *engine, const ValueRef value);
static ReturnedValue unwindException(ExecutionEngine *engine);
- static void pushWithScope(const ValueRef o, NoThrowEngine *engine);
+ static void pushWithScope(const ValueRef o, ExecutionEngine *engine);
static void pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex);
static void popScope(ExecutionEngine *engine);
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index cb35c78204..6d555d505d 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -95,13 +95,13 @@ Heap::StringObject::StringObject(ExecutionEngine *engine, const ValueRef val)
s->defineReadonlyProperty(engine->id_length, Primitive::fromUInt32(value.stringValue()->toQString().length()));
}
-Property *StringObject::getIndex(uint index) const
+Property *Heap::StringObject::getIndex(uint index) const
{
- QString str = d()->value.stringValue()->toQString();
+ QString str = value.stringValue()->toQString();
if (index >= (uint)str.length())
return 0;
- d()->tmpProperty.value = Encode(internalClass()->engine->newString(str.mid(index, 1)));
- return &d()->tmpProperty;
+ tmpProperty.value = Encode(internalClass->engine->newString(str.mid(index, 1)));
+ return &tmpProperty;
}
bool StringObject::deleteIndexedProperty(Managed *m, uint index)
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index 031b09c093..ba441c9326 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -47,6 +47,8 @@ struct StringObject : Object {
StringObject(InternalClass *ic, QV4::Object *prototype);
StringObject(ExecutionEngine *engine, const ValueRef value);
Value value;
+
+ Property *getIndex(uint index) const;
// ### get rid of tmpProperty
mutable Property tmpProperty;
};
@@ -61,7 +63,9 @@ struct StringObject: Object {
V4_OBJECT2(StringObject, Object)
Q_MANAGED_TYPE(StringObject)
- Property *getIndex(uint index) const;
+ Property *getIndex(uint index) const {
+ return d()->getIndex(index);
+ }
static bool deleteIndexedProperty(Managed *m, uint index);
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 07f70d3604..1e1c17ffef 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -421,8 +421,9 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(CallBuiltinPushCatchScope)
MOTH_BEGIN_INSTR(CallBuiltinPushScope)
- Runtime::pushWithScope(VALUEPTR(instr.arg), static_cast<QV4::NoThrowEngine*>(engine));
+ Runtime::pushWithScope(VALUEPTR(instr.arg), engine);
context = engine->currentContext();
+ CHECK_EXCEPTION;
MOTH_END_INSTR(CallBuiltinPushScope)
MOTH_BEGIN_INSTR(CallBuiltinPopScope)