Return a Heap::Object in Object::prototype()
authorLars Knoll <lars.knoll@digia.com>
Thu, 27 Nov 2014 07:56:03 +0000 (08:56 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Wed, 17 Dec 2014 10:01:10 +0000 (11:01 +0100)
Change-Id: Ice0265ae558ba14497421a5bbf25ee9db76adab5
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
14 files changed:
src/qml/jsruntime/qv4context.cpp
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4lookup.cpp
src/qml/jsruntime/qv4managed_p.h
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4objectiterator.cpp
src/qml/jsruntime/qv4objectiterator_p.h
src/qml/jsruntime/qv4objectproto.cpp
src/qml/jsruntime/qv4runtime.cpp
src/qml/jsruntime/qv4runtime_p.h
src/qml/jsruntime/qv4stringobject.cpp
src/qml/jsruntime/qv4stringobject_p.h
src/qml/jsruntime/qv4vme_moth.cpp

index 8b510fd..5b993ab 100644 (file)
@@ -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);
index 160dbe4..637947d 100644 (file)
@@ -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()));
 
index ebdc7be..62d4eea 100644 (file)
@@ -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;
index b67876b..e474a43 100644 (file)
@@ -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: \
index 7ec0c82..fea8097 100644 (file)
@@ -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;
index fed0589..ade5383 100644 (file)
@@ -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);
index dfe37df..338f756 100644 (file)
@@ -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;
index 4398ea9..7710543 100644 (file)
@@ -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());
 }
index a4e6b5f..aad894b 100644 (file)
@@ -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());
index 5d9eb6d..b5fbf89 100644 (file)
@@ -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));
index ee3aeb2..4d70a66 100644 (file)
@@ -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);
 
index cb35c78..6d555d5 100644 (file)
@@ -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)
index 031b09c..ba441c9 100644 (file)
@@ -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);
 
index 07f70d3..1e1c17f 100644 (file)
@@ -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)