Fix failing assertion in debug builds for JS that calls constants
authorSimon Hausmann <simon.hausmann@theqtcompany.com>
Tue, 13 Jan 2015 15:59:22 +0000 (16:59 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 15 Jan 2015 10:29:37 +0000 (11:29 +0100)
For
    true()

we generate IR that looks like this:

    temp = true
    result = call temp()

and therefore the move at isel time has IR::Call as source and a temp
as base for the call. However constant propagation in the optimizer transforms
this to

    result = call true()

and that's a case we didn't handle in the IR visitor. Since we have
Runtime::callValue we can however handle this case as well and the run-time
will consequently produce the expected run-time error.

Change-Id: Ia94a8116388e66f9f339913307f68e33a5c18a19
Task-number: QTBUG-43819
Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
Reviewed-by: Jan Kundrát <jkt@kde.org>
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
src/qml/compiler/qv4isel_p.cpp
src/qml/jsruntime/qv4runtime.cpp
tests/auto/qml/qjsengine/tst_qjsengine.cpp

index e419084..4bb8666 100644 (file)
@@ -182,7 +182,7 @@ void IRDecoder::visitMove(IR::Move *s)
             } else if (Subscript *ss = c->base->asSubscript()) {
                 callSubscript(ss->base, ss->index, c->args, s->target);
                 return;
-            } else if (c->base->asTemp() || c->base->asArgLocal()) {
+            } else if (c->base->asTemp() || c->base->asArgLocal() || c->base->asConst()) {
                 callValue(c->base, c->args, s->target);
                 return;
             }
index f72f25b..b019d4d 100644 (file)
@@ -961,7 +961,7 @@ ReturnedValue Runtime::callElement(ExecutionContext *context, const ValueRef ind
 ReturnedValue Runtime::callValue(ExecutionContext *context, const ValueRef func, CallData *callData)
 {
     if (!func->isObject())
-        return context->throwTypeError();
+        return context->throwTypeError(QStringLiteral("%1 is not a function").arg(func->toQStringNoThrow()));
 
     return func->objectValue()->call(callData);
 }
index d24a1a4..158ee15 100644 (file)
@@ -3140,6 +3140,8 @@ void tst_QJSEngine::callConstants()
                     "  var one; one();\n"
                     "  var two = null; two();\n"
                     "}\n");
+    QJSValue exceptionResult = engine.evaluate("true()");
+    QCOMPARE(exceptionResult.toString(), QString("TypeError: true is not a function"));
 }
 
 void tst_QJSEngine::installTranslatorFunctions()