[parsing]: eval/arguments parameter names are ok in sloppy mode
BUG=v8:3891 LOG=N R=arv@chromium.org, marja@chromium.org Review URL: https://codereview.chromium.org/924403002 Cr-Commit-Position: refs/heads/master@{#26673}
This commit is contained in:
parent
03cad07aca
commit
663a9eeae4
@ -3702,7 +3702,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
if (!reserved_error_loc.IsValid() && is_strict_reserved) {
|
||||
reserved_error_loc = scanner()->location();
|
||||
}
|
||||
if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
|
||||
if (!dupe_error_loc.IsValid() &&
|
||||
scope_->IsDeclaredParameter(param_name)) {
|
||||
duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
|
||||
dupe_error_loc = scanner()->location();
|
||||
}
|
||||
|
@ -475,7 +475,7 @@ class ParserBase : public Traits {
|
||||
bool* ok) {
|
||||
if (is_sloppy(language_mode) && !strict_params) return;
|
||||
|
||||
if (eval_args_error_loc.IsValid()) {
|
||||
if (is_strict(language_mode) && eval_args_error_loc.IsValid()) {
|
||||
Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
|
||||
*ok = false;
|
||||
return;
|
||||
|
@ -467,6 +467,13 @@ class Scope: public ZoneObject {
|
||||
return variables_.Lookup(name) != NULL;
|
||||
}
|
||||
|
||||
bool IsDeclaredParameter(const AstRawString* name) {
|
||||
// If IsSimpleParameterList is false, duplicate parameters are not allowed,
|
||||
// however `arguments` may be allowed if function is not strict code. Thus,
|
||||
// the assumptions explained above do not hold.
|
||||
return params_.Contains(variables_.Lookup(name));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Debugging.
|
||||
|
||||
|
@ -3965,8 +3965,6 @@ TEST(MethodDefinitionStrictFormalParamereters) {
|
||||
const char* params_data[] = {
|
||||
"x, x",
|
||||
"x, y, x",
|
||||
"eval",
|
||||
"arguments",
|
||||
"var",
|
||||
"const",
|
||||
NULL
|
||||
@ -3978,6 +3976,57 @@ TEST(MethodDefinitionStrictFormalParamereters) {
|
||||
}
|
||||
|
||||
|
||||
TEST(MethodDefinitionEvalArguments) {
|
||||
const char* strict_context_data[][2] =
|
||||
{{"'use strict'; ({method(", "){}});"},
|
||||
{"'use strict'; ({*method(", "){}});"},
|
||||
{NULL, NULL}};
|
||||
const char* sloppy_context_data[][2] =
|
||||
{{"({method(", "){}});"},
|
||||
{"({*method(", "){}});"},
|
||||
{NULL, NULL}};
|
||||
|
||||
const char* data[] = {
|
||||
"eval",
|
||||
"arguments",
|
||||
NULL};
|
||||
|
||||
static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
|
||||
|
||||
// Fail in strict mode
|
||||
RunParserSyncTest(strict_context_data, data, kError, NULL, 0, always_flags,
|
||||
arraysize(always_flags));
|
||||
|
||||
// OK in sloppy mode
|
||||
RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, always_flags,
|
||||
arraysize(always_flags));
|
||||
}
|
||||
|
||||
|
||||
TEST(MethodDefinitionDuplicateEvalArguments) {
|
||||
const char* context_data[][2] =
|
||||
{{"'use strict'; ({method(", "){}});"},
|
||||
{"'use strict'; ({*method(", "){}});"},
|
||||
{"({method(", "){}});"},
|
||||
{"({*method(", "){}});"},
|
||||
{NULL, NULL}};
|
||||
|
||||
const char* data[] = {
|
||||
"eval, eval",
|
||||
"eval, a, eval",
|
||||
"arguments, arguments",
|
||||
"arguments, a, arguments",
|
||||
NULL};
|
||||
|
||||
static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
|
||||
|
||||
// In strict mode, the error is using "eval" or "arguments" as parameter names
|
||||
// In sloppy mode, the error is that eval / arguments are duplicated
|
||||
RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
|
||||
arraysize(always_flags));
|
||||
}
|
||||
|
||||
|
||||
TEST(MethodDefinitionDuplicateProperty) {
|
||||
const char* context_data[][2] = {{"'use strict'; ({", "});"},
|
||||
{NULL, NULL}};
|
||||
@ -4880,6 +4929,59 @@ TEST(ParseRestParametersErrors) {
|
||||
}
|
||||
|
||||
|
||||
TEST(RestParametersEvalArguments) {
|
||||
const char* strict_context_data[][2] =
|
||||
{{"'use strict';(function(",
|
||||
"){ return;})(1, [], /regexp/, 'str',function(){});"},
|
||||
{NULL, NULL}};
|
||||
const char* sloppy_context_data[][2] =
|
||||
{{"(function(",
|
||||
"){ return;})(1, [],/regexp/, 'str', function(){});"},
|
||||
{NULL, NULL}};
|
||||
|
||||
const char* data[] = {
|
||||
"...eval",
|
||||
"eval, ...args",
|
||||
"...arguments",
|
||||
"arguments, ...args",
|
||||
NULL};
|
||||
|
||||
static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters};
|
||||
|
||||
// Fail in strict mode
|
||||
RunParserSyncTest(strict_context_data, data, kError, NULL, 0, always_flags,
|
||||
arraysize(always_flags));
|
||||
|
||||
// OK in sloppy mode
|
||||
RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, always_flags,
|
||||
arraysize(always_flags));
|
||||
}
|
||||
|
||||
|
||||
TEST(RestParametersDuplicateEvalArguments) {
|
||||
const char* context_data[][2] =
|
||||
{{"'use strict';(function(",
|
||||
"){ return;})(1, [], /regexp/, 'str',function(){});"},
|
||||
{"(function(",
|
||||
"){ return;})(1, [],/regexp/, 'str', function(){});"},
|
||||
{NULL, NULL}};
|
||||
|
||||
const char* data[] = {
|
||||
"eval, ...eval",
|
||||
"eval, eval, ...args",
|
||||
"arguments, ...arguments",
|
||||
"arguments, arguments, ...args",
|
||||
NULL};
|
||||
|
||||
static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters};
|
||||
|
||||
// In strict mode, the error is using "eval" or "arguments" as parameter names
|
||||
// In sloppy mode, the error is that eval / arguments are duplicated
|
||||
RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
|
||||
arraysize(always_flags));
|
||||
}
|
||||
|
||||
|
||||
TEST(LexicalScopingSloppyMode) {
|
||||
const char* context_data[][2] = {
|
||||
{"", ""},
|
||||
@ -5317,3 +5419,37 @@ TEST(PropertyNameEvalArguments) {
|
||||
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
|
||||
always_flags, arraysize(always_flags));
|
||||
}
|
||||
|
||||
|
||||
TEST(FunctionLiteralDuplicateParameters) {
|
||||
const char* strict_context_data[][2] =
|
||||
{{"'use strict';(function(", "){})();"},
|
||||
{"(function(", ") { 'use strict'; })();"},
|
||||
{"'use strict'; function fn(", ") {}; fn();"},
|
||||
{"function fn(", ") { 'use strict'; }; fn();"},
|
||||
{"'use strong';(function(", "){})();"},
|
||||
{"(function(", ") { 'use strong'; })();"},
|
||||
{"'use strong'; function fn(", ") {}; fn();"},
|
||||
{"function fn(", ") { 'use strong'; }; fn();"},
|
||||
{NULL, NULL}};
|
||||
|
||||
const char* sloppy_context_data[][2] =
|
||||
{{"(function(", "){})();"},
|
||||
{"(function(", ") {})();"},
|
||||
{"function fn(", ") {}; fn();"},
|
||||
{"function fn(", ") {}; fn();"},
|
||||
{NULL, NULL}};
|
||||
|
||||
const char* data[] = {
|
||||
"a, a",
|
||||
"a, a, a",
|
||||
"b, a, a",
|
||||
"a, b, c, c",
|
||||
"a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, w",
|
||||
NULL};
|
||||
|
||||
static const ParserFlag always_flags[] = { kAllowStrongMode };
|
||||
RunParserSyncTest(strict_context_data, data, kError, NULL, 0, always_flags,
|
||||
arraysize(always_flags));
|
||||
RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, NULL, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user