Fix tst_qjsvalue::engineDeleted()
authorSimon Hausmann <simon.hausmann@digia.com>
Fri, 21 Jun 2013 13:19:20 +0000 (15:19 +0200)
committerLars Knoll <lars.knoll@digia.com>
Fri, 21 Jun 2013 14:09:36 +0000 (16:09 +0200)
Move the engine pointer from QJSValuePrivate to PersistentValuePrivate
and set it back to null in the memory manager destructor.

Change-Id: I904b365221e1559701353cb359eac768928ad918
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/v4/qv4mm.cpp
src/qml/qml/v4/qv4value.cpp
src/qml/qml/v4/qv4value_p.h
src/qml/qml/v8/qjsengine.cpp
src/qml/qml/v8/qjsvalue.cpp
src/qml/qml/v8/qjsvalue_p.h

index 66f92b2..bcc6af5 100644 (file)
@@ -474,6 +474,7 @@ MemoryManager::~MemoryManager()
     while (persistent) {
         PersistentValuePrivate *n = persistent->next;
         persistent->value = Value::undefinedValue();
+        persistent->engine = 0;
         persistent->prev = 0;
         persistent->next = 0;
         persistent = n;
index 97bf93f..5f31a20 100644 (file)
@@ -269,7 +269,7 @@ PersistentValue::~PersistentValue()
 }
 
 WeakValue::WeakValue(const Value &val)
-    : d(new PersistentValuePrivate(val, /*weak*/true))
+    : d(new PersistentValuePrivate(val, /*engine*/0, /*weak*/true))
 {
 }
 
@@ -299,7 +299,7 @@ WeakValue &WeakValue::operator=(const WeakValue &other)
 WeakValue &WeakValue::operator =(const Value &other)
 {
     if (!d) {
-        d = new PersistentValuePrivate(other, /*weak*/true);
+        d = new PersistentValuePrivate(other, /*engine*/0, /*weak*/true);
         return *this;
     }
     d = d->detach(other, /*weak*/true);
@@ -323,17 +323,20 @@ void WeakValue::markOnce()
     m->mark();
 }
 
-PersistentValuePrivate::PersistentValuePrivate(const Value &v, bool weak)
+PersistentValuePrivate::PersistentValuePrivate(const Value &v, ExecutionEngine *e, bool weak)
     : value(v)
     , refcount(1)
     , prev(0)
     , next(0)
+    , engine(e)
 {
-    Managed *m = v.asManaged();
-    if (!m)
-        return;
+    if (!engine) {
+        Managed *m = v.asManaged();
+        if (!m)
+            return;
 
-    ExecutionEngine *engine = m->engine();
+        engine = m->engine();
+    }
     if (engine) {
         PersistentValuePrivate **listRoot = weak ? &engine->memoryManager->m_weakValues : &engine->memoryManager->m_persistentValues;
 
@@ -394,6 +397,6 @@ PersistentValuePrivate *PersistentValuePrivate::detach(const QV4::Value &value,
         return this;
     }
     --refcount;
-    return new PersistentValuePrivate(value, weak);
+    return new PersistentValuePrivate(value, engine, weak);
 }
 
index bd706e8..c9c4bba 100644 (file)
@@ -562,10 +562,11 @@ inline Value Managed::call(ExecutionContext *context, const Value &thisObject, V
 
 struct PersistentValuePrivate
 {
-    PersistentValuePrivate(const Value &v, bool weak = false);
+    PersistentValuePrivate(const Value &v, ExecutionEngine *engine = 0, bool weak = false);
     virtual ~PersistentValuePrivate();
     Value value;
     uint refcount;
+    QV4::ExecutionEngine *engine;
     PersistentValuePrivate **prev;
     PersistentValuePrivate *next;
 
@@ -573,6 +574,14 @@ struct PersistentValuePrivate
     void ref() { ++refcount; }
     void deref();
     PersistentValuePrivate *detach(const QV4::Value &value, bool weak = false);
+
+    bool checkEngine(QV4::ExecutionEngine *otherEngine) {
+        if (!engine) {
+            Q_ASSERT(!value.isObject());
+            engine = otherEngine;
+        }
+        return (engine == otherEngine);
+    }
 };
 
 class Q_QML_EXPORT PersistentValue
index 9a3b7f2..24d4627 100644 (file)
@@ -356,8 +356,7 @@ QJSValue QJSEngine::create(int type, const void *ptr)
 bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
 {
     QJSValuePrivate *vp = QJSValuePrivate::get(value);
-    QV4::ExecutionEngine *e = vp->engine();
-    QV8Engine *engine = e ? e->v8Engine : 0;
+    QV8Engine *engine = vp->engine ? vp->engine->v8Engine : 0;
     if (engine) {
         return engine->metaTypeFromJS(vp->getValue(engine->m_v4Engine), type, ptr);
     } else {
index 38975b0..f3563a7 100644 (file)
 
 QV4::Value QJSValuePrivate::getValue(QV4::ExecutionEngine *e)
 {
-    if (!this->e)
-        this->e = e;
-    else if (this->e != e) {
+    if (!this->engine)
+        this->engine = e;
+    else if (this->engine != e) {
         qWarning("JSValue can't be reassigned to another engine.");
         return QV4::Value::emptyValue();
     }
     if (value.asString() == &string) {
-        value = QV4::Value::fromString(e->newString(string.toQString()));
-        PersistentValuePrivate **listRoot = &e->memoryManager->m_persistentValues;
+        value = QV4::Value::fromString(engine->newString(string.toQString()));
+        PersistentValuePrivate **listRoot = &engine->memoryManager->m_persistentValues;
         prev = listRoot;
         next = *listRoot;
         *prev = this;
@@ -375,8 +375,7 @@ QString QJSValue::toString() const
 */
 double QJSValue::toNumber() const
 {
-    QV4::ExecutionEngine *e = d->engine();
-    QV4::ExecutionContext *ctx = e ? e->current : 0;
+    QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
     try {
         return d->value.toNumber();
     } catch (Exception &e) {
@@ -399,8 +398,7 @@ double QJSValue::toNumber() const
 */
 bool QJSValue::toBool() const
 {
-    QV4::ExecutionEngine *e = d->engine();
-    QV4::ExecutionContext *ctx = e ? e->current : 0;
+    QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
     try {
         return d->value.toBoolean();
     } catch (Exception &e) {
@@ -423,8 +421,7 @@ bool QJSValue::toBool() const
 */
 qint32 QJSValue::toInt() const
 {
-    QV4::ExecutionEngine *e = d->engine();
-    QV4::ExecutionContext *ctx = e ? e->current : 0;
+    QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
     try {
         return d->value.toInt32();
     } catch (Exception &e) {
@@ -447,8 +444,7 @@ qint32 QJSValue::toInt() const
 */
 quint32 QJSValue::toUInt() const
 {
-    QV4::ExecutionEngine *e = d->engine();
-    QV4::ExecutionContext *ctx = e ? e->current : 0;
+    QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
     try {
         return d->value.toUInt32();
     } catch (Exception &e) {
@@ -505,7 +501,7 @@ QJSValue QJSValue::call(const QJSValueList &args)
     if (!f)
         return QJSValue();
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     assert(engine);
 
     QVarLengthArray<Value, 9> arguments(args.length());
@@ -555,7 +551,7 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
     if (!f)
         return QJSValue();
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     assert(engine);
 
     if (!instance.d->checkEngine(engine)) {
@@ -608,7 +604,7 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
     if (!f)
         return QJSValue();
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     assert(engine);
 
     QVarLengthArray<Value, 9> arguments(args.length());
@@ -643,7 +639,7 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
 */
 QJSEngine* QJSValue::engine() const
 {
-    QV4::ExecutionEngine *engine = d->engine();
+    QV4::ExecutionEngine *engine = d->engine;
     if (engine)
         return engine->v8Engine->publicEngine();
 }
@@ -798,7 +794,7 @@ QJSValue QJSValue::property(const QString& name) const
     if (!o)
         return QJSValue();
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     String *s = engine->newString(name);
     uint idx = s->asArrayIndex();
     if (idx < UINT_MAX)
@@ -833,7 +829,7 @@ QJSValue QJSValue::property(quint32 arrayIndex) const
     if (!o)
         return QJSValue();
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     QV4::ExecutionContext *ctx = engine->current;
     try {
         QV4::Value v = arrayIndex == UINT_MAX ? o->get(ctx, engine->id_uintMax) : o->getIndexed(ctx, arrayIndex);
@@ -866,7 +862,7 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
         return;
     }
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     String *s = engine->newString(name);
     uint idx = s->asArrayIndex();
     if (idx < UINT_MAX) {
@@ -901,7 +897,7 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
     if (!o)
         return;
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     QV4::ExecutionContext *ctx = engine->current;
     try {
         if (arrayIndex != UINT_MAX)
@@ -939,7 +935,7 @@ bool QJSValue::deleteProperty(const QString &name)
     if (!o)
         return false;
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     String *s = engine->newString(name);
     return o->deleteProperty(engine->current, s);
 }
@@ -956,7 +952,7 @@ bool QJSValue::hasProperty(const QString &name) const
     if (!o)
         return false;
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     String *s = engine->newIdentifier(name);
     return o->__hasProperty__(s);
 }
@@ -973,7 +969,7 @@ bool QJSValue::hasOwnProperty(const QString &name) const
     if (!o)
         return false;
 
-    ExecutionEngine *engine = d->engine();
+    ExecutionEngine *engine = d->engine;
     String *s = engine->newIdentifier(name);
     return o->__getOwnProperty__(s);
 }
index a1cd471..ef94dea 100644 (file)
@@ -69,46 +69,29 @@ class QJSValuePrivate : public QV4::PersistentValuePrivate
 {
 public:
     QJSValuePrivate(QV4::ExecutionEngine *engine, const QV4::Value &v)
-        : PersistentValuePrivate(v)
-        , e(engine)
+        : PersistentValuePrivate(v, engine)
     {
         if (value.isEmpty())
             value = QV4::Value::undefinedValue();
     }
     QJSValuePrivate(QV4::Object *o)
         : PersistentValuePrivate(QV4::Value::fromObject(o))
-    { e = o->engine(); }
+    { }
     QJSValuePrivate(QV4::String *s)
         : PersistentValuePrivate(QV4::Value::fromString(s))
-    { e = s->engine(); }
+    { }
     QJSValuePrivate(const QString &s)
         : PersistentValuePrivate(QV4::Value::undefinedValue())
         , string(0, s)
-        , e(0)
     {
         value = QV4::Value::fromString(&string);
     }
 
     QV4::Value getValue(QV4::ExecutionEngine *e);
 
-    bool checkEngine(QV4::ExecutionEngine *otherEngine) {
-        if (!e) {
-            assert(!value.isObject());
-            e = otherEngine;
-        }
-        return (e == otherEngine);
-    }
-
-    QV4::ExecutionEngine *engine() const {
-        if (!e)
-            e = value.engine();
-        return e;
-    }
-
     static QJSValuePrivate *get(const QJSValue &v) { return v.d; }
 
     QV4::String string;
-    mutable QV4::ExecutionEngine *e;
 };
 
 QT_END_NAMESPACE