From 430dfd326cb9d8dab8ebd11e83dd52e6d55c4229 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 30 Sep 2013 13:48:05 +0200 Subject: Fix ObjectIterator API to be GC safe Change-Id: I3a9c48d53d8dbadcb9b32c00fcef1f89447c4b8c Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4debugging.cpp | 2 +- src/qml/jsruntime/qv4engine.cpp | 3 +- src/qml/jsruntime/qv4engine_p.h | 2 +- src/qml/jsruntime/qv4jsonobject.cpp | 14 ++--- src/qml/jsruntime/qv4managed.cpp | 5 ++ src/qml/jsruntime/qv4managed_p.h | 5 +- src/qml/jsruntime/qv4object.cpp | 17 +----- src/qml/jsruntime/qv4object_p.h | 18 +----- src/qml/jsruntime/qv4objectiterator.cpp | 98 +++++++++++++++++++++++++-------- src/qml/jsruntime/qv4objectiterator_p.h | 34 ++++++++++-- src/qml/jsruntime/qv4objectproto.cpp | 12 ++-- src/qml/jsruntime/qv4qobjectwrapper.cpp | 16 ++---- src/qml/jsruntime/qv4qobjectwrapper_p.h | 2 +- src/qml/jsruntime/qv4regexp.cpp | 2 +- src/qml/jsruntime/qv4regexp_p.h | 2 +- src/qml/jsruntime/qv4runtime.cpp | 2 +- src/qml/jsruntime/qv4scopedvalue_p.h | 15 ++++- src/qml/jsruntime/qv4sequenceobject.cpp | 6 +- src/qml/jsruntime/qv4stringobject.cpp | 3 +- src/qml/jsruntime/qv4stringobject_p.h | 2 +- src/qml/jsruntime/qv4value_def_p.h | 2 + 21 files changed, 158 insertions(+), 104 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index b4da4bba87..f95178c8f7 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -245,7 +245,7 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string return; } - Object *o = v.objectValue(); + ScopedObject o(scope, v); if (!o) return; diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 8808678b54..7b9071ed43 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -535,7 +536,7 @@ Returned *ExecutionEngine::newVariantObject(const QVariant &v) return o->asReturned(); } -Returned *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, Object *o) +Returned *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o) { Object *obj = new (memoryManager) ForEachIteratorObject(ctx, o); return obj->asReturned(); diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 32dcac4512..d93202df6e 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -301,7 +301,7 @@ struct Q_QML_EXPORT ExecutionEngine Returned *newVariantObject(const QVariant &v); - Returned *newForEachIteratorObject(ExecutionContext *ctx, Object *o); + Returned *newForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o); Returned *qmlContextObject() const; diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index 3649163626..10d30756a1 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -791,16 +791,14 @@ QString Stringify::JO(ObjectRef o) QStringList partial; if (propertyList.isEmpty()) { - ObjectIterator it(o.getPointer(), ObjectIterator::EnumerableOnly); + ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly); ScopedValue name(scope); ScopedValue val(scope); while (1) { - Value v; - name = it.nextPropertyNameAsString(&v); + name = it.nextPropertyNameAsString(val); if (name->isNull()) break; - val = v; QString key = name->toQStringNoThrow(); QString member = makeMember(key, val); if (!member.isEmpty()) @@ -1024,16 +1022,14 @@ QJsonObject JsonObject::toJsonObject(ObjectRef o, V4ObjectSet &visitedObjects) visitedObjects.insert(o); - ObjectIterator it(o, ObjectIterator::EnumerableOnly); + ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly); ScopedValue name(scope); + QV4::ScopedValue val(scope); while (1) { - Value v; - name = it.nextPropertyNameAsString(&v); + name = it.nextPropertyNameAsString(val); if (name->isNull()) break; - QV4::ScopedValue val(scope, v); - QString key = name->toQStringNoThrow(); if (!val->asFunctionObject()) result.insert(key, toJsonValue(val, visitedObjects)); diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index f5715d51ec..03608d2556 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -241,3 +241,8 @@ bool Managed::deleteProperty(const StringRef name) { return vtbl->deleteProperty(this, name); } + +Property *Managed::advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes) +{ + return vtbl->advanceIterator(this, it, name, index, attributes); +} diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index c369353422..aca41bed06 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -108,7 +108,7 @@ struct ManagedVTable ReturnedValue (*getLookup)(Managed *m, Lookup *l); void (*setLookup)(Managed *m, Lookup *l, const ValueRef v); bool (*isEqualTo)(Managed *m, Managed *other); - Property *(*advanceIterator)(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes); + Property *(*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes); const char *className; }; @@ -278,8 +278,7 @@ public: bool isEqualTo(Managed *other) { return vtbl->isEqualTo(this, other); } - Property *advanceIterator(ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes) - { return vtbl->advanceIterator(this, it, name, index, attributes); } + Property *advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes); static void destroy(Managed *that) { that->_data = 0; } static bool hasInstance(Managed *that, const ValueRef value); diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index ed2bf09bb7..399cd2e0bd 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -544,10 +544,10 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value) l->setter = Lookup::setterInsert2; } -Property *Object::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs) +Property *Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs) { Object *o = static_cast(m); - *name = 0; + name = (String *)0; *index = UINT_MAX; if (!it->arrayIndex) @@ -595,7 +595,7 @@ Property *Object::advanceIterator(Managed *m, ObjectIterator *it, String **name, PropertyAttributes a = o->internalClass->propertyData[it->memberIndex]; ++it->memberIndex; if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) { - *name = n; + name = n; if (attrs) *attrs = a; return p; @@ -1435,14 +1435,3 @@ QStringList ArrayObject::toQStringList() const } return result; } - - -DEFINE_MANAGED_VTABLE(ForEachIteratorObject); - -void ForEachIteratorObject::markObjects(Managed *that) -{ - ForEachIteratorObject *o = static_cast(that); - Object::markObjects(that); - if (o->it.object) - o->it.object->mark(); -} diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index c28edcae66..77f8d11e4f 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -49,7 +49,6 @@ #include "qv4managed_p.h" #include "qv4property_p.h" #include "qv4internalclass_p.h" -#include "qv4objectiterator_p.h" #include "qv4sparsearray_p.h" #include @@ -314,7 +313,7 @@ protected: static bool deleteIndexedProperty(Managed *m, uint index); static ReturnedValue getLookup(Managed *m, Lookup *l); static void setLookup(Managed *m, Lookup *l, const ValueRef v); - static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes); + static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes); private: @@ -329,21 +328,6 @@ private: friend struct ObjectPrototype; }; -struct ForEachIteratorObject: Object { - Q_MANAGED - ObjectIterator it; - ForEachIteratorObject(ExecutionContext *ctx, Object *o) - : Object(ctx->engine), it(o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) { - vtbl = &static_vtbl; - type = Type_ForeachIteratorObject; - } - - ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); } - -protected: - static void markObjects(Managed *that); -}; - struct BooleanObject: Object { SafeValue value; BooleanObject(ExecutionEngine *engine, const ValueRef val) diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp index fc85a3f04c..2030489ea1 100644 --- a/src/qml/jsruntime/qv4objectiterator.cpp +++ b/src/qml/jsruntime/qv4objectiterator.cpp @@ -45,22 +45,40 @@ using namespace QV4; -ObjectIterator::ObjectIterator(Object *o, uint flags) - : object(o) - , current(o) +ObjectIterator::ObjectIterator(SafeObject *scratch1, SafeObject *scratch2, const ObjectRef o, uint flags) + : object(*scratch1) + , current(*scratch2) , arrayNode(0) , arrayIndex(0) , memberIndex(0) , flags(flags) { + object = o; + current = o; tmpDynamicProperty.value = Primitive::undefinedValue(); } -Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *attrs) +ObjectIterator::ObjectIterator(Scope &scope, const ObjectRef o, uint flags) + : object(*static_cast(scope.alloc(1))) + , current(*static_cast(scope.alloc(1))) + , arrayNode(0) + , arrayIndex(0) + , memberIndex(0) + , flags(flags) { - Property *p = 0; - *name = 0; + object = o; + current = o; + tmpDynamicProperty.value = Primitive::undefinedValue(); +} + +Property *ObjectIterator::next(StringRef name, uint *index, PropertyAttributes *attrs) +{ + name = (String *)0; *index = UINT_MAX; + if (!object) + return 0; + + Property *p = 0; while (1) { if (!current) break; @@ -69,10 +87,8 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a // check the property is not already defined earlier in the proto chain if (current != object) { Property *pp; - if (*name) { - Scope scope(object->engine()); - ScopedString n(scope, *name); - pp = object->__getPropertyDescriptor__(n); + if (name) { + pp = object->__getPropertyDescriptor__(name); } else { assert (*index != UINT_MAX); pp = object->__getPropertyDescriptor__(*index); @@ -86,7 +102,7 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a if (flags & WithProtoChain) current = current->prototype(); else - current = 0; + current = (Object *)0; arrayIndex = 0; memberIndex = 0; @@ -94,38 +110,74 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a return 0; } -ReturnedValue ObjectIterator::nextPropertyName(Value *value) +ReturnedValue ObjectIterator::nextPropertyName(ValueRef value) { + if (!object) + return Encode::null(); + PropertyAttributes attrs; uint index; - String *name; - Property *p = next(&name, &index, &attrs); + Scope scope(object->engine()); + ScopedString name(scope); + Property *p = next(name, &index, &attrs); if (!p) return Encode::null(); - if (value) - *value = Value::fromReturnedValue(object->getValue(p, attrs)); + value = Value::fromReturnedValue(object->getValue(p, attrs)); - if (name) + if (!!name) return name->asReturnedValue(); assert(index < UINT_MAX); return Encode(index); } -ReturnedValue ObjectIterator::nextPropertyNameAsString(Value *value) +ReturnedValue ObjectIterator::nextPropertyNameAsString(ValueRef value) { + if (!object) + return Encode::null(); + PropertyAttributes attrs; uint index; - String *name; - Property *p = next(&name, &index, &attrs); + Scope scope(object->engine()); + ScopedString name(scope); + Property *p = next(name, &index, &attrs); if (!p) return Encode::null(); - if (value) - *value = Value::fromReturnedValue(object->getValue(p, attrs)); + value = Value::fromReturnedValue(object->getValue(p, attrs)); - if (name) + if (!!name) return name->asReturnedValue(); assert(index < UINT_MAX); return Encode(object->engine()->newString(QString::number(index))); } + +ReturnedValue ObjectIterator::nextPropertyNameAsString() +{ + if (!object) + return Encode::null(); + + PropertyAttributes attrs; + uint index; + Scope scope(object->engine()); + ScopedString name(scope); + Property *p = next(name, &index, &attrs); + if (!p) + return Encode::null(); + + if (!!name) + return name->asReturnedValue(); + assert(index < UINT_MAX); + return Encode(object->engine()->newString(QString::number(index))); +} + + +DEFINE_MANAGED_VTABLE(ForEachIteratorObject); + +void ForEachIteratorObject::markObjects(Managed *that) +{ + ForEachIteratorObject *o = static_cast(that); + o->workArea[0].mark(); + o->workArea[1].mark(); + Object::markObjects(that); +} diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h index d5464891f1..e38fa8d7b6 100644 --- a/src/qml/jsruntime/qv4objectiterator_p.h +++ b/src/qml/jsruntime/qv4objectiterator_p.h @@ -43,6 +43,8 @@ #include "qv4global_p.h" #include "qv4property_p.h" +#include "qv4scopedvalue_p.h" +#include "qv4object_p.h" QT_BEGIN_NAMESPACE @@ -65,8 +67,8 @@ struct Q_QML_EXPORT ObjectIterator WithProtoChain = 0x2, }; - Object *object; - Object *current; + ObjectRef object; + ObjectRef current; SparseArrayNode *arrayNode; uint arrayIndex; uint memberIndex; @@ -74,12 +76,32 @@ struct Q_QML_EXPORT ObjectIterator Property tmpDynamicProperty; - ObjectIterator(Object *o, uint flags); - Property *next(String **name, uint *index, PropertyAttributes *attributes = 0); - ReturnedValue nextPropertyName(Value *value = 0); - ReturnedValue nextPropertyNameAsString(Value *value = 0); + ObjectIterator(SafeObject *scratch1, SafeObject *scratch2, const ObjectRef o, uint flags); + ObjectIterator(Scope &scope, const ObjectRef o, uint flags); + Property *next(StringRef name, uint *index, PropertyAttributes *attributes = 0); + ReturnedValue nextPropertyName(ValueRef value); + ReturnedValue nextPropertyNameAsString(ValueRef value); + ReturnedValue nextPropertyNameAsString(); }; +struct ForEachIteratorObject: Object { + Q_MANAGED + ObjectIterator it; + ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o) + : Object(ctx->engine), it(workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) { + vtbl = &static_vtbl; + type = Type_ForeachIteratorObject; + } + + ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); } + +protected: + static void markObjects(Managed *that); + + SafeObject workArea[2]; +}; + + } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 65fd2188ac..20a5c51692 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -222,14 +222,12 @@ ReturnedValue ObjectPrototype::method_defineProperties(SimpleCallContext *ctx) Scoped o(scope, ctx->argument(1), Scoped::Convert); ScopedValue val(scope); - ObjectIterator it(o.getPointer(), ObjectIterator::EnumerableOnly); + ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly); + ScopedString name(scope); while (1) { uint index; - ScopedString name(scope); PropertyAttributes attrs; - String *tmp = 0; - Property *pd = it.next(&tmp, &index, &attrs); - name = tmp; + Property *pd = it.next(name, &index, &attrs); if (!pd) break; Property n; @@ -375,7 +373,7 @@ ReturnedValue ObjectPrototype::method_keys(SimpleCallContext *ctx) Scoped a(scope, ctx->engine->newArrayObject()); - ObjectIterator it(o.getPointer(), ObjectIterator::EnumerableOnly); + ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly); ScopedValue name(scope); while (1) { name = it.nextPropertyNameAsString(); @@ -652,7 +650,7 @@ Returned *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, Scoped array(scope, v4->newArrayObject()); ScopedObject O(scope, o); if (O) { - ObjectIterator it(O.getPointer(), ObjectIterator::NoFlags); + ObjectIterator it(scope, O, ObjectIterator::NoFlags); ScopedValue name(scope); while (1) { name = it.nextPropertyNameAsString(); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 53e915c1a4..90a1950395 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -646,13 +646,11 @@ PropertyAttributes QObjectWrapper::query(const Managed *m, StringRef name) return QV4::Object::query(m, name); } -Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes) +Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes) { - *name = 0; + name = (String *)0; *index = UINT_MAX; - QV4::Scope scope(m->engine()); - QObjectWrapper *that = static_cast(m); if (!that->m_object) @@ -661,22 +659,20 @@ Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String const QMetaObject *mo = that->m_object->metaObject(); const int propertyCount = mo->propertyCount(); if (it->arrayIndex < propertyCount) { - ScopedString n(scope, that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name()))); - *name = n.getPointer(); + name = that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name())); ++it->arrayIndex; if (attributes) *attributes = QV4::Attr_Data; - it->tmpDynamicProperty.value = that->get(n); + it->tmpDynamicProperty.value = that->get(name); return &it->tmpDynamicProperty; } const int methodCount = mo->methodCount(); if (it->arrayIndex < propertyCount + methodCount) { - ScopedString n(scope, that->engine()->newString(QString::fromUtf8(mo->method(it->arrayIndex - propertyCount).name()))); - *name = n.getPointer(); + name = that->engine()->newString(QString::fromUtf8(mo->method(it->arrayIndex - propertyCount).name())); ++it->arrayIndex; if (attributes) *attributes = QV4::Attr_Data; - it->tmpDynamicProperty.value = that->get(n); + it->tmpDynamicProperty.value = that->get(name); return &it->tmpDynamicProperty; } return QV4::Object::advanceIterator(m, it, name, index, attributes); diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 74c436ca64..7b9e985f21 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -108,7 +108,7 @@ private: static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty); static void put(Managed *m, const StringRef name, const ValueRef value); static PropertyAttributes query(const Managed *, StringRef name); - static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes); + static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes); static void markObjects(Managed *that); static void collectDeletables(Managed *m, GCDeletable **deletable); static void destroy(Managed *that) diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index bc0955f547..103605ee7a 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -174,7 +174,7 @@ bool RegExp::deleteIndexedProperty(Managed *m, uint index) return false; } -Property *RegExp::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes) +Property *RegExp::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes) { return 0; } diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h index 8aa173ca38..f674bea042 100644 --- a/src/qml/jsruntime/qv4regexp_p.h +++ b/src/qml/jsruntime/qv4regexp_p.h @@ -119,7 +119,7 @@ protected: static PropertyAttributes queryIndexed(const Managed *m, uint index); static bool deleteProperty(Managed *, const StringRef); static bool deleteIndexedProperty(Managed *m, uint index); - static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes); + static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes); private: friend class RegExpCache; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 8187da6556..1dd35fcee2 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -544,7 +544,7 @@ ReturnedValue __qmljs_foreach_iterator_object(ExecutionContext *ctx, const Value Scoped o(scope, (Object *)0); if (!in->isNullOrUndefined()) o = in; - Scoped it(scope, ctx->engine->newForEachIteratorObject(ctx, o.getPointer())); + Scoped it(scope, ctx->engine->newForEachIteratorObject(ctx, o)); return it.asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 3a7526197e..a1f6f4b2ac 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -463,9 +463,18 @@ struct Referenced { Referenced &operator=(const Referenced &o) { *ptr = *o.ptr; return *this; } Referenced &operator=(T *t) - { ptr->val = t->asReturnedValue(); return *this; } - Referenced &operator=(const Returned *t) { - ptr->val = t->getPointer()->asReturnedValue(); + { +#if QT_POINTER_SIZE == 4 + ptr->tag = Value::Managed_Type; +#endif + ptr->m = t; + return *this; + } + Referenced &operator=(Returned *t) { +#if QT_POINTER_SIZE == 4 + ptr->tag = Value::Managed_Type; +#endif + ptr->m = t->getPointer(); return *this; } diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 6b55a09486..10293a7d9e 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -277,9 +277,9 @@ public: return (signedIdx < m_container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid; } - Property *containerAdvanceIterator(ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs) + Property *containerAdvanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs) { - *name = 0; + name = (String *)0; *index = UINT_MAX; if (m_isReference) { @@ -500,7 +500,7 @@ private: { return static_cast *>(that)->containerDeleteIndexedProperty(index); } static bool isEqualTo(Managed *that, Managed *other) { return static_cast *>(that)->containerIsEqualTo(other); } - static Property *advanceIterator(Managed *that, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs) + static Property *advanceIterator(Managed *that, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs) { return static_cast *>(that)->containerAdvanceIterator(it, name, index, attrs); } static void destroy(Managed *that) diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index fd15d7ef73..7e503e4b1a 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -127,8 +127,9 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index) return true; } -Property *StringObject::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs) +Property *StringObject::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs) { + name = (String *)0; StringObject *s = static_cast(m); uint slen = s->value.stringValue()->toQString().length(); if (it->arrayIndex < slen) { diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h index e02a6a759f..08892d1222 100644 --- a/src/qml/jsruntime/qv4stringobject_p.h +++ b/src/qml/jsruntime/qv4stringobject_p.h @@ -62,7 +62,7 @@ struct StringObject: Object { protected: StringObject(InternalClass *ic); - static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs); + static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs); static void markObjects(Managed *that); }; diff --git a/src/qml/jsruntime/qv4value_def_p.h b/src/qml/jsruntime/qv4value_def_p.h index 4ee277ca38..76f41dca71 100644 --- a/src/qml/jsruntime/qv4value_def_p.h +++ b/src/qml/jsruntime/qv4value_def_p.h @@ -386,6 +386,8 @@ struct Safe : public SafeValue Safe &operator =(const Safe &t); + bool operator!() const { return !managed(); } + // ### GC: remove me operator T*() { return static_cast(managed()); } Value *operator->() { return this; } -- cgit v1.2.3