diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-07-15 12:10:10 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-07-15 12:10:10 (GMT) |
commit | 8e932d7d53168fda6ed39109659efcaf88a32487 (patch) | |
tree | a1a68e31082ee788e66e232f148f3f80268ee5ee /src | |
parent | c32c9c2d2b868cb34fb8917b25273eb52f2c9581 (diff) | |
download | Qt-8e932d7d53168fda6ed39109659efcaf88a32487.zip Qt-8e932d7d53168fda6ed39109659efcaf88a32487.tar.gz Qt-8e932d7d53168fda6ed39109659efcaf88a32487.tar.bz2 |
initial attempt at implementing QScriptEngine::setGlobalObject()
Doesn't actually replace the global object, but rather has the
standard global object act as a proxy to the custom one.
Diffstat (limited to 'src')
-rw-r--r-- | src/script/api/qscriptengine.cpp | 72 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 15 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject.cpp | 8 |
3 files changed, 84 insertions, 11 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 562515d..c69f1ee 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -560,9 +560,12 @@ void GlobalObject::mark() { JSC::JSGlobalObject::mark(); - if (engine->uncaughtException) + if (engine->uncaughtException && !engine->uncaughtException.marked()) engine->uncaughtException.mark(); + if (engine->customGlobalObject && !engine->customGlobalObject->marked()) + engine->customGlobalObject->mark(); + if (engine->qobjectPrototype && !engine->qobjectPrototype->marked()) engine->qobjectPrototype->mark(); if (engine->qmetaobjectPrototype && !engine->qmetaobjectPrototype->marked()) @@ -598,6 +601,50 @@ void GlobalObject::mark() } } +bool GlobalObject::getOwnPropertySlot(JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::PropertySlot& slot) +{ + if (engine->customGlobalObject) + return engine->customGlobalObject->getOwnPropertySlot(exec, propertyName, slot); + return JSC::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot); +} + +void GlobalObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue value, JSC::PutPropertySlot& slot) +{ + if (engine->customGlobalObject) { + engine->customGlobalObject->put(exec, propertyName, value, slot); + return; + } + JSC::JSGlobalObject::put(exec, propertyName, value, slot); +} + +bool GlobalObject::deleteProperty(JSC::ExecState* exec, + const JSC::Identifier& propertyName) +{ + if (engine->customGlobalObject) + return engine->customGlobalObject->deleteProperty(exec, propertyName); + return JSC::JSGlobalObject::deleteProperty(exec, propertyName); +} + +bool GlobalObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, + unsigned& attributes) const +{ + if (engine->customGlobalObject) + return engine->customGlobalObject->getPropertyAttributes(exec, propertyName, attributes); + return JSC::JSGlobalObject::getPropertyAttributes(exec, propertyName, attributes); +} + +void GlobalObject::getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames) +{ + if (engine->customGlobalObject) { + engine->customGlobalObject->getPropertyNames(exec, propertyNames); + return; + } + JSC::JSGlobalObject::getPropertyNames(exec, propertyNames); +} + static JSC::JSValue JSC_HOST_CALL functionPrint(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); static JSC::JSValue JSC_HOST_CALL functionGC(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); static JSC::JSValue JSC_HOST_CALL functionVersion(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); @@ -790,6 +837,7 @@ QScriptEnginePrivate::QScriptEnginePrivate() : idGenerator(1) currentFrame = exec; + customGlobalObject = 0; agent = 0; processEventsInterval = -1; } @@ -832,7 +880,8 @@ void QScriptEnginePrivate::releaseJSCValue(JSC::JSValue value) // ### Q_ASSERT(!JSC::JSImmediate::isImmediate(value)); Q_ASSERT(value.isCell()); JSC::JSCell *cell = value.asCell(); - Q_ASSERT(keepAliveValues.contains(cell)); + if (!keepAliveValues.contains(cell)) + qWarning("QScriptEnginePrivate::releaseJSCValue(): cell %p doesn't need releasing", cell); if (!keepAliveValues[cell].deref()) keepAliveValues.remove(cell); } @@ -990,6 +1039,11 @@ void QScriptEnginePrivate::releaseContextForFrame(JSC::ExecState *frame) delete ctx; } +bool QScriptEnginePrivate::isCollecting() const +{ + return globalObject->globalData()->heap.isBusy(); +} + #ifndef QT_NO_QOBJECT JSC::JSValue QScriptEnginePrivate::newQObject( @@ -1263,7 +1317,8 @@ QScriptEngine::~QScriptEngine() QScriptValue QScriptEngine::globalObject() const { Q_D(const QScriptEngine); - return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(d->globalObject); + JSC::JSObject *result = d->customGlobalObject ? d->customGlobalObject : d->globalObject; + return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(result); } /*! @@ -1280,9 +1335,14 @@ QScriptValue QScriptEngine::globalObject() const */ void QScriptEngine::setGlobalObject(const QScriptValue &object) { - qWarning("QScriptEngine::setGlobalObject() is not implemented"); - // ### not possible with JSC? - Q_UNUSED(object); + Q_D(QScriptEngine); + if (!object.isObject() || globalObject().strictlyEquals(object)) + return; + JSC::JSObject *jscObject = JSC::asObject(d->scriptValueToJSCValue(object)); + if (jscObject == d->globalObject) + d->customGlobalObject = 0; + else + d->customGlobalObject = jscObject; } /*! diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 64f2145..29581e4 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -110,6 +110,8 @@ public: QScriptContext *contextForFrame(JSC::ExecState *frame); void releaseContextForFrame(JSC::ExecState *frame); + bool isCollecting() const; + #ifndef QT_NO_QOBJECT JSC::JSValue newQObject(QObject *object, QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, @@ -155,6 +157,7 @@ public: #endif JSC::JSGlobalObject *globalObject; + JSC::JSObject *customGlobalObject; JSC::ExecState *currentFrame; QHash<JSC::ExecState*, QScriptContext*> contextForFrameHash; JSC::JSValue uncaughtException; @@ -198,9 +201,19 @@ class GlobalObject : public JSC::JSGlobalObject { public: GlobalObject(QScriptEnginePrivate*); - ~GlobalObject(); + virtual ~GlobalObject(); virtual JSC::UString className() const { return "global"; } virtual void mark(); + virtual bool getOwnPropertySlot(JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertySlot&); + virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue, JSC::PutPropertySlot&); + virtual bool deleteProperty(JSC::ExecState*, + const JSC::Identifier& propertyName); + virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, + unsigned&) const; + virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); public: QScriptEnginePrivate *engine; diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 15d48c3..4a7cd1e 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -1032,7 +1032,7 @@ JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, object = object.prototype(); qobject = object.toQObject(); } - Q_ASSERT(qobject); + Q_ASSERT_X(qobject, Q_FUNC_INFO, "this-object must be a QObject"); QMetaProperty prop = data->meta->property(data->index); Q_ASSERT(prop.isScriptable()); @@ -1771,16 +1771,16 @@ void QObjectConnectionManager::execute(int slotIndex, void **argv) } } } -// Q_ASSERT(slot != 0); + Q_ASSERT(slot && slot.isObject()); -#if 0 - // ### fixme if (engine->isCollecting()) { + qWarning("QtScript: can't execute signal handler during GC"); // we can't do a script function call during GC, // so we're forced to ignore this signal return; } +#if 0 QScriptFunction *fun = engine->convertToNativeFunction(slot); if (fun == 0) { // the signal handler has been GC'ed. This can only happen when |