Revision: 20536
Author:   [email protected]
Date:     Mon Apr  7 10:47:54 2014 UTC
Log:      Version 3.25.28.6 (merged r20316, r20366, r20428, r20451)

Don't pass the hole to SetElement when creating Array.observe change records

Fix Type::Intersect to skip uninhabited bitsets

Make invalid LHSs that are calls late errors

BUG=chromium:356589,chromium:357330,chromium:358346
LOG=N
[email protected]

Review URL: https://codereview.chromium.org/227483006
http://code.google.com/p/v8/source/detail?r=20536

Added:
 /branches/3.25/test/mjsunit/regress/regress-356589.js
 /branches/3.25/test/mjsunit/regress/regress-crbug-357330.js
Modified:
 /branches/3.25/src/arm/full-codegen-arm.cc
 /branches/3.25/src/arm64/full-codegen-arm64.cc
 /branches/3.25/src/ast.cc
 /branches/3.25/src/ast.h
 /branches/3.25/src/heap.h
 /branches/3.25/src/ia32/full-codegen-ia32.cc
 /branches/3.25/src/mips/full-codegen-mips.cc
 /branches/3.25/src/objects.cc
 /branches/3.25/src/parser.cc
 /branches/3.25/src/parser.h
 /branches/3.25/src/preparser.cc
 /branches/3.25/src/preparser.h
 /branches/3.25/src/types.cc
 /branches/3.25/src/variables.cc
 /branches/3.25/src/variables.h
 /branches/3.25/src/version.cc
 /branches/3.25/src/x64/full-codegen-x64.cc
 /branches/3.25/test/cctest/test-parsing.cc
 /branches/3.25/test/mjsunit/invalid-lhs.js
 /branches/3.25/test/webkit/fast/js/modify-non-references-expected.txt
 /branches/3.25/test/webkit/fast/js/modify-non-references.js

=======================================
--- /dev/null
+++ /branches/3.25/test/mjsunit/regress/regress-356589.js Mon Apr 7 10:47:54 2014 UTC
@@ -0,0 +1,34 @@
+// Copyright 2014 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.
+
+// This test passes if it does not crash in debug mode
+
+arr = ['a', 'b', 'c', 'd'];
+Object.defineProperty(arr.__proto__, '0', { get: function(){} });
+Object.defineProperty(arr, '2', {get: function(){} });
+Object.observe(arr, function() {});
+arr.length = 2;
=======================================
--- /dev/null
+++ /branches/3.25/test/mjsunit/regress/regress-crbug-357330.js Mon Apr 7 10:47:54 2014 UTC
@@ -0,0 +1,16 @@
+// Copyright 2014 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: --allow-natives-syntax
+
+function f(foo) {
+  var g;
+  true ? (g = foo + 0) : g = null;
+  if (null != g) {}
+};
+
+f(1.4);
+f(1.4);
+%OptimizeFunctionOnNextCall(f);
+f(1.4);
=======================================
--- /branches/3.25/src/arm/full-codegen-arm.cc  Fri Apr  4 09:30:01 2014 UTC
+++ /branches/3.25/src/arm/full-codegen-arm.cc  Mon Apr  7 10:47:54 2014 UTC
@@ -1890,7 +1890,7 @@


 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
