}
-ObjectLiteralProperty::ObjectLiteralProperty(Zone* zone,
- AstValueFactory* ast_value_factory,
+ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value,
+ Kind kind, bool is_static,
+ bool is_computed_name)
+ : key_(key),
+ value_(value),
+ kind_(kind),
+ emit_store_(true),
+ is_static_(is_static),
+ is_computed_name_(is_computed_name) {}
+
+
+ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory,
Expression* key, Expression* value,
bool is_static,
bool is_computed_name)
}
-ObjectLiteralProperty::ObjectLiteralProperty(Zone* zone, bool is_getter,
- Expression* key,
- FunctionLiteral* value,
- bool is_static,
- bool is_computed_name)
- : key_(key),
- value_(value),
- kind_(is_getter ? GETTER : SETTER),
- emit_store_(true),
- is_static_(is_static),
- is_computed_name_(is_computed_name) {}
-
-
bool ObjectLiteral::Property::IsCompileTimeValue() {
return kind_ == CONSTANT ||
(kind_ == MATERIALIZED_LITERAL &&
ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity,
allocator);
+ bool seen_prototype = false;
for (int i = properties()->length() - 1; i >= 0; i--) {
ObjectLiteral::Property* property = properties()->at(i);
if (property->is_computed_name()) continue;
property->kind() == ObjectLiteral::Property::COMPUTED) &&
table.Lookup(literal, hash, false, allocator) != NULL) {
property->set_emit_store(false);
+ } else if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
+ // Only emit a store for the last prototype property. Make sure we do not
+ // clobber the "__proto__" name for instance properties (using method or
+ // literal shorthand syntax).
+ property->set_emit_store(!seen_prototype);
+ seen_prototype = true;
} else {
// Add key to the table.
table.Lookup(literal, hash, true, allocator);
protected:
friend class AstNodeFactory;
- ObjectLiteralProperty(Zone* zone, AstValueFactory* ast_value_factory,
- Expression* key, Expression* value, bool is_static,
- bool is_computed_name);
-
- ObjectLiteralProperty(Zone* zone, bool is_getter, Expression* key,
- FunctionLiteral* value, bool is_static,
+ ObjectLiteralProperty(Expression* key, Expression* value, Kind kind,
+ bool is_static, bool is_computed_name);
+ ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key,
+ Expression* value, bool is_static,
bool is_computed_name);
private:
boilerplate_properties, has_function, pos);
}
+ ObjectLiteral::Property* NewObjectLiteralProperty(
+ Expression* key, Expression* value, ObjectLiteralProperty::Kind kind,
+ bool is_static, bool is_computed_name) {
+ return new (zone_)
+ ObjectLiteral::Property(key, value, kind, is_static, is_computed_name);
+ }
+
ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key,
Expression* value,
bool is_static,
bool is_computed_name) {
- return new (zone_) ObjectLiteral::Property(
- zone_, ast_value_factory_, key, value, is_static, is_computed_name);
- }
-
- ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
- Expression* key,
- FunctionLiteral* value,
- int pos, bool is_static,
- bool is_computed_name) {
- return new (zone_) ObjectLiteral::Property(zone_, is_getter, key, value,
+ return new (zone_) ObjectLiteral::Property(ast_value_factory_, key, value,
is_static, is_computed_name);
}
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+ case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE();
- case ObjectLiteral::Property::COMPUTED:
- case ObjectLiteral::Property::PROTOTYPE: {
+ case ObjectLiteral::Property::COMPUTED: {
const Operator* op =
javascript()->CallRuntime(Runtime::kDefineClassMethod, 3);
NewNode(op, receiver, key, value);
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
case ObjectLiteral::Property::MATERIALIZED_LITERAL:
- case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::PROTOTYPE:
+ UNREACHABLE();
+ case ObjectLiteral::Property::COMPUTED:
__ CallRuntime(Runtime::kDefineClassMethod, 3);
break;
case ObjectLiteral::Property::SETTER:
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3);
break;
-
- default:
- UNREACHABLE();
}
}
int pos) {
return PreParserExpression::Default();
}
- PreParserExpression NewObjectLiteralProperty(bool is_getter,
- PreParserExpression key,
+ PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
PreParserExpression value,
- int pos, bool is_static,
+ ObjectLiteralProperty::Kind kind,
+ bool is_static,
bool is_computed_name) {
return PreParserExpression::Default();
}
FunctionLiteral::NORMAL_ARITY,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ return factory()->NewObjectLiteralProperty(name_expression, value,
+ ObjectLiteralProperty::COMPUTED,
+ is_static, *is_computed_name);
+
} else if (in_class && name_is_static && !is_static) {
// static MethodDefinition
return ParsePropertyDefinition(checker, true, true, is_computed_name, NULL,
}
return factory()->NewObjectLiteralProperty(
- is_get, name_expression, value, next_pos, is_static, *is_computed_name);
+ name_expression, value,
+ is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
+ is_static, *is_computed_name);
} else if (!in_class && allow_harmony_object_literals_ &&
Token::IsIdentifier(name_token, strict_mode(),
this->is_generator())) {
+ DCHECK(!*is_computed_name);
+ DCHECK(!is_static);
value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory());
+ return factory()->NewObjectLiteralProperty(
+ name_expression, value, ObjectLiteralProperty::COMPUTED, false, false);
} else {
Token::Value next = Next();
};
assertEquals('*method() { yield 1; }', object.method.toString());
})();
+
+
+(function TestProtoName() {
+ var object = {
+ __proto__() {
+ return 1;
+ }
+ };
+ assertEquals(Object.prototype, Object.getPrototypeOf(object));
+ assertEquals(1, object.__proto__());
+})();
+
+
+(function TestProtoName2() {
+ var p = {};
+ var object = {
+ __proto__() {
+ return 1;
+ },
+ __proto__: p
+ };
+ assertEquals(p, Object.getPrototypeOf(object));
+ assertEquals(1, object.__proto__());
+})();
function f(x) { return {x}; }
assertEquals('function f(x) { return {x}; }', f.toString());
})();
+
+
+(function TestProtoName() {
+ var __proto__ = 1;
+ var object = {
+ __proto__
+ };
+ assertEquals(Object.prototype, Object.getPrototypeOf(object));
+ assertEquals(1, object.__proto__);
+})();
+
+
+(function TestProtoName2() {
+ var __proto__ = 1;
+ var p = {};
+ var object = {
+ __proto__: p,
+ __proto__,
+ };
+ assertEquals(p, Object.getPrototypeOf(object));
+ assertEquals(1, object.__proto__);
+})();
--- /dev/null
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var p1 = {};
+var p2 = {};
+var p3 = {};
+var x = 0;
+var y = 0;
+var z = 0;
+var o = {
+ __proto__: (x++, p1),
+ __proto__: (y++, p2),
+ __proto__: (z++, p3)
+};
+assertEquals(1, x);
+assertEquals(1, y);
+assertEquals(1, z);
+assertEquals(Object.getPrototypeOf(o), p3);