diff options
-rw-r--r-- | src/script/api/qscriptengine.cpp | 14 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 15 | ||||
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 29 | ||||
-rw-r--r-- | src/script/api/qscriptvalue_p.h | 56 | ||||
-rw-r--r-- | tests/auto/qscriptvalue/tst_qscriptvalue.cpp | 2 |
5 files changed, 111 insertions, 5 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 3d72990..122c3e5 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -20,6 +20,7 @@ #include "qscriptvalue_p.h" #include "qscriptvalueiterator.h" #include "qscriptclass.h" +#include "qdebug.h" #include <QtCore/qstringlist.h> #include <QtCore/qmetaobject.h> @@ -868,6 +869,7 @@ QScriptEnginePrivate::QScriptEnginePrivate() QScriptEnginePrivate::~QScriptEnginePrivate() { + detachAllRegisteredScriptValues(); qDeleteAll(m_qobjectData); qDeleteAll(m_typeInfos); } @@ -1198,6 +1200,18 @@ bool QScriptEnginePrivate::scriptDisconnect(JSC::JSValue signal, JSC::JSValue re #endif +void QScriptEnginePrivate::detachAllRegisteredScriptValues() +{ + //make copy of attachedScriptValues (orignal set will be modified) + QSet<QScriptValuePrivate*> tmpSet(attachedScriptValues); + QSet<QScriptValuePrivate*>::const_iterator i = tmpSet.begin(); + while (i != tmpSet.end()) { + //this will autmagicly remove *i from attachedScriptValues + (*i)->detachEngine(); + i++; + } +} + QScriptEnginePrivate *QScriptEnginePrivate::get(QScriptEngine *q) { if (!q) diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 666aeff..b3aab9b 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -59,6 +59,7 @@ class QString; class QStringList; class QScriptContext; class QScriptValue; +class QScriptValuePrivate; class QScriptTypeInfo; class QScriptEngineAgent; @@ -135,6 +136,18 @@ public: bool scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver, JSC::JSValue function); + void registerScriptValue(QScriptValuePrivate *value) + { + attachedScriptValues.insert(value); + } + + void unregisterScriptValue(QScriptValuePrivate *value) + { + attachedScriptValues.remove(value); + } + + void detachAllRegisteredScriptValues(); + // private slots void _q_objectDestroyed(QObject *); #endif @@ -163,6 +176,8 @@ public: QSet<QString> importedExtensions; QSet<QString> extensionsBeingImported; + QSet<QScriptValuePrivate*> attachedScriptValues; + #ifndef QT_NO_QOBJECT QHash<QObject*, QScript::QObjectData*> m_qobjectData; #endif diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index bcbc3f7..b1e70b5 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -243,7 +243,7 @@ qsreal ToInteger(qsreal n) } // namespace QScript -QScriptValuePrivate::QScriptValuePrivate() +QScriptValuePrivate::QScriptValuePrivate() : engine(this), valid(true) { ref = 0; } @@ -252,6 +252,28 @@ QScriptValuePrivate::~QScriptValuePrivate() { } +QScriptValuePrivate::QScriptValueAutoRegister::QScriptValueAutoRegister(QScriptValuePrivate *value,const QScriptEngine *engine): + val(value), ptr(const_cast<QScriptEngine*>(engine)) +{ + QScriptEnginePrivate::get(ptr)->registerScriptValue(val); +} + +QScriptValuePrivate::QScriptValueAutoRegister::~QScriptValueAutoRegister() +{ + if (ptr) QScriptEnginePrivate::get(ptr)->unregisterScriptValue(val); +} + +QScriptValuePrivate::QScriptValueAutoRegister& QScriptValuePrivate::QScriptValueAutoRegister::operator=(const QScriptEngine *pointer) +{ + if (ptr) + QScriptEnginePrivate::get(ptr)->unregisterScriptValue(val); + ptr = const_cast<QScriptEngine*> (pointer); + if (ptr) + QScriptEnginePrivate::get(ptr)->registerScriptValue(val); + return *this; +}; + + void QScriptValuePrivate::initFromJSCValue(JSC::JSValue value) { type = JSC; @@ -2270,7 +2292,10 @@ bool QScriptValue::isQMetaObject() const bool QScriptValue::isValid() const { Q_D(const QScriptValue); - return (d != 0); + if (d) + return d->isValid(); + else + return false; } /*! diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h index 87a228f..f0c13a4 100644 --- a/src/script/api/qscriptvalue_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -31,12 +31,54 @@ QT_BEGIN_NAMESPACE #include "wtf/Platform.h" #include "JSValue.h" +#include "qscriptengine.h" class QString; -class QScriptEngine; class QScriptValue; + + class QScriptValuePrivate { + /** Helper class used only in QScriptValuePrivate. Supports atomatic invalidation of all script + values evaluated and contained by QScriptEngine when the engine is above to be deleted. + On change it call QScriptEnginePrivate to unregister old and register new pointer value. + It should behave as pointer to QScriptEngine. + */ + class QScriptValueAutoRegister + { + QScriptValuePrivate *val; + QScriptEngine *ptr; + public: + QScriptValueAutoRegister(QScriptValuePrivate *value) : val(value), ptr(0) {}; + QScriptValueAutoRegister(QScriptValuePrivate *value, const QScriptEngine *engine); + ~QScriptValueAutoRegister(); + + QScriptValueAutoRegister& operator=(const QScriptEngine* pointer); + + operator QScriptEngine*() const + { + return ptr; + } + + operator bool() const + { + return ptr; + } + + bool operator==(const int i) const + { + return ptr == (void *)i; + } + + bool operator!=(const int i) const + { + return ptr != (void *)i; + } + + private: + QScriptValueAutoRegister(QScriptValueAutoRegister &/*enigne*/){}; //block it + }; + public: enum Type { JSC, @@ -65,13 +107,23 @@ public: QScriptValue property(const QString &name, int resolveMode) const; QScriptValue property(quint32 index, int resolveMode) const; - QScriptEngine *engine; + bool isValid() const {return valid;} + void detachEngine() + { + // if type is not developed in js engine there is no + // need to invalidate the object + if (isJSC()) valid=false; + engine=0; + } + + QScriptValueAutoRegister engine; Type type; JSC::JSValue jscValue; double numberValue; QString *stringValue; QBasicAtomicInt ref; + bool valid; }; QT_END_NAMESPACE diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp index 938c527..c8762c3 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp +++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp @@ -3196,7 +3196,7 @@ void tst_QScriptValue::prettyPrinter() void tst_QScriptValue::engineDeleted() { - QFAIL("Crashes (need to invalidate scriptvalues when engine is deleted)"); + //QFAIL("Crashes (need to invalidate scriptvalues when engine is deleted)"); QScriptEngine *eng = new QScriptEngine; QScriptValue v1(eng, 123); |