From 2e571b141ce50349790ca943455427185442ed16 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 3 Jul 2009 15:14:54 +0200 Subject: start implementing QScriptClass extensions Callable seems to work, HasInstance not quite there yet. --- src/script/api/qscriptengine.cpp | 43 ++++++++++++++++++++++++++++ src/script/api/qscriptengine_p.h | 8 +++++- tests/auto/qscriptclass/tst_qscriptclass.cpp | 1 + 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 16c0371..4321370 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -52,6 +52,10 @@ Q_DECLARE_METATYPE(QObjectList) #endif Q_DECLARE_METATYPE(QList) +// ### move +Q_DECLARE_METATYPE(QScriptContext*) +Q_DECLARE_METATYPE(QScriptValueList) + QT_BEGIN_NAMESPACE /*! @@ -386,6 +390,45 @@ void ClassObject::getPropertyNames(JSC::ExecState *exec, JSC::JSObject::getPropertyNames(exec, propertyNames); } +JSC::CallType ClassObject::getCallData(JSC::CallData &callData) +{ + if (!data->scriptClass->supportsExtension(QScriptClass::Callable)) + return JSC::CallTypeNone; + callData.native.function = call; + return JSC::CallTypeHost; +} + +JSC::JSValue JSC_HOST_CALL ClassObject::call(JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + if (!callee->isObject(&ClassObject::info)) + return throwError(exec, JSC::TypeError, "callee is not a ClassObject object"); + ClassObject *obj = static_cast(callee); + QScriptEnginePrivate *eng_p = static_cast(exec->dynamicGlobalObject())->engine; + QScriptContext *previousContext = eng_p->currentContext; + QScriptContextPrivate ctx_p(callee, thisValue, args, + /*calledAsConstructor=*/false, + previousContext, eng_p); + QScriptContext *ctx = QScriptContextPrivate::create(ctx_p); + eng_p->currentContext = ctx; + QScriptValue scriptObject = eng_p->scriptValueFromJSCValue(obj); + QVariant result = obj->scriptClass()->extension(QScriptClass::Callable, qVariantFromValue(ctx)); + eng_p->currentContext = previousContext; + delete ctx; + return eng_p->jscValueFromVariant(result); +} + +bool ClassObject::hasInstance(JSC::ExecState *exec, JSC::JSValue value, JSC::JSValue proto) +{ + if (!scriptClass()->supportsExtension(QScriptClass::HasInstance)) + return JSC::JSObject::hasInstance(exec, value, proto); + QScriptValueList args; + QScriptEnginePrivate *eng_p = static_cast(exec->dynamicGlobalObject())->engine; + args << eng_p->scriptValueFromJSCValue(value) << eng_p->scriptValueFromJSCValue(proto); + QVariant result = scriptClass()->extension(QScriptClass::HasInstance, qVariantFromValue(args)); + return result.toBool(); +} + const JSC::ClassInfo* ClassObject::classInfo() const { // ### respect QScriptClass::name() diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index b1b0d2d..c828162 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -210,12 +210,18 @@ public: unsigned&) const; virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); + virtual JSC::CallType getCallData(JSC::CallData&); + static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, + JSC::JSValue, const JSC::ArgList&); + + virtual bool hasInstance(JSC::ExecState*, JSC::JSValue value, JSC::JSValue proto); + virtual const JSC::ClassInfo* classInfo() const; static const JSC::ClassInfo info; static WTF::PassRefPtr createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance)); } QScriptClass *scriptClass() const; diff --git a/tests/auto/qscriptclass/tst_qscriptclass.cpp b/tests/auto/qscriptclass/tst_qscriptclass.cpp index 10d2183..6aad73a 100644 --- a/tests/auto/qscriptclass/tst_qscriptclass.cpp +++ b/tests/auto/qscriptclass/tst_qscriptclass.cpp @@ -764,6 +764,7 @@ void tst_QScriptClass::extension() QScriptValueList args; args << QScriptValue(&eng, 4) << QScriptValue(&eng, 5); QScriptValue ret = obj.call(obj, args); + QVERIFY(ret.isNumber()); QCOMPARE(ret.toNumber(), qsreal(15)); } -- cgit v0.12