From 0ebd870f720c8f3175b89257dd42386f98b056f8 Mon Sep 17 00:00:00 2001 From: rossberg Date: Thu, 19 Feb 2015 06:58:32 -0800 Subject: [PATCH] [strong] Deprecate arguments R=marja@chromium.org BUG= Review URL: https://codereview.chromium.org/932333004 Cr-Commit-Position: refs/heads/master@{#26753} --- src/ast-value-factory.h | 7 ------- src/messages.js | 1 + src/parser.cc | 13 +++++++++++-- src/parser.h | 2 ++ src/preparser.h | 36 +++++++++++++++++++++++------------- test/mjsunit/strong/arguments.js | 16 ++++++++++++++++ 6 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 test/mjsunit/strong/arguments.js diff --git a/src/ast-value-factory.h b/src/ast-value-factory.h index 294a281..fe33325 100644 --- a/src/ast-value-factory.h +++ b/src/ast-value-factory.h @@ -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 diff --git a/src/messages.js b/src/messages.js index 510147f..049f7f6 100644 --- a/src/messages.js +++ b/src/messages.js @@ -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"], diff --git a/src/parser.cc b/src/parser.cc index 1fc131c..84a94ef 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -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); } diff --git a/src/parser.h b/src/parser.h index bdfe440..713133a 100644 --- a/src/parser.h +++ b/src/parser.h @@ -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; diff --git a/src/preparser.h b/src/preparser.h index 0f9cb46..f7f5323 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -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::IdentifierT ParserBase::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::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::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 index 0000000..b40b661 --- /dev/null +++ b/test/mjsunit/strong/arguments.js @@ -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); +})(); -- 2.7.4