summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-03-20 12:18:19 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-03-20 12:18:19 (GMT)
commit754e72d64ee4da72fc8f277f697270be57f8a18e (patch)
tree3b150120c28bb5478a4dd2c1283cac1cd07005e0
parent309c79b4697c02160c6245bcd207f913064f90da (diff)
parent6ccff8baa04c4467f7185676b5c632f17fd7ae4c (diff)
downloadQt-754e72d64ee4da72fc8f277f697270be57f8a18e.zip
Qt-754e72d64ee4da72fc8f277f697270be57f8a18e.tar.gz
Qt-754e72d64ee4da72fc8f277f697270be57f8a18e.tar.bz2
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.6-integration
* '4.6' of scm.dev.nokia.troll.no:qt/oslo-staging-1: QScriptClass-implemented constructors lead to application crash Improve test coverage of QScriptClass::Callable extension
-rw-r--r--src/script/bridge/qscriptclassobject.cpp4
-rw-r--r--tests/auto/qscriptclass/tst_qscriptclass.cpp118
2 files changed, 119 insertions, 3 deletions
diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp
index a3dd239..a4d9cc1 100644
--- a/src/script/bridge/qscriptclassobject.cpp
+++ b/src/script/bridge/qscriptclassobject.cpp
@@ -226,7 +226,7 @@ JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObjec
QScriptClass *scriptClass = static_cast<ClassObjectDelegate*>(delegate)->scriptClass();
QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
- //JSC::ExecState *oldFrame = eng_p->currentFrame;
+ JSC::ExecState *oldFrame = eng_p->currentFrame;
eng_p->pushContext(exec, JSC::JSValue(), args, callee, true);
QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
@@ -234,6 +234,8 @@ JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObjec
QScriptValue result = qvariant_cast<QScriptValue>(scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx)));
if (!result.isObject())
result = defaultObject;
+ eng_p->popContext();
+ eng_p->currentFrame = oldFrame;
return JSC::asObject(eng_p->scriptValueToJSCValue(result));
}
diff --git a/tests/auto/qscriptclass/tst_qscriptclass.cpp b/tests/auto/qscriptclass/tst_qscriptclass.cpp
index 41c674c..3012da1 100644
--- a/tests/auto/qscriptclass/tst_qscriptclass.cpp
+++ b/tests/auto/qscriptclass/tst_qscriptclass.cpp
@@ -98,7 +98,12 @@ public:
NotCallable,
CallableReturnsSum,
CallableReturnsArgument,
- CallableReturnsInvalidVariant
+ CallableReturnsInvalidVariant,
+ CallableReturnsGlobalObject,
+ CallableReturnsThisObject,
+ CallableReturnsCallee,
+ CallableReturnsArgumentsObject,
+ CallableInitializesThisObject
};
TestClass(QScriptEngine *engine);
@@ -348,7 +353,7 @@ QVariant TestClass::extension(Extension extension,
qsreal sum = 0;
for (int i = 0; i < ctx->argumentCount(); ++i)
sum += ctx->argument(i).toNumber();
- QScriptValueIterator it(ctx->thisObject());
+ QScriptValueIterator it(ctx->callee());
while (it.hasNext()) {
it.next();
sum += it.value().toNumber();
@@ -358,6 +363,17 @@ QVariant TestClass::extension(Extension extension,
return qVariantFromValue(ctx->argument(0));
} else if (m_callableMode == CallableReturnsInvalidVariant) {
return QVariant();
+ } else if (m_callableMode == CallableReturnsGlobalObject) {
+ return qVariantFromValue(engine()->globalObject());
+ } else if (m_callableMode == CallableReturnsThisObject) {
+ return qVariantFromValue(ctx->thisObject());
+ } else if (m_callableMode == CallableReturnsCallee) {
+ return qVariantFromValue(ctx->callee());
+ } else if (m_callableMode == CallableReturnsArgumentsObject) {
+ return qVariantFromValue(ctx->argumentsObject());
+ } else if (m_callableMode == CallableInitializesThisObject) {
+ engine()->newQObject(ctx->thisObject(), engine());
+ return QVariant();
}
} else if (extension == HasInstance) {
Q_ASSERT(m_hasInstance);
@@ -796,9 +812,11 @@ void tst_QScriptClass::extension()
QVERIFY(cls.supportsExtension(QScriptClass::Callable));
QScriptValue obj = eng.newObject(&cls);
+ eng.globalObject().setProperty("obj", obj);
obj.setProperty("one", QScriptValue(&eng, 1));
obj.setProperty("two", QScriptValue(&eng, 2));
obj.setProperty("three", QScriptValue(&eng, 3));
+ // From C++
cls.clearReceivedArgs();
{
QScriptValueList args;
@@ -809,8 +827,18 @@ void tst_QScriptClass::extension()
QVERIFY(ret.isNumber());
QCOMPARE(ret.toNumber(), qsreal(15));
}
+ // From JS
+ cls.clearReceivedArgs();
+ {
+ QScriptValue ret = eng.evaluate("obj(4, 5)");
+ QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
+ QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
+ QVERIFY(ret.isNumber());
+ QCOMPARE(ret.toNumber(), qsreal(15));
+ }
cls.setCallableMode(TestClass::CallableReturnsArgument);
+ // From C++
cls.clearReceivedArgs();
{
QScriptValue ret = obj.call(obj, QScriptValueList() << 123);
@@ -842,6 +870,13 @@ void tst_QScriptClass::extension()
QScriptValue ret = obj.call(obj, QScriptValueList() << QScriptValue());
QVERIFY(ret.isUndefined());
}
+ // From JS
+ cls.clearReceivedArgs();
+ {
+ QScriptValue ret = eng.evaluate("obj(123)");
+ QVERIFY(ret.isNumber());
+ QCOMPARE(ret.toInt32(), 123);
+ }
cls.setCallableMode(TestClass::CallableReturnsInvalidVariant);
{
@@ -849,13 +884,92 @@ void tst_QScriptClass::extension()
QVERIFY(ret.isUndefined());
}
+ cls.setCallableMode(TestClass::CallableReturnsThisObject);
+ // From C++
+ {
+ QScriptValue ret = obj.call(obj);
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.strictlyEquals(obj));
+ }
+ // From JS
+ {
+ QScriptValue ret = eng.evaluate("obj()");
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.strictlyEquals(eng.globalObject()));
+ }
+
+ cls.setCallableMode(TestClass::CallableReturnsCallee);
+ // From C++
+ {
+ QScriptValue ret = obj.call();
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.strictlyEquals(obj));
+ }
+ // From JS
+ {
+ QScriptValue ret = eng.evaluate("obj()");
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.strictlyEquals(obj));
+ }
+
+ cls.setCallableMode(TestClass::CallableReturnsArgumentsObject);
+ // From C++
+ {
+ QScriptValue ret = obj.call(obj, QScriptValueList() << 123);
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.property("length").isNumber());
+ QCOMPARE(ret.property("length").toInt32(), 1);
+ QVERIFY(ret.property(0).isNumber());
+ QCOMPARE(ret.property(0).toInt32(), 123);
+ }
+ // From JS
+ {
+ QScriptValue ret = eng.evaluate("obj(123)");
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.property("length").isNumber());
+ QCOMPARE(ret.property("length").toInt32(), 1);
+ QVERIFY(ret.property(0).isNumber());
+ QCOMPARE(ret.property(0).toInt32(), 123);
+ }
+
// construct()
+ // From C++
cls.clearReceivedArgs();
+ cls.setCallableMode(TestClass::CallableReturnsGlobalObject);
{
QScriptValue ret = obj.construct();
QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
QVERIFY(ret.isObject());
+ QVERIFY(ret.strictlyEquals(eng.globalObject()));
+ }
+ // From JS
+ cls.clearReceivedArgs();
+ {
+ QScriptValue ret = eng.evaluate("new obj()");
+ QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
+ QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.strictlyEquals(eng.globalObject()));
+ }
+ // From C++
+ cls.clearReceivedArgs();
+ cls.setCallableMode(TestClass::CallableInitializesThisObject);
+ {
+ QScriptValue ret = obj.construct();
+ QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
+ QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
+ QVERIFY(ret.isQObject());
+ QCOMPARE(ret.toQObject(), (QObject*)&eng);
+ }
+ // From JS
+ cls.clearReceivedArgs();
+ {
+ QScriptValue ret = eng.evaluate("new obj()");
+ QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable);
+ QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>());
+ QVERIFY(ret.isQObject());
+ QCOMPARE(ret.toQObject(), (QObject*)&eng);
}
}
// HasInstance