expr->CalculateEmitStore(zone());
AccessorTable accessor_table(zone());
- int property_index = 0;
- for (; property_index < expr->properties()->length(); property_index++) {
- ObjectLiteral::Property* property = expr->properties()->at(property_index);
- if (property->is_computed_name()) break;
+ for (int i = 0; i < expr->properties()->length(); i++) {
+ ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->IsCompileTimeValue()) continue;
- Literal* key = property->key()->AsLiteral();
+ Literal* key = property->key();
Expression* value = property->value();
if (!result_saved) {
__ push(r0); // Save result on stack
__ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
}
- // Object literals have two parts. The "static" part on the left contains no
- // computed property names, and so we can compute its map ahead of time; see
- // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
- // starts with the first computed property name, and continues with all
- // properties to its right. All the code from above initializes the static
- // component of the object literal, and arranges for the map of the result to
- // reflect the static order in which the keys appear. For the dynamic
- // properties, we compile them into a series of "SetOwnProperty" runtime
- // calls. This will preserve insertion order.
- for (; property_index < expr->properties()->length(); property_index++) {
- ObjectLiteral::Property* property = expr->properties()->at(property_index);
-
- Expression* value = property->value();
- if (!result_saved) {
- __ push(r0); // Save result on the stack
- result_saved = true;
- }
-
- __ ldr(r0, MemOperand(sp)); // Duplicate receiver.
- __ push(r0);
-
- if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
- DCHECK(!property->is_computed_name());
- VisitForStackValue(value);
- if (property->emit_store()) {
- __ CallRuntime(Runtime::kInternalSetPrototype, 2);
- } else {
- __ Drop(2);
- }
- } else {
- EmitPropertyKey(property);
- VisitForStackValue(value);
-
- switch (property->kind()) {
- case ObjectLiteral::Property::CONSTANT:
- case ObjectLiteral::Property::MATERIALIZED_LITERAL:
- case ObjectLiteral::Property::COMPUTED:
- if (property->emit_store()) {
- __ mov(r0, Operand(Smi::FromInt(NONE)));
- __ push(r0);
- __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
- } else {
- __ Drop(3);
- }
- break;
-
- case ObjectLiteral::Property::PROTOTYPE:
- UNREACHABLE();
- break;
-
- case ObjectLiteral::Property::GETTER:
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3);
- break;
-
- case ObjectLiteral::Property::SETTER:
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3);
- break;
- }
- }
- }
-
if (expr->has_function()) {
DCHECK(result_saved);
__ ldr(r0, MemOperand(sp));
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
+ Literal* key = property->key()->AsLiteral();
Expression* value = property->value();
+ DCHECK(key != NULL);
if (property->is_static()) {
__ ldr(scratch, MemOperand(sp, kPointerSize)); // constructor
__ ldr(scratch, MemOperand(sp, 0)); // prototype
}
__ push(scratch);
- EmitPropertyKey(property);
+ VisitForStackValue(key);
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
break;
case ObjectLiteral::Property::GETTER:
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3);
+ __ CallRuntime(Runtime::kDefineClassGetter, 3);
break;
case ObjectLiteral::Property::SETTER:
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3);
+ __ CallRuntime(Runtime::kDefineClassSetter, 3);
break;
default:
expr->CalculateEmitStore(zone());
AccessorTable accessor_table(zone());
- int property_index = 0;
- for (; property_index < expr->properties()->length(); property_index++) {
- ObjectLiteral::Property* property = expr->properties()->at(property_index);
- if (property->is_computed_name()) break;
+ for (int i = 0; i < expr->properties()->length(); i++) {
+ ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->IsCompileTimeValue()) continue;
- Literal* key = property->key()->AsLiteral();
+ Literal* key = property->key();
Expression* value = property->value();
if (!result_saved) {
__ Push(x0); // Save result on stack
__ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
}
- // Object literals have two parts. The "static" part on the left contains no
- // computed property names, and so we can compute its map ahead of time; see
- // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
- // starts with the first computed property name, and continues with all
- // properties to its right. All the code from above initializes the static
- // component of the object literal, and arranges for the map of the result to
- // reflect the static order in which the keys appear. For the dynamic
- // properties, we compile them into a series of "SetOwnProperty" runtime
- // calls. This will preserve insertion order.
- for (; property_index < expr->properties()->length(); property_index++) {
- ObjectLiteral::Property* property = expr->properties()->at(property_index);
-
- Expression* value = property->value();
- if (!result_saved) {
- __ Push(x0); // Save result on stack
- result_saved = true;
- }
-
- __ Peek(x10, 0); // Duplicate receiver.
- __ Push(x10);
-
- if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
- DCHECK(!property->is_computed_name());
- VisitForStackValue(value);
- if (property->emit_store()) {
- __ CallRuntime(Runtime::kInternalSetPrototype, 2);
- } else {
- __ Drop(2);
- }
- } else {
- EmitPropertyKey(property);
- VisitForStackValue(value);
-
- switch (property->kind()) {
- case ObjectLiteral::Property::CONSTANT:
- case ObjectLiteral::Property::MATERIALIZED_LITERAL:
- case ObjectLiteral::Property::COMPUTED:
- if (property->emit_store()) {
- __ Mov(x0, Smi::FromInt(NONE));
- __ Push(x0);
- __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
- } else {
- __ Drop(3);
- }
- break;
-
- case ObjectLiteral::Property::PROTOTYPE:
- UNREACHABLE();
- break;
-
- case ObjectLiteral::Property::GETTER:
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3);
- break;
-
- case ObjectLiteral::Property::SETTER:
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3);
- break;
- }
- }
- }
-
if (expr->has_function()) {
DCHECK(result_saved);
__ Peek(x0, 0);
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
+ Literal* key = property->key()->AsLiteral();
Expression* value = property->value();
+ DCHECK(key != NULL);
if (property->is_static()) {
__ Peek(scratch, kPointerSize); // constructor
__ Peek(scratch, 0); // prototype
}
__ Push(scratch);
- EmitPropertyKey(property);
+ VisitForStackValue(key);
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
break;
case ObjectLiteral::Property::GETTER:
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3);
+ __ CallRuntime(Runtime::kDefineClassGetter, 3);
break;
case ObjectLiteral::Property::SETTER:
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3);
+ __ CallRuntime(Runtime::kDefineClassSetter, 3);
break;
default:
void AstNumberingVisitor::VisitObjectLiteralProperty(
ObjectLiteralProperty* node) {
- if (node->is_computed_name()) DisableTurbofan(kComputedPropertyName);
Visit(node->key());
Visit(node->value());
}
ObjectLiteralProperty::ObjectLiteralProperty(Zone* zone,
AstValueFactory* ast_value_factory,
- Expression* key, Expression* value,
- bool is_static,
- bool is_computed_name)
- : key_(key),
- value_(value),
- emit_store_(true),
- is_static_(is_static),
- is_computed_name_(is_computed_name) {
- if (!is_computed_name &&
- key->AsLiteral()->raw_value()->EqualsString(
- ast_value_factory->proto_string())) {
+ Literal* key, Expression* value,
+ bool is_static) {
+ emit_store_ = true;
+ key_ = key;
+ value_ = value;
+ is_static_ = is_static;
+ if (key->raw_value()->EqualsString(ast_value_factory->proto_string())) {
kind_ = PROTOTYPE;
} else if (value_->AsMaterializedLiteral() != NULL) {
kind_ = MATERIALIZED_LITERAL;
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 is_static) {
+ emit_store_ = true;
+ value_ = value;
+ kind_ = is_getter ? GETTER : SETTER;
+ is_static_ = is_static;
+}
bool ObjectLiteral::Property::IsCompileTimeValue() {
allocator);
for (int i = properties()->length() - 1; i >= 0; i--) {
ObjectLiteral::Property* property = properties()->at(i);
- if (property->is_computed_name()) continue;
- Literal* literal = property->key()->AsLiteral();
+ Literal* literal = property->key();
if (literal->value()->IsNull()) continue;
uint32_t hash = literal->Hash();
- // If the key of a computed property value is in the table, do not emit
+ // If the key of a computed property is in the table, do not emit
// a store for the property later.
if ((property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL ||
property->kind() == ObjectLiteral::Property::COMPUTED) &&
is_simple = false;
continue;
}
-
- if (position == boilerplate_properties_ * 2) {
- DCHECK(property->is_computed_name());
- break;
- }
- DCHECK(!property->is_computed_name());
-
MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
if (m_literal != NULL) {
m_literal->BuildConstants(isolate);
// Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
// value for COMPUTED properties, the real value is filled in at
// runtime. The enumeration order is maintained.
- Handle<Object> key = property->key()->AsLiteral()->value();
+ Handle<Object> key = property->key()->value();
Handle<Object> value = GetBoilerplateValue(property->value(), isolate);
// Ensure objects that may, at any point in time, contain fields with double
void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
- DCHECK(!is_computed_name());
- TypeFeedbackId id = key()->AsLiteral()->LiteralFeedbackId();
+ TypeFeedbackId id = key()->LiteralFeedbackId();
SmallMapList maps;
oracle->CollectReceiverTypes(id, &maps);
receiver_type_ = maps.length() == 1 ? maps.at(0)
PROTOTYPE // Property is __proto__.
};
- Expression* key() { return key_; }
+ ObjectLiteralProperty(Zone* zone, AstValueFactory* ast_value_factory,
+ Literal* key, Expression* value, bool is_static);
+
+ Literal* key() { return key_; }
Expression* value() { return value_; }
Kind kind() { return kind_; }
bool emit_store();
bool is_static() const { return is_static_; }
- bool is_computed_name() const { return is_computed_name_; }
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,
- bool is_computed_name);
+ ObjectLiteralProperty(Zone* zone, bool is_getter, FunctionLiteral* value,
+ bool is_static);
+ void set_key(Literal* key) { key_ = key; }
private:
- Expression* key_;
+ Literal* key_;
Expression* value_;
Kind kind_;
bool emit_store_;
bool is_static_;
- bool is_computed_name_;
Handle<Map> receiver_type_;
};
boilerplate_properties, has_function, pos);
}
- ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key,
+ ObjectLiteral::Property* NewObjectLiteralProperty(Literal* 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);
+ bool is_static) {
+ return new (zone_) ObjectLiteral::Property(zone_, ast_value_factory_, key,
+ value, is_static);
}
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,
- is_static, is_computed_name);
+ int pos, bool is_static) {
+ ObjectLiteral::Property* prop =
+ new (zone_) ObjectLiteral::Property(zone_, is_getter, value, is_static);
+ prop->set_key(NewStringLiteral(value->raw_name(), pos));
+ return prop;
}
RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern,
V(kCodeGenerationFailed, "Code generation failed") \
V(kCodeObjectNotProperlyPatched, "Code object not properly patched") \
V(kCompoundAssignmentToLookupSlot, "Compound assignment to lookup slot") \
- V(kComputedPropertyName, "Computed property name") \
V(kContextAllocatedArguments, "Context-allocated arguments") \
V(kCopyBuffersOverlap, "Copy buffers overlap") \
V(kCouldNotGenerateZero, "Could not generate +0.0") \
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_templates)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_sloppy)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_unicode)
-EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_computed_property_names)
void Genesis::InstallNativeFunctions_harmony_proxies() {
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_templates)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode)
-EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_computed_property_names)
void Genesis::InitializeGlobal_harmony_regexps() {
Handle<JSObject> builtins(native_context()->builtins());
"native harmony-templates.js", NULL};
static const char* harmony_sloppy_natives[] = {NULL};
static const char* harmony_unicode_natives[] = {NULL};
- static const char* harmony_computed_property_names_natives[] = {NULL};
for (int i = ExperimentalNatives::GetDebuggerCount();
i < ExperimentalNatives::GetBuiltinsCount(); i++) {
DEBUG_BREAK)
// Define list of builtins implemented in JavaScript.
-#define BUILTINS_LIST_JS(V) \
- V(EQUALS, 1) \
- V(STRICT_EQUALS, 1) \
- V(COMPARE, 2) \
- V(ADD, 1) \
- V(SUB, 1) \
- V(MUL, 1) \
- V(DIV, 1) \
- V(MOD, 1) \
- V(BIT_OR, 1) \
- V(BIT_AND, 1) \
- V(BIT_XOR, 1) \
- V(SHL, 1) \
- V(SAR, 1) \
- V(SHR, 1) \
- V(DELETE, 2) \
- V(IN, 1) \
- V(INSTANCE_OF, 1) \
- V(FILTER_KEY, 1) \
- V(CALL_NON_FUNCTION, 0) \
- V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \
+#define BUILTINS_LIST_JS(V) \
+ V(EQUALS, 1) \
+ V(STRICT_EQUALS, 1) \
+ V(COMPARE, 2) \
+ V(ADD, 1) \
+ V(SUB, 1) \
+ V(MUL, 1) \
+ V(DIV, 1) \
+ V(MOD, 1) \
+ V(BIT_OR, 1) \
+ V(BIT_AND, 1) \
+ V(BIT_XOR, 1) \
+ V(SHL, 1) \
+ V(SAR, 1) \
+ V(SHR, 1) \
+ V(DELETE, 2) \
+ V(IN, 1) \
+ V(INSTANCE_OF, 1) \
+ V(FILTER_KEY, 1) \
+ V(CALL_NON_FUNCTION, 0) \
+ V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \
V(CALL_FUNCTION_PROXY, 1) \
V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, 1) \
- V(TO_OBJECT, 0) \
- V(TO_NUMBER, 0) \
- V(TO_STRING, 0) \
- V(TO_NAME, 0) \
- V(STRING_ADD_LEFT, 1) \
- V(STRING_ADD_RIGHT, 1) \
- V(APPLY_PREPARE, 1) \
+ V(TO_OBJECT, 0) \
+ V(TO_NUMBER, 0) \
+ V(TO_STRING, 0) \
+ V(STRING_ADD_LEFT, 1) \
+ V(STRING_ADD_RIGHT, 1) \
+ V(APPLY_PREPARE, 1) \
V(STACK_OVERFLOW, 1)
class BuiltinFunctionTable;
ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->IsCompileTimeValue()) continue;
- Literal* key = property->key()->AsLiteral();
+ Literal* key = property->key();
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
UNREACHABLE();
DEFINE_IMPLICATION(es_staging, harmony)
// Features that are still work in progress (behind individual flags).
-#define HARMONY_INPROGRESS(V) \
- V(harmony_modules, "harmony modules (implies block scoping)") \
- V(harmony_arrays, "harmony array methods") \
- V(harmony_array_includes, "harmony Array.prototype.includes") \
- V(harmony_regexps, "harmony regular expression extensions") \
- V(harmony_arrow_functions, "harmony arrow functions") \
- V(harmony_proxies, "harmony proxies") \
- V(harmony_sloppy, "harmony features in sloppy mode") \
- V(harmony_unicode, "harmony unicode escapes") \
- V(harmony_computed_property_names, "harmony computed property names")
+#define HARMONY_INPROGRESS(V) \
+ V(harmony_modules, "harmony modules (implies block scoping)") \
+ V(harmony_arrays, "harmony array methods") \
+ V(harmony_array_includes, "harmony Array.prototype.includes") \
+ V(harmony_regexps, "harmony regular expression extensions") \
+ V(harmony_arrow_functions, "harmony arrow functions") \
+ V(harmony_proxies, "harmony proxies") \
+ V(harmony_sloppy, "harmony features in sloppy mode") \
+ V(harmony_unicode, "harmony unicode escapes")
// Features that are complete (but still behind --harmony/es-staging flag).
#define HARMONY_STAGED(V) \
}
-void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property) {
- VisitForStackValue(property->key());
- __ InvokeBuiltin(Builtins::TO_NAME, CALL_FUNCTION);
- __ Push(result_register());
-}
-
-
void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt);
// in the accumulator after installing all the properties.
void EmitClassDefineProperties(ClassLiteral* lit);
- // Pushes the property key as a Name on the stack.
- void EmitPropertyKey(ObjectLiteralProperty* property);
-
// Apply the compound assignment operator. Expects the left operand on top
// of the stack and the right one in the accumulator.
void EmitBinaryOp(BinaryOperation* expr,
for (int i = 0; i < expr->properties()->length(); i++) {
ObjectLiteral::Property* property = expr->properties()->at(i);
- if (property->is_computed_name()) {
- return Bailout(kComputedPropertyName);
- }
if (property->IsCompileTimeValue()) continue;
- Literal* key = property->key()->AsLiteral();
+ Literal* key = property->key();
Expression* value = property->value();
switch (property->kind()) {
}
Handle<Map> map = property->GetReceiverType();
- Handle<String> name = key->AsPropertyName();
+ Handle<String> name = property->key()->AsPropertyName();
HInstruction* store;
if (map.is_null()) {
// If we don't know the monomorphic type, do a generic store.
expr->CalculateEmitStore(zone());
AccessorTable accessor_table(zone());
- int property_index = 0;
- for (; property_index < expr->properties()->length(); property_index++) {
- ObjectLiteral::Property* property = expr->properties()->at(property_index);
- if (property->is_computed_name()) break;
+ for (int i = 0; i < expr->properties()->length(); i++) {
+ ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->IsCompileTimeValue()) continue;
- Literal* key = property->key()->AsLiteral();
+ Literal* key = property->key();
Expression* value = property->value();
if (!result_saved) {
__ push(eax); // Save result on the stack
__ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
}
- // Object literals have two parts. The "static" part on the left contains no
- // computed property names, and so we can compute its map ahead of time; see
- // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
- // starts with the first computed property name, and continues with all
- // properties to its right. All the code from above initializes the static
- // component of the object literal, and arranges for the map of the result to
- // reflect the static order in which the keys appear. For the dynamic
- // properties, we compile them into a series of "SetOwnProperty" runtime
- // calls. This will preserve insertion order.
- for (; property_index < expr->properties()->length(); property_index++) {
- ObjectLiteral::Property* property = expr->properties()->at(property_index);
-
- Expression* value = property->value();
- if (!result_saved) {
- __ push(eax); // Save result on the stack
- result_saved = true;
- }
-
- __ push(Operand(esp, 0)); // Duplicate receiver.
-
- if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
- DCHECK(!property->is_computed_name());
- VisitForStackValue(value);
- if (property->emit_store()) {
- __ CallRuntime(Runtime::kInternalSetPrototype, 2);
- } else {
- __ Drop(2);
- }
- } else {
- EmitPropertyKey(property);
- VisitForStackValue(value);
-
- switch (property->kind()) {
- case ObjectLiteral::Property::CONSTANT:
- case ObjectLiteral::Property::MATERIALIZED_LITERAL:
- case ObjectLiteral::Property::COMPUTED:
- if (property->emit_store()) {
- __ push(Immediate(Smi::FromInt(NONE)));
- __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
- } else {
- __ Drop(3);
- }
- break;
-
- case ObjectLiteral::Property::PROTOTYPE:
- UNREACHABLE();
- break;
-
- case ObjectLiteral::Property::GETTER:
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3);
- break;
-
- case ObjectLiteral::Property::SETTER:
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3);
- break;
- }
- }
- }
-
if (expr->has_function()) {
DCHECK(result_saved);
__ push(Operand(esp, 0));
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
+ Literal* key = property->key()->AsLiteral();
Expression* value = property->value();
+ DCHECK(key != NULL);
if (property->is_static()) {
__ push(Operand(esp, kPointerSize)); // constructor
} else {
__ push(Operand(esp, 0)); // prototype
}
- EmitPropertyKey(property);
+ VisitForStackValue(key);
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
break;
case ObjectLiteral::Property::GETTER:
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3);
+ __ CallRuntime(Runtime::kDefineClassGetter, 3);
break;
case ObjectLiteral::Property::SETTER:
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3);
+ __ CallRuntime(Runtime::kDefineClassSetter, 3);
break;
default:
bool ParserTraits::IsThisProperty(Expression* expression) {
DCHECK(expression != NULL);
Property* property = expression->AsProperty();
- return property != NULL && property->obj()->IsVariableProxy() &&
- property->obj()->AsVariableProxy()->is_this();
+ return property != NULL &&
+ property->obj()->AsVariableProxy() != NULL &&
+ property->obj()->AsVariableProxy()->is_this();
}
void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
Expression* right) {
DCHECK(left != NULL);
- if (left->IsProperty() && right->IsFunctionLiteral()) {
+ if (left->AsProperty() != NULL &&
+ right->AsFunctionLiteral() != NULL) {
right->AsFunctionLiteral()->set_pretenure();
}
}
set_allow_harmony_templates(FLAG_harmony_templates);
set_allow_harmony_sloppy(FLAG_harmony_sloppy);
set_allow_harmony_unicode(FLAG_harmony_unicode);
- set_allow_harmony_computed_property_names(
- FLAG_harmony_computed_property_names);
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
++feature) {
use_counts_[feature] = 0;
reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates());
reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy());
reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode());
- reusable_preparser_->set_allow_harmony_computed_property_names(
- allow_harmony_computed_property_names());
}
PreParser::PreParseResult result =
reusable_preparser_->PreParseLazyFunction(strict_mode(),
if (fni_ != NULL) fni_->Enter();
const bool in_class = true;
const bool is_static = false;
- bool is_computed_name = false; // Classes do not care about computed
- // property names here.
- ObjectLiteral::Property* property =
- ParsePropertyDefinition(NULL, in_class, is_static, &is_computed_name,
- &has_seen_constructor, CHECK_OK);
+ ObjectLiteral::Property* property = ParsePropertyDefinition(
+ NULL, in_class, is_static, &has_seen_constructor, CHECK_OK);
if (has_seen_constructor && constructor == NULL) {
constructor = GetPropertyValue(property);
return string->AsArrayIndex(index);
}
+ bool IsConstructorProperty(ObjectLiteral::Property* property) {
+ return property->key()->raw_value()->EqualsString(
+ ast_value_factory()->constructor_string());
+ }
+
static Expression* GetPropertyValue(ObjectLiteral::Property* property) {
return property->value();
}
static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
fni->PushLiteralName(id);
}
-
void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
-
static void InferFunctionName(FuncNameInferrer* fni,
FunctionLiteral* func_to_infer) {
fni->AddFunction(func_to_infer);
if (Check(Token::SEMICOLON)) continue;
const bool in_class = true;
const bool is_static = false;
- bool is_computed_name = false; // Classes do not care about computed
- // property names here.
- ParsePropertyDefinition(NULL, in_class, is_static, &is_computed_name,
- &has_seen_constructor, CHECK_OK);
+ ParsePropertyDefinition(NULL, in_class, is_static, &has_seen_constructor,
+ CHECK_OK);
}
Expect(Token::RBRACE, CHECK_OK);
allow_harmony_arrow_functions_(false),
allow_harmony_object_literals_(false),
allow_harmony_sloppy_(false),
- allow_harmony_computed_property_names_(false),
zone_(zone) {}
// Getters that indicate whether certain syntactical constructs are
bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); }
bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; }
bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); }
- bool allow_harmony_computed_property_names() const {
- return allow_harmony_computed_property_names_;
- }
// Setters that determine whether certain syntactical constructs are
// allowed to be parsed by this instance of the parser.
void set_allow_harmony_unicode(bool allow) {
scanner()->SetHarmonyUnicode(allow);
}
- void set_allow_harmony_computed_property_names(bool allow) {
- allow_harmony_computed_property_names_ = allow;
- }
protected:
enum AllowEvalOrArgumentsAsIdentifier {
ExpressionT ParsePrimaryExpression(bool* ok);
ExpressionT ParseExpression(bool accept_IN, bool* ok);
ExpressionT ParseArrayLiteral(bool* ok);
- ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
- bool* is_static, bool* is_computed_name,
+ IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static,
bool* ok);
ExpressionT ParseObjectLiteral(bool* ok);
ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker,
bool in_class, bool is_static,
- bool* is_computed_name,
bool* has_seen_constructor,
bool* ok);
typename Traits::Type::ExpressionList ParseArguments(bool* ok);
bool allow_harmony_arrow_functions_;
bool allow_harmony_object_literals_;
bool allow_harmony_sloppy_;
- bool allow_harmony_computed_property_names_;
typename Traits::Type::Zone* zone_; // Only used by Parser.
};
return PreParserExpression::Default();
}
PreParserExpression NewObjectLiteralProperty(bool is_getter,
- PreParserExpression key,
PreParserExpression value,
- int pos, bool is_static,
- bool is_computed_name) {
+ int pos, bool is_static) {
return PreParserExpression::Default();
}
PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
PreParserExpression value,
- bool is_static,
- bool is_computed_name) {
+ bool is_static) {
return PreParserExpression::Default();
}
PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
// PreParser should not use FuncNameInferrer.
UNREACHABLE();
}
-
static void PushPropertyName(FuncNameInferrer* fni,
PreParserExpression expression) {
// PreParser should not use FuncNameInferrer.
UNREACHABLE();
}
-
static void InferFunctionName(FuncNameInferrer* fni,
PreParserExpression expression) {
// PreParser should not use FuncNameInferrer.
template <class Traits>
-typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
- IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
- bool* is_computed_name, bool* ok) {
- Token::Value token = peek();
- int pos = peek_position();
-
- // For non computed property names we normalize the name a bit:
- //
- // "12" -> 12
- // 12.3 -> "12.3"
- // 12.30 -> "12.3"
- // identifier -> "identifier"
- //
- // This is important because we use the property name as a key in a hash
- // table when we compute constant properties.
- switch (token) {
+typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName(
+ bool* is_get, bool* is_set, bool* is_static, bool* ok) {
+ Token::Value next = peek();
+ switch (next) {
case Token::STRING:
Consume(Token::STRING);
- *name = this->GetSymbol(scanner());
- break;
-
+ return this->GetSymbol(scanner_);
case Token::NUMBER:
Consume(Token::NUMBER);
- *name = this->GetNumberAsSymbol(scanner());
- break;
-
- case Token::LBRACK:
- if (allow_harmony_computed_property_names_) {
- *is_computed_name = true;
- Consume(Token::LBRACK);
- ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
- Expect(Token::RBRACK, CHECK_OK);
- return expression;
- }
-
- // Fall through.
+ return this->GetNumberAsSymbol(scanner_);
case Token::STATIC:
*is_static = true;
-
- // Fall through.
+ // Fall through.
default:
- *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
- break;
+ return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok);
}
-
- uint32_t index;
- return this->IsArrayIndex(*name, &index)
- ? factory()->NewNumberLiteral(index, pos)
- : factory()->NewStringLiteral(*name, pos);
+ UNREACHABLE();
+ return this->EmptyIdentifier();
}
typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase<
Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker,
bool in_class, bool is_static,
- bool* is_computed_name,
bool* has_seen_constructor, bool* ok) {
DCHECK(!in_class || is_static || has_seen_constructor != NULL);
ExpressionT value = this->EmptyExpression();
- IdentifierT name = this->EmptyIdentifier();
bool is_get = false;
bool is_set = false;
bool name_is_static = false;
Token::Value name_token = peek();
int next_pos = peek_position();
- ExpressionT name_expression = ParsePropertyName(
- &name, &is_get, &is_set, &name_is_static, is_computed_name,
- CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ IdentifierT name =
+ ParsePropertyName(&is_get, &is_set, &name_is_static,
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
- if (fni_ != NULL && !*is_computed_name) {
- this->PushLiteralName(fni_, name);
- }
+ if (fni_ != NULL) this->PushLiteralName(fni_, name);
if (!in_class && !is_generator && peek() == Token::COLON) {
// PropertyDefinition : PropertyName ':' AssignmentExpression
- if (!*is_computed_name && checker != NULL) {
+ if (checker != NULL) {
checker->CheckProperty(name_token, kValueProperty,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
}
kind = FunctionKind::kNormalFunction;
}
- if (!*is_computed_name && checker != NULL) {
+ if (checker != NULL) {
checker->CheckProperty(name_token, kValueProperty,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
}
} else if (in_class && name_is_static && !is_static) {
// static MethodDefinition
- return ParsePropertyDefinition(checker, true, true, is_computed_name, NULL,
- ok);
+ return ParsePropertyDefinition(checker, true, true, NULL, ok);
} else if (is_get || is_set) {
// Accessor
- name = this->EmptyIdentifier();
bool dont_care = false;
name_token = peek();
-
- name_expression = ParsePropertyName(
- &name, &dont_care, &dont_care, &dont_care, is_computed_name,
- CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ name = ParsePropertyName(&dont_care, &dont_care, &dont_care,
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
// Validate the property.
if (is_static && this->IsPrototype(name)) {
*ok = false;
return this->EmptyObjectLiteralProperty();
}
- if (!*is_computed_name && checker != NULL) {
+ if (checker != NULL) {
checker->CheckProperty(name_token,
is_get ? kGetterProperty : kSetterProperty,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
FunctionLiteral::ANONYMOUS_EXPRESSION,
is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
-
- // Make sure the name expression is a string since we need a Name for
- // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
- // statically we can skip the extra runtime check.
- if (!*is_computed_name) {
- name_expression =
- factory()->NewStringLiteral(name, name_expression->position());
- }
-
- return factory()->NewObjectLiteralProperty(
- is_get, name_expression, value, next_pos, is_static, *is_computed_name);
+ return factory()->NewObjectLiteralProperty(is_get, value, next_pos,
+ is_static);
} else if (!in_class && allow_harmony_object_literals_ &&
Token::IsIdentifier(name_token, strict_mode(),
return this->EmptyObjectLiteralProperty();
}
- return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
- *is_computed_name);
+ uint32_t index;
+ LiteralT key = this->IsArrayIndex(name, &index)
+ ? factory()->NewNumberLiteral(index, next_pos)
+ : factory()->NewStringLiteral(name, next_pos);
+
+ return factory()->NewObjectLiteralProperty(key, value, is_static);
}
this->NewPropertyList(4, zone_);
int number_of_boilerplate_properties = 0;
bool has_function = false;
- bool has_computed_names = false;
ObjectLiteralChecker checker(this, strict_mode());
const bool in_class = false;
const bool is_static = false;
- bool is_computed_name = false;
ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
- &checker, in_class, is_static, &is_computed_name, NULL, CHECK_OK);
-
- if (is_computed_name) {
- has_computed_names = true;
- }
+ &checker, in_class, is_static, NULL, CHECK_OK);
// Mark top-level object literals that contain function literals and
// pretenure the literal so it can be added as a constant function
&has_function);
// Count CONSTANT or COMPUTED properties to maintain the enumeration order.
- if (!has_computed_names && this->IsBoilerplateProperty(property)) {
+ if (this->IsBoilerplateProperty(property)) {
number_of_boilerplate_properties++;
}
properties->Add(property, zone());
}
-// Convert the receiver to a string or symbol - forward to ToName.
-function TO_NAME() {
- return %ToName(this);
-}
-
-
/* -------------------------------------
- - - C o n v e r s i o n s - - -
-------------------------------------
HandleScope scope(isolate);
DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
- CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2);
uint32_t index;
+ if (key->ToArrayIndex(&index)) {
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSObject::SetOwnElement(object, index, function, STRICT));
+ }
+
+ Handle<Name> name;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+ Runtime::ToName(isolate, key));
if (name->AsArrayIndex(&index)) {
RETURN_FAILURE_ON_EXCEPTION(
isolate, JSObject::SetOwnElement(object, index, function, STRICT));
}
+RUNTIME_FUNCTION(Runtime_DefineClassGetter) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
+
+ Handle<Name> name;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+ Runtime::ToName(isolate, key));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::DefineAccessor(object, name, getter,
+ isolate->factory()->null_value(), NONE));
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefineClassSetter) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
+
+ Handle<Name> name;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+ Runtime::ToName(isolate, key));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
+ setter, NONE));
+ return isolate->heap()->undefined_value();
+}
+
+
RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
HandleScope shs(isolate);
DCHECK(args.length() == 1);
if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
return JSReceiver::cast(obj)->class_name();
}
-
-
-RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
- CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
-
- RETURN_FAILURE_ON_EXCEPTION(
- isolate,
- JSObject::DefineAccessor(object, name, getter,
- isolate->factory()->null_value(), NONE));
- return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
- CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
-
- RETURN_FAILURE_ON_EXCEPTION(
- isolate,
- JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
- setter, NONE));
- return isolate->heap()->undefined_value();
-}
}
} // namespace v8::internal
F(HomeObjectSymbol, 0, 1) \
F(DefineClass, 6, 1) \
F(DefineClassMethod, 3, 1) \
+ F(DefineClassGetter, 3, 1) \
+ F(DefineClassSetter, 3, 1) \
F(ClassGetSourceCode, 1, 1) \
F(ThrowNonMethodError, 0, 1) \
F(ThrowUnsupportedSuperError, 0, 1) \
F(DefineDataPropertyUnchecked, 4, 1) \
F(DefineAccessorPropertyUnchecked, 5, 1) \
F(GetDataProperty, 2, 1) \
- F(DefineGetterPropertyUnchecked, 3, 1) \
- F(DefineSetterPropertyUnchecked, 3, 1) \
\
/* Arrays */ \
F(RemoveArrayHoles, 2, 1) \
if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
!CompileTimeValue::IsCompileTimeValue(prop->value())) ||
prop->kind() == ObjectLiteral::Property::COMPUTED) {
- if (!prop->is_computed_name() &&
- prop->key()->AsLiteral()->value()->IsInternalizedString() &&
- prop->emit_store()) {
+ if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) {
prop->RecordTypeFeedback(oracle());
}
}
expr->CalculateEmitStore(zone());
AccessorTable accessor_table(zone());
- int property_index = 0;
- for (; property_index < expr->properties()->length(); property_index++) {
- ObjectLiteral::Property* property = expr->properties()->at(property_index);
- if (property->is_computed_name()) break;
+ for (int i = 0; i < expr->properties()->length(); i++) {
+ ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->IsCompileTimeValue()) continue;
- Literal* key = property->key()->AsLiteral();
+ Literal* key = property->key();
Expression* value = property->value();
if (!result_saved) {
__ Push(rax); // Save result on the stack
__ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
}
- // Object literals have two parts. The "static" part on the left contains no
- // computed property names, and so we can compute its map ahead of time; see
- // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
- // starts with the first computed property name, and continues with all
- // properties to its right. All the code from above initializes the static
- // component of the object literal, and arranges for the map of the result to
- // reflect the static order in which the keys appear. For the dynamic
- // properties, we compile them into a series of "SetOwnProperty" runtime
- // calls. This will preserve insertion order.
- for (; property_index < expr->properties()->length(); property_index++) {
- ObjectLiteral::Property* property = expr->properties()->at(property_index);
-
- Expression* value = property->value();
- if (!result_saved) {
- __ Push(rax); // Save result on the stack
- result_saved = true;
- }
-
- __ Push(Operand(rsp, 0)); // Duplicate receiver.
-
- if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
- DCHECK(!property->is_computed_name());
- VisitForStackValue(value);
- if (property->emit_store()) {
- __ CallRuntime(Runtime::kInternalSetPrototype, 2);
- } else {
- __ Drop(2);
- }
- } else {
- EmitPropertyKey(property);
- VisitForStackValue(value);
-
- switch (property->kind()) {
- case ObjectLiteral::Property::CONSTANT:
- case ObjectLiteral::Property::MATERIALIZED_LITERAL:
- case ObjectLiteral::Property::COMPUTED:
- if (property->emit_store()) {
- __ Push(Smi::FromInt(NONE));
- __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
- } else {
- __ Drop(3);
- }
- break;
-
- case ObjectLiteral::Property::PROTOTYPE:
- UNREACHABLE();
- break;
-
- case ObjectLiteral::Property::GETTER:
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3);
- break;
-
- case ObjectLiteral::Property::SETTER:
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3);
- break;
- }
- }
- }
-
if (expr->has_function()) {
DCHECK(result_saved);
__ Push(Operand(rsp, 0));
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
+ Literal* key = property->key()->AsLiteral();
Expression* value = property->value();
+ DCHECK(key != NULL);
if (property->is_static()) {
__ Push(Operand(rsp, kPointerSize)); // constructor
} else {
__ Push(Operand(rsp, 0)); // prototype
}
- EmitPropertyKey(property);
+ VisitForStackValue(key);
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
break;
case ObjectLiteral::Property::GETTER:
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3);
+ __ CallRuntime(Runtime::kDefineClassGetter, 3);
break;
case ObjectLiteral::Property::SETTER:
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3);
+ __ CallRuntime(Runtime::kDefineClassSetter, 3);
break;
default:
kAllowHarmonyObjectLiterals,
kAllowHarmonyTemplates,
kAllowHarmonySloppy,
- kAllowHarmonyUnicode,
- kAllowHarmonyComputedPropertyNames
+ kAllowHarmonyUnicode
};
parser->set_allow_harmony_templates(flags.Contains(kAllowHarmonyTemplates));
parser->set_allow_harmony_sloppy(flags.Contains(kAllowHarmonySloppy));
parser->set_allow_harmony_unicode(flags.Contains(kAllowHarmonyUnicode));
- parser->set_allow_harmony_computed_property_names(
- flags.Contains(kAllowHarmonyComputedPropertyNames));
}
always_true_flags, arraysize(always_true_flags),
always_false_flags, arraysize(always_false_flags));
}
-
-
-TEST(ComputedPropertyName) {
- const char* context_data[][2] = {{"({[", "]: 1});"},
- {"({get [", "]() {}});"},
- {"({set [", "](_) {}});"},
- {"({[", "]() {}});"},
- {"({*[", "]() {}});"},
- {"(class {get [", "]() {}});"},
- {"(class {set [", "](_) {}});"},
- {"(class {[", "]() {}});"},
- {"(class {*[", "]() {}});"},
- {NULL, NULL}};
- const char* error_data[] = {
- "1, 2",
- "var name",
- NULL};
-
- static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyComputedPropertyNames,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy,
- };
- RunParserSyncTest(context_data, error_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
-
- const char* name_data[] = {
- "1",
- "1 + 2",
- "'name'",
- "\"name\"",
- "[]",
- "{}",
- NULL};
-
- RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
-}
-
-
-TEST(ComputedPropertyNameShorthandError) {
- const char* context_data[][2] = {{"({", "});"},
- {NULL, NULL}};
- const char* error_data[] = {
- "a: 1, [2]",
- "[1], a: 1",
- NULL};
-
- static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyComputedPropertyNames,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy,
- };
- RunParserSyncTest(context_data, error_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
-}
+++ /dev/null
-// 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.
-
-'use strict';
-
-// Flags: --harmony-computed-property-names --harmony-classes
-
-
-function ID(x) {
- return x;
-}
-
-
-(function TestClassMethodString() {
- class C {
- a() { return 'A'}
- ['b']() { return 'B'; }
- c() { return 'C'; }
- [ID('d')]() { return 'D'; }
- }
- assertEquals('A', new C().a());
- assertEquals('B', new C().b());
- assertEquals('C', new C().c());
- assertEquals('D', new C().d());
- assertArrayEquals(['a', 'b', 'c', 'd'], Object.keys(C.prototype));
-})();
-
-
-(function TestClassMethodNumber() {
- class C {
- a() { return 'A'; }
- [1]() { return 'B'; }
- c() { return 'C'; }
- [ID(2)]() { return 'D'; }
- }
- assertEquals('A', new C().a());
- assertEquals('B', new C()[1]());
- assertEquals('C', new C().c());
- assertEquals('D', new C()[2]());
- // Array indexes first.
- assertArrayEquals(['1', '2', 'a', 'c'], Object.keys(C.prototype));
-})();
-
-
-(function TestClassMethodSymbol() {
- var sym1 = Symbol();
- var sym2 = Symbol();
- class C {
- a() { return 'A'; }
- [sym1]() { return 'B'; }
- c() { return 'C'; }
- [ID(sym2)]() { return 'D'; }
- }
- assertEquals('A', new C().a());
- assertEquals('B', new C()[sym1]());
- assertEquals('C', new C().c());
- assertEquals('D', new C()[sym2]());
- assertArrayEquals(['a', 'c'], Object.keys(C.prototype));
- assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(C.prototype));
-})();
-
-
-
-(function TestStaticClassMethodString() {
- class C {
- static a() { return 'A'}
- static ['b']() { return 'B'; }
- static c() { return 'C'; }
- static ['d']() { return 'D'; }
- }
- assertEquals('A', C.a());
- assertEquals('B', C.b());
- assertEquals('C', C.c());
- assertEquals('D', C.d());
- assertArrayEquals(['a', 'b', 'c', 'd'], Object.keys(C));
-})();
-
-
-(function TestStaticClassMethodNumber() {
- class C {
- static a() { return 'A'; }
- static [1]() { return 'B'; }
- static c() { return 'C'; }
- static [2]() { return 'D'; }
- }
- assertEquals('A', C.a());
- assertEquals('B', C[1]());
- assertEquals('C', C.c());
- assertEquals('D', C[2]());
- // Array indexes first.
- assertArrayEquals(['1', '2', 'a', 'c'], Object.keys(C));
-})();
-
-
-(function TestStaticClassMethodSymbol() {
- var sym1 = Symbol();
- var sym2 = Symbol();
- class C {
- static a() { return 'A'; }
- static [sym1]() { return 'B'; }
- static c() { return 'C'; }
- static [sym2]() { return 'D'; }
- }
- assertEquals('A', C.a());
- assertEquals('B', C[sym1]());
- assertEquals('C', C.c());
- assertEquals('D', C[sym2]());
- assertArrayEquals(['a', 'c'], Object.keys(C));
- assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(C));
-})();
-
-
-
-function assertIteratorResult(value, done, result) {
- assertEquals({ value: value, done: done}, result);
-}
-
-
-(function TestGeneratorComputedName() {
- class C {
- *['a']() {
- yield 1;
- yield 2;
- }
- }
- var iter = new C().a();
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(undefined, true, iter.next());
- assertArrayEquals(['a'], Object.keys(C.prototype));
-})();
-
-
-(function TestToNameSideEffects() {
- var counter = 0;
- var key1 = {
- toString: function() {
- assertEquals(0, counter++);
- return 'b';
- }
- };
- var key2 = {
- toString: function() {
- assertEquals(1, counter++);
- return 'd';
- }
- };
- class C {
- a() { return 'A'; }
- [key1]() { return 'B'; }
- c() { return 'C'; }
- [key2]() { return 'D'; }
- }
- assertEquals(2, counter);
- assertEquals('A', new C().a());
- assertEquals('B', new C().b());
- assertEquals('C', new C().c());
- assertEquals('D', new C().d());
- assertArrayEquals(['a', 'b', 'c', 'd'], Object.keys(C.prototype));
-})();
-
-
-(function TestToNameSideEffectsNumbers() {
- var counter = 0;
- var key1 = {
- valueOf: function() {
- assertEquals(0, counter++);
- return 1;
- },
- toString: null
- };
- var key2 = {
- valueOf: function() {
- assertEquals(1, counter++);
- return 2;
- },
- toString: null
- };
-
- class C {
- a() { return 'A'; }
- [key1]() { return 'B'; }
- c() { return 'C'; }
- [key2]() { return 'D'; }
- }
- assertEquals(2, counter);
- assertEquals('A', new C().a());
- assertEquals('B', new C()[1]());
- assertEquals('C', new C().c());
- assertEquals('D', new C()[2]());
- // Array indexes first.
- assertArrayEquals(['1', '2', 'a', 'c'], Object.keys(C.prototype));
-})();
-
-
-(function TestGetter() {
- class C {
- get ['a']() {
- return 'A';
- }
- }
- assertEquals('A', new C().a);
-
- class C2 {
- get b() {
- assertUnreachable();
- }
- get ['b']() {
- return 'B';
- }
- }
- assertEquals('B', new C2().b);
-
- class C3 {
- get c() {
- assertUnreachable();
- }
- get ['c']() {
- assertUnreachable();
- }
- get ['c']() {
- return 'C';
- }
- }
- assertEquals('C', new C3().c);
-
- class C4 {
- get ['d']() {
- assertUnreachable();
- }
- get d() {
- return 'D';
- }
- }
- assertEquals('D', new C4().d);
-})();
-
-
-(function TestSetter() {
- var calls = 0;
- class C {
- set ['a'](_) {
- calls++;
- }
- }
- new C().a = 'A';
- assertEquals(1, calls);
-
- calls = 0;
- class C2 {
- set b(_) {
- assertUnreachable();
- }
- set ['b'](_) {
- calls++;
- }
- }
- new C2().b = 'B';
- assertEquals(1, calls);
-
- calls = 0;
- class C3 {
- set c(_) {
- assertUnreachable()
- }
- set ['c'](_) {
- assertUnreachable()
- }
- set ['c'](_) {
- calls++
- }
- }
- new C3().c = 'C';
- assertEquals(1, calls);
-
- calls = 0;
- class C4 {
- set ['d'](_) {
- assertUnreachable()
- }
- set d(_) {
- calls++
- }
- }
- new C4().d = 'D';
- assertEquals(1, calls);
-})();
-
-
-(function TestPrototype() {
- // Normally a static prototype property is not allowed.
- class C {
- static ['prototype']() {
- return 1;
- }
- }
- assertEquals(1, C.prototype());
-
- class C2 {
- static get ['prototype']() {
- return 2;
- }
- }
- assertEquals(2, C2.prototype);
-
- var calls = 0;
- class C3 {
- static set ['prototype'](x) {
- assertEquals(3, x);
- calls++;
- }
- }
- C3.prototype = 3;
- assertEquals(1, calls);
-
- class C4 {
- static *['prototype']() {
- yield 1;
- yield 2;
- }
- }
- var iter = C4.prototype();
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(undefined, true, iter.next());
-})();
-
-
-(function TestConstructor() {
- // Normally a constructor property is not allowed.
- class C {
- ['constructor']() {
- return 1;
- }
- }
- assertTrue(C !== C.prototype.constructor);
- assertEquals(1, new C().constructor());
-
- class C2 {
- get ['constructor']() {
- return 2;
- }
- }
- assertEquals(2, new C2().constructor);
-
- var calls = 0;
- class C3 {
- set ['constructor'](x) {
- assertEquals(3, x);
- calls++;
- }
- }
- new C3().constructor = 3;
- assertEquals(1, calls);
-
- class C4 {
- *['constructor']() {
- yield 1;
- yield 2;
- }
- }
- var iter = new C4().constructor();
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(undefined, true, iter.next());
-})();
+++ /dev/null
-// 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: --harmony-computed-property-names --harmony-object-literals
-
-
-function ID(x) {
- return x;
-}
-
-
-(function TestMethodComputedNameString() {
- var object = {
- a() { return 'A'},
- ['b']() { return 'B'; },
- c() { return 'C'; },
- [ID('d')]() { return 'D'; },
- };
- assertEquals('A', object.a());
- assertEquals('B', object.b());
- assertEquals('C', object.c());
- assertEquals('D', object.d());
- assertArrayEquals(['a', 'b', 'c', 'd'], Object.keys(object));
-})();
-
-
-(function TestMethodComputedNameNumber() {
- var object = {
- a() { return 'A'; },
- [1]() { return 'B'; },
- c() { return 'C'; },
- [ID(2)]() { return 'D'; },
- };
- assertEquals('A', object.a());
- assertEquals('B', object[1]());
- assertEquals('C', object.c());
- assertEquals('D', object[2]());
- // Array indexes first.
- assertArrayEquals(['1', '2', 'a', 'c'], Object.keys(object));
-})();
-
-
-(function TestMethodComputedNameSymbol() {
- var sym1 = Symbol();
- var sym2 = Symbol();
- var object = {
- a() { return 'A'; },
- [sym1]() { return 'B'; },
- c() { return 'C'; },
- [ID(sym2)]() { return 'D'; },
- };
- assertEquals('A', object.a());
- assertEquals('B', object[sym1]());
- assertEquals('C', object.c());
- assertEquals('D', object[sym2]());
- assertArrayEquals(['a', 'c'], Object.keys(object));
- assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(object));
-})();
-
-
-function assertIteratorResult(value, done, result) {
- assertEquals({ value: value, done: done}, result);
-}
-
-
-(function TestGeneratorComputedName() {
- var object = {
- *['a']() {
- yield 1;
- yield 2;
- }
- };
- var iter = object.a();
- assertIteratorResult(1, false, iter.next());
- assertIteratorResult(2, false, iter.next());
- assertIteratorResult(undefined, true, iter.next());
- assertArrayEquals(['a'], Object.keys(object));
-})();
-
-
-(function TestToNameSideEffects() {
- var counter = 0;
- var key1 = {
- toString: function() {
- assertEquals(0, counter++);
- return 'b';
- }
- };
- var key2 = {
- toString: function() {
- assertEquals(1, counter++);
- return 'd';
- }
- };
- var object = {
- a() { return 'A'; },
- [key1]() { return 'B'; },
- c() { return 'C'; },
- [key2]() { return 'D'; },
- };
- assertEquals(2, counter);
- assertEquals('A', object.a());
- assertEquals('B', object.b());
- assertEquals('C', object.c());
- assertEquals('D', object.d());
- assertArrayEquals(['a', 'b', 'c', 'd'], Object.keys(object));
-})();
-
-
-(function TestDuplicateKeys() {
- 'use strict';
- // ES5 does not allow duplicate keys.
- // ES6 does but we haven't changed our code yet.
-
- var object = {
- a() { return 1; },
- ['a']() { return 2; },
- };
- assertEquals(2, object.a());
-})();
+++ /dev/null
-// 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: --harmony-computed-property-names
-
-
-function ID(x) {
- return x;
-}
-
-
-
-(function TestBasicsString() {
- var object = {
- a: 'A',
- ['b']: 'B',
- c: 'C',
- [ID('d')]: 'D',
- };
- assertEquals('A', object.a);
- assertEquals('B', object.b);
- assertEquals('C', object.c);
- assertEquals('D', object.d);
- assertArrayEquals(['a', 'b', 'c', 'd'], Object.keys(object));
-})();
-
-
-(function TestBasicsNumber() {
- var object = {
- a: 'A',
- [1]: 'B',
- c: 'C',
- [ID(2)]: 'D',
- };
- assertEquals('A', object.a);
- assertEquals('B', object[1]);
- assertEquals('C', object.c);
- assertEquals('D', object[2]);
- // Array indexes first.
- assertArrayEquals(['1', '2', 'a', 'c'], Object.keys(object));
-})();
-
-
-(function TestBasicsSymbol() {
- var sym1 = Symbol();
- var sym2 = Symbol();
- var object = {
- a: 'A',
- [sym1]: 'B',
- c: 'C',
- [ID(sym2)]: 'D',
- };
- assertEquals('A', object.a);
- assertEquals('B', object[sym1]);
- assertEquals('C', object.c);
- assertEquals('D', object[sym2]);
- assertArrayEquals(['a', 'c'], Object.keys(object));
- assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(object));
-})();
-
-
-(function TestToNameSideEffects() {
- var counter = 0;
- var key1 = {
- toString: function() {
- assertEquals(0, counter++);
- return 'b';
- }
- };
- var key2 = {
- toString: function() {
- assertEquals(1, counter++);
- return 'd';
- }
- };
- var object = {
- a: 'A',
- [key1]: 'B',
- c: 'C',
- [key2]: 'D',
- };
- assertEquals(2, counter);
- assertEquals('A', object.a);
- assertEquals('B', object.b);
- assertEquals('C', object.c);
- assertEquals('D', object.d);
- assertArrayEquals(['a', 'b', 'c', 'd'], Object.keys(object));
-})();
-
-
-(function TestToNameSideEffectsNumbers() {
- var counter = 0;
- var key1 = {
- valueOf: function() {
- assertEquals(0, counter++);
- return 1;
- },
- toString: null
- };
- var key2 = {
- valueOf: function() {
- assertEquals(1, counter++);
- return 2;
- },
- toString: null
- };
-
- var object = {
- a: 'A',
- [key1]: 'B',
- c: 'C',
- [key2]: 'D',
- };
- assertEquals(2, counter);
- assertEquals('A', object.a);
- assertEquals('B', object[1]);
- assertEquals('C', object.c);
- assertEquals('D', object[2]);
- // Array indexes first.
- assertArrayEquals(['1', '2', 'a', 'c'], Object.keys(object));
-})();
-
-
-(function TestDoubleName() {
- var object = {
- [1.2]: 'A',
- [1e55]: 'B',
- [0.000001]: 'C',
- [-0]: 'D',
- [Infinity]: 'E',
- [-Infinity]: 'F',
- [NaN]: 'G',
- };
- assertEquals('A', object['1.2']);
- assertEquals('B', object['1e+55']);
- assertEquals('C', object['0.000001']);
- assertEquals('D', object[0]);
- assertEquals('E', object[Infinity]);
- assertEquals('F', object[-Infinity]);
- assertEquals('G', object[NaN]);
-})();
-
-
-(function TestGetter() {
- var object = {
- get ['a']() {
- return 'A';
- }
- };
- assertEquals('A', object.a);
-
- object = {
- get b() {
- assertUnreachable();
- },
- get ['b']() {
- return 'B';
- }
- };
- assertEquals('B', object.b);
-
- object = {
- get c() {
- assertUnreachable();
- },
- get ['c']() {
- assertUnreachable();
- },
- get ['c']() {
- return 'C';
- }
- };
- assertEquals('C', object.c);
-
- object = {
- get ['d']() {
- assertUnreachable();
- },
- get d() {
- return 'D';
- }
- };
- assertEquals('D', object.d);
-})();
-
-
-(function TestSetter() {
- var calls = 0;
- var object = {
- set ['a'](_) {
- calls++;
- }
- };
- object.a = 'A';
- assertEquals(1, calls);
-
- calls = 0;
- object = {
- set b(_) {
- assertUnreachable();
- },
- set ['b'](_) {
- calls++;
- }
- };
- object.b = 'B';
- assertEquals(1, calls);
-
- calls = 0;
- object = {
- set c(_) {
- assertUnreachable()
- },
- set ['c'](_) {
- assertUnreachable()
- },
- set ['c'](_) {
- calls++
- }
- };
- object.c = 'C';
- assertEquals(1, calls);
-
- calls = 0;
- object = {
- set ['d'](_) {
- assertUnreachable()
- },
- set d(_) {
- calls++
- }
- };
- object.d = 'D';
- assertEquals(1, calls);
-})();
-
-
-(function TestDuplicateKeys() {
- 'use strict';
- // ES5 does not allow duplicate keys.
- // ES6 does but we haven't changed our code yet.
-
- var object = {
- a: 1,
- ['a']: 2,
- };
- assertEquals(2, object.a);
-})();
-
-
-(function TestProto() {
- var proto = {};
- var object = {
- __proto__: proto
- };
- assertEquals(proto, Object.getPrototypeOf(object));
-
- object = {
- '__proto__': proto
- };
- assertEquals(proto, Object.getPrototypeOf(object));
-
- var object = {
- ['__proto__']: proto
- };
- assertEquals(Object.prototype, Object.getPrototypeOf(object));
- assertEquals(proto, object.__proto__);
- assertTrue(object.hasOwnProperty('__proto__'));
-})();