summaryrefslogtreecommitdiffstats
path: root/src/script
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-07-15 12:10:10 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-07-15 12:10:10 (GMT)
commit8e932d7d53168fda6ed39109659efcaf88a32487 (patch)
treea1a68e31082ee788e66e232f148f3f80268ee5ee /src/script
parentc32c9c2d2b868cb34fb8917b25273eb52f2c9581 (diff)
downloadQt-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/script')
-rw-r--r--src/script/api/qscriptengine.cpp72
-rw-r--r--src/script/api/qscriptengine_p.h15
-rw-r--r--src/script/bridge/qscriptqobject.cpp8
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