From: Lars Knoll Date: Thu, 27 Nov 2014 07:56:03 +0000 (+0100) Subject: Return a Heap::Object in Object::prototype() X-Git-Tag: v5.5.90+alpha1~661 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9d2a5ea28adf8ab35212ca8a71b479bc50960e3d;p=platform%2Fupstream%2Fqtdeclarative.git Return a Heap::Object in Object::prototype() Change-Id: Ice0265ae558ba14497421a5bbf25ee9db76adab5 Reviewed-by: Simon Hausmann --- diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 8b510fd..5b993ab 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(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(ctx); c->exceptionVarName->mark(engine); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 160dbe4..637947d 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -331,7 +331,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) variantPrototype = memoryManager->alloc(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(arrayClass, arrayPrototype.asObject())); diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index ebdc7be..62d4eea 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->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->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 b67876b..e474a43 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(Managed::data); } \ - QV4::Heap::DataClass *d() { return &static_cast(Managed::data); } + QV4::Heap::DataClass *d() const { return &static_cast(const_cast(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(Managed::data); } \ - Data *d() { return &static_cast(Managed::data); } + Data *d() const { return &static_cast(const_cast(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(Managed::data); } \ - QV4::Heap::DataClass *d() { return &static_cast(Managed::data); } + QV4::Heap::DataClass *d() const { return &static_cast(const_cast(Managed::data)); } #define Q_MANAGED_TYPE(type) \ public: \ diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 7ec0c82..fea8097 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(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(o)->getIndex(index); + if (o->internalClass->vtable->type == Type_StringObject) { + Property *p = static_cast(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(o)->getIndex(index); + pd = static_cast(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 fed0589..ade5383 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(memberData->data + index); } + Property *propertyAt(uint index) { return reinterpret_cast(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(memberData()->data + index); } - Property *propertyAt(uint index) { return reinterpret_cast(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(internalClass()->vtable); } - // ### GC - Object *prototype() const { return reinterpret_cast(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 dfe37df..338f756 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 4398ea9..7710543 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 a4e6b5f..aad894b 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 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 5d9eb6d..b5fbf89 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(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 ee3aeb2..4d70a66 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 cb35c78..6d555d5 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 031b09c..ba441c9 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 07f70d3..1e1c17f 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(engine)); + Runtime::pushWithScope(VALUEPTR(instr.arg), engine); context = engine->currentContext(); + CHECK_EXCEPTION; MOTH_END_INSTR(CallBuiltinPushScope) MOTH_BEGIN_INSTR(CallBuiltinPopScope)