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:
parent
b366e5509b
commit
bc9e86ef58
|
@ -239,7 +239,7 @@ void IRDecoder::visitExp(IR::Exp *s)
|
||||||
// These are calls where the result is ignored.
|
// These are calls where the result is ignored.
|
||||||
if (c->base->asName()) {
|
if (c->base->asName()) {
|
||||||
callBuiltin(c, 0);
|
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);
|
callValue(c->base, c->args, 0);
|
||||||
} else if (Member *member = c->base->asMember()) {
|
} else if (Member *member = c->base->asMember()) {
|
||||||
Q_ASSERT(member->base->asTemp() || member->base->asArgLocal());
|
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()) {
|
} else if (Subscript *s = c->base->asSubscript()) {
|
||||||
callSubscript(s->base, s->index, c->args, 0);
|
callSubscript(s->base, s->index, c->args, 0);
|
||||||
} else {
|
} else {
|
||||||
Q_UNIMPLEMENTED();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Q_UNIMPLEMENTED();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -532,9 +532,14 @@ void InstructionSelection::callValue(IR::Expr *value, IR::ExprList *args, IR::Ex
|
||||||
Q_ASSERT(value);
|
Q_ASSERT(value);
|
||||||
|
|
||||||
prepareCallData(args, 0);
|
prepareCallData(args, 0);
|
||||||
generateFunctionCall(result, Runtime::callValue, Assembler::ContextRegister,
|
if (value->asConst())
|
||||||
Assembler::Reference(value),
|
generateFunctionCall(result, Runtime::callValue, Assembler::ContextRegister,
|
||||||
baseAddressForCallData());
|
Assembler::PointerToValue(value),
|
||||||
|
baseAddressForCallData());
|
||||||
|
else
|
||||||
|
generateFunctionCall(result, Runtime::callValue, Assembler::ContextRegister,
|
||||||
|
Assembler::Reference(value),
|
||||||
|
baseAddressForCallData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstructionSelection::loadThisObject(IR::Expr *temp)
|
void InstructionSelection::loadThisObject(IR::Expr *temp)
|
||||||
|
|
|
@ -159,6 +159,8 @@ private slots:
|
||||||
|
|
||||||
void scopeOfEvaluate();
|
void scopeOfEvaluate();
|
||||||
|
|
||||||
|
void callConstants();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void testSignal();
|
void testSignal();
|
||||||
};
|
};
|
||||||
|
@ -3050,6 +3052,15 @@ void tst_QJSEngine::scopeOfEvaluate()
|
||||||
QCOMPARE(result.toInt(), 42);
|
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)
|
QTEST_MAIN(tst_QJSEngine)
|
||||||
|
|
||||||
#include "tst_qjsengine.moc"
|
#include "tst_qjsengine.moc"
|
||||||
|
|
Loading…
Reference in New Issue