summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/script/api/qscriptengine.cpp14
-rw-r--r--src/script/api/qscriptengine_p.h15
-rw-r--r--src/script/api/qscriptvalue.cpp29
-rw-r--r--src/script/api/qscriptvalue_p.h56
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp2
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);