Commit 663a9eea authored by caitpotter88's avatar caitpotter88 Committed by Commit bot

[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}
parent 03cad07a
...@@ -3702,7 +3702,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -3702,7 +3702,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (!reserved_error_loc.IsValid() && is_strict_reserved) { if (!reserved_error_loc.IsValid() && is_strict_reserved) {
reserved_error_loc = scanner()->location(); 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; duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
dupe_error_loc = scanner()->location(); dupe_error_loc = scanner()->location();
} }
......
...@@ -475,7 +475,7 @@ class ParserBase : public Traits { ...@@ -475,7 +475,7 @@ class ParserBase : public Traits {
bool* ok) { bool* ok) {
if (is_sloppy(language_mode) && !strict_params) return; 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"); Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
*ok = false; *ok = false;
return; return;
......
...@@ -467,6 +467,13 @@ class Scope: public ZoneObject { ...@@ -467,6 +467,13 @@ class Scope: public ZoneObject {
return variables_.Lookup(name) != NULL; 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. // Debugging.
......
...@@ -3965,8 +3965,6 @@ TEST(MethodDefinitionStrictFormalParamereters) { ...@@ -3965,8 +3965,6 @@ TEST(MethodDefinitionStrictFormalParamereters) {
const char* params_data[] = { const char* params_data[] = {
"x, x", "x, x",
"x, y, x", "x, y, x",
"eval",
"arguments",
"var", "var",
"const", "const",
NULL NULL
...@@ -3978,6 +3976,57 @@ TEST(MethodDefinitionStrictFormalParamereters) { ...@@ -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) { TEST(MethodDefinitionDuplicateProperty) {
const char* context_data[][2] = {{"'use strict'; ({", "});"}, const char* context_data[][2] = {{"'use strict'; ({", "});"},
{NULL, NULL}}; {NULL, NULL}};
...@@ -4880,6 +4929,59 @@ TEST(ParseRestParametersErrors) { ...@@ -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) { TEST(LexicalScopingSloppyMode) {
const char* context_data[][2] = { const char* context_data[][2] = {
{"", ""}, {"", ""},
...@@ -5317,3 +5419,37 @@ TEST(PropertyNameEvalArguments) { ...@@ -5317,3 +5419,37 @@ TEST(PropertyNameEvalArguments) {
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags)); 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment