Make the Ref classes not template based
authorLars Knoll <lars.knoll@digia.com>
Mon, 27 Jan 2014 13:58:52 +0000 (14:58 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 7 Feb 2014 09:44:00 +0000 (10:44 +0100)
Move to a class hierarchy that mirrors the main classes. This will
allow moving functionality over into the Ref classes, as the current
Managed classes become mainly something that holds the data. This
is required to make objects movable by the GC.

Change-Id: I4ca88ab0e5d8c88c8dc56d51937990500a33e0d9
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
22 files changed:
src/imports/localstorage/plugin.cpp
src/qml/jsruntime/qv4debugging.cpp
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4engine_p.h
src/qml/jsruntime/qv4functionobject_p.h
src/qml/jsruntime/qv4global_p.h
src/qml/jsruntime/qv4managed_p.h
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4objectiterator.cpp
src/qml/jsruntime/qv4objectiterator_p.h
src/qml/jsruntime/qv4persistent_p.h
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/jsruntime/qv4qobjectwrapper_p.h
src/qml/jsruntime/qv4regexpobject.cpp
src/qml/jsruntime/qv4regexpobject_p.h
src/qml/jsruntime/qv4scopedvalue_p.h
src/qml/jsruntime/qv4script.cpp
src/qml/jsruntime/qv4string_p.h
src/qml/jsruntime/qv4value_p.h
src/qml/jsruntime/qv4variantobject_p.h
src/qml/qml/qqmlvmemetaobject.cpp
src/quick/items/context2d/qquickcontext2d.cpp

index c5e6db4..7a7649c 100644 (file)
@@ -131,6 +131,7 @@ public:
     bool forwardOnly; // type == Rows
 };
 
+DEFINE_REF(QQmlSqlDatabaseWrapper, Object);
 DEFINE_OBJECT_VTABLE(QQmlSqlDatabaseWrapper);
 
 static ReturnedValue qmlsqldatabase_version(CallContext *ctx)
@@ -206,7 +207,7 @@ static QString qmlsqldatabase_databaseFile(const QString& connectionName, QV8Eng
     return qmlsqldatabase_databasesPath(engine) + QDir::separator() + connectionName;
 }
 
-static ReturnedValue qmlsqldatabase_rows_index(QV4::ManagedRef<QQmlSqlDatabaseWrapper> r, ExecutionEngine *v4, quint32 index, bool *hasProperty = 0)
+static ReturnedValue qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapperRef r, ExecutionEngine *v4, quint32 index, bool *hasProperty = 0)
 {
     Scope scope(v4);
     QV8Engine *v8 = v4->v8Engine;
index 32d8c1f..9ab1622 100644 (file)
@@ -179,7 +179,7 @@ void Debugger::resume(Speed speed)
         return;
 
     if (!m_returnedValue.isUndefined())
-        m_returnedValue = Primitive::undefinedValue();
+        m_returnedValue = Encode::undefined();
 
     clearTemporaryBreakPoints();
     if (speed == StepOver)
index 6de40f4..16bacbf 100644 (file)
@@ -560,7 +560,7 @@ Returned<RegExpObject> *ExecutionEngine::newRegExpObject(const QString &pattern,
     return newRegExpObject(re, global);
 }
 
-Returned<RegExpObject> *ExecutionEngine::newRegExpObject(ManagedRef<RegExp> re, bool global)
+Returned<RegExpObject> *ExecutionEngine::newRegExpObject(RegExpRef re, bool global)
 {
     RegExpObject *object = new (memoryManager) RegExpObject(this, re, global);
     return object->asReturned<RegExpObject>();
index 4fbef14..63c57b8 100644 (file)
@@ -317,7 +317,7 @@ public:
     Returned<DateObject> *newDateObject(const QDateTime &dt);
 
     Returned<RegExpObject> *newRegExpObject(const QString &pattern, int flags);
-    Returned<RegExpObject> *newRegExpObject(ManagedRef<RegExp> re, bool global);
+    Returned<RegExpObject> *newRegExpObject(RegExpRef re, bool global);
     Returned<RegExpObject> *newRegExpObject(const QRegExp &re);
 
     Returned<Object> *newErrorObject(const ValueRef value);
index d1fc56a..af4ec02 100644 (file)
@@ -155,6 +155,8 @@ inline FunctionObject *value_cast(const Value &v) {
     return v.asFunctionObject();
 }
 
+DEFINE_REF(FunctionObject, Object);
+
 struct FunctionCtor: FunctionObject
 {
     V4_OBJECT
index d3764d0..746513c 100644 (file)
@@ -156,11 +156,12 @@ template<typename T> struct Returned;
 typedef Returned<String> ReturnedString;
 typedef Returned<Object> ReturnedObject;
 typedef Returned<FunctionObject> ReturnedFunctionObject;
-template<typename T> struct ManagedRef;
-typedef ManagedRef<String> StringRef;
-typedef ManagedRef<Object> ObjectRef;
-typedef ManagedRef<ArrayObject> ArrayObjectRef;
-typedef ManagedRef<FunctionObject> FunctionObjectRef;
+struct ManagedRef;
+struct StringRef;
+struct ObjectRef;
+struct ArrayObjectRef;
+struct FunctionObjectRef;
+struct RegExpRef;
 
 struct PersistentValuePrivate;
 class PersistentValue;
index ed4637e..8c6f2da 100644 (file)
@@ -353,80 +353,6 @@ private:
     friend struct ObjectIterator;
 };
 
-template<typename T>
-struct ManagedRef {
-    // Important: Do NOT add a copy constructor to this class or any derived class
-    // adding a copy constructor actually changes the calling convention, ie.
-    // is not even binary compatible. Adding it would break assumptions made
-    // in the jit'ed code.
-    ManagedRef(const ScopedValue);
-    ManagedRef(const Scoped<T> &v);
-    ManagedRef(TypedValue<T> &v) { ptr = &v; }
-    ManagedRef(Value &v) {
-        ptr = value_cast<T>(v) ? &v : 0;
-    }
-    static ManagedRef fromValuePointer(Value *s) {
-        ManagedRef r(s);
-        if (sizeof(void *) == 8)
-            r.ptr->val = 0;
-        else
-            *r.ptr = Value::fromManaged(0);
-        return r;
-    }
-
-    ManagedRef &operator=(T *t)
-    {
-        if (sizeof(void *) == 4)
-            ptr->tag = Value::Managed_Type;
-        ptr->m = t;
-        return *this;
-    }
-    ManagedRef &operator=(Returned<T> *t) {
-        if (sizeof(void *) == 4)
-            ptr->tag = Value::Managed_Type;
-        ptr->m = t->getPointer();
-        return *this;
-    }
-
-    operator const T *() const {
-        return ptr ? static_cast<T*>(ptr->managed()) : 0;
-    }
-    const T *operator->() const {
-        return static_cast<T*>(ptr->managed());
-    }
-
-    operator T *() {
-        return ptr ? static_cast<T*>(ptr->managed()) : 0;
-    }
-    T *operator->() {
-        return static_cast<T*>(ptr->managed());
-    }
-
-    T *getPointer() const {
-        return static_cast<T *>(ptr->managed());
-    }
-    ReturnedValue asReturnedValue() const { return ptr ? ptr->val : Primitive::undefinedValue().asReturnedValue(); }
-    operator Returned<T> *() const { return ptr ? Returned<T>::create(getPointer()) : 0; }
-
-    bool operator==(const ManagedRef<T> &other) {
-        if (ptr == other.ptr)
-            return true;
-        return ptr && other.ptr && ptr->m == other.ptr->m;
-    }
-    bool operator!=(const ManagedRef<T> &other) {
-        return !operator==(other);
-    }
-    bool operator!() const { return !ptr || !ptr->managed(); }
-
-    static ManagedRef null() { return ManagedRef((Value *)0); }
-    bool isNull() const { return !ptr; }
-protected:
-    ManagedRef(Value *v) {
-        ptr = v;
-    }
-    Value *ptr;
-};
-
 
 template<>
 inline Managed *value_cast(const Value &v) {
@@ -456,6 +382,68 @@ inline FunctionObject *managed_cast(Managed *m)
 }
 
 
+Value *extractValuePointer(const ScopedValue &);
+template<typename T>
+Value *extractValuePointer(const Scoped<T> &);
+
+#define DEFINE_REF_METHODS(Class, Base) \
+    Class##Ref(const QV4::ScopedValue &v) \
+    { QV4::Value *val = extractValuePointer(v); ptr = QV4::value_cast<Class>(*val) ? val : 0; } \
+    Class##Ref(const QV4::Scoped<Class> &v) { ptr = extractValuePointer(v); } \
+    Class##Ref(QV4::TypedValue<Class> &v) { ptr = &v; } \
+    Class##Ref(QV4::Value &v) { ptr = QV4::value_cast<Class>(v) ? &v : 0; } \
+    Class##Ref &operator=(Class *t) { \
+        if (sizeof(void *) == 4) \
+            ptr->tag = QV4::Value::Managed_Type; \
+        ptr->m = t; \
+        return *this; \
+    } \
+    Class##Ref &operator=(QV4::Returned<Class> *t) { \
+        if (sizeof(void *) == 4) \
+            ptr->tag = QV4::Value::Managed_Type; \
+        ptr->m = t->getPointer(); \
+        return *this; \
+    } \
+    operator const Class *() const { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
+    const Class *operator->() const { return static_cast<Class*>(ptr->managed()); } \
+    operator Class *() { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
+    Class *operator->() { return static_cast<Class*>(ptr->managed()); } \
+    Class *getPointer() const { return static_cast<Class *>(ptr->managed()); } \
+    operator QV4::Returned<Class> *() const { return ptr ? QV4::Returned<Class>::create(getPointer()) : 0; } \
+    static Class##Ref null() { Class##Ref c; c.ptr = 0; return c; } \
+protected: \
+    Class##Ref() {} \
+public: \
+
+#define DEFINE_REF(Class, Base) \
+struct Class##Ref : public Base##Ref \
+{ DEFINE_REF_METHODS(Class, Base) } \
+
+
+struct ManagedRef {
+    // Important: Do NOT add a copy constructor to this class or any derived class
+    // adding a copy constructor actually changes the calling convention, ie.
+    // is not even binary compatible. Adding it would break assumptions made
+    // in the jit'ed code.
+    DEFINE_REF_METHODS(Managed, Managed);
+
+    bool operator==(const ManagedRef &other) {
+        if (ptr == other.ptr)
+            return true;
+        return ptr && other.ptr && ptr->m == other.ptr->m;
+    }
+    bool operator!=(const ManagedRef &other) {
+        return !operator==(other);
+    }
+    bool operator!() const { return !ptr || !ptr->managed(); }
+
+    bool isNull() const { return !ptr; }
+    ReturnedValue asReturnedValue() const { return ptr ? ptr->val : Primitive::undefinedValue().asReturnedValue(); }
+
+public:
+    Value *ptr;
+};
+
 }
 
 
index 3a4cb3d..e3361ae 100644 (file)
@@ -422,6 +422,23 @@ inline ReturnedValue value_convert<Object>(ExecutionEngine *e, const Value &v)
     return v.toObject(e->currentContext())->asReturnedValue();
 }
 
