From 87f9c823a96d693c95a7dd4d969b652891eb4fbe Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 14 Jan 2010 14:18:55 +1000 Subject: Support calling in QScriptDeclarativeClass --- src/script/bridge/qscriptdeclarativeclass.cpp | 20 ++++++++++++++++- src/script/bridge/qscriptdeclarativeclass_p.h | 4 ++++ src/script/bridge/qscriptdeclarativeobject.cpp | 31 +++++++++++++++++++++++++- src/script/bridge/qscriptdeclarativeobject_p.h | 6 ++++- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index d67804a..9f5d6b3 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -47,7 +47,7 @@ collection. If you need to store a Value, convert it to a QScriptValue and stor QScriptDeclarativeClass::Value::Value() { - new (this) JSC::JSValue(); + new (this) JSC::JSValue(JSC::jsUndefined()); } QScriptDeclarativeClass::Value::Value(const Value &other) @@ -406,6 +406,16 @@ QScriptEngine *QScriptDeclarativeClass::engine() const return d_ptr->engine; } +bool QScriptDeclarativeClass::supportsCall() const +{ + return d_ptr->supportsCall; +} + +void QScriptDeclarativeClass::setSupportsCall(bool c) +{ + d_ptr->supportsCall = c; +} + QScriptDeclarativeClass::PersistentIdentifier QScriptDeclarativeClass::createPersistentIdentifier(const QString &str) { @@ -479,6 +489,14 @@ QScriptDeclarativeClass::propertyFlags(Object *object, const Identifier &name) return 0; } +QScriptDeclarativeClass::Value QScriptDeclarativeClass::call(Object *object, + QScriptContext *ctxt) +{ + Q_UNUSED(object); + Q_UNUSED(ctxt); + return Value(); +} + QStringList QScriptDeclarativeClass::propertyNames(Object *object) { Q_UNUSED(object); diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index eb94390..aec70e1 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -111,6 +111,9 @@ public: QScriptEngine *engine() const; + bool supportsCall() const; + void setSupportsCall(bool); + PersistentIdentifier createPersistentIdentifier(const QString &); PersistentIdentifier createPersistentIdentifier(const Identifier &); @@ -123,6 +126,7 @@ public: virtual Value property(Object *, const Identifier &); virtual void setProperty(Object *, const Identifier &name, const QScriptValue &); virtual QScriptValue::PropertyFlags propertyFlags(Object *, const Identifier &); + virtual Value call(Object *, QScriptContext *); virtual QStringList propertyNames(Object *); diff --git a/src/script/bridge/qscriptdeclarativeobject.cpp b/src/script/bridge/qscriptdeclarativeobject.cpp index 72e31a9..c2fa46c 100644 --- a/src/script/bridge/qscriptdeclarativeobject.cpp +++ b/src/script/bridge/qscriptdeclarativeobject.cpp @@ -155,7 +155,36 @@ void DeclarativeObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC:: JSC::CallType DeclarativeObjectDelegate::getCallData(QScriptObject *object, JSC::CallData &callData) { - return QScriptObjectDelegate::getCallData(object, callData); + if (!QScriptDeclarativeClassPrivate::get(m_class)->supportsCall) + return JSC::CallTypeNone; + callData.native.function = call; + return JSC::CallTypeHost; +} + +JSC::JSValue DeclarativeObjectDelegate::call(JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + if (!callee->inherits(&QScriptObject::info)) + return JSC::throwError(exec, JSC::TypeError, "callee is not a DeclarativeObject object"); + QScriptObject *obj = static_cast(callee); + QScriptObjectDelegate *delegate = obj->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + return JSC::throwError(exec, JSC::TypeError, "callee is not a DeclarativeObject object"); + + QScriptDeclarativeClass *scriptClass = static_cast(delegate)->m_class; + QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); + + JSC::ExecState *oldFrame = eng_p->currentFrame; + eng_p->pushContext(exec, thisValue, args, callee); + QScriptContext *ctxt = eng_p->contextForFrame(eng_p->currentFrame); + + QScriptValue scriptObject = eng_p->scriptValueFromJSCValue(obj); + QScriptDeclarativeClass::Value result = + scriptClass->call(static_cast(delegate)->m_object, ctxt); + + eng_p->popContext(); + eng_p->currentFrame = oldFrame; + return (JSC::JSValue &)(result); } JSC::ConstructType DeclarativeObjectDelegate::getConstructData(QScriptObject* object, JSC::ConstructData &constructData) diff --git a/src/script/bridge/qscriptdeclarativeobject_p.h b/src/script/bridge/qscriptdeclarativeobject_p.h index 2aa3fb0..38542c8 100644 --- a/src/script/bridge/qscriptdeclarativeobject_p.h +++ b/src/script/bridge/qscriptdeclarativeobject_p.h @@ -48,11 +48,12 @@ class QScriptClass; class QScriptDeclarativeClassPrivate { public: - QScriptDeclarativeClassPrivate() : engine(0), q_ptr(0), context(0) {} + QScriptDeclarativeClassPrivate() : engine(0), q_ptr(0), context(0), supportsCall(false) {} QScriptEngine *engine; QScriptDeclarativeClass *q_ptr; QScriptContext *context; + bool supportsCall:1; static QScriptDeclarativeClassPrivate *get(QScriptDeclarativeClass *c) { return c->d_ptr.data(); @@ -90,6 +91,9 @@ public: bool includeNonEnumerable = false); virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&); + static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, + JSC::JSValue, const JSC::ArgList&); + virtual JSC::ConstructType getConstructData(QScriptObject*, JSC::ConstructData&); virtual bool hasInstance(QScriptObject*, JSC::ExecState*, -- cgit v0.12