summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/script/api/qscriptengine.cpp42
-rw-r--r--src/script/api/qscriptengine_p.h10
-rw-r--r--src/script/api/qscriptvalue.cpp56
-rw-r--r--src/script/api/qscriptvalue_p.h49
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp2
5 files changed, 41 insertions, 118 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 230a8c5..9fc2f72 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -854,7 +854,7 @@ QScriptValue QScriptEnginePrivate::scriptValueFromJSCValue(JSC::JSValue value)
QScriptValuePrivate *p_value = new QScriptValuePrivate();
p_value->engine = this;
p_value->initFrom(value);
- return QScriptValuePrivate::get(p_value);
+ return QScriptValuePrivate::toPublic(p_value);
}
JSC::JSValue QScriptEnginePrivate::scriptValueToJSCValue(const QScriptValue &value)
@@ -874,17 +874,6 @@ JSC::JSValue QScriptEnginePrivate::scriptValueToJSCValue(const QScriptValue &val
return vv->jscValue;
}
-void QScriptEnginePrivate::releaseJSCValue(JSC::JSValue value)
-{
-// ### Q_ASSERT(!JSC::JSImmediate::isImmediate(value));
- Q_ASSERT(value.isCell());
- JSC::JSCell *cell = value.asCell();
- if (!keepAliveValues.contains(cell))
- qWarning("QScriptEnginePrivate::releaseJSCValue(): cell %p doesn't need releasing", cell);
- if (!keepAliveValues[cell].deref())
- keepAliveValues.remove(cell);
-}
-
QScriptValue QScriptEnginePrivate::scriptValueFromVariant(const QVariant &v)
{
Q_Q(QScriptEngine);
@@ -1150,11 +1139,11 @@ void QScriptEnginePrivate::mark()
variantPrototype->mark();
{
- QHash<JSC::JSCell*,QBasicAtomicInt>::const_iterator it;
- for (it = keepAliveValues.constBegin(); it != keepAliveValues.constEnd(); ++it) {
- JSC::JSCell *cell = it.key();
- if (!cell->marked())
- cell->mark();
+ QList<QScriptValuePrivate*>::const_iterator it;
+ for (it = registeredScriptValues.constBegin(); it != registeredScriptValues.constEnd(); ++it) {
+ QScriptValuePrivate *val = *it;
+ if (val->isJSC() && !val->jscValue.marked())
+ val->jscValue.mark();
}
}
@@ -1373,21 +1362,22 @@ bool QScriptEnginePrivate::scriptDisconnect(JSC::JSValue signal, JSC::JSValue re
}
#endif
+
void QScriptEnginePrivate::registerScriptValue(QScriptValuePrivate *value)
{
- attachedScriptValues.insert(value);
+ registeredScriptValues.append(value);
+}
+
+void QScriptEnginePrivate::unregisterScriptValue(QScriptValuePrivate *value)
+{
+ registeredScriptValues.removeOne(value);
}
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++;
- }
+ for (int i = 0; i < registeredScriptValues.size(); ++i)
+ registeredScriptValues.at(i)->detachFromEngine();
+ registeredScriptValues.clear();
}
#ifdef QT_NO_QOBJECT
diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h
index 8a7dd1a..0d034f5 100644
--- a/src/script/api/qscriptengine_p.h
+++ b/src/script/api/qscriptengine_p.h
@@ -122,7 +122,6 @@ public:
QScriptValue scriptValueFromJSCValue(JSC::JSValue value);
JSC::JSValue scriptValueToJSCValue(const QScriptValue &value);
- void releaseJSCValue(JSC::JSValue value);
QScriptValue scriptValueFromVariant(const QVariant &value);
QVariant scriptValueToVariant(const QScriptValue &value, int targetType);
@@ -212,10 +211,7 @@ public:
JSC::JSValue function);
void registerScriptValue(QScriptValuePrivate *value);
- void unregisterScriptValue(QScriptValuePrivate *value)
- {
- attachedScriptValues.remove(value);
- }
+ void unregisterScriptValue(QScriptValuePrivate *value);
void detachAllRegisteredScriptValues();
// private slots
@@ -240,7 +236,7 @@ public:
QList<QScriptEngineAgent*> ownedAgents;
QScriptEngineAgent *activeAgent;
int agentLineNumber;
- QHash<JSC::JSCell*, QBasicAtomicInt> keepAliveValues;
+ QList<QScriptValuePrivate*> registeredScriptValues;
QHash<int, QScriptTypeInfo*> m_typeInfos;
int processEventsInterval;
QScriptValue abortResult;
@@ -249,8 +245,6 @@ public:
QSet<QString> importedExtensions;
QSet<QString> extensionsBeingImported;
- QSet<QScriptValuePrivate*> attachedScriptValues; //keep trace to all QScriptValue evalueted
-
#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 c44bd2b..ad7efbd 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -275,7 +275,7 @@ qsreal ToInteger(qsreal n)
} // namespace QScript
-QScriptValuePrivate::QScriptValuePrivate() : engine(this)
+QScriptValuePrivate::QScriptValuePrivate() : engine(0)
{
ref = 0;
}
@@ -284,28 +284,6 @@ QScriptValuePrivate::~QScriptValuePrivate()
{
}
-QScriptValuePrivate::QScriptValueAutoRegister::QScriptValueAutoRegister(QScriptValuePrivate *value,const QScriptEnginePrivate *engine):
- val(value), ptr(const_cast<QScriptEnginePrivate*>(engine))
-{
- ptr->registerScriptValue(val);
-}
-
-QScriptValuePrivate::QScriptValueAutoRegister::~QScriptValueAutoRegister()
-{
- if (ptr)
- ptr->unregisterScriptValue(val);
-}
-
-QScriptValuePrivate::QScriptValueAutoRegister& QScriptValuePrivate::QScriptValueAutoRegister::operator=(const QScriptEnginePrivate *pointer)
-{
- if (ptr)
- ptr->unregisterScriptValue(val);
- ptr = const_cast<QScriptEnginePrivate*> (pointer);
- if (ptr)
- ptr->registerScriptValue(val);
- return *this;
-};
-
void QScriptValuePrivate::initFrom(JSC::JSValue value)
{
if (value.isCell()) {
@@ -313,24 +291,27 @@ void QScriptValuePrivate::initFrom(JSC::JSValue value)
value = engine->toUsableValue(value);
JSC::JSCell *cell = JSC::asCell(value);
Q_ASSERT(cell != engine->originalGlobalObject());
- if (!engine->keepAliveValues.contains(cell))
- engine->keepAliveValues[cell] = 0;
- engine->keepAliveValues[cell].ref();
}
type = JSC;
jscValue = value;
+ if (engine)
+ engine->registerScriptValue(this);
}
void QScriptValuePrivate::initFrom(double value)
{
type = Number;
numberValue = value;
+ if (engine)
+ engine->registerScriptValue(this);
}
void QScriptValuePrivate::initFrom(const QString &value)
{
type = String;
stringValue = value;
+ if (engine)
+ engine->registerScriptValue(this);
}
bool QScriptValuePrivate::isJSC() const
@@ -346,7 +327,7 @@ QScriptValue QScriptValuePrivate::property(const QString &name, int resolveMode)
QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const
{
- Q_ASSERT(type == JSC);
+ Q_ASSERT(isJSC());
JSC::ExecState *exec = engine->currentFrame;
JSC::JSObject *object = jscValue.getObject();
JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
@@ -369,7 +350,7 @@ QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolv
QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const
{
- Q_ASSERT(type == JSC);
+ Q_ASSERT(isJSC());
JSC::ExecState *exec = engine->currentFrame;
JSC::JSObject *object = jscValue.getObject();
JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
@@ -415,6 +396,13 @@ void QScriptValuePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue va
exec->setException(val);
}
+void QScriptValuePrivate::detachFromEngine()
+{
+ if (isJSC())
+ jscValue = JSC::JSValue();
+ engine = 0;
+}
+
/*!
Constructs an invalid QScriptValue.
*/
@@ -429,10 +417,8 @@ QScriptValue::QScriptValue()
QScriptValue::~QScriptValue()
{
if (d_ptr && !d_ptr->ref.deref()) {
- if (d_ptr->engine && d_ptr->isJSC()
- && !JSC::JSImmediate::isImmediate(d_ptr->jscValue)) {
- d_ptr->engine->releaseJSCValue(d_ptr->jscValue);
- }
+ if (d_ptr->engine)
+ d_ptr->engine->unregisterScriptValue(d_ptr);
delete d_ptr;
}
}
@@ -741,10 +727,8 @@ QScriptValue &QScriptValue::operator=(const QScriptValue &other)
if (d_ptr == other.d_ptr)
return *this;
if (d_ptr && !d_ptr->ref.deref()) {
- if (d_ptr->engine && d_ptr->isJSC()
- && !JSC::JSImmediate::isImmediate(d_ptr->jscValue)) {
- d_ptr->engine->releaseJSCValue(d_ptr->jscValue);
- }
+ if (d_ptr->engine)
+ d_ptr->engine->unregisterScriptValue(d_ptr);
delete d_ptr;
}
d_ptr = other.d_ptr;
diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h
index a438178..a9abff2 100644
--- a/src/script/api/qscriptvalue_p.h
+++ b/src/script/api/qscriptvalue_p.h
@@ -66,41 +66,6 @@ class QScriptEnginePrivate;
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;
- QScriptEnginePrivate *ptr;
- public:
- QScriptValueAutoRegister(QScriptValuePrivate *value) : val(value), ptr(0) {};
- QScriptValueAutoRegister(QScriptValuePrivate *value, const QScriptEnginePrivate *engine);
- ~QScriptValueAutoRegister();
-
- QScriptValueAutoRegister& operator=(const QScriptEnginePrivate* pointer);
-
- operator QScriptEnginePrivate*() const
- {
- return ptr;
- }
-
- operator bool() const
- {
- return ptr;
- }
-
- QScriptEnginePrivate* operator->() const
- {
- return ptr;
- }
-
- private:
- QScriptValueAutoRegister(QScriptValueAutoRegister &/*engine*/){}; //block it
- };
-
Q_DISABLE_COPY(QScriptValuePrivate);
public:
enum Type {
@@ -126,7 +91,7 @@ public:
return q.d_ptr;
}
- static QScriptValue get(QScriptValuePrivate *d)
+ static QScriptValue toPublic(QScriptValuePrivate *d)
{
QScriptValue tmp;
tmp.d_ptr = d;
@@ -138,15 +103,7 @@ public:
QScriptValue property(quint32 index, int resolveMode) const;
QScriptValue property(const QString &, int resolveMode) const;
- void detachEngine()
- {
- // if type is not developed in js engine there is no
- // need to invalidate the object
- if (isJSC()) {
- jscValue = JSC::JSValue();
- }
- engine = 0;
- }
+ void detachFromEngine();
qint64 objectId()
{
@@ -159,7 +116,7 @@ public:
static void saveException(JSC::ExecState*, JSC::JSValue*);
static void restoreException(JSC::ExecState*, JSC::JSValue);
- QScriptValueAutoRegister engine;
+ QScriptEnginePrivate *engine;
Type type;
JSC::JSValue jscValue;
double numberValue;
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
index 718632b..16a9e87 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
@@ -3239,8 +3239,6 @@ void tst_QScriptValue::prettyPrinter()
void tst_QScriptValue::engineDeleted()
{
- //QFAIL("Crashes (need to invalidate scriptvalues when engine is deleted)");
-
QScriptEngine *eng = new QScriptEngine;
QScriptValue v1(eng, 123);
QVERIFY(v1.isNumber());