+struct ObjectRef : public ManagedRef
+{
+    DEFINE_REF_METHODS(Object, Managed)
+
+    static ObjectRef fromValuePointer(Value *s) {
+        ObjectRef r;
+        r.ptr = s;
+        if (sizeof(void *) == 8)
+            r.ptr->val = 0;
+        else
+            *r.ptr = Value::fromManaged(0);
+        return r;
+    }
+};
+
+DEFINE_REF(ArrayObject, Object);
+
 }
 
 QT_END_NAMESPACE
index 707bea0..e5f693c 100644 (file)
 
 using namespace QV4;
 
-ObjectIterator::ObjectIterator(ObjectRef scratch1, ObjectRef scratch2, const ObjectRef o, uint flags)
-    : object(scratch1)
-    , current(scratch2)
+ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, const ObjectRef o, uint flags)
+    : object(ObjectRef::fromValuePointer(scratch1))
+    , current(ObjectRef::fromValuePointer(scratch2))
     , arrayNode(0)
     , arrayIndex(0)
     , memberIndex(0)
     , flags(flags)
 {
-    object = o;
-    current = o;
+    object = o.getPointer();
+    current = o.getPointer();
 
-    if (object && object->asArgumentsObject()) {
+    if (!!object && object->asArgumentsObject()) {
         Scope scope(object->engine());
         Scoped<ArgumentsObject> (scope, object->asReturnedValue())->fullyCreate();
     }
@@ -74,7 +74,7 @@ ObjectIterator::ObjectIterator(Scope &scope, const ObjectRef o, uint flags)
     object = o;
     current = o;
 
-    if (object && object->asArgumentsObject()) {
+    if (!!object && object->asArgumentsObject()) {
         Scope scope(object->engine());
         Scoped<ArgumentsObject> (scope, object->asReturnedValue())->fullyCreate();
     }
@@ -103,7 +103,7 @@ void ObjectIterator::next(StringRef name, uint *index, Property *pd, PropertyAtt
                 Object *o = object;
                 bool shadowed = false;
                 while (o != current) {
-                    if ((name && o->hasOwnProperty(name)) ||
+                    if ((!!name && o->hasOwnProperty(name)) ||
                         (*index != UINT_MAX && o->hasOwnProperty(*index))) {
                         shadowed = true;
                         break;
index dafd269..c87f284 100644 (file)
@@ -74,7 +74,7 @@ struct Q_QML_EXPORT ObjectIterator
     uint memberIndex;
     uint flags;
 
-    ObjectIterator(ObjectRef scratch1, ObjectRef scratch2, const ObjectRef o, uint flags);
+    ObjectIterator(Value *scratch1, Value *scratch2, const ObjectRef o, uint flags);
     ObjectIterator(Scope &scope, const ObjectRef o, uint flags);
     void next(StringRef name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
     ReturnedValue nextPropertyName(ValueRef value);
@@ -87,7 +87,7 @@ struct ForEachIteratorObject: Object {
     Q_MANAGED_TYPE(ForeachIteratorObject)
     ObjectIterator it;
     ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
-        : Object(ctx->engine), it(ObjectRef::fromValuePointer(workArea), ObjectRef::fromValuePointer(workArea + 1),
+        : Object(ctx->engine), it(workArea, workArea + 1,
                                   o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
         setVTable(staticVTable());
     }
index 34cf9ba..21f37f3 100644 (file)
@@ -84,14 +84,13 @@ public:
     PersistentValue(ReturnedValue val);
     template<typename T>
     PersistentValue(Returned<T> *obj);
-    template<typename T>
-    PersistentValue(const ManagedRef<T> obj);
+    PersistentValue(const ManagedRef obj);
     PersistentValue &operator=(const ValueRef other);
+    PersistentValue &operator=(const ScopedValue &other);
     PersistentValue &operator =(ReturnedValue other);
     template<typename T>
     PersistentValue &operator=(Returned<T> *obj);
-    template<typename T>
-    PersistentValue &operator=(const ManagedRef<T> obj);
+    PersistentValue &operator=(const ManagedRef obj);
     ~PersistentValue();
 
     ReturnedValue value() const {
index 4645efc..9bc01d1 100644 (file)
@@ -1702,7 +1702,8 @@ QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine)
     } else if (type == -1 || type == qMetaTypeId<QVariant>()) {
         QVariant value = *qvariantPtr;
         QV4::ScopedValue rv(scope, engine->fromVariant(value));
-        if (QV4::ManagedRef<QObjectWrapper> qobjectWrapper = rv) {
+        QV4::QObjectWrapperRef qobjectWrapper = rv;
+        if (!!qobjectWrapper) {
             if (QObject *object = qobjectWrapper->object())
                 QQmlData::get(object, true)->setImplicitDestructible();
         }
index 38003eb..ca38c5b 100644 (file)
@@ -200,6 +200,8 @@ private Q_SLOTS:
     void removeDestroyedObject(QObject*);
 };
 
+DEFINE_REF(QObjectWrapper, Object);
+
 }
 
 QT_END_NAMESPACE
index 35ba9bc..74c8a2d 100644 (file)
@@ -80,7 +80,7 @@ RegExpObject::RegExpObject(InternalClass *ic)
     init(ic->engine);
 }
 
-RegExpObject::RegExpObject(ExecutionEngine *engine, ManagedRef<RegExp> value, bool global)
+RegExpObject::RegExpObject(ExecutionEngine *engine, RegExpRef value, bool global)
     : Object(engine->regExpClass)
     , value(value)
     , global(global)
index ce3d017..1b40874 100644 (file)
@@ -84,7 +84,7 @@ struct RegExpObject: Object {
     Property *lastIndexProperty(ExecutionContext *ctx);
     bool global;
 
-    RegExpObject(ExecutionEngine *engine, ManagedRef<RegExp> value, bool global);
+    RegExpObject(ExecutionEngine *engine, RegExpRef value, bool global);
     RegExpObject(ExecutionEngine *engine, const QRegExp &re);
     ~RegExpObject() {}
 
@@ -101,6 +101,7 @@ protected:
     static void markObjects(Managed *that, ExecutionEngine *e);
 };
 
+DEFINE_REF(RegExp, Object);
 
 struct RegExpCtor: FunctionObject
 {
index 9b9f062..5d471ab 100644 (file)
@@ -379,9 +379,9 @@ struct ScopedCallData {
 };
 
 
-typedef ManagedRef<String> StringRef;
-typedef ManagedRef<Object> ObjectRef;
-typedef ManagedRef<FunctionObject> FunctionObjectRef;
+struct StringRef;
+struct ObjectRef;
+struct FunctionObjectRef;
 
 template<typename T>
 inline Scoped<T>::Scoped(const Scope &scope, const ValueRef &v)
@@ -485,12 +485,12 @@ inline TypedValue<T> &TypedValue<T>::operator=(Returned<T> *t)
     return *this;
 }
 
-template<typename T>
-inline TypedValue<T> &TypedValue<T>::operator =(const ManagedRef<T> &v)
-{
-    val = v.asReturnedValue();
-    return *this;
-}
+//template<typename T>
+//inline TypedValue<T> &TypedValue<T>::operator =(const ManagedRef<T> &v)
+//{
+//    val = v.asReturnedValue();
+//    return *this;
+//}
 
 template<typename T>
 inline TypedValue<T> &TypedValue<T>::operator=(const TypedValue<T> &t)
@@ -517,9 +517,8 @@ PersistentValue::PersistentValue(Returned<T> *obj)
 {
 }
 
-template<typename T>
-inline PersistentValue::PersistentValue(const ManagedRef<T> obj)
-    : d(new PersistentValuePrivate(*obj.ptr))
+inline PersistentValue::PersistentValue(const ManagedRef obj)
+    : d(new PersistentValuePrivate(obj.asReturnedValue()))
 {
 }
 
@@ -529,12 +528,15 @@ inline PersistentValue &PersistentValue::operator=(Returned<T> *obj)
     return operator=(QV4::Value::fromManaged(obj->getPointer()).asReturnedValue());
 }
 
-template<typename T>
-inline PersistentValue &PersistentValue::operator=(const ManagedRef<T> obj)
+inline PersistentValue &PersistentValue::operator=(const ManagedRef obj)
 {
-    return operator=(*obj.ptr);
+    return operator=(obj.asReturnedValue());
 }
 
+inline PersistentValue &PersistentValue::operator=(const ScopedValue &other)
+{
+    return operator=(other.asReturnedValue());
+}
 
 template<typename T>
 inline WeakValue::WeakValue(Returned<T> *obj)
@@ -572,16 +574,16 @@ inline ValueRef &ValueRef::operator=(const ScopedValue &o)
 }
 
 
-template<typename T>
-ManagedRef<T>::ManagedRef(const ScopedValue v)
+inline Value *extractValuePointer(const ScopedValue &v)
 {
-    ptr = value_cast<T>(*v.ptr) ? v.ptr : 0;
+    return v.ptr;
 }
 
 template<typename T>
-ManagedRef<T>::ManagedRef(const Scoped<T> &v)
-    : ptr(v.ptr)
-{}
+Value *extractValuePointer(const Scoped<T> &v)
+{
+    return v.ptr;
+}
 
 struct ScopedProperty
 {
index c50b025..7d94195 100644 (file)
@@ -168,7 +168,7 @@ Script::Script(ExecutionEngine *v4, ObjectRef qml, CompiledData::CompilationUnit
         Q_ASSERT(vmFunction);
         Scope valueScope(v4);
         ScopedValue holder(valueScope, new (v4->memoryManager) CompilationUnitHolder(v4, compilationUnit));
-        compilationUnitHolder = holder;
+        compilationUnitHolder = holder.asReturnedValue();
     } else
         vmFunction = 0;
 }
@@ -236,7 +236,7 @@ void Script::parse()
         QV4::CompiledData::CompilationUnit *compilationUnit = isel->compile();
         vmFunction = compilationUnit->linkToEngine(v4);
         ScopedValue holder(valueScope, new (v4->memoryManager) CompilationUnitHolder(v4, compilationUnit));
-        compilationUnitHolder = holder;
+        compilationUnitHolder = holder.asReturnedValue();
     }
 
     if (!vmFunction) {
index c981472..ade64d1 100644 (file)
@@ -187,6 +187,8 @@ inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
     return v.toString(e)->asReturnedValue();
 }
 
+DEFINE_REF(String, Managed);
+
 }
 
 QT_END_NAMESPACE
index 2aefcc4..27c81d5 100644 (file)
@@ -433,7 +433,7 @@ struct TypedValue : public Value
     }
     TypedValue &operator =(T *t);
     TypedValue &operator =(const Scoped<T> &v);
-    TypedValue &operator =(const ManagedRef<T> &v);
+//    TypedValue &operator =(const ManagedRef<T> &v);
     TypedValue &operator =(Returned<T> *t);
 
     TypedValue &operator =(const TypedValue<T> &t);
index 6c4a365..656608d 100644 (file)
@@ -82,6 +82,8 @@ public:
     static bool isEqualTo(Managed *m, Managed *other);
 };
 
+DEFINE_REF(VariantObject, Object);
+
 struct VariantPrototype : VariantObject
 {
 public:
index 48893c1..f9cb956 100644 (file)
@@ -1086,7 +1086,8 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
         // And, if the new value is a scarce resource, we need to ensure that it does not get
         // automatically released by the engine until no other references to it exist.
         QV4::ScopedValue newv(scope, QQmlEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value));
-        if (QV4::ManagedRef<QV4::VariantObject> v = newv)
+        QV4::VariantObjectRef v = newv;
+        if (!!v)
             v->addVmePropertyReference();
 
         // Write the value and emit change signal as appropriate.
index 120397c..9851983 100644 (file)
@@ -921,6 +921,8 @@ struct QQuickJSContext2DImageData : public QV4::Object
     QV4::Value pixelData;
 };
 
+DEFINE_REF(QQuickJSContext2DImageData, QV4::Object);
+
 DEFINE_OBJECT_VTABLE(QQuickJSContext2DImageData);
 
 static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV8Engine* engine, const QImage& image)
