From 91cb5464a35d2f461644677973ffdcc91985e7fd Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 18 Aug 2009 14:26:14 +0200 Subject: implement getter/setter proxying for Global Object and activation object --- src/script/bridge/qscriptactivationobject.cpp | 30 ++++++++++++++++++++++++++ src/script/bridge/qscriptactivationobject_p.h | 5 +++++ src/script/bridge/qscriptglobalobject.cpp | 30 ++++++++++++++++++++++++++ src/script/bridge/qscriptglobalobject_p.h | 12 +++++++++++ tests/auto/qscriptengine/tst_qscriptengine.cpp | 25 +++++++++++++++++++++ 5 files changed, 102 insertions(+) diff --git a/src/script/bridge/qscriptactivationobject.cpp b/src/script/bridge/qscriptactivationobject.cpp index 5faf7fe..a8a2181 100644 --- a/src/script/bridge/qscriptactivationobject.cpp +++ b/src/script/bridge/qscriptactivationobject.cpp @@ -136,6 +136,36 @@ bool QScriptActivationObject::deleteProperty(JSC::ExecState* exec, const JSC::Id return JSC::JSVariableObject::deleteProperty(exec, propertyName, checkDontDelete); } +void QScriptActivationObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction) +{ + if (d_ptr()->delegate != 0) + d_ptr()->delegate->defineGetter(exec, propertyName, getterFunction); + else + JSC::JSVariableObject::defineGetter(exec, propertyName, getterFunction); +} + +void QScriptActivationObject::defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction) +{ + if (d_ptr()->delegate != 0) + d_ptr()->delegate->defineSetter(exec, propertyName, setterFunction); + else + JSC::JSVariableObject::defineSetter(exec, propertyName, setterFunction); +} + +JSC::JSValue QScriptActivationObject::lookupGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) +{ + if (d_ptr()->delegate != 0) + return d_ptr()->delegate->lookupGetter(exec, propertyName); + return JSC::JSVariableObject::lookupGetter(exec, propertyName); +} + +JSC::JSValue QScriptActivationObject::lookupSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) +{ + if (d_ptr()->delegate != 0) + return d_ptr()->delegate->lookupSetter(exec, propertyName); + return JSC::JSVariableObject::lookupSetter(exec, propertyName); +} + } // namespace QScript QT_END_NAMESPACE diff --git a/src/script/bridge/qscriptactivationobject_p.h b/src/script/bridge/qscriptactivationobject_p.h index fd7b0be..cb28341 100644 --- a/src/script/bridge/qscriptactivationobject_p.h +++ b/src/script/bridge/qscriptactivationobject_p.h @@ -78,6 +78,11 @@ public: virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName, bool checkDontDelete = true); + virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); + virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); + virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); + virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); + virtual const JSC::ClassInfo* classInfo() const { return &info; } static const JSC::ClassInfo info; diff --git a/src/script/bridge/qscriptglobalobject.cpp b/src/script/bridge/qscriptglobalobject.cpp index 5f374ed..eb8673e 100644 --- a/src/script/bridge/qscriptglobalobject.cpp +++ b/src/script/bridge/qscriptglobalobject.cpp @@ -123,6 +123,36 @@ void GlobalObject::getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray JSC::JSGlobalObject::getPropertyNames(exec, propertyNames, listedAttributes); } +void GlobalObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction) +{ + if (customGlobalObject) + customGlobalObject->defineGetter(exec, propertyName, getterFunction); + else + JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction); +} + +void GlobalObject::defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction) +{ + if (customGlobalObject) + customGlobalObject->defineSetter(exec, propertyName, setterFunction); + else + JSC::JSGlobalObject::defineSetter(exec, propertyName, setterFunction); +} + +JSC::JSValue GlobalObject::lookupGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) +{ + if (customGlobalObject) + return customGlobalObject->lookupGetter(exec, propertyName); + return JSC::JSGlobalObject::lookupGetter(exec, propertyName); +} + +JSC::JSValue GlobalObject::lookupSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) +{ + if (customGlobalObject) + return customGlobalObject->lookupSetter(exec, propertyName); + return JSC::JSGlobalObject::lookupSetter(exec, propertyName); +} + } // namespace QScript QT_END_NAMESPACE diff --git a/src/script/bridge/qscriptglobalobject_p.h b/src/script/bridge/qscriptglobalobject_p.h index 5365a21..673f7f6 100644 --- a/src/script/bridge/qscriptglobalobject_p.h +++ b/src/script/bridge/qscriptglobalobject_p.h @@ -81,6 +81,10 @@ public: unsigned&) const; virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, unsigned listedAttributes = JSC::Structure::Prototype); + virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); + virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); + virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); + virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); public: JSC::JSObject *customGlobalObject; @@ -120,6 +124,14 @@ public: virtual void getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, unsigned listedAttributes = JSC::Structure::Prototype) { originalGlobalObject->JSC::JSGlobalObject::getPropertyNames(exec, propertyNames, listedAttributes); } + virtual void defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction) + { originalGlobalObject->JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction); } + virtual void defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction) + { originalGlobalObject->JSC::JSGlobalObject::defineSetter(exec, propertyName, setterFunction); } + virtual JSC::JSValue lookupGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) + { return originalGlobalObject->JSC::JSGlobalObject::lookupGetter(exec, propertyName); } + virtual JSC::JSValue lookupSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) + { return originalGlobalObject->JSC::JSGlobalObject::lookupSetter(exec, propertyName); } private: JSC::JSGlobalObject *originalGlobalObject; }; diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index cf6ebd8..ef86f2a 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -79,6 +79,7 @@ private slots: void newActivationObject(); void getSetGlobalObject(); void globalObjectProperties(); + void globalObjectGetterSetterProperty(); void checkSyntax_data(); void checkSyntax(); void canEvaluate_data(); @@ -955,6 +956,13 @@ void tst_QScriptEngine::getSetGlobalObject() } } +static QScriptValue getSetFoo(QScriptContext *ctx, QScriptEngine *) +{ + if (ctx->argumentCount() > 0) + ctx->thisObject().setProperty("foo", ctx->argument(0)); + return ctx->thisObject().property("foo"); +} + void tst_QScriptEngine::globalObjectProperties() { QScriptEngine eng; @@ -1094,6 +1102,23 @@ void tst_QScriptEngine::globalObjectProperties() QVERIFY(remainingNames.isEmpty()); } +void tst_QScriptEngine::globalObjectGetterSetterProperty() +{ + QScriptEngine engine; + QScriptValue global = engine.globalObject(); + global.setProperty("bar", engine.newFunction(getSetFoo), + QScriptValue::PropertySetter | QScriptValue::PropertyGetter); + global.setProperty("foo", 123); + QVERIFY(global.property("bar").equals(global.property("foo"))); + QVERIFY(engine.evaluate("bar").equals(global.property("foo"))); + global.setProperty("bar", 456); + QVERIFY(global.property("bar").equals(global.property("foo"))); + + engine.evaluate("__defineGetter__('baz', function() { return 789; })"); + QVERIFY(engine.evaluate("baz").equals(789)); + QVERIFY(global.property("baz").equals(789)); +} + void tst_QScriptEngine::checkSyntax_data() { QTest::addColumn("code"); -- cgit v0.12