V4: support calling constants.

Consider:
  function f() {
    var a;
    a();
  }

Here the constant propagation will propagate the value for a (undefined)
to the call site. This was not yet handled, resulting in Q_UNIMPLEMENTED
warnings when running a debug build.

Change-Id: I5f85f681d975b54df7a9e00bd5b50e6f4350139a
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Erik Verbruggen 2014-05-09 13:10:16 +02:00 committed by The Qt Project
parent b366e5509b
commit bc9e86ef58
3 changed files with 22 additions and 6 deletions

View File

@ -239,7 +239,7 @@ void IRDecoder::visitExp(IR::Exp *s)
// These are calls where the result is ignored.
if (c->base->asName()) {
callBuiltin(c, 0);
} else if (c->base->asTemp() || c->base->asArgLocal()) {
} else if (c->base->asTemp() || c->base->asArgLocal() || c->base->asConst()) {
callValue(c->base, c->args, 0);
} else if (Member *member = c->base->asMember()) {
Q_ASSERT(member->base->asTemp() || member->base->asArgLocal());
@ -247,10 +247,10 @@ void IRDecoder::visitExp(IR::Exp *s)
} else if (Subscript *s = c->base->asSubscript()) {
callSubscript(s->base, s->index, c->args, 0);
} else {
Q_UNIMPLEMENTED();
Q_UNREACHABLE();
}
} else {
Q_UNIMPLEMENTED();
Q_UNREACHABLE();
}
}

View File

@ -532,9 +532,14 @@ void InstructionSelection::callValue(IR::Expr *value, IR::ExprList *args, IR::Ex
Q_ASSERT(value);
prepareCallData(args, 0);
generateFunctionCall(result, Runtime::callValue, Assembler::ContextRegister,
Assembler::Reference(value),
baseAddressForCallData());
if (value->asConst())
generateFunctionCall(result, Runtime::callValue, Assembler::ContextRegister,
Assembler::PointerToValue(value),
baseAddressForCallData());
else
generateFunctionCall(result, Runtime::callValue, Assembler::ContextRegister,
Assembler::Reference(value),
baseAddressForCallData());
}
void InstructionSelection::loadThisObject(IR::Expr *temp)

View File

@ -159,6 +159,8 @@ private slots:
void scopeOfEvaluate();
void callConstants();
signals:
void testSignal();
};
@ -3050,6 +3052,15 @@ void tst_QJSEngine::scopeOfEvaluate()
QCOMPARE(result.toInt(), 42);
}
void tst_QJSEngine::callConstants()
{
QJSEngine engine;
engine.evaluate("function f() {\n"
" var one; one();\n"
" var two = null; two();\n"
"}\n");
}
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"