@@ -2112,7 +2114,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::CallContext *ctx)
 
     QV4::ScopedValue value(scope, ctx->argument(0));
     r->context->beginPath();
-    if (QV4::ManagedRef<QV4::QObjectWrapper> qobjectWrapper = value) {
+    QV4::QObjectWrapperRef qobjectWrapper = value;
+    if (!!qobjectWrapper) {
         if (QQuickPath *path = qobject_cast<QQuickPath*>(qobjectWrapper->object()))
             r->context->m_path = path->path();
     } else {
@@ -2983,7 +2986,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
 
         pixmap = r->context->createPixmap(url);
     } else if (arg->isObject()) {
-        if (QV4::ManagedRef<QV4::QObjectWrapper> qobjectWrapper = arg) {
+        QV4::QObjectWrapperRef qobjectWrapper = arg;
+        if (!!qobjectWrapper) {
             if (QQuickImage *imageItem = qobject_cast<QQuickImage*>(qobjectWrapper->object())) {
                 pixmap = r->context->createPixmap(imageItem->source());
             } else if (QQuickCanvasItem *canvas = qobject_cast<QQuickCanvasItem*>(qobjectWrapper->object())) {
@@ -2993,19 +2997,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
             } else {
                 V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
             }
-        } else if (QV4::ManagedRef<QQuickJSContext2DImageData> imageData = arg) {
-            QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->pixelData.as<QQuickJSContext2DPixelData>());
-            if (pix && !pix->image.isNull()) {
-                pixmap.take(new QQuickCanvasPixmap(pix->image));
+        } else {
+            QQuickJSContext2DImageDataRef imageData = arg;
+            if (!!imageData) {
+                QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->pixelData.as<QQuickJSContext2DPixelData>());
+                if (pix && !pix->image.isNull()) {
+                    pixmap.take(new QQuickCanvasPixmap(pix->image));
+                } else {
+                    V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+                }
             } else {
-                V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+                QUrl url(arg->toQStringNoThrow());
+                if (url.isValid())
+                    pixmap = r->context->createPixmap(url);
+                else
+                    V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
             }
-        } else {
-            QUrl url(arg->toQStringNoThrow());
-            if (url.isValid())
-                pixmap = r->context->createPixmap(url);
-            else
-                V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
         }
     } else {
         V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
@@ -3263,7 +3270,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(QV4::CallC
 
     if (ctx->callData->argc == 1) {
         QV4::ScopedValue arg0(scope, ctx->callData->args[0]);
-        if (QV4::ManagedRef<QQuickJSContext2DImageData> imgData = arg0) {
+        QQuickJSContext2DImageDataRef imgData = arg0;
+        if (!!imgData) {
             QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->pixelData.as<QQuickJSContext2DPixelData>());
             if (pa) {
                 qreal w = pa->image.width();
@@ -3340,7 +3348,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
     if (!qIsFinite(dx) || !qIsFinite(dy))
         V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
 
-    QV4::ManagedRef<QQuickJSContext2DImageData> imageData = arg0;
+    QQuickJSContext2DImageDataRef imageData = arg0;
     if (!imageData)
         return ctx->callData->thisObject.asReturnedValue();