Correctly check for duplicate parameter names
Those are not allowed as soon as we have default values for parameters or rest arguments. Change-Id: I7dec826c37e6045e4dd1f6b0adb90301efe33daf Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
219485d898
commit
31026b2e83
|
@ -1824,6 +1824,9 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
|
|||
}
|
||||
scan.leaveEnvironment();
|
||||
|
||||
if (hasError)
|
||||
return QVector<int>();
|
||||
|
||||
_context = nullptr;
|
||||
|
||||
for (int i = 0; i < functions.count(); ++i) {
|
||||
|
|
|
@ -120,6 +120,9 @@ void Codegen::generateFromProgram(const QString &fileName,
|
|||
ScanFunctions scan(this, sourceCode, mode);
|
||||
scan(node);
|
||||
|
||||
if (hasError)
|
||||
return;
|
||||
|
||||
defineFunction(QStringLiteral("%entry"), node, nullptr, node->elements);
|
||||
}
|
||||
|
||||
|
@ -2210,16 +2213,6 @@ static bool endsWithReturn(Node *node)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool isSimpleParameterList(AST::FormalParameterList *formals)
|
||||
{
|
||||
while (formals) {
|
||||
if (formals->isRest || formals->defaultExpression)
|
||||
return false;
|
||||
formals = formals->next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int Codegen::defineFunction(const QString &name, AST::Node *ast,
|
||||
AST::FormalParameterList *formals,
|
||||
AST::SourceElements *body)
|
||||
|
@ -2324,7 +2317,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
|
|||
}
|
||||
}
|
||||
if (_context->usesArgumentsObject == Context::ArgumentsObjectUsed) {
|
||||
if (_context->isStrict || !isSimpleParameterList(formals)) {
|
||||
if (_context->isStrict || !formals->isSimpleParameterList()) {
|
||||
Instruction::CreateUnmappedArgumentsObject setup;
|
||||
bytecodeGenerator->addInstruction(setup);
|
||||
} else {
|
||||
|
|
|
@ -431,12 +431,14 @@ void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete
|
|||
if (body && !_context->isStrict)
|
||||
checkDirectivePrologue(body->elements);
|
||||
|
||||
bool isSimpleParameterList = formals->isSimpleParameterList();
|
||||
|
||||
for (FormalParameterList *it = formals; it; it = it->next) {
|
||||
QString arg = it->name.toString();
|
||||
int duplicateIndex = _context->arguments.indexOf(arg);
|
||||
if (duplicateIndex != -1) {
|
||||
if (_context->isStrict) {
|
||||
_cg->throwSyntaxError(it->identifierToken, QStringLiteral("Duplicate parameter name '%1' is not allowed in strict mode").arg(arg));
|
||||
if (_context->isStrict || !isSimpleParameterList) {
|
||||
_cg->throwSyntaxError(it->identifierToken, QStringLiteral("Duplicate parameter name '%1' is not allowed.").arg(arg));
|
||||
return;
|
||||
} else {
|
||||
// change the name of the earlier argument to enforce the specified lookup semantics
|
||||
|
|
|
@ -240,6 +240,9 @@ ReturnedValue FunctionCtor::callAsConstructor(const FunctionObject *f, const Val
|
|||
RuntimeCodegen cg(scope.engine, &jsGenerator, false);
|
||||
cg.generateFromFunctionExpression(QString(), function, fe, &module);
|
||||
|
||||
if (scope.hasException())
|
||||
return Encode::undefined();
|
||||
|
||||
QQmlRefPointer<CompiledData::CompilationUnit> compilationUnit = cg.generateCompilationUnit();
|
||||
Function *vmf = compilationUnit->linkToEngine(scope.engine);
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@ void RuntimeCodegen::generateFromFunctionExpression(const QString &fileName,
|
|||
scan(ast);
|
||||
scan.leaveEnvironment();
|
||||
|
||||
if (hasError)
|
||||
return;
|
||||
|
||||
int index = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : nullptr);
|
||||
_module->rootContext = _module->functions.at(index);
|
||||
}
|
||||
|
|
|
@ -2099,6 +2099,18 @@ public:
|
|||
return n;
|
||||
}
|
||||
|
||||
bool isSimpleParameterList()
|
||||
{
|
||||
AST::FormalParameterList *formals = this;
|
||||
while (formals) {
|
||||
if (formals->isRest || formals->defaultExpression)
|
||||
return false;
|
||||
formals = formals->next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
||||
SourceLocation firstSourceLocation() const override
|
||||
|
|
Loading…
Reference in New Issue