-  ASSERT(expr->target()->IsValidLeftHandSide());
+  ASSERT(expr->target()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ Assignment");

@@ -2432,7 +2432,7 @@


 void FullCodeGenerator::EmitAssignment(Expression* expr) {
-  ASSERT(expr->IsValidLeftHandSide());
+  ASSERT(expr->IsValidReferenceExpression());

// Left-hand side can only be a property, a global or a (parameter or local)
   // slot.
@@ -4314,7 +4314,7 @@


 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
-  ASSERT(expr->expression()->IsValidLeftHandSide());
+  ASSERT(expr->expression()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
=======================================
--- /branches/3.25/src/arm64/full-codegen-arm64.cc Fri Apr 4 09:30:01 2014 UTC +++ /branches/3.25/src/arm64/full-codegen-arm64.cc Mon Apr 7 10:47:54 2014 UTC
@@ -1890,7 +1890,7 @@


 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
-  ASSERT(expr->target()->IsValidLeftHandSide());
+  ASSERT(expr->target()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ Assignment");

@@ -2131,7 +2131,7 @@


 void FullCodeGenerator::EmitAssignment(Expression* expr) {
-  ASSERT(expr->IsValidLeftHandSide());
+  ASSERT(expr->IsValidReferenceExpression());

// Left-hand side can only be a property, a global or a (parameter or local)
   // slot.
@@ -4025,7 +4025,7 @@


 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
-  ASSERT(expr->expression()->IsValidLeftHandSide());
+  ASSERT(expr->expression()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
=======================================
--- /branches/3.25/src/ast.cc   Tue Mar 25 13:44:35 2014 UTC
+++ /branches/3.25/src/ast.cc   Mon Apr  7 10:47:54 2014 UTC
@@ -56,23 +56,23 @@
 // Implementation of other node functionality.


-bool Expression::IsSmiLiteral() {
+bool Expression::IsSmiLiteral() const {
   return AsLiteral() != NULL && AsLiteral()->value()->IsSmi();
 }


-bool Expression::IsStringLiteral() {
+bool Expression::IsStringLiteral() const {
   return AsLiteral() != NULL && AsLiteral()->value()->IsString();
 }


-bool Expression::IsNullLiteral() {
+bool Expression::IsNullLiteral() const {
   return AsLiteral() != NULL && AsLiteral()->value()->IsNull();
 }


-bool Expression::IsUndefinedLiteral(Isolate* isolate) {
-  VariableProxy* var_proxy = AsVariableProxy();
+bool Expression::IsUndefinedLiteral(Isolate* isolate) const {
+  const VariableProxy* var_proxy = AsVariableProxy();
   if (var_proxy == NULL) return false;
   Variable* var = var_proxy->var();
   // The global identifier "undefined" is immutable. Everything
@@ -463,7 +463,7 @@
 }


-bool BinaryOperation::ResultOverwriteAllowed() {
+bool BinaryOperation::ResultOverwriteAllowed() const {
   switch (op_) {
     case Token::COMMA:
     case Token::OR:
=======================================
--- /branches/3.25/src/ast.h    Thu Mar 20 01:04:55 2014 UTC
+++ /branches/3.25/src/ast.h    Mon Apr  7 10:47:54 2014 UTC
@@ -215,9 +215,14 @@
   int position() const { return position_; }

   // Type testing & conversion functions overridden by concrete subclasses.
-#define DECLARE_NODE_FUNCTIONS(type)                  \
-  bool Is##type() { return node_type() == AstNode::k##type; }          \
- type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
+#define DECLARE_NODE_FUNCTIONS(type) \
+  bool Is##type() const { return node_type() == AstNode::k##type; } \
+  type* As##type() { \
+    return Is##type() ? reinterpret_cast<type*>(this) : NULL; \
+  } \
+  const type* As##type() const { \
+    return Is##type() ? reinterpret_cast<const type*>(this) : NULL; \
+  }
   AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
 #undef DECLARE_NODE_FUNCTIONS

@@ -325,35 +330,35 @@
     kTest
   };

-  virtual bool IsValidLeftHandSide() { return false; }
+  virtual bool IsValidReferenceExpression() const { return false; }

   // Helpers for ToBoolean conversion.
-  virtual bool ToBooleanIsTrue() { return false; }
-  virtual bool ToBooleanIsFalse() { return false; }
+  virtual bool ToBooleanIsTrue() const { return false; }
+  virtual bool ToBooleanIsFalse() const { return false; }

   // Symbols that cannot be parsed as array indices are considered property
   // names.  We do not treat symbols that can be array indexes as property
   // names because [] for string objects is handled only by keyed ICs.
-  virtual bool IsPropertyName() { return false; }
+  virtual bool IsPropertyName() const { return false; }

   // True iff the result can be safely overwritten (to avoid allocation).
   // False for operations that can return one of their operands.
-  virtual bool ResultOverwriteAllowed() { return false; }
+  virtual bool ResultOverwriteAllowed() const { return false; }

   // True iff the expression is a literal represented as a smi.
-  bool IsSmiLiteral();
+  bool IsSmiLiteral() const;

   // True iff the expression is a string literal.
-  bool IsStringLiteral();
+  bool IsStringLiteral() const;

   // True iff the expression is the null literal.
-  bool IsNullLiteral();
+  bool IsNullLiteral() const;

   // True if we can prove that the expression is the undefined literal.
-  bool IsUndefinedLiteral(Isolate* isolate);
+  bool IsUndefinedLiteral(Isolate* isolate) const;

   // Expression type bounds
-  Bounds bounds() { return bounds_; }
+  Bounds bounds() const { return bounds_; }
   void set_bounds(Bounds bounds) { bounds_ = bounds; }

   // Type feedback information for assignments and properties.
@@ -1346,7 +1351,7 @@
  public:
   DECLARE_NODE_TYPE(Literal)

-  virtual bool IsPropertyName() V8_OVERRIDE {
+  virtual bool IsPropertyName() const V8_OVERRIDE {
     if (value_->IsInternalizedString()) {
       uint32_t ignored;
       return !String::cast(*value_)->AsArrayIndex(&ignored);
@@ -1359,10 +1364,10 @@
     return Handle<String>::cast(value_);
   }

-  virtual bool ToBooleanIsTrue() V8_OVERRIDE {
+  virtual bool ToBooleanIsTrue() const V8_OVERRIDE {
     return value_->BooleanValue();
   }
-  virtual bool ToBooleanIsFalse() V8_OVERRIDE {
+  virtual bool ToBooleanIsFalse() const V8_OVERRIDE {
     return !value_->BooleanValue();
   }

@@ -1637,19 +1642,17 @@
  public:
   DECLARE_NODE_TYPE(VariableProxy)

-  virtual bool IsValidLeftHandSide() V8_OVERRIDE {
-    return var_ == NULL ? true : var_->IsValidLeftHandSide();
+  virtual bool IsValidReferenceExpression() const V8_OVERRIDE {
+    return var_ == NULL ? true : var_->IsValidReference();
   }

-  bool IsVariable(Handle<String> n) {
+  bool IsVariable(Handle<String> n) const {
     return !is_this() && name().is_identical_to(n);
   }

-  bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
+  bool IsArguments() const { return var_ != NULL && var_->is_arguments(); }

-  bool IsLValue() {
-    return is_lvalue_;
-  }
+  bool IsLValue() const { return is_lvalue_; }

   Handle<String> name() const { return name_; }
   Variable* var() const { return var_; }
@@ -1687,7 +1690,7 @@
  public:
   DECLARE_NODE_TYPE(Property)

-  virtual bool IsValidLeftHandSide() V8_OVERRIDE { return true; }
+ virtual bool IsValidReferenceExpression() const V8_OVERRIDE { return true; }

   Expression* obj() const { return obj_; }
   Expression* key() const { return key_; }
@@ -1970,7 +1973,7 @@
  public:
   DECLARE_NODE_TYPE(BinaryOperation)

-  virtual bool ResultOverwriteAllowed();
+  virtual bool ResultOverwriteAllowed() const V8_OVERRIDE;

   Token::Value op() const { return op_; }
   Expression* left() const { return left_; }
=======================================
--- /branches/3.25/src/heap.h   Thu Mar 27 01:04:43 2014 UTC
+++ /branches/3.25/src/heap.h   Mon Apr  7 10:47:54 2014 UTC
@@ -349,11 +349,7 @@
   V(MakeReferenceError_string, "MakeReferenceError")                     \
   V(MakeSyntaxError_string, "MakeSyntaxError")                           \
   V(MakeTypeError_string, "MakeTypeError")                               \
-  V(illegal_return_string, "illegal_return")                             \
-  V(illegal_break_string, "illegal_break")                               \
-  V(illegal_continue_string, "illegal_continue")                         \
   V(unknown_label_string, "unknown_label")                               \
-  V(redeclaration_string, "redeclaration")                               \
   V(space_string, " ")                                                   \
   V(exec_string, "exec")                                                 \
   V(zero_string, "0")                                                    \
=======================================
--- /branches/3.25/src/ia32/full-codegen-ia32.cc Fri Apr 4 09:30:01 2014 UTC +++ /branches/3.25/src/ia32/full-codegen-ia32.cc Mon Apr 7 10:47:54 2014 UTC
@@ -1851,7 +1851,7 @@


 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
-  ASSERT(expr->target()->IsValidLeftHandSide());
+  ASSERT(expr->target()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ Assignment");

@@ -2382,7 +2382,7 @@


 void FullCodeGenerator::EmitAssignment(Expression* expr) {
-  ASSERT(expr->IsValidLeftHandSide());
+  ASSERT(expr->IsValidReferenceExpression());

// Left-hand side can only be a property, a global or a (parameter or local)
   // slot.
@@ -4317,7 +4317,7 @@


 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
-  ASSERT(expr->expression()->IsValidLeftHandSide());
+  ASSERT(expr->expression()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
=======================================
--- /branches/3.25/src/mips/full-codegen-mips.cc Fri Apr 4 09:30:01 2014 UTC +++ /branches/3.25/src/mips/full-codegen-mips.cc Mon Apr 7 10:47:54 2014 UTC
@@ -1906,7 +1906,7 @@


 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
-  ASSERT(expr->target()->IsValidLeftHandSide());
+  ASSERT(expr->target()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ Assignment");

@@ -2446,7 +2446,7 @@


 void FullCodeGenerator::EmitAssignment(Expression* expr) {
-  ASSERT(expr->IsValidLeftHandSide());
+  ASSERT(expr->IsValidReferenceExpression());

// Left-hand side can only be a property, a global or a (parameter or local)
   // slot.
@@ -4362,7 +4362,7 @@


 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
-  ASSERT(expr->expression()->IsValidLeftHandSide());
+  ASSERT(expr->expression()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
=======================================
--- /branches/3.25/src/objects.cc       Tue Apr  1 18:39:50 2014 UTC
+++ /branches/3.25/src/objects.cc       Mon Apr  7 10:47:54 2014 UTC
@@ -11376,6 +11376,9 @@
   BeginPerformSplice(array);

   for (int i = 0; i < indices.length(); ++i) {
+    // For deletions where the property was an accessor, old_values[i]
+    // will be the hole, which instructs EnqueueChangeRecord to elide
+    // the "oldValue" property.
     JSObject::EnqueueChangeRecord(
         array, "delete", isolate->factory()->Uint32ToString(indices[i]),
         old_values[i]);
@@ -11392,6 +11395,9 @@
   Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
   if (delete_count > 0) {
     for (int i = indices.length() - 1; i >= 0; i--) {
+      // Skip deletions where the property was an accessor, leaving holes
+      // in the array of old values.
+      if (old_values[i]->IsTheHole()) continue;
JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE,
                            SLOPPY);
     }
=======================================
--- /branches/3.25/src/parser.cc        Thu Mar 27 01:04:43 2014 UTC
+++ /branches/3.25/src/parser.cc        Mon Apr  7 10:47:54 2014 UTC
@@ -418,10 +418,9 @@
 // Implementation of Parser

 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const {
-  return identifier.is_identical_to(
-             parser_->isolate()->factory()->eval_string()) ||
-         identifier.is_identical_to(
-             parser_->isolate()->factory()->arguments_string());
+  Factory* factory = parser_->isolate()->factory();
+  return identifier.is_identical_to(factory->eval_string())
+      || identifier.is_identical_to(factory->arguments_string());
 }


@@ -478,19 +477,6 @@
   if (proxy != NULL) proxy->MarkAsLValue();
   return expression;
 }
-
-
-void ParserTraits::CheckStrictModeLValue(Expression* expression,
-                                         bool* ok) {
-  VariableProxy* lhs = expression != NULL
-      ? expression->AsVariableProxy()
-      : NULL;
-  if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
-    parser_->ReportMessage("strict_eval_arguments",
-                           Vector<const char*>::empty());
-    *ok = false;
-  }
-}


 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
@@ -597,6 +583,62 @@
   }
   return factory->NewUnaryOperation(op, expression, pos);
 }
+
+
+Expression* ParserTraits::NewThrowReferenceError(
+    const char* message, int pos) {
+  return NewThrowError(
+      parser_->isolate()->factory()->MakeReferenceError_string(),
+      message, HandleVector<Object>(NULL, 0), pos);
+}
+
+
+Expression* ParserTraits::NewThrowSyntaxError(
+    const char* message, Handle<Object> arg, int pos) {
+  int argc = arg.is_null() ? 0 : 1;
+  Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc);
+  return NewThrowError(
+      parser_->isolate()->factory()->MakeSyntaxError_string(),
+      message, arguments, pos);
+}
+
+
+Expression* ParserTraits::NewThrowTypeError(
+ const char* message, Handle<Object> arg1, Handle<Object> arg2, int pos) {
+  ASSERT(!arg1.is_null() && !arg2.is_null());
+  Handle<Object> elements[] = { arg1, arg2 };
+  Vector< Handle<Object> > arguments =
+      HandleVector<Object>(elements, ARRAY_SIZE(elements));
+  return NewThrowError(
+      parser_->isolate()->factory()->MakeTypeError_string(),
+      message, arguments, pos);
+}
+
+
+Expression* ParserTraits::NewThrowError(
+    Handle<String> constructor, const char* message,
+    Vector<Handle<Object> > arguments, int pos) {
+  Zone* zone = parser_->zone();
+  Factory* factory = parser_->isolate()->factory();
+  int argc = arguments.length();
+  Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED);
+  for (int i = 0; i < argc; i++) {
+    Handle<Object> element = arguments[i];
+    if (!element.is_null()) {
+      elements->set(i, *element);
+    }
+  }
+  Handle<JSArray> array =
+      factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED);
+
+  ZoneList<Expression*>* args = new(zone) ZoneList<Expression*>(2, zone);
+  Handle<String> type = factory->InternalizeUtf8String(message);
+  args->Add(parser_->factory()->NewLiteral(type, pos), zone);
+  args->Add(parser_->factory()->NewLiteral(array, pos), zone);
+  CallRuntime* call_constructor =
+      parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
+  return parser_->factory()->NewThrow(call_constructor, pos);
+}


 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
@@ -675,7 +717,7 @@
     }
   }
   Handle<String> result =
-      parser_->scanner()->AllocateInternalizedString(parser_->isolate_);
+      parser_->scanner()->AllocateInternalizedString(parser_->isolate());
   ASSERT(!result.is_null());
   return result;
 }
@@ -1717,8 +1759,8 @@
           isolate()->factory()->InternalizeOneByteString(
               STATIC_ASCII_VECTOR("Variable"));
       Expression* expression =
-          NewThrowTypeError(isolate()->factory()->redeclaration_string(),
-                            message_string, name);
+          NewThrowTypeError("redeclaration",
+                            message_string, name, declaration->position());
       declaration_scope->SetIllegalRedeclaration(expression);
     }
   }
@@ -2506,9 +2548,8 @@
   Scope* declaration_scope = scope_->DeclarationScope();
   if (declaration_scope->is_global_scope() ||
       declaration_scope->is_eval_scope()) {
-    Handle<String> message = isolate()->factory()->illegal_return_string();
     Expression* throw_error =
-        NewThrowSyntaxError(message, Handle<Object>::null());
+        NewThrowSyntaxError("illegal_return", Handle<Object>::null(), pos);
     return factory()->NewExpressionStatement(throw_error, pos);
   }
   return result;
@@ -2987,11 +3028,9 @@
       bool accept_OF = expression->AsVariableProxy();

       if (CheckInOrOf(accept_OF, &mode)) {
-        if (expression == NULL || !expression->IsValidLeftHandSide()) {
-          ReportMessageAt(lhs_location, "invalid_lhs_in_for", true);
-          *ok = false;
-          return NULL;
-        }
+        expression = this->CheckAndRewriteReferenceExpression(
+            expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
+
         ForEachStatement* loop =
             factory()->NewForEachStatement(mode, labels, pos);
         Target target(&this->target_stack_, loop);
@@ -3693,58 +3732,6 @@
     if (collector != NULL) collector->AddTarget(target, zone());
   }
 }
-
-
-Expression* Parser::NewThrowReferenceError(Handle<String> message) {
-  return NewThrowError(isolate()->factory()->MakeReferenceError_string(),
-                       message, HandleVector<Object>(NULL, 0));
-}
-
-
-Expression* Parser::NewThrowSyntaxError(Handle<String> message,
-                                        Handle<Object> first) {
-  int argc = first.is_null() ? 0 : 1;
-  Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
-  return NewThrowError(
-      isolate()->factory()->MakeSyntaxError_string(), message, arguments);
-}
-
-
-Expression* Parser::NewThrowTypeError(Handle<String> message,
-                                      Handle<Object> first,
-                                      Handle<Object> second) {
-  ASSERT(!first.is_null() && !second.is_null());
-  Handle<Object> elements[] = { first, second };
-  Vector< Handle<Object> > arguments =
-      HandleVector<Object>(elements, ARRAY_SIZE(elements));
-  return NewThrowError(
-      isolate()->factory()->MakeTypeError_string(), message, arguments);
-}
-
-
-Expression* Parser::NewThrowError(Handle<String> constructor,
-                                  Handle<String> message,
-                                  Vector< Handle<Object> > arguments) {
-  int argc = arguments.length();
-  Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
- TENURED);
-  for (int i = 0; i < argc; i++) {
-    Handle<Object> element = arguments[i];
-    if (!element.is_null()) {
-      elements->set(i, *element);
-    }
-  }
-  Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(
-      elements, FAST_ELEMENTS, TENURED);
-
-  int pos = position();
- ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone());
-  args->Add(factory()->NewLiteral(message, pos), zone());
-  args->Add(factory()->NewLiteral(array, pos), zone());
-  CallRuntime* call_constructor =
-      factory()->NewCallRuntime(constructor, NULL, args, pos);
-  return factory()->NewThrow(call_constructor, pos);
-}


// ----------------------------------------------------------------------------
=======================================
--- /branches/3.25/src/parser.h Mon Mar 24 08:11:09 2014 UTC
+++ /branches/3.25/src/parser.h Mon Apr  7 10:47:54 2014 UTC
@@ -462,6 +462,11 @@

   static bool IsIdentifier(Expression* expression);

+  static Handle<String> AsIdentifier(Expression* expression) {
+    ASSERT(IsIdentifier(expression));
+    return expression->AsVariableProxy()->name();
+  }
+
   static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
     return ObjectLiteral::IsBoilerplateProperty(property);
   }
@@ -501,10 +506,6 @@
// used on for the statically checking assignments to harmony const bindings.
   static Expression* MarkExpressionAsLValue(Expression* expression);

- // Checks LHS expression for assignment and prefix/postfix increment/decrement
-  // in strict mode.
-  void CheckStrictModeLValue(Expression* expression, bool* ok);
-
   // Returns true if we have a binary expression between two numeric
// literals. In that case, *x will be changed to an expression which is the
   // computed value.
@@ -527,6 +528,25 @@
       Expression* expression, Token::Value op, int pos,
       AstNodeFactory<AstConstructionVisitor>* factory);

+  // Generate AST node that throws a ReferenceError with the given type.
+  Expression* NewThrowReferenceError(const char* type, int pos);
+
+  // Generate AST node that throws a SyntaxError with the given
+  // type. The first argument may be null (in the handle sense) in
+  // which case no arguments are passed to the constructor.
+  Expression* NewThrowSyntaxError(
+      const char* type, Handle<Object> arg, int pos);
+
+  // Generate AST node that throws a TypeError with the given
+  // type. Both arguments must be non-null (in the handle sense).
+  Expression* NewThrowTypeError(
+      const char* type, Handle<Object> arg1, Handle<Object> arg2, int pos);
+
+  // Generic AST generator for throwing errors from compiled code.
+  Expression* NewThrowError(
+      Handle<String> constructor, const char* type,
+      Vector<Handle<Object> > arguments, int pos);
+
   // Reporting errors.
   void ReportMessageAt(Scanner::Location source_location,
                        const char* message,
@@ -778,25 +798,6 @@

   Handle<String> LookupCachedSymbol(int symbol_id);

-  // Generate AST node that throw a ReferenceError with the given type.
-  Expression* NewThrowReferenceError(Handle<String> type);
-
-  // Generate AST node that throw a SyntaxError with the given
-  // type. The first argument may be null (in the handle sense) in
-  // which case no arguments are passed to the constructor.
- Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
-
-  // Generate AST node that throw a TypeError with the given
-  // type. Both arguments must be non-null (in the handle sense).
-  Expression* NewThrowTypeError(Handle<String> type,
-                                Handle<Object> first,
-                                Handle<Object> second);
-
-  // Generic AST generator for throwing errors from compiled code.
-  Expression* NewThrowError(Handle<String> constructor,
-                            Handle<String> type,
-                            Vector< Handle<Object> > arguments);
-
   PreParser::PreParseResult LazyParseFunctionLiteral(
        SingletonLogger* logger);

=======================================
--- /branches/3.25/src/preparser.cc     Tue Mar 25 07:30:47 2014 UTC
+++ /branches/3.25/src/preparser.cc     Mon Apr  7 10:47:54 2014 UTC
@@ -54,17 +54,6 @@

 namespace v8 {
 namespace internal {
-
-
-void PreParserTraits::CheckStrictModeLValue(PreParserExpression expression,
-                                            bool* ok) {
-  if (expression.IsIdentifier() &&
-      expression.AsIdentifier().IsEvalOrArguments()) {
-    pre_parser_->ReportMessage("strict_eval_arguments",
-                               Vector<const char*>::empty());
-    *ok = false;
-  }
-}


 void PreParserTraits::ReportMessageAt(Scanner::Location location,
=======================================
--- /branches/3.25/src/preparser.h      Tue Mar 25 07:30:47 2014 UTC
+++ /branches/3.25/src/preparser.h      Mon Apr  7 10:47:54 2014 UTC
@@ -425,6 +425,13 @@
   ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
                                                 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, + // we allow calls for web compatibility and rewrite them to a runtime throw.
+  ExpressionT CheckAndRewriteReferenceExpression(
+      ExpressionT expression,
+      Scanner::Location location, const char* message, bool* ok);
+
   // Used to detect duplicates in object literals. Each of the values
   // kGetterProperty, kSetterProperty and kValueProperty represents
   // a type of object literal property. When parsing a property, its
@@ -588,11 +595,15 @@
   static PreParserExpression Property() {
     return PreParserExpression(kPropertyExpression);
   }
+
+  static PreParserExpression Call() {
+    return PreParserExpression(kCallExpression);
+  }

   bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; }

-  // Only works corretly if it is actually an identifier expression.
   PreParserIdentifier AsIdentifier() {
+    ASSERT(IsIdentifier());
     return PreParserIdentifier(
         static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
   }
@@ -611,13 +622,14 @@
return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
   }

-  bool IsValidLeftHandSide() {
+  bool IsCall() { return code_ == kCallExpression; }
+
+  bool IsValidReferenceExpression() {
     return IsIdentifier() || IsProperty();
   }

   // At the moment PreParser doesn't track these expression types.
   bool IsFunctionLiteral() const { return false; }
-  bool IsCall() const { return false; }
   bool IsCallNew() const { return false; }

   PreParserExpression AsFunctionLiteral() { return *this; }
@@ -651,7 +663,8 @@
     // 2 least significant bits for flags.
     kThisExpression = 1 << 2,
     kThisPropertyExpression = 2 << 2,
-    kPropertyExpression = 3 << 2
+    kPropertyExpression = 3 << 2,
+    kCallExpression = 4 << 2
   };

explicit PreParserExpression(int expression_code) : code_(expression_code) {}
@@ -782,7 +795,7 @@
   PreParserExpression NewCall(PreParserExpression expression,
                               PreParserExpressionList arguments,
                               int pos) {
-    return PreParserExpression::Default();
+    return PreParserExpression::Call();
   }
   PreParserExpression NewCallNew(PreParserExpression expression,
                                  PreParserExpressionList arguments,
@@ -844,6 +857,10 @@
   static bool IsIdentifier(PreParserExpression expression) {
     return expression.IsIdentifier();
   }
+
+  static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
+    return expression.AsIdentifier();
+  }

   static bool IsBoilerplateProperty(PreParserExpression property) {
     // PreParser doesn't count boilerplate properties.
@@ -882,10 +899,6 @@
// to start tracking which expressions are variables and which are lvalues.
     return expression;
   }
-
- // Checks LHS expression for assignment and prefix/postfix increment/decrement
-  // in strict mode.
-  void CheckStrictModeLValue(PreParserExpression expression, bool* ok);

   bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
                                               PreParserExpression y,
@@ -900,6 +913,18 @@
                                            PreParserFactory* factory) {
     return PreParserExpression::Default();
   }
+
+  PreParserExpression NewThrowReferenceError(const char* type, int pos) {
+    return PreParserExpression::Default();
+  }
+  PreParserExpression NewThrowSyntaxError(
+      const char* type, Handle<Object> arg, int pos) {
+    return PreParserExpression::Default();
+  }
+  PreParserExpression NewThrowTypeError(
+ const char* type, Handle<Object> arg1, Handle<Object> arg2, int pos) {
+    return PreParserExpression::Default();
+  }

   // Reporting errors.
   void ReportMessageAt(Scanner::Location location,
@@ -1695,16 +1720,8 @@
     return expression;
   }

-  if (!expression->IsValidLeftHandSide()) {
-    this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true);
-    *ok = false;
-    return this->EmptyExpression();
-  }
-
-  if (strict_mode() == STRICT) {
-    // Assignment to eval or arguments is disallowed in strict mode.
-    this->CheckStrictModeLValue(expression, CHECK_OK);
-  }
+  expression = this->CheckAndRewriteReferenceExpression(
+      expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
   expression = this->MarkExpressionAsLValue(expression);

   Token::Value op = Next();  // Get assignment operator.
@@ -1864,17 +1881,9 @@
   } else if (Token::IsCountOp(op)) {
     op = Next();
     Scanner::Location lhs_location = scanner()->peek_location();
-    ExpressionT expression = ParseUnaryExpression(CHECK_OK);
-    if (!expression->IsValidLeftHandSide()) {
-      ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true);
-      *ok = false;
-      return this->EmptyExpression();
-    }
-
-    if (strict_mode() == STRICT) {
- // Prefix expression operand in strict mode may not be eval or arguments.
-      this->CheckStrictModeLValue(expression, CHECK_OK);
-    }
+    ExpressionT expression = this->ParseUnaryExpression(CHECK_OK);
+    expression = this->CheckAndRewriteReferenceExpression(
+        expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
     this->MarkExpressionAsLValue(expression);

     return factory()->NewCountOperation(op,
@@ -1898,16 +1907,8 @@
   ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK);
   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
       Token::IsCountOp(peek())) {
-    if (!expression->IsValidLeftHandSide()) {
-      ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true);
-      *ok = false;
-      return this->EmptyExpression();
-    }
-
-    if (strict_mode() == STRICT) {
- // Postfix expression operand in strict mode may not be eval or arguments.
-      this->CheckStrictModeLValue(expression, CHECK_OK);
-    }
+    expression = this->CheckAndRewriteReferenceExpression(
+        expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK);
     expression = this->MarkExpressionAsLValue(expression);

     Token::Value next = Next();
@@ -2115,6 +2116,32 @@
   ASSERT(false);
   return this->EmptyExpression();
 }
+
+
+template <typename Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::CheckAndRewriteReferenceExpression(
+    ExpressionT expression,
+    Scanner::Location location, const char* message, bool* ok) {
+  if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
+      this->IsEvalOrArguments(this->AsIdentifier(expression))) {
+    this->ReportMessageAt(location, "strict_eval_arguments", false);
+    *ok = false;
+    return this->EmptyExpression();
+  } else if (expression->IsValidReferenceExpression()) {
+    return expression;
+  } else if (expression->IsCall()) {
+ // If it is a call, make it a runtime error for legacy web compatibility.
+    // Rewrite `expr' to `expr[throw ReferenceError]'.
+    int pos = location.beg_pos;
+    ExpressionT error = this->NewThrowReferenceError(message, pos);
+    return factory()->NewProperty(expression, error, pos);
+  } else {
+    this->ReportMessageAt(location, message, true);
+    *ok = false;
+    return this->EmptyExpression();
+  }
+}


 #undef CHECK_OK
=======================================
--- /branches/3.25/src/types.cc Tue Mar 18 13:03:00 2014 UTC
+++ /branches/3.25/src/types.cc Mon Apr  7 10:47:54 2014 UTC
@@ -424,10 +424,8 @@
   }

   // Fast case: top or bottom types.
-  if (type1->IsAny()) return type1;
-  if (type2->IsAny()) return type2;
-  if (type1->IsNone()) return type2;
-  if (type2->IsNone()) return type1;
+  if (type1->IsAny() || type2->IsNone()) return type1;
+  if (type2->IsAny() || type1->IsNone()) return type2;

   // Semi-fast case: Unioned objects are neither involved nor produced.
   if (!(type1->IsUnion() || type2->IsUnion())) {
@@ -436,19 +434,20 @@
   }

   // Slow case: may need to produce a Unioned object.
-  int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0;
+  int size = 0;
   if (!type1->IsBitset()) {
size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
   }
   if (!type2->IsBitset()) {
size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
   }
-  ASSERT(size >= 2);
+  int bitset = type1->GlbBitset() | type2->GlbBitset();
+  if (IsInhabited(bitset)) ++size;
+  ASSERT(size >= 1);
   UnionedHandle unioned = Config::union_create(size, region);
+
   size = 0;
-
-  int bitset = type1->GlbBitset() | type2->GlbBitset();
-  if (bitset != kNone) {
+  if (IsInhabited(bitset)) {
Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
   }
   size = ExtendUnion(unioned, type1, size);
@@ -500,10 +499,8 @@
   }

   // Fast case: top or bottom types.
-  if (type1->IsNone()) return type1;
-  if (type2->IsNone()) return type2;
-  if (type1->IsAny()) return type2;
-  if (type2->IsAny()) return type1;
+  if (type1->IsNone() || type2->IsAny()) return type1;
+  if (type2->IsNone() || type1->IsAny()) return type2;

   // Semi-fast case: Unioned objects are neither involved nor produced.
   if (!(type1->IsUnion() || type2->IsUnion())) {
@@ -512,20 +509,21 @@
   }

   // Slow case: may need to produce a Unioned object.
-  int size = 0;
+  int size = INT_MAX;
   if (!type1->IsBitset()) {
-    size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 2);
+    size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
   }
   if (!type2->IsBitset()) {
- int size2 = (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 2);
-    size = (size == 0 ? size2 : Min(size, size2));
+    size = Min(size,
+ type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
   }
-  ASSERT(size >= 2);
+  int bitset = type1->GlbBitset() & type2->GlbBitset();
+  if (IsInhabited(bitset)) ++size;
+  ASSERT(size >= 1);
   UnionedHandle unioned = Config::union_create(size, region);
+
   size = 0;
-
-  int bitset = type1->GlbBitset() & type2->GlbBitset();
-  if (bitset != kNone) {
+  if (IsInhabited(bitset)) {
Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
   }
   size = ExtendIntersection(unioned, type1, type2, size);
@@ -645,7 +643,7 @@
     switch (dim) {
       case BOTH_DIMS:
         BitsetTypePrint(out, bitset & kSemantic);
-        PrintF("/");
+        PrintF(out, "/");
         BitsetTypePrint(out, bitset & kRepresentation);
         break;
       case SEMANTIC_DIM:
@@ -658,18 +656,18 @@
   } else if (this->IsConstant()) {
     PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant()));
     Config::from_bitset(this->LubBitset())->TypePrint(out);
-    PrintF(")");
+    PrintF(out, ")");
   } else if (this->IsClass()) {
     PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()));
     Config::from_bitset(this->LubBitset())->TypePrint(out);
-    PrintF(")");
+    PrintF(out, ")");
   } else if (this->IsUnion()) {
     PrintF(out, "(");
     UnionedHandle unioned = this->AsUnion();
     for (int i = 0; i < Config::union_length(unioned); ++i) {
       TypeHandle type_i = Config::union_get(unioned, i);
       if (i > 0) PrintF(out, " | ");
-      type_i->TypePrint(out);
+      type_i->TypePrint(out, dim);
     }
     PrintF(out, ")");
   }
=======================================
--- /branches/3.25/src/variables.cc     Wed Mar 12 13:09:18 2014 UTC
+++ /branches/3.25/src/variables.cc     Mon Apr  7 10:47:54 2014 UTC
@@ -58,7 +58,7 @@
 Variable::Variable(Scope* scope,
                    Handle<String> name,
                    VariableMode mode,
-                   bool is_valid_LHS,
+                   bool is_valid_ref,
                    Kind kind,
                    InitializationFlag initialization_flag,
                    Interface* interface)
@@ -70,7 +70,7 @@
     index_(-1),
     initializer_position_(RelocInfo::kNoPosition),
     local_if_not_shadowed_(NULL),
-    is_valid_LHS_(is_valid_LHS),
+    is_valid_ref_(is_valid_ref),
     force_context_allocation_(false),
     is_used_(false),
     initialization_flag_(initialization_flag),
=======================================
--- /branches/3.25/src/variables.h      Wed Mar 12 13:09:18 2014 UTC
+++ /branches/3.25/src/variables.h      Mon Apr  7 10:47:54 2014 UTC
@@ -77,7 +77,7 @@
   Variable(Scope* scope,
            Handle<String> name,
            VariableMode mode,
-           bool is_valid_lhs,
+           bool is_valid_ref,
            Kind kind,
            InitializationFlag initialization_flag,
            Interface* interface = Interface::NewValue());
@@ -85,7 +85,7 @@
   // Printing support
   static const char* Mode2String(VariableMode mode);

-  bool IsValidLeftHandSide() { return is_valid_LHS_; }
+  bool IsValidReference() { return is_valid_ref_; }

   // The source code for an eval() call may refer to a variable that is
   // in an outer scope about which we don't know anything (it may not
@@ -172,8 +172,8 @@
   // binding scope (exclusive).
   Variable* local_if_not_shadowed_;

-  // Valid as a LHS? (const and this are not valid LHS, for example)
-  bool is_valid_LHS_;
+  // Valid as a reference? (const and this are not valid, for example)
+  bool is_valid_ref_;

   // Usage info.
   bool force_context_allocation_;  // set by variable resolver
=======================================
--- /branches/3.25/src/version.cc       Fri Apr  4 09:30:01 2014 UTC
+++ /branches/3.25/src/version.cc       Mon Apr  7 10:47:54 2014 UTC
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     25
 #define BUILD_NUMBER      28
-#define PATCH_LEVEL       5
+#define PATCH_LEVEL       6
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.25/src/x64/full-codegen-x64.cc  Fri Apr  4 09:30:01 2014 UTC
+++ /branches/3.25/src/x64/full-codegen-x64.cc  Mon Apr  7 10:47:54 2014 UTC
@@ -1879,7 +1879,7 @@


 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
-  ASSERT(expr->target()->IsValidLeftHandSide());
+  ASSERT(expr->target()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ Assignment");

@@ -2378,7 +2378,7 @@


 void FullCodeGenerator::EmitAssignment(Expression* expr) {
-  ASSERT(expr->IsValidLeftHandSide());
+  ASSERT(expr->IsValidReferenceExpression());

// Left-hand side can only be a property, a global or a (parameter or local)
   // slot.
@@ -4317,7 +4317,7 @@


 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
-  ASSERT(expr->expression()->IsValidLeftHandSide());
+  ASSERT(expr->expression()->IsValidReferenceExpression());

   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
=======================================
--- /branches/3.25/test/cctest/test-parsing.cc  Tue Mar 25 07:30:47 2014 UTC
+++ /branches/3.25/test/cctest/test-parsing.cc  Mon Apr  7 10:47:54 2014 UTC
@@ -2557,13 +2557,22 @@
     "this[foo]",
     "new foo()[bar]",
     "new foo().bar",
+    "foo()",
+    "foo(bar)",
+    "foo[bar]()",
+    "foo.bar()",
+    "this()",
+    "this.foo()",
+    "this[foo].bar()",
+    "this.foo[foo].bar(this)(bar)[foo]()",
     NULL
   };

   // Bad left hand sides for assigment or prefix / postfix operations.
   const char* bad_statement_data_common[] = {
     "2",
-    "foo()",
+    "new foo",
+    "new foo()",
     "null",
     "if",  // Unexpected token
     "{x: 1}",  // Unexpected token
=======================================
--- /branches/3.25/test/mjsunit/invalid-lhs.js  Tue Mar 18 01:05:18 2014 UTC
+++ /branches/3.25/test/mjsunit/invalid-lhs.js  Mon Apr  7 10:47:54 2014 UTC
@@ -32,27 +32,34 @@
 assertThrows("12 = 12", ReferenceError);
 assertThrows("x++ = 12", ReferenceError);
 assertThrows("eval('var x') = 12", ReferenceError);
-assertThrows("if (false) eval('var x') = 12", ReferenceError);
+assertThrows("if (false) 12 = 12", ReferenceError);
+assertDoesNotThrow("if (false) eval('var x') = 12", ReferenceError);

 // Pre- and post-fix operations:
 assertThrows("12++", ReferenceError);
 assertThrows("12--", ReferenceError);
+assertThrows("++12", ReferenceError);
 assertThrows("--12", ReferenceError);
-assertThrows("++12", ReferenceError);
 assertThrows("++(eval('12'))", ReferenceError);
 assertThrows("(eval('12'))++", ReferenceError);
-assertThrows("if (false) ++(eval('12'))", ReferenceError);
-assertThrows("if (false) (eval('12'))++", ReferenceError);
+assertThrows("if (false) 12++", ReferenceError);
+assertThrows("if (false) 12--", ReferenceError);
+assertThrows("if (false) ++12", ReferenceError);
+assertThrows("if (false) --12", ReferenceError);
+assertDoesNotThrow("if (false) ++(eval('12'))", ReferenceError);
+assertDoesNotThrow("if (false) (eval('12'))++", ReferenceError);

 // For in:
 assertThrows("for (12 in [1]) print(12);", ReferenceError);
 assertThrows("for (eval('var x') in [1]) print(12);", ReferenceError);
-assertThrows("if (false) for (eval('0') in [1]) print(12);", ReferenceError);
+assertThrows("if (false) for (12 in [1]) print(12);", ReferenceError);
+assertDoesNotThrow("if (false) for (eval('0') in [1]) print(12);", ReferenceError);

 // For:
 assertThrows("for (12 = 1;;) print(12);", ReferenceError);
 assertThrows("for (eval('var x') = 1;;) print(12);", ReferenceError);
-assertThrows("if (false) for (eval('var x') = 1;;) print(12);", ReferenceError);
+assertThrows("if (false) for (12 = 1;;) print(12);", ReferenceError);
+assertDoesNotThrow("if (false) for (eval('var x') = 1;;) print(12);", ReferenceError);

 // Assignments to 'this'.
 assertThrows("this = 42", ReferenceError);
@@ -63,3 +70,5 @@
 assertThrows("++this", ReferenceError);
 assertThrows("this--", ReferenceError);
 assertThrows("--this", ReferenceError);
+assertThrows("if (false) this = 42", ReferenceError);
+assertThrows("if (false) this++", ReferenceError);
=======================================
--- /branches/3.25/test/webkit/fast/js/modify-non-references-expected.txt Tue Mar 18 01:05:18 2014 UTC +++ /branches/3.25/test/webkit/fast/js/modify-non-references-expected.txt Mon Apr 7 10:47:54 2014 UTC
@@ -21,18 +21,18 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-FAIL function f() { g()++; } f.toString() should be function f() { g()++; }. Threw exception ReferenceError: Invalid left-hand side expression in postfix operation -FAIL function f() { g()--; } f.toString() should be function f() { g()--; }. Threw exception ReferenceError: Invalid left-hand side expression in postfix operation -FAIL function f() { ++g(); } f.toString() should be function f() { ++g(); }. Threw exception ReferenceError: Invalid left-hand side expression in prefix operation -FAIL function f() { --g(); } f.toString() should be function f() { --g(); }. Threw exception ReferenceError: Invalid left-hand side expression in prefix operation -FAIL function f() { g() = 1; } f.toString() should be function f() { g() = 1; }. Threw exception ReferenceError: Invalid left-hand side in assignment -FAIL function f() { g() += 1; } f.toString() should be function f() { g() += 1; }. Threw exception ReferenceError: Invalid left-hand side in assignment -FAIL g()++ should throw ReferenceError: Postfix ++ operator applied to value that is not a reference.. Threw exception ReferenceError: Invalid left-hand side expression in postfix operation. -FAIL g()-- should throw ReferenceError: Postfix -- operator applied to value that is not a reference.. Threw exception ReferenceError: Invalid left-hand side expression in postfix operation. -FAIL ++g() should throw ReferenceError: Prefix ++ operator applied to value that is not a reference.. Threw exception ReferenceError: Invalid left-hand side expression in prefix operation. -FAIL --g() should throw ReferenceError: Prefix -- operator applied to value that is not a reference.. Threw exception ReferenceError: Invalid left-hand side expression in prefix operation. -FAIL g() = 1 should throw ReferenceError: Left side of assignment is not a reference.. Threw exception ReferenceError: Invalid left-hand side in assignment. -FAIL g() += 1 should throw ReferenceError: Left side of assignment is not a reference.. Threw exception ReferenceError: Invalid left-hand side in assignment.
+PASS function f() { g()++; } f.toString() is 'function f() { g()++; }'
+PASS function f() { g()--; } f.toString() is 'function f() { g()--; }'
+PASS function f() { ++g(); } f.toString() is 'function f() { ++g(); }'
+PASS function f() { --g(); } f.toString() is 'function f() { --g(); }'
+PASS function f() { g() = 1; } f.toString() is 'function f() { g() = 1; }'
+PASS function f() { g() += 1; } f.toString() is 'function f() { g() += 1; }' +PASS Number()++ threw exception ReferenceError: Invalid left-hand side expression in postfix operation. +PASS Number()-- threw exception ReferenceError: Invalid left-hand side expression in postfix operation. +PASS ++Number() threw exception ReferenceError: Invalid left-hand side expression in prefix operation. +PASS --Number() threw exception ReferenceError: Invalid left-hand side expression in prefix operation. +PASS Number() = 1 threw exception ReferenceError: Invalid left-hand side in assignment. +PASS Number() += 1 threw exception ReferenceError: Invalid left-hand side in assignment.
 PASS successfullyParsed is true

 TEST COMPLETE
=======================================
--- /branches/3.25/test/webkit/fast/js/modify-non-references.js Fri Jul 26 10:27:09 2013 UTC +++ /branches/3.25/test/webkit/fast/js/modify-non-references.js Mon Apr 7 10:47:54 2014 UTC
@@ -27,9 +27,9 @@
shouldBe("function f() { --g(); } f.toString()", "'function f() { --g(); }'"); shouldBe("function f() { g() = 1; } f.toString()", "'function f() { g() = 1; }'"); shouldBe("function f() { g() += 1; } f.toString()", "'function f() { g() += 1; }'"); -shouldThrow("g()++", "'ReferenceError: Postfix ++ operator applied to value that is not a reference.'"); -shouldThrow("g()--", "'ReferenceError: Postfix -- operator applied to value that is not a reference.'"); -shouldThrow("++g()", "'ReferenceError: Prefix ++ operator applied to value that is not a reference.'"); -shouldThrow("--g()", "'ReferenceError: Prefix -- operator applied to value that is not a reference.'"); -shouldThrow("g() = 1", "'ReferenceError: Left side of assignment is not a reference.'"); -shouldThrow("g() += 1", "'ReferenceError: Left side of assignment is not a reference.'"); +shouldThrow("Number()++", "'ReferenceError: Invalid left-hand side expression in postfix operation'"); +shouldThrow("Number()--", "'ReferenceError: Invalid left-hand side expression in postfix operation'"); +shouldThrow("++Number()", "'ReferenceError: Invalid left-hand side expression in prefix operation'"); +shouldThrow("--Number()", "'ReferenceError: Invalid left-hand side expression in prefix operation'"); +shouldThrow("Number() = 1", "'ReferenceError: Invalid left-hand side in assignment'"); +shouldThrow("Number() += 1", "'ReferenceError: Invalid left-hand side in assignment'");

--
--
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