Reviewers: arv,

Message:
PTAL

Description:
[parser] report SyntaxError if rest parameter used in Setter MethodDefinition

BUG=v8:4107, v8:2159
LOG=N
[email protected]

Please review this at https://codereview.chromium.org/1141223002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+43, -14 lines):
  M src/messages.js
  M src/parser.cc
  M src/preparser.h
  M src/preparser.cc
  A + test/message/rest-param-class-setter-strict.js
  A test/message/rest-param-class-setter-strict.out
  A + test/message/rest-param-object-setter-sloppy.js
  A test/message/rest-param-object-setter-sloppy.out
  A + test/message/rest-param-object-setter-strict.js
  A test/message/rest-param-object-setter-strict.out


Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index eb6e07fb07bdf6df49ead6f9288edf183127dae0..bb5789fd60a7ab84f3b964234b4cd03c4d3f9946 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -141,6 +141,7 @@ var kMessages = {
super_constructor_call: ["A 'super' constructor call may only appear as the first statement of a function, and its arguments may not access 'this'. Other forms are not yet supported."], duplicate_proto: ["Duplicate __proto__ fields are not allowed in object literals"], param_after_rest: ["Rest parameter must be last formal parameter"], + setter_rest_param: ["Setter function argument must not be a rest parameter"], derived_constructor_return: ["Derived constructors may only return object or undefined"], for_in_loop_initializer: ["for-in loop variable declaration may not have an initializer."], for_of_loop_initializer: ["for-of loop variable declaration may not have an initializer."],
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 5be6d82b67d582b11601b227c0f7b9d739ba2480..8e2d306bc0c1ece9af81dcd4592b81617b5de402 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -3883,8 +3883,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
     Expect(Token::RPAREN, CHECK_OK);
     int formals_end_position = scanner()->location().end_pos;

- CheckArityRestrictions(num_parameters, arity_restriction, start_position,
-                           formals_end_position, CHECK_OK);
+    CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
+                           start_position, formals_end_position, CHECK_OK);

     Expect(Token::LBRACE, CHECK_OK);

Index: src/preparser.cc
diff --git a/src/preparser.cc b/src/preparser.cc
index f2502bbbb72fa84ea6f8fa3adc4819547a10e591..d8b33120f61119783eb881c4cf713c06825bead0 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -1026,21 +1026,21 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
                                &factory);
   ExpressionClassifier formals_classifier;

-  bool is_rest = false;
+  bool has_rest = false;
   Expect(Token::LPAREN, CHECK_OK);
   int start_position = scanner()->location().beg_pos;
   function_scope->set_start_position(start_position);
   int num_parameters;
   {
     DuplicateFinder duplicate_finder(scanner()->unicode_cache());
-    num_parameters = ParseFormalParameterList(&duplicate_finder, &is_rest,
+    num_parameters = ParseFormalParameterList(&duplicate_finder, &has_rest,
&formals_classifier, CHECK_OK);
   }
   Expect(Token::RPAREN, CHECK_OK);
   int formals_end_position = scanner()->location().end_pos;

-  CheckArityRestrictions(num_parameters, arity_restriction, start_position,
-                         formals_end_position, CHECK_OK);
+  CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
+                         start_position, formals_end_position, CHECK_OK);

// See Parser::ParseFunctionLiteral for more information about lazy parsing
   // and lazy compilation.
@@ -1060,7 +1060,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
   // function, since the function can declare itself strict.
   CheckFunctionName(language_mode(), kind, function_name,
name_is_strict_reserved, function_name_location, CHECK_OK);
-  const bool strict_formal_parameters = is_rest || IsConciseMethod(kind);
+  const bool strict_formal_parameters = has_rest || IsConciseMethod(kind);
   const bool allow_duplicate_parameters =
       is_sloppy(language_mode()) && !strict_formal_parameters;
   ValidateFormalParameters(&formals_classifier, language_mode(),
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index aeef700bfe7593a8369b4c4b5f0350fa8dc5b707..072ebca27cbacea94c730e070e792e7d17ee675a 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -881,7 +881,7 @@ class ParserBase : public Traits {
                                ExpressionClassifier* classifier, bool* ok);
   void CheckArityRestrictions(
       int param_count, FunctionLiteral::ArityRestriction arity_restriction,
-      int formals_start_pos, int formals_end_pos, bool* ok);
+      bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);

   // Checks if the expression is a valid reference expression (e.g., on the
