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.