aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4context.cpp63
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp36
2 files changed, 68 insertions, 31 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index ba72a9e43b..6807c835b0 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -237,16 +237,14 @@ bool ExecutionContext::deleteProperty(String *name)
return global->deleteProperty(name);
break;
}
- case Heap::ExecutionContext::Type_CallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
+ case Heap::ExecutionContext::Type_CallContext:
+ Q_FALLTHROUGH();
+ case Heap::ExecutionContext::Type_SimpleCallContext: {
+ Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
uint index = c->v4Function->internalClass->find(id);
if (index < UINT_MAX)
// ### throw in strict mode?
return false;
- Q_FALLTHROUGH();
- }
- case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
ScopedObject qml(scope, c->activation);
if (qml && qml->hasProperty(name))
return qml->deleteProperty(name);
@@ -418,26 +416,21 @@ ReturnedValue ExecutionContext::getProperty(String *name)
return v->asReturnedValue();
break;
}
- case Heap::ExecutionContext::Type_CallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
+ case Heap::ExecutionContext::Type_CallContext:
+ Q_FALLTHROUGH();
+ case Heap::ExecutionContext::Type_SimpleCallContext: {
+ Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
+
name->makeIdentifier();
Identifier *id = name->identifier();
-
uint index = c->v4Function->internalClass->find(id);
if (index < UINT_MAX) {
if (index < c->v4Function->nFormals)
return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue();
- Q_ASSERT(c->type == Heap::ExecutionContext::Type_CallContext);
- return c->locals[index - c->v4Function->nFormals].asReturnedValue();
+ if (c->type == Heap::ExecutionContext::Type_CallContext)
+ return static_cast<Heap::CallContext *>(c)->locals[index - c->v4Function->nFormals].asReturnedValue();
}
- if (c->v4Function->isNamedExpression()) {
- if (c->function && name->equals(ScopedString(scope, c->v4Function->name())))
- return c->function->asReturnedValue();
- }
- Q_FALLTHROUGH();
- }
- case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
+
ScopedObject activation(scope, c->activation);
if (activation) {
bool hasProperty = false;
@@ -445,6 +438,12 @@ ReturnedValue ExecutionContext::getProperty(String *name)
if (hasProperty)
return v->asReturnedValue();
}
+
+ if (c->v4Function->isNamedExpression() && c->type == Heap::ExecutionContext::Type_CallContext) {
+ if (name->equals(ScopedString(scope, c->v4Function->name())))
+ if (auto func = static_cast<Heap::CallContext *>(c)->function)
+ return func->asReturnedValue();
+ }
break;
}
case Heap::ExecutionContext::Type_QmlContext: {
@@ -498,25 +497,21 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base)
return v->asReturnedValue();
break;
}
- case Heap::ExecutionContext::Type_CallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
+ case Heap::ExecutionContext::Type_CallContext:
+ Q_FALLTHROUGH();
+ case Heap::ExecutionContext::Type_SimpleCallContext: {
+ Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
+
name->makeIdentifier();
Identifier *id = name->identifier();
-
uint index = c->v4Function->internalClass->find(id);
if (index < UINT_MAX) {
if (index < c->v4Function->nFormals)
return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue();
- return c->locals[index - c->v4Function->nFormals].asReturnedValue();
- }
- if (c->v4Function->isNamedExpression()) {
- if (c->function && name->equals(ScopedString(scope, c->v4Function->name())))
- return c->function->asReturnedValue();
+ if (c->type == Heap::ExecutionContext::Type_CallContext)
+ return static_cast<Heap::CallContext *>(c)->locals[index - c->v4Function->nFormals].asReturnedValue();
}
- Q_FALLTHROUGH();
- }
- case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
+
ScopedObject activation(scope, c->activation);
if (activation) {
bool hasProperty = false;
@@ -524,6 +519,12 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base)
if (hasProperty)
return v->asReturnedValue();
}
+
+ if (c->v4Function->isNamedExpression() && c->type == Heap::ExecutionContext::Type_CallContext) {
+ if (name->equals(ScopedString(scope, c->v4Function->name())))
+ if (auto func = static_cast<Heap::CallContext *>(c)->function)
+ return func->asReturnedValue();
+ }
break;
}
case Heap::ExecutionContext::Type_QmlContext: {
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index b7e616a050..1f80ff46d0 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -43,6 +43,7 @@ private slots:
void loadGeneratedFile();
void translationExpressionSupport();
+ void signalHandlerParameters();
};
// A wrapper around QQmlComponent to ensure the temporary reference counts
@@ -158,6 +159,41 @@ void tst_qmlcachegen::translationExpressionSupport()
QCOMPARE(obj->property("text").toString(), QString("All Ok"));
}
+void tst_qmlcachegen::signalHandlerParameters()
+{
+ QTemporaryDir tempDir;
+ QVERIFY(tempDir.isValid());
+
+ const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) {
+ QFile f(tempDir.path() + '/' + fileName);
+ const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ Q_ASSERT(ok);
+ f.write(contents);
+ return f.fileName();
+ };
+
+ const QString testFilePath = writeTempFile("test.qml", "import QtQml 2.0\n"
+ "QtObject {\n"
+ " property real result: 0\n"
+ " signal testMe(real value);\n"
+ " onTestMe: result = value;\n"
+ " function runTest() { testMe(42); }\n"
+ "}");
+
+ QVERIFY(generateCache(testFilePath));
+
+ const QString cacheFilePath = testFilePath + QLatin1Char('c');
+ QVERIFY(QFile::exists(cacheFilePath));
+ QVERIFY(QFile::remove(testFilePath));
+
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QMetaObject::invokeMethod(obj.data(), "runTest");
+ QCOMPARE(obj->property("result").toInt(), 42);
+}
+
QTEST_GUILESS_MAIN(tst_qmlcachegen)
#include "tst_qmlcachegen.moc"