// left-hand side of assignments). Although ruled out by ECMA as early errors,
@@ -3623,7 +3623,7 @@ int ParserBase<Traits>::ParseFormalParameterList(
 template <class Traits>
 void ParserBase<Traits>::CheckArityRestrictions(
     int param_count, FunctionLiteral::ArityRestriction arity_restriction,
-    int formals_start_pos, int formals_end_pos, bool* ok) {
+    bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
   switch (arity_restriction) {
     case FunctionLiteral::GETTER_ARITY:
       if (param_count != 0) {
@@ -3638,6 +3638,11 @@ void ParserBase<Traits>::CheckArityRestrictions(
                         "bad_setter_arity");
         *ok = false;
       }
+      if (has_rest) {
+ ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
+                        "setter_rest_param");
+        *ok = false;
+      }
       break;
     default:
       break;
Index: test/message/rest-param-class-setter-strict.js
diff --git a/test/message/super-in-function.js b/test/message/rest-param-class-setter-strict.js
similarity index 52%
copy from test/message/super-in-function.js
copy to test/message/rest-param-class-setter-strict.js
index edaa0e4eadc7befdb7ed28a3e06eaa827c4388f0..d37edb6f3f70373b0b513e29363eddcafb343f1b 100644
--- a/test/message/super-in-function.js
+++ b/test/message/rest-param-class-setter-strict.js
@@ -2,9 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Flags: --harmony-classes
+// Flags: --harmony-rest-parameters --harmony-classes
 'use strict';

-function f() {
-  super.x();
+var _bad = "setting this should fail!";
+class C {
+  get bad() { return _bad; }
+  set bad(...args) { _bad = args[0]; }
 }
Index: test/message/rest-param-class-setter-strict.out
diff --git a/test/message/rest-param-class-setter-strict.out b/test/message/rest-param-class-setter-strict.out
new file mode 100644
index 0000000000000000000000000000000000000000..3296a0f2c8dcc7decb8cd64cd83288d4c44de6d7
--- /dev/null
+++ b/test/message/rest-param-class-setter-strict.out
@@ -0,0 +1,4 @@
+*%(basename)s:11: SyntaxError: Setter function argument must not be a rest parameter
+  set bad(...args) { _bad = args[0]; }
+         ^^^^^^^^^
+SyntaxError: Setter function argument must not be a rest parameter
Index: test/message/rest-param-object-setter-sloppy.js
diff --git a/test/message/formal-parameters-bad-rest.js b/test/message/rest-param-object-setter-sloppy.js
similarity index 65%
copy from test/message/formal-parameters-bad-rest.js
copy to test/message/rest-param-object-setter-sloppy.js
index c67e1de93fed808fb0578e9029dabef201ab51e4..08c03298dc26dfee9f31e39108ba0b1519a96988 100644
--- a/test/message/formal-parameters-bad-rest.js
+++ b/test/message/rest-param-object-setter-sloppy.js
@@ -4,4 +4,8 @@
 //
 // Flags: --harmony-rest-parameters

-function foo(...b, a) { return a }
+var _bad = "this should fail!";
+({
+  get bad() { return _bad; },
+  set bad(...args) { _bad = args[0]; }
+});
Index: test/message/rest-param-object-setter-sloppy.out
diff --git a/test/message/rest-param-object-setter-sloppy.out b/test/message/rest-param-object-setter-sloppy.out
new file mode 100644
index 0000000000000000000000000000000000000000..9400a2a9ce3ee16a535b5663d6ea70322a89e521
--- /dev/null
+++ b/test/message/rest-param-object-setter-sloppy.out
@@ -0,0 +1,4 @@
+*%(basename)s:10: SyntaxError: Setter function argument must not be a rest parameter
+  set bad(...args) { _bad = args[0]; }
+         ^^^^^^^^^
+SyntaxError: Setter function argument must not be a rest parameter
Index: test/message/rest-param-object-setter-strict.js
diff --git a/test/message/formal-parameters-bad-rest.js b/test/message/rest-param-object-setter-strict.js
similarity index 62%
copy from test/message/formal-parameters-bad-rest.js
copy to test/message/rest-param-object-setter-strict.js
index c67e1de93fed808fb0578e9029dabef201ab51e4..e3a8f604e64ae75b5941c878c34280f352af7d00 100644
--- a/test/message/formal-parameters-bad-rest.js
+++ b/test/message/rest-param-object-setter-strict.js
@@ -3,5 +3,10 @@
 // found in the LICENSE file.
 //
 // Flags: --harmony-rest-parameters
+'use strict';

-function foo(...b, a) { return a }
+var _bad = "this should fail!";
+({
+  get bad() { return _bad; },
+  set bad(...args) { _bad = args[0]; }
+});
Index: test/message/rest-param-object-setter-strict.out
diff --git a/test/message/rest-param-object-setter-strict.out b/test/message/rest-param-object-setter-strict.out
new file mode 100644
index 0000000000000000000000000000000000000000..3296a0f2c8dcc7decb8cd64cd83288d4c44de6d7
--- /dev/null
+++ b/test/message/rest-param-object-setter-strict.out
@@ -0,0 +1,4 @@
+*%(basename)s:11: SyntaxError: Setter function argument must not be a rest parameter
+  set bad(...args) { _bad = args[0]; }
+         ^^^^^^^^^
+SyntaxError: Setter function argument must not be a rest parameter


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to