Reviewers: Lasse Reichstein, Mads Ager,

Description:
Make arguments read only in strict mode.
Propagate strict mode flag through the lazy compilation.

BUG=
TEST=test/mjsunit/strict-mode-arguments.js


Please review this at http://codereview.chromium.org/6349020/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/compiler.cc
  M src/objects-inl.h
  M src/objects.h
  M src/parser.cc
  M src/scopes.h
  M src/scopes.cc
  M src/variables.h
  A test/mjsunit/strict-mode-arguments.js


Index: src/compiler.cc
diff --git a/src/compiler.cc b/src/compiler.cc
index 5c18c3e53ebc8d6d3eb2dfc0e36301481621d20d..424bae80706093b7a22bc48bb9e9b326cf951b18 100755
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -762,6 +762,7 @@ void Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
       *lit->this_property_assignments());
   function_info->set_try_full_codegen(lit->try_full_codegen());
   function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
+  function_info->set_strict_mode(lit->strict_mode());
 }


Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index db9e2ef7b10f95e01cfce86773eed94bd6a6ce32..a729db49b8863c10a79b429fc607054b53430ee2 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2984,6 +2984,18 @@ void SharedFunctionInfo::set_optimization_disabled(bool disable) {
 }


+bool SharedFunctionInfo::strict_mode() {
+  return BooleanBit::get(compiler_hints(), kStrictModeFunction);
+}
+
+
+void SharedFunctionInfo::set_strict_mode(bool value) {
+  set_compiler_hints(BooleanBit::set(compiler_hints(),
+                                     kStrictModeFunction,
+                                     value));
+}
+
+
 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)

Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index 8c63022db8a0ac94928987882ddf258aabc599fd..0b81674e44983e36e56fbeb40d39e2ac1092e613 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4170,6 +4170,10 @@ class SharedFunctionInfo: public HeapObject {
   inline bool optimization_disabled();
   inline void set_optimization_disabled(bool value);

+  // Indicates whether the function is a strict mode function.
+  inline bool strict_mode();
+  inline void set_strict_mode(bool value);
+
   // Indicates whether or not the code in the shared function support
   // deoptimization.
   inline bool has_deoptimization_support();
@@ -4351,6 +4355,7 @@ class SharedFunctionInfo: public HeapObject {
   static const int kCodeAgeShift = 4;
   static const int kCodeAgeMask = 0x7;
   static const int kOptimizationDisabled = 7;
+  static const int kStrictModeFunction = 8;

   DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
 };
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index c0976988ea3c077800842816c03981ee5cf7b248..8d88032eadbe4e5824f5af9b8e17b7111cb65805 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -747,6 +747,10 @@ FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info,
                                scope);
     TemporaryScope temp_scope(&this->temp_scope_);

+    if (info->strict_mode()) {
+      temp_scope.EnableStrictMode();
+    }
+
     FunctionLiteralType type =
         info->is_expression() ? EXPRESSION : DECLARATION;
     bool ok = true;
@@ -3540,7 +3544,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
       end_pos = scanner().location().end_pos;
     }

-    // Validate strict mode.
+    // Strict mode.
     if (temp_scope_->StrictMode()) {
       if (IsEvalOrArguments(name)) {
         int position = function_token_position != RelocInfo::kNoPosition
@@ -3564,6 +3568,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
         return NULL;
       }
       CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
+
+      // In strict mode, arguments are const.
+      top_scope_->SetArgumentsConst();
     }

     FunctionLiteral* function_literal =
Index: src/scopes.cc
diff --git a/src/scopes.cc b/src/scopes.cc
index d3f54ad3f2d9ad8b47fefae2d89fd692bd3e2eda..afc89ac98d2ddde3222385bc114665ac5b208b76 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -491,6 +491,15 @@ int Scope::ContextChainLength(Scope* scope) {
 }


+// In strict mode, arguments are const.
+void Scope::SetArgumentsConst() {
+  Variable* arguments = LocalLookup(Factory::arguments_symbol());
+ ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly
+  ASSERT(arguments->mode() == Variable::VAR);
+  arguments->set_mode(Variable::CONST);
+}
+
+
 #ifdef DEBUG
 static const char* Header(Scope::Type type) {
   switch (type) {
Index: src/scopes.h
diff --git a/src/scopes.h b/src/scopes.h
index a9220eb827566e94e7a126f1085bdc90d6c3a67c..a8f2db4e03e844a5e2bcd3a77405072d627131d4 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -299,6 +299,8 @@ class Scope: public ZoneObject {
     return variables_.Lookup(name) != NULL;
   }

+  void SetArgumentsConst();
+
// ---------------------------------------------------------------------------
   // Debugging.

Index: src/variables.h
diff --git a/src/variables.h b/src/variables.h
index 5d27a02d5375ec70b84934e637b0a18a0e621f41..75af977c908c771ec0ffecebf572f433e76ef88f 100644
--- a/src/variables.h
+++ b/src/variables.h
@@ -135,6 +135,8 @@ class Variable: public ZoneObject {

   Handle<String> name() const { return name_; }
   Mode mode() const { return mode_; }
+  void set_mode(Mode mode) { mode_ = mode; }
+
   bool is_accessed_from_inner_scope() const {
     return is_accessed_from_inner_scope_;
   }
Index: test/mjsunit/strict-mode-arguments.js
diff --git a/test/mjsunit/strict-mode-arguments.js b/test/mjsunit/strict-mode-arguments.js
new file mode 100644
index 0000000000000000000000000000000000000000..ac57e77a6742432bf63ab19726ac6b8173295193
--- /dev/null
+++ b/test/mjsunit/strict-mode-arguments.js
@@ -0,0 +1,44 @@
+// 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.
+
+"use strict";
+
+// arguments must be read only in strict mode.
+// NOTE: this test will be obsoleted in future changes when
+// assignment to arguments/eval will become syntax error in
+// strict mode eval code
+function TestArgumentsIsReadOnlyInStrict() {
+  // Lazy compiled. It verifies that the strict mode is correctly
+  // propagated from the initial parse to lazy compilation of the function.
+  function inner(a) {
+    eval('arguments = ["assigned"];');
+    return arguments[0];
+  }
+  return inner('argument');
+}
+
+assertEquals('argument', TestArgumentsIsReadOnlyInStrict());


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to