Index: src/arm64/full-codegen-arm64.cc |
diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc |
index 3a46a93f5fcb6bb8566d335473f7a5121a48f1e3..5dcde45d5652239f75423c1f3cd114d27deb2b03 100644 |
--- a/src/arm64/full-codegen-arm64.cc |
+++ b/src/arm64/full-codegen-arm64.cc |
@@ -1667,11 +1667,13 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
expr->CalculateEmitStore(zone()); |
AccessorTable accessor_table(zone()); |
- for (int i = 0; i < expr->properties()->length(); i++) { |
- ObjectLiteral::Property* property = expr->properties()->at(i); |
+ 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; |
if (property->IsCompileTimeValue()) continue; |
- Literal* key = property->key(); |
+ Literal* key = property->key()->AsLiteral(); |
Expression* value = property->value(); |
if (!result_saved) { |
__ Push(x0); // Save result on stack |
@@ -1759,6 +1761,67 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
__ 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); |
@@ -2175,9 +2238,7 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
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 |
@@ -2185,7 +2246,7 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
__ Peek(scratch, 0); // prototype |
} |
__ Push(scratch); |
- VisitForStackValue(key); |
+ EmitPropertyKey(property); |
VisitForStackValue(value); |
EmitSetHomeObjectIfNeeded(value, 2); |
@@ -2198,11 +2259,11 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
break; |
case ObjectLiteral::Property::GETTER: |
- __ CallRuntime(Runtime::kDefineClassGetter, 3); |
+ __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3); |
break; |
case ObjectLiteral::Property::SETTER: |
- __ CallRuntime(Runtime::kDefineClassSetter, 3); |
+ __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3); |
break; |
default: |