[strong] Deprecate arguments
authorrossberg <rossberg@chromium.org>
Thu, 19 Feb 2015 14:58:32 +0000 (06:58 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 19 Feb 2015 14:58:42 +0000 (14:58 +0000)
R=marja@chromium.org
BUG=

Review URL: https://codereview.chromium.org/932333004

Cr-Commit-Position: refs/heads/master@{#26753}

src/ast-value-factory.h
src/messages.js
src/parser.cc
src/parser.h
src/preparser.h
test/mjsunit/strong/arguments.js [new file with mode: 0644]

index 294a281..fe33325 100644 (file)
@@ -88,8 +88,6 @@ class AstRawString : public AstString {
     return *c;
   }
 
-  V8_INLINE bool IsArguments(AstValueFactory* ast_value_factory) const;
-
   // For storing AstRawStrings in a hash map.
   uint32_t hash() const {
     return hash_;
@@ -357,11 +355,6 @@ class AstValueFactory {
   OTHER_CONSTANTS(F)
 #undef F
 };
-
-
-bool AstRawString::IsArguments(AstValueFactory* ast_value_factory) const {
-  return ast_value_factory->arguments_string() == this;
-}
 } }  // namespace v8::internal
 
 #undef STRING_CONSTANTS
index 510147f..049f7f6 100644 (file)
@@ -161,6 +161,7 @@ var kMessages = {
   strict_cannot_assign:          ["Cannot assign to read only '", "%0", "' in strict mode"],
   strict_poison_pill:            ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
   strict_caller:                 ["Illegal access to a strict mode caller function."],
+  strong_arguments:              ["Please don't use 'arguments' in strong mode, use '...args' instead"],
   strong_equal:                  ["Please don't use '==' or '!=' in strong mode, use '===' or '!==' instead"],
   strong_delete:                 ["Please don't use 'delete' in strong mode, use maps or sets instead"],
   strong_var:                    ["Please don't use 'var' in strong mode, use 'let' or 'const' instead"],
index 1fc131c..84a94ef 100644 (file)
@@ -382,9 +382,18 @@ class TargetScope BASE_EMBEDDED {
 // ----------------------------------------------------------------------------
 // Implementation of Parser
 
+bool ParserTraits::IsEval(const AstRawString* identifier) const {
+  return identifier == parser_->ast_value_factory()->eval_string();
+}
+
+
+bool ParserTraits::IsArguments(const AstRawString* identifier) const {
+  return identifier == parser_->ast_value_factory()->arguments_string();
+}
+
+
 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
-  return identifier == parser_->ast_value_factory()->eval_string() ||
-         identifier == parser_->ast_value_factory()->arguments_string();
+  return IsEval(identifier) || IsArguments(identifier);
 }
 
 
index bdfe440..713133a 100644 (file)
@@ -383,6 +383,8 @@ class ParserTraits {
   explicit ParserTraits(Parser* parser) : parser_(parser) {}
 
   // Helper functions for recursive descent.
+  bool IsEval(const AstRawString* identifier) const;
+  bool IsArguments(const AstRawString* identifier) const;
   bool IsEvalOrArguments(const AstRawString* identifier) const;
   V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
 
index 0f9cb46..f7f5323 100644 (file)
@@ -725,17 +725,13 @@ class PreParserIdentifier {
     return PreParserIdentifier(kConstructorIdentifier);
   }
   bool IsEval() const { return type_ == kEvalIdentifier; }
-  bool IsArguments(const AstValueFactory* = NULL) const {
-    return type_ == kArgumentsIdentifier;
-  }
+  bool IsArguments() const { return type_ == kArgumentsIdentifier; }
+  bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
   bool IsLet() const { return type_ == kLetIdentifier; }
   bool IsStatic() const { return type_ == kStaticIdentifier; }
   bool IsYield() const { return type_ == kYieldIdentifier; }
   bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
   bool IsConstructor() const { return type_ == kConstructorIdentifier; }
-  bool IsEvalOrArguments() const {
-    return type_ == kEvalIdentifier || type_ == kArgumentsIdentifier;
-  }
   bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
   bool IsFutureStrictReserved() const {
     return type_ == kFutureStrictReservedIdentifier ||
@@ -1236,6 +1232,14 @@ class PreParserTraits {
   explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
 
   // Helper functions for recursive descent.
+  static bool IsEval(PreParserIdentifier identifier) {
+    return identifier.IsEval();
+  }
+
+  static bool IsArguments(PreParserIdentifier identifier) {
+    return identifier.IsArguments();
+  }
+
   static bool IsEvalOrArguments(PreParserIdentifier identifier) {
     return identifier.IsEvalOrArguments();
   }
@@ -1729,12 +1733,18 @@ typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
   Token::Value next = Next();
   if (next == Token::IDENTIFIER) {
     IdentifierT name = this->GetSymbol(scanner());
-    if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
-        is_strict(language_mode()) && this->IsEvalOrArguments(name)) {
-      ReportMessage("strict_eval_arguments");
-      *ok = false;
+    if (allow_eval_or_arguments == kDontAllowEvalOrArguments) {
+      if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) {
+        ReportMessage("strict_eval_arguments");
+        *ok = false;
+      }
+    } else {
+      if (is_strong(language_mode()) && this->IsArguments(name)) {
+        ReportMessage("strong_arguments");
+        *ok = false;
+      }
     }
-    if (name->IsArguments(ast_value_factory())) scope_->RecordArgumentsUsage();
+    if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
     return name;
   } else if (is_sloppy(language_mode()) &&
              (next == Token::FUTURE_STRICT_RESERVED_WORD ||
@@ -1767,7 +1777,7 @@ typename ParserBase<Traits>::IdentifierT ParserBase<
   }
 
   IdentifierT name = this->GetSymbol(scanner());
-  if (name->IsArguments(ast_value_factory())) scope_->RecordArgumentsUsage();
+  if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
   return name;
 }
 
@@ -1785,7 +1795,7 @@ ParserBase<Traits>::ParseIdentifierName(bool* ok) {
   }
 
   IdentifierT name = this->GetSymbol(scanner());
-  if (name->IsArguments(ast_value_factory())) scope_->RecordArgumentsUsage();
+  if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
   return name;
 }
 
diff --git a/test/mjsunit/strong/arguments.js b/test/mjsunit/strong/arguments.js
new file mode 100644 (file)
index 0000000..b40b661
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --strong-mode
+
+(function NoArguments() {
+  assertThrows("'use strong'; arguments", SyntaxError);
+  assertThrows("'use strong'; function f() { arguments }", SyntaxError);
+  assertThrows("'use strong'; let f = function() { arguments }", SyntaxError);
+  assertThrows("'use strong'; let f = () => arguments", SyntaxError);
+  // The following are strict mode errors already.
+  assertThrows("'use strong'; let arguments", SyntaxError);
+  assertThrows("'use strong'; function f(arguments) {}", SyntaxError);
+  assertThrows("'use strong'; let f = (arguments) => {}", SyntaxError);
+})();