Revert strict mode (Mozilla test failure).
authormmaly@chromium.org <mmaly@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 18 Jan 2011 23:01:50 +0000 (23:01 +0000)
committermmaly@chromium.org <mmaly@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 18 Jan 2011 23:01:50 +0000 (23:01 +0000)
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6374 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/ast.h
src/flag-definitions.h
src/heap.h
src/messages.js
src/parser.cc
src/scopes.cc
src/scopes.h
test/mjsunit/strict-mode.js [deleted file]

index a897e88..f55ddcd 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1675,8 +1675,7 @@ class FunctionLiteral: public Expression {
                   int start_position,
                   int end_position,
                   bool is_expression,
-                  bool contains_loops,
-                  bool strict_mode)
+                  bool contains_loops)
       : name_(name),
         scope_(scope),
         body_(body),
@@ -1690,7 +1689,6 @@ class FunctionLiteral: public Expression {
         end_position_(end_position),
         is_expression_(is_expression),
         contains_loops_(contains_loops),
-        strict_mode_(strict_mode),
         function_token_position_(RelocInfo::kNoPosition),
         inferred_name_(Heap::empty_string()),
         try_full_codegen_(false),
@@ -1707,7 +1705,6 @@ class FunctionLiteral: public Expression {
   int end_position() const { return end_position_; }
   bool is_expression() const { return is_expression_; }
   bool contains_loops() const { return contains_loops_; }
-  bool strict_mode() const { return strict_mode_; }
 
   int materialized_literal_count() { return materialized_literal_count_; }
   int expected_property_count() { return expected_property_count_; }
@@ -1750,7 +1747,6 @@ class FunctionLiteral: public Expression {
   int end_position_;
   bool is_expression_;
   bool contains_loops_;
-  bool strict_mode_;
   int function_token_position_;
   Handle<String> inferred_name_;
   bool try_full_codegen_;
index b90534c..fb892d6 100644 (file)
@@ -301,7 +301,6 @@ DEFINE_bool(use_verbose_printer, true, "allows verbose printing")
 
 // parser.cc
 DEFINE_bool(allow_natives_syntax, false, "allow natives syntax")
-DEFINE_bool(strict_mode, true, "allow strict mode directives")
 
 // rewriter.cc
 DEFINE_bool(optimize_ast, true, "optimize the ast")
index 1c86817..ac52ab4 100644 (file)
@@ -204,7 +204,6 @@ namespace internal {
   V(global_eval_symbol, "GlobalEval")                                    \
   V(identity_hash_symbol, "v8::IdentityHash")                            \
   V(closure_symbol, "(closure)")                                         \
-  V(use_strict, "use strict")                                            \
   V(KeyedLoadExternalArray_symbol, "KeyedLoadExternalArray")             \
   V(KeyedStoreExternalArray_symbol, "KeyedStoreExternalArray")
 
index e62f06f..a30ef8a 100644 (file)
@@ -202,13 +202,7 @@ function FormatMessage(message) {
       array_indexof_not_defined:    "Array.getIndexOf: Argument undefined",
       object_not_extensible:        "Can't add property %0, object is not extensible",
       illegal_access:               "Illegal access",
-      invalid_preparser_data:       "Invalid preparser data for function %0",
-      strict_mode_with:             "Strict mode code may not include a with statement",
-      strict_catch_variable:        "Catch variable may not be eval or arguments in strict mode",
-      strict_param_name:            "Parameter name eval or arguments is not allowed in strict mode",
-      strict_param_dupe:            "Strict mode function may not have duplicate parameter names",
-      strict_var_name:              "Variable name may not be eval or arguments in strict mode",
-      strict_function_name:         "Function name may not be eval or arguments in strict mode",
+      invalid_preparser_data:       "Invalid preparser data for function %0"
     };
   }
   var format = kMessages[message.type];
index af2010b..6ad9ab3 100644 (file)
@@ -283,11 +283,6 @@ class TemporaryScope BASE_EMBEDDED {
   void AddLoop() { loop_count_++; }
   bool ContainsLoops() const { return loop_count_ > 0; }
 
-  bool StrictMode() { return strict_mode_; }
-  void EnableStrictMode() {
-    strict_mode_ = FLAG_strict_mode;
-  }
-
  private:
   // Captures the number of literals that need materialization in the
   // function.  Includes regexp literals, and boilerplate for object
@@ -305,9 +300,6 @@ class TemporaryScope BASE_EMBEDDED {
   // Captures the number of loops inside the scope.
   int loop_count_;
 
-  // Parsing strict mode code.
-  bool strict_mode_;
-
   // Bookkeeping
   TemporaryScope** variable_;
   TemporaryScope* parent_;
@@ -322,8 +314,6 @@ TemporaryScope::TemporaryScope(TemporaryScope** variable)
     loop_count_(0),
     variable_(variable),
     parent_(*variable) {
-  // Inherit the strict mode from the parent scope.
-  strict_mode_ = (parent_ != NULL) && parent_->strict_mode_;
   *variable = this;
 }
 
@@ -571,6 +561,7 @@ class LexicalScope BASE_EMBEDDED {
   int prev_level_;
 };
 
+
 // ----------------------------------------------------------------------------
 // The CHECK_OK macro is a convenient macro to enforce error
 // handling for functions that may fail (by returning !*ok).
@@ -678,8 +669,7 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
           0,
           source->length(),
           false,
-          temp_scope.ContainsLoops(),
-          temp_scope.StrictMode());
+          temp_scope.ContainsLoops());
     } else if (stack_overflow_) {
       Top::StackOverflow();
     }
@@ -1085,46 +1075,9 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
   ASSERT(processor != NULL);
   InitializationBlockFinder block_finder;
   ThisNamedPropertyAssigmentFinder this_property_assignment_finder;
-  bool directive_prologue = true;     // Parsing directive prologue.
-
   while (peek() != end_token) {
-    if (directive_prologue && peek() != Token::STRING) {
-      directive_prologue = false;
-    }
-
-    Scanner::Location token_loc = scanner().peek_location();
     Statement* stat = ParseStatement(NULL, CHECK_OK);
-
-    if (stat == NULL || stat->IsEmpty()) {
-      directive_prologue = false;   // End of directive prologue.
-      continue;
-    }
-
-    if (directive_prologue) {
-      // A shot at a directive.
-      ExpressionStatement *e_stat;
-      Literal *literal;
-      // Still processing directive prologue?
-      if ((e_stat = stat->AsExpressionStatement()) != NULL &&
-          (literal = e_stat->expression()->AsLiteral()) != NULL &&
-          literal->handle()->IsString()) {
-        Handle<String> directive = Handle<String>::cast(literal->handle());
-
-        // Check "use strict" directive (ES5 14.1).
-        if (!temp_scope_->StrictMode() &&
-            directive->Equals(Heap::use_strict()) &&
-            token_loc.end_pos - token_loc.beg_pos ==
-              Heap::use_strict()->length() + 2) {
-          temp_scope_->EnableStrictMode();
-          // "use strict" is the only directive for now.
-          directive_prologue = false;
-        }
-      } else {
-        // End of the directive prologue.
-        directive_prologue = false;
-      }
-    }
-
+    if (stat == NULL || stat->IsEmpty()) continue;
     // We find and mark the initialization blocks on top level code only.
     // This is because the optimization prevents reuse of the map transitions,
     // so it should be used only for code that will only be run once.
@@ -1478,10 +1431,6 @@ Block* Parser::ParseVariableStatement(bool* ok) {
   return result;
 }
 
-static bool IsEvalOrArguments(Handle<String> string) {
-  return string.is_identical_to(Factory::eval_symbol()) ||
-         string.is_identical_to(Factory::arguments_symbol());
-}
 
 // If the variable declaration declares exactly one non-const
 // variable, then *var is set to that variable. In all other cases,
@@ -1530,13 +1479,6 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
     Handle<String> name = ParseIdentifier(CHECK_OK);
     if (fni_ != NULL) fni_->PushVariableName(name);
 
-    // Strict mode variables may not be named eval or arguments
-    if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
-      ReportMessage("strict_var_name", Vector<const char*>::empty());
-      *ok = false;
-      return NULL;
-    }
-
     // Declare variable.
     // Note that we *always* must treat the initial value via a separate init
     // assignment for variables and constants because the value must be assigned
@@ -1897,13 +1839,6 @@ Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
   //   'with' '(' Expression ')' Statement
 
   Expect(Token::WITH, CHECK_OK);
-
-  if (temp_scope_->StrictMode()) {
-    ReportMessage("strict_mode_with", Vector<const char*>::empty());
-    *ok = false;
-    return NULL;
-  }
-
   Expect(Token::LPAREN, CHECK_OK);
   Expression* expr = ParseExpression(true, CHECK_OK);
   Expect(Token::RPAREN, CHECK_OK);
@@ -2036,13 +1971,6 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
 
     Expect(Token::LPAREN, CHECK_OK);
     Handle<String> name = ParseIdentifier(CHECK_OK);
-
-    if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
-      ReportMessage("strict_catch_variable", Vector<const char*>::empty());
-      *ok = false;
-      return NULL;
-    }
-
     Expect(Token::RPAREN, CHECK_OK);
 
     if (peek() == Token::LBRACE) {
@@ -3296,27 +3224,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
     //    '(' (Identifier)*[','] ')'
     Expect(Token::LPAREN, CHECK_OK);
     int start_pos = scanner().location().beg_pos;
-    Scanner::Location eval_loc(RelocInfo::kNoPosition, RelocInfo::kNoPosition);
-    Scanner::Location dupe_loc(RelocInfo::kNoPosition, RelocInfo::kNoPosition);
-
     bool done = (peek() == Token::RPAREN);
     while (!done) {
       Handle<String> param_name = ParseIdentifier(CHECK_OK);
-      Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
-
-      // Store locations for possible future error reports.
-      if (eval_loc.beg_pos == RelocInfo::kNoPosition &&
-          IsEvalOrArguments(param_name)) {
-        // Store location for later
-        eval_loc = scanner().location();
-      }
-      if (dupe_loc.beg_pos == RelocInfo::kNoPosition &&
-        top_scope_->IsParameterDeclared(param_name)) {
-        // Store location for later
-        dupe_loc = scanner().location();
-      }
-
-      top_scope_->AddParameter(parameter);
+      top_scope_->AddParameter(top_scope_->DeclareLocal(param_name,
+                                                        Variable::VAR));
       num_parameters++;
       done = (peek() == Token::RPAREN);
       if (!done) Expect(Token::COMMA, CHECK_OK);
@@ -3388,32 +3300,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
       end_pos = scanner().location().end_pos;
     }
 
-    // Validate strict mode.
-    if (temp_scope_->StrictMode()) {
-      if (IsEvalOrArguments(name)) {
-        int position = function_token_position != RelocInfo::kNoPosition
-                         ? function_token_position
-                         : (start_pos > 0 ? start_pos - 1 : start_pos);
-        ReportMessageAt(Scanner::Location(position, start_pos),
-                        "strict_function_name", Vector<const char*>::empty());
-        *ok = false;
-        return NULL;
-      }
-      if (eval_loc.beg_pos != RelocInfo::kNoPosition) {
-        ReportMessageAt(eval_loc, "strict_param_name",
-                        Vector<const char*>::empty());
-        *ok = false;
-        return NULL;
-      }
-      if (dupe_loc.beg_pos != RelocInfo::kNoPosition) {
-        ReportMessageAt(dupe_loc, "strict_param_dupe",
-                        Vector<const char*>::empty());
-        *ok = false;
-        return NULL;
-      }
-      // TODO(mmaly): Check for octal escape sequence here.
-    }
-
     FunctionLiteral* function_literal =
         new FunctionLiteral(name,
                             top_scope_,
@@ -3426,8 +3312,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
                             start_pos,
                             end_pos,
                             function_name->length() > 0,
-                            temp_scope.ContainsLoops(),
-                            temp_scope.StrictMode());
+                            temp_scope.ContainsLoops());
     function_literal->set_function_token_position(function_token_position);
 
     if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
index e96ca99..58a10ee 100644 (file)
@@ -445,18 +445,6 @@ int Scope::ContextChainLength(Scope* scope) {
 }
 
 
-bool Scope::IsParameterDeclared(Handle<String> name) {
-  ASSERT(name->IsSymbol());
-  for (int i = 0, length = num_parameters(); i < length; i ++) {
-    ASSERT(parameter(i)->name()->IsSymbol());
-    if (name.is_identical_to(parameter(i)->name())) {
-      return true;
-    }
-  }
-  return false;
-}
-
-
 #ifdef DEBUG
 static const char* Header(Scope::Type type) {
   switch (type) {
index 85b059c..09901ad 100644 (file)
@@ -289,10 +289,6 @@ class Scope: public ZoneObject {
   int ContextChainLength(Scope* scope);
 
   // ---------------------------------------------------------------------------
-  // Strict mode support.
-  bool IsParameterDeclared(Handle<String> name);
-
-  // ---------------------------------------------------------------------------
   // Debugging.
 
 #ifdef DEBUG
diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js
deleted file mode 100644 (file)
index 68a0d7d..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-function CheckStrictMode(code, exception) {
-  assertDoesNotThrow(code);
-  assertThrows("'use strict';\n" + code, exception);
-  assertThrows('"use strict";\n' + code, exception);
-  assertDoesNotThrow("\
-    function outer() {\
-      function inner() {\n"
-        + code +
-      "\n}\
-    }");
-  assertThrows("\
-    function outer() {\
-      'use strict';\
-      function inner() {\n"
-        + code +
-      "\n}\
-    }", exception);
-}
-
-// Incorrect 'use strict' directive.
-function UseStrictEscape() {
-  "use\\x20strict";
-  with ({}) {};
-}
-
-// 'use strict' in non-directive position.
-function UseStrictNonDirective() {
-  void(0);
-  "use strict";
-  with ({}) {};
-}
-
-// Multiple directives, including "use strict".
-assertThrows('\
-"directive 1";\
-"another directive";\
-"use strict";\
-"directive after strict";\
-"and one more";\
-with({}) {}', SyntaxError);
-
-// 'with' disallowed in strict mode.
-CheckStrictMode("with({}) {}", SyntaxError);
-
-// Function named 'eval'.
-CheckStrictMode("function eval() {}", SyntaxError)
-
-// Function named 'arguments'.
-CheckStrictMode("function arguments() {}", SyntaxError)
-
-// Function parameter named 'eval'.
-CheckStrictMode("function foo(a, b, eval, c, d) {}", SyntaxError)
-
-// Function parameter named 'arguments'.
-CheckStrictMode("function foo(a, b, arguments, c, d) {}", SyntaxError)
-
-// Property accessor parameter named 'eval'.
-CheckStrictMode("var o = { set foo(eval) {} }", SyntaxError)
-
-// Property accessor parameter named 'arguments'.
-CheckStrictMode("var o = { set foo(arguments) {} }", SyntaxError)
-
-// Duplicate function parameter name.
-CheckStrictMode("function foo(a, b, c, d, b) {}", SyntaxError)
-
-// catch(eval)
-CheckStrictMode("try{}catch(eval){};", SyntaxError)
-
-// catch(arguments)
-CheckStrictMode("try{}catch(arguments){};", SyntaxError)
-
-// var eval
-CheckStrictMode("var eval;", SyntaxError)
-
-// var arguments
-CheckStrictMode("var arguments;", SyntaxError)
-
-// Strict mode applies to the function in which the directive is used..
-assertThrows('\
-function foo(eval) {\
-  "use strict";\
-}', SyntaxError);
-
-// Strict mode doesn't affect the outer stop of strict code.
-function NotStrict(eval) {
-  function Strict() {
-    "use strict";
-  }
-  with ({}) {};
-}