summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-07-02 11:04:38 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-07-02 11:04:38 (GMT)
commitc320a2c42820a5b31f6611463330c46ea644d8dc (patch)
treee3181887058dfc7053a2e7f8a19a78cdff1e36a3
parentab4eea9aa8d2156d12c85317a78de266cf5f8145 (diff)
downloadQt-c320a2c42820a5b31f6611463330c46ea644d8dc.zip
Qt-c320a2c42820a5b31f6611463330c46ea644d8dc.tar.gz
Qt-c320a2c42820a5b31f6611463330c46ea644d8dc.tar.bz2
implement caching of slot wrapper functions
-rw-r--r--src/script/bridge/qscriptqobject.cpp40
-rw-r--r--src/script/bridge/qscriptqobject_p.h3
-rw-r--r--tests/auto/qscriptqobject/tst_qscriptqobject.cpp3
3 files changed, 42 insertions, 4 deletions
diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp
index a33f001..188ded9 100644
--- a/src/script/bridge/qscriptqobject.cpp
+++ b/src/script/bridge/qscriptqobject.cpp
@@ -980,6 +980,14 @@ bool QObjectWrapperObject::getOwnPropertySlot(JSC::ExecState *exec,
return false;
}
+ {
+ QHash<QByteArray, JSC::JSValue>::const_iterator it = data->cachedMembers.constFind(name);
+ if (it != data->cachedMembers.constEnd()) {
+ slot.setValue(it.value());
+ return true;
+ }
+ }
+
const QScriptEngine::QObjectWrapOptions &opt = data->options;
const QMetaObject *meta = qobject->metaObject();
QScriptEnginePrivate *eng = static_cast<QScript::GlobalObject*>(exec->dynamicGlobalObject())->engine;
@@ -996,6 +1004,7 @@ bool QObjectWrapperObject::getOwnPropertySlot(JSC::ExecState *exec,
&exec->globalData(), exec->dynamicGlobalObject()->functionStructure(),
propertyName);
slot.setValue(fun);
+ data->cachedMembers.insert(name, fun);
return true;
}
}
@@ -1038,6 +1047,7 @@ bool QObjectWrapperObject::getOwnPropertySlot(JSC::ExecState *exec,
&exec->globalData(), exec->dynamicGlobalObject()->functionStructure(),
propertyName);
slot.setValue(fun);
+ data->cachedMembers.insert(name, fun);
return true;
}
}
@@ -1081,7 +1091,7 @@ void QObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& prop
if (hasMethodAccess(method, index, opt)) {
if (!(opt & QScriptEngine::ExcludeSuperClassMethods)
|| (index >= meta->methodOffset())) {
- Q_ASSERT(0);
+ data->cachedMembers.insert(name, value);
return;
}
}
@@ -1108,6 +1118,17 @@ void QObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& prop
return;
}
+ const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods)
+ ? meta->methodOffset() : 0;
+ for (index = meta->methodCount() - 1; index >= offset; --index) {
+ QMetaMethod method = meta->method(index);
+ if (hasMethodAccess(method, index, opt)
+ && (methodName(method) == name)) {
+ data->cachedMembers.insert(name, value);
+ return;
+ }
+ }
+
JSC::JSObject::put(exec, propertyName, value, slot);
}
@@ -1123,6 +1144,14 @@ bool QObjectWrapperObject::deleteProperty(JSC::ExecState *exec,
return false;
}
+ {
+ QHash<QByteArray, JSC::JSValue>::iterator it = data->cachedMembers.find(name);
+ if (it != data->cachedMembers.end()) {
+ data->cachedMembers.erase(it);
+ return true;
+ }
+ }
+
int index = qobject->dynamicPropertyNames().indexOf(name);
if (index != -1) {
(void)qobject->setProperty(name, QVariant());
@@ -1256,6 +1285,15 @@ void QObjectWrapperObject::getPropertyNames(JSC::ExecState *exec, JSC::PropertyN
JSC::JSObject::getPropertyNames(exec, propertyNames);
}
+void QObjectWrapperObject::mark()
+{
+ QHash<QByteArray, JSC::JSValue>::const_iterator it;
+ for (it = data->cachedMembers.constBegin(); it != data->cachedMembers.constEnd(); ++it)
+ JSC::asObject(it.value())->mark();
+
+ JSC::JSObject::mark();
+}
+
static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChild(JSC::ExecState *exec, JSC::JSObject*,
JSC::JSValue thisValue, const JSC::ArgList &args)
{
diff --git a/src/script/bridge/qscriptqobject_p.h b/src/script/bridge/qscriptqobject_p.h
index 2e508ba..b35b6ba 100644
--- a/src/script/bridge/qscriptqobject_p.h
+++ b/src/script/bridge/qscriptqobject_p.h
@@ -53,6 +53,8 @@ public:
QScriptEngine::ValueOwnership ownership;
QScriptEngine::QObjectWrapOptions options;
+ QHash<QByteArray, JSC::JSValue> cachedMembers;
+
Data(QObject *o, QScriptEngine::ValueOwnership own,
QScriptEngine::QObjectWrapOptions opt)
: value(o), ownership(own), options(opt) {}
@@ -74,6 +76,7 @@ public:
virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&,
unsigned&) const;
virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
+ virtual void mark();
virtual const JSC::ClassInfo* classInfo() const { return &info; }
static const JSC::ClassInfo info;
diff --git a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp
index f1fec9f..89dbd3d 100644
--- a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp
+++ b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp
@@ -859,7 +859,6 @@ void tst_QScriptExtQObject::getSetStaticProperty()
QScriptValue slot = m_engine->evaluate("myObject.mySlot");
QVERIFY(slot.isFunction());
QScriptValue sameSlot = m_engine->evaluate("myObject.mySlot");
- QEXPECT_FAIL("", "Slot wrappers aren't persistent yet", Continue);
QVERIFY(sameSlot.strictlyEquals(slot));
sameSlot = m_engine->evaluate("myObject[mySlot()]");
QEXPECT_FAIL("", "Slot wrappers aren't persistent yet", Continue);
@@ -1673,7 +1672,6 @@ void tst_QScriptExtQObject::connectAndDisconnect()
QVERIFY(m_engine->evaluate("myObject.mySignal.connect(yetAnotherObject, 'func')").isUndefined());
QVERIFY(m_engine->evaluate("myObject.mySignal.connect(myObject, 'mySlot')").isUndefined());
QVERIFY(m_engine->evaluate("myObject.mySignal.disconnect(yetAnotherObject, 'func')").isUndefined());
- QEXPECT_FAIL("", "Slot wrappers aren't persistent yet", Continue);
QVERIFY(m_engine->evaluate("myObject.mySignal.disconnect(myObject, 'mySlot')").isUndefined());
// check that emitting signals from script works
@@ -1683,7 +1681,6 @@ void tst_QScriptExtQObject::connectAndDisconnect()
m_myObject->resetQtFunctionInvoked();
QCOMPARE(m_engine->evaluate("myObject.mySignal()").isUndefined(), true);
QCOMPARE(m_myObject->qtFunctionInvoked(), 20);
- QEXPECT_FAIL("", "Slot wrappers aren't persistent yet", Continue);
QVERIFY(m_engine->evaluate("myObject.mySignal.disconnect(myObject.mySlot)").isUndefined());
// one argument