diff options
-rw-r--r-- | src/script/api/qscriptengine.cpp | 42 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 10 | ||||
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 56 | ||||
-rw-r--r-- | src/script/api/qscriptvalue_p.h | 49 | ||||
-rw-r--r-- | tests/auto/qscriptvalue/tst_qscriptvalue.cpp | 2 |
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()); |