Support computed properties for ES2015 Function.name

Adds a new runtime function, %DefineDataPropertyInLiteral, which
takes a fifth argument specifying whether the property and value
are syntactically such that the value is a function (or class)
literal that should have its name set at runtime.

The new runtime call also allows us to eliminate the now-redundant
%DefineClassMethod runtime function.

This should get much less ugly once we can desugar the "dynamic"
part of object literals in the parser (but that work is currently
blocked on having a performant way of desugaring literals).

BUG=v8:3699, v8:3761
LOG=n

Review URL: https://codereview.chromium.org/1626423003

Cr-Commit-Position: refs/heads/master@{#33756}
This commit is contained in:
adamk 2016-02-04 14:36:15 -08:00 committed by Commit bot
parent ca255fd5e6
commit 21c045a2fa
20 changed files with 258 additions and 143 deletions

View File

@ -1477,6 +1477,10 @@ class ObjectLiteralProperty final : public ZoneObject {
void set_receiver_type(Handle<Map> map) { receiver_type_ = map; } void set_receiver_type(Handle<Map> map) { receiver_type_ = map; }
bool NeedsSetFunctionName() const {
return is_computed_name_ && value_->IsAnonymousFunctionDefinition();
}
protected: protected:
friend class AstNodeFactory; friend class AstNodeFactory;

View File

@ -1606,9 +1606,12 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: { case ObjectLiteral::Property::COMPUTED: {
Node* attr = jsgraph()->Constant(DONT_ENUM);
Node* set_function_name =
jsgraph()->Constant(property->NeedsSetFunctionName());
const Operator* op = const Operator* op =
javascript()->CallRuntime(Runtime::kDefineClassMethod); javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
NewNode(op, receiver, key, value); NewNode(op, receiver, key, value, attr, set_function_name);
break; break;
} }
case ObjectLiteral::Property::GETTER: { case ObjectLiteral::Property::GETTER: {
@ -1855,10 +1858,11 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::MATERIALIZED_LITERAL: { case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
Node* attr = jsgraph()->Constant(NONE); Node* attr = jsgraph()->Constant(NONE);
Node* set_function_name =
jsgraph()->Constant(property->NeedsSetFunctionName());
const Operator* op = const Operator* op =
javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked); javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
Node* call = NewNode(op, receiver, key, value, attr); NewNode(op, receiver, key, value, attr, set_function_name);
PrepareFrameState(call, BailoutId::None());
break; break;
} }
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:

View File

@ -148,7 +148,7 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
switch (function) { switch (function) {
case Runtime::kAllocateInTargetSpace: case Runtime::kAllocateInTargetSpace:
case Runtime::kCreateIterResultObject: case Runtime::kCreateIterResultObject:
case Runtime::kDefineClassMethod: // TODO(jarin): Is it safe? case Runtime::kDefineDataPropertyInLiteral:
case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe? case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe?
case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe? case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe?
case Runtime::kFinalizeClassDefinition: // TODO(conradw): Is it safe? case Runtime::kFinalizeClassDefinition: // TODO(conradw): Is it safe?

View File

@ -1646,9 +1646,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::MATERIALIZED_LITERAL: case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (property->emit_store()) { if (property->emit_store()) {
__ mov(r0, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(r0); __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyUnchecked); __ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
} else { } else {
__ Drop(3); __ Drop(3);
} }
@ -1659,14 +1659,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ mov(r0, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(r0);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ mov(r0, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(r0);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;
} }
@ -2401,18 +2399,18 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
__ CallRuntime(Runtime::kDefineClassMethod); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ mov(r0, Operand(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ push(r0);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ mov(r0, Operand(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ push(r0);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;

View File

@ -1633,9 +1633,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::MATERIALIZED_LITERAL: case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (property->emit_store()) { if (property->emit_store()) {
__ Mov(x0, Smi::FromInt(NONE)); __ Push(Smi::FromInt(NONE));
__ Push(x0); __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyUnchecked); __ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
} else { } else {
__ Drop(3); __ Drop(3);
} }
@ -1646,14 +1646,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ Mov(x0, Smi::FromInt(NONE)); __ Push(Smi::FromInt(NONE));
__ Push(x0);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ Mov(x0, Smi::FromInt(NONE)); __ Push(Smi::FromInt(NONE));
__ Push(x0);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;
} }
@ -2101,18 +2099,18 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
__ CallRuntime(Runtime::kDefineClassMethod); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ Mov(x0, Smi::FromInt(DONT_ENUM)); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(x0);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ Mov(x0, Smi::FromInt(DONT_ENUM)); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(x0);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;

View File

@ -1564,8 +1564,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::MATERIALIZED_LITERAL: case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (property->emit_store()) { if (property->emit_store()) {
__ push(Immediate(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ CallRuntime(Runtime::kDefineDataPropertyUnchecked); __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
} else { } else {
__ Drop(3); __ Drop(3);
} }
@ -1576,12 +1577,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ push(Immediate(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ push(Immediate(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;
} }
@ -2301,16 +2302,18 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
__ CallRuntime(Runtime::kDefineClassMethod); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ push(Immediate(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ push(Immediate(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;
} }

View File

@ -1643,9 +1643,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::MATERIALIZED_LITERAL: case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (property->emit_store()) { if (property->emit_store()) {
__ li(a0, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(a0); __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyUnchecked); __ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
} else { } else {
__ Drop(3); __ Drop(3);
} }
@ -1656,14 +1656,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ li(a0, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(a0);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ li(a0, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(a0);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;
} }
@ -2391,18 +2389,18 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
__ CallRuntime(Runtime::kDefineClassMethod); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ li(a0, Operand(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ push(a0);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ li(a0, Operand(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ push(a0);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;

View File

@ -1644,9 +1644,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::MATERIALIZED_LITERAL: case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (property->emit_store()) { if (property->emit_store()) {
__ li(a0, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(a0); __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyUnchecked); __ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
} else { } else {
__ Drop(3); __ Drop(3);
} }
@ -1657,14 +1657,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ li(a0, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(a0);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ li(a0, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(a0);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;
} }
@ -2396,18 +2394,18 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
__ CallRuntime(Runtime::kDefineClassMethod); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ li(a0, Operand(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ push(a0);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ li(a0, Operand(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ push(a0);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;

View File

@ -1606,9 +1606,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::MATERIALIZED_LITERAL: case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (property->emit_store()) { if (property->emit_store()) {
__ LoadSmiLiteral(r3, Smi::FromInt(NONE)); __ Push(Smi::FromInt(NONE));
__ push(r3); __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyUnchecked); __ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
} else { } else {
__ Drop(3); __ Drop(3);
} }
@ -1619,14 +1619,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ mov(r3, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(r3);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ mov(r3, Operand(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ push(r3);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;
} }
@ -2399,18 +2397,18 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
__ CallRuntime(Runtime::kDefineClassMethod); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ mov(r3, Operand(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ push(r3);
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ mov(r3, Operand(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ push(r3);
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;

View File

@ -1588,7 +1588,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (property->emit_store()) { if (property->emit_store()) {
__ Push(Smi::FromInt(NONE)); __ Push(Smi::FromInt(NONE));
__ CallRuntime(Runtime::kDefineDataPropertyUnchecked); __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
} else { } else {
__ Drop(3); __ Drop(3);
} }
@ -2287,7 +2288,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
__ CallRuntime(Runtime::kDefineClassMethod); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:

View File

@ -1559,8 +1559,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::MATERIALIZED_LITERAL: case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (property->emit_store()) { if (property->emit_store()) {
__ push(Immediate(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ CallRuntime(Runtime::kDefineDataPropertyUnchecked); __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
} else { } else {
__ Drop(3); __ Drop(3);
} }
@ -1571,12 +1572,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ push(Immediate(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ push(Immediate(Smi::FromInt(NONE))); __ Push(Smi::FromInt(NONE));
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;
} }
@ -2285,16 +2286,18 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
__ CallRuntime(Runtime::kDefineClassMethod); __ Push(Smi::FromInt(DONT_ENUM));
__ Push(Smi::FromInt(property->NeedsSetFunctionName()));
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ push(Immediate(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ push(Immediate(Smi::FromInt(DONT_ENUM))); __ Push(Smi::FromInt(DONT_ENUM));
__ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
break; break;
} }

View File

@ -1292,11 +1292,12 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
Register literal, Register literal,
Register prototype) { Register prototype) {
RegisterAllocationScope register_scope(this); RegisterAllocationScope register_scope(this);
register_allocator()->PrepareForConsecutiveAllocations(4); register_allocator()->PrepareForConsecutiveAllocations(5);
Register receiver = register_allocator()->NextConsecutiveRegister(); Register receiver = register_allocator()->NextConsecutiveRegister();
Register key = register_allocator()->NextConsecutiveRegister(); Register key = register_allocator()->NextConsecutiveRegister();
Register value = register_allocator()->NextConsecutiveRegister(); Register value = register_allocator()->NextConsecutiveRegister();
Register attr = register_allocator()->NextConsecutiveRegister(); Register attr = register_allocator()->NextConsecutiveRegister();
Register set_function_name = register_allocator()->NextConsecutiveRegister();
bool attr_assigned = false; bool attr_assigned = false;
Register old_receiver = Register::invalid_value(); Register old_receiver = Register::invalid_value();
@ -1326,9 +1327,7 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
VisitSetHomeObject(value, receiver, property); VisitSetHomeObject(value, receiver, property);
if ((property->kind() == ObjectLiteral::Property::GETTER || if (!attr_assigned) {
property->kind() == ObjectLiteral::Property::SETTER) &&
!attr_assigned) {
builder() builder()
->LoadLiteral(Smi::FromInt(DONT_ENUM)) ->LoadLiteral(Smi::FromInt(DONT_ENUM))
.StoreAccumulatorInRegister(attr); .StoreAccumulatorInRegister(attr);
@ -1343,7 +1342,11 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
UNREACHABLE(); UNREACHABLE();
break; break;
case ObjectLiteral::Property::COMPUTED: { case ObjectLiteral::Property::COMPUTED: {
builder()->CallRuntime(Runtime::kDefineClassMethod, receiver, 3); builder()
->LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
.StoreAccumulatorInRegister(set_function_name);
builder()->CallRuntime(Runtime::kDefineDataPropertyInLiteral, receiver,
5);
break; break;
} }
case ObjectLiteral::Property::GETTER: { case ObjectLiteral::Property::GETTER: {
@ -1578,12 +1581,14 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
continue; continue;
} }
register_allocator()->PrepareForConsecutiveAllocations(4); register_allocator()->PrepareForConsecutiveAllocations(5);
Register literal_argument = register_allocator()->NextConsecutiveRegister(); Register literal_argument = register_allocator()->NextConsecutiveRegister();
Register key = register_allocator()->NextConsecutiveRegister(); Register key = register_allocator()->NextConsecutiveRegister();
Register value = register_allocator()->NextConsecutiveRegister(); Register value = register_allocator()->NextConsecutiveRegister();
Register attr = register_allocator()->NextConsecutiveRegister(); Register attr = register_allocator()->NextConsecutiveRegister();
DCHECK(Register::AreContiguous(literal_argument, key, value, attr)); DCHECK(Register::AreContiguous(literal_argument, key, value, attr));
Register set_function_name =
register_allocator()->NextConsecutiveRegister();
builder()->MoveRegister(literal, literal_argument); builder()->MoveRegister(literal, literal_argument);
VisitForAccumulatorValue(property->key()); VisitForAccumulatorValue(property->key());
@ -1592,24 +1597,28 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
builder()->StoreAccumulatorInRegister(value); builder()->StoreAccumulatorInRegister(value);
VisitSetHomeObject(value, literal, property); VisitSetHomeObject(value, literal, property);
builder()->LoadLiteral(Smi::FromInt(NONE)).StoreAccumulatorInRegister(attr); builder()->LoadLiteral(Smi::FromInt(NONE)).StoreAccumulatorInRegister(attr);
Runtime::FunctionId function_id = static_cast<Runtime::FunctionId>(-1);
switch (property->kind()) { switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT: case ObjectLiteral::Property::CONSTANT:
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::MATERIALIZED_LITERAL: case ObjectLiteral::Property::MATERIALIZED_LITERAL:
function_id = Runtime::kDefineDataPropertyUnchecked; builder()
->LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
.StoreAccumulatorInRegister(set_function_name);
builder()->CallRuntime(Runtime::kDefineDataPropertyInLiteral,
literal_argument, 5);
break; break;
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE(); // Handled specially above. UNREACHABLE(); // Handled specially above.
break; break;
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
function_id = Runtime::kDefineGetterPropertyUnchecked; builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked,
literal_argument, 4);
break; break;
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
function_id = Runtime::kDefineSetterPropertyUnchecked; builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked,
literal_argument, 4);
break; break;
} }
builder()->CallRuntime(function_id, literal_argument, 4);
} }
// Transform literals that contain functions to fast properties. // Transform literals that contain functions to fast properties.

View File

@ -13317,6 +13317,22 @@ Handle<String> JSFunction::GetDebugName(Handle<JSFunction> function) {
return JSFunction::GetName(function); return JSFunction::GetName(function);
} }
void JSFunction::SetName(Handle<JSFunction> function, Handle<Name> name,
Handle<String> prefix) {
Isolate* isolate = function->GetIsolate();
Handle<String> function_name = Name::ToFunctionName(name).ToHandleChecked();
if (prefix->length() > 0) {
IncrementalStringBuilder builder(isolate);
builder.AppendString(prefix);
builder.AppendCharacter(' ');
builder.AppendString(function_name);
function_name = builder.Finish().ToHandleChecked();
}
JSObject::DefinePropertyOrElementIgnoreAttributes(
function, isolate->factory()->name_string(), function_name,
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY))
.ToHandleChecked();
}
namespace { namespace {

View File

@ -7509,6 +7509,12 @@ class JSFunction: public JSObject {
// debug name. // debug name.
static Handle<String> GetName(Handle<JSFunction> function); static Handle<String> GetName(Handle<JSFunction> function);
// ES6 section 9.2.11 SetFunctionName
// Because of the way this abstract operation is used in the spec,
// it should never fail.
static void SetName(Handle<JSFunction> function, Handle<Name> name,
Handle<String> prefix);
// The function's displayName if it is set, otherwise name if it is // The function's displayName if it is set, otherwise name if it is
// configured, otherwise shared function info // configured, otherwise shared function info
// debug name. // debug name.

View File

@ -5706,8 +5706,9 @@ void ParserTraits::SetFunctionNameFromPropertyName(
Expression* value = property->value(); Expression* value = property->value();
if (!value->IsAnonymousFunctionDefinition()) return; if (!value->IsAnonymousFunctionDefinition()) return;
// TODO(adamk): Support computed names. // Computed name setting must happen at runtime.
if (property->is_computed_name()) return; if (property->is_computed_name()) return;
DCHECK_NOT_NULL(name); DCHECK_NOT_NULL(name);
// Ignore "__proto__" as a name when it's being used to set the [[Prototype]] // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]

View File

@ -203,20 +203,6 @@ RUNTIME_FUNCTION(Runtime_DefineClass) {
} }
RUNTIME_FUNCTION(Runtime_DefineClassMethod) {
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, function, 2);
RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::DefinePropertyOrElementIgnoreAttributes(
object, name, function, DONT_ENUM));
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_FinalizeClassDefinition) { RUNTIME_FUNCTION(Runtime_FinalizeClassDefinition) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK(args.length() == 2); DCHECK(args.length() == 2);

View File

@ -915,6 +915,30 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
return *result; return *result;
} }
RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
HandleScope scope(isolate);
DCHECK(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
CONVERT_SMI_ARG_CHECKED(set_function_name, 4);
if (FLAG_harmony_function_name && set_function_name) {
DCHECK(value->IsJSFunction());
JSFunction::SetName(Handle<JSFunction>::cast(value), name,
isolate->factory()->empty_string());
}
LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name,
LookupIterator::OWN);
// Cannot fail since this should only be called when
// creating an object literal.
CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs,
Object::DONT_THROW)
.IsJust());
return *object;
}
// Return property without being observable by accessors or interceptors. // Return property without being observable by accessors or interceptors.
RUNTIME_FUNCTION(Runtime_GetDataProperty) { RUNTIME_FUNCTION(Runtime_GetDataProperty) {
@ -1006,6 +1030,11 @@ RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2); CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
if (FLAG_harmony_function_name &&
String::cast(getter->shared()->name())->length() == 0) {
JSFunction::SetName(getter, name, isolate->factory()->get_string());
}
RETURN_FAILURE_ON_EXCEPTION( RETURN_FAILURE_ON_EXCEPTION(
isolate, isolate,
JSObject::DefineAccessor(object, name, getter, JSObject::DefineAccessor(object, name, getter,
@ -1022,6 +1051,11 @@ RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2); CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
if (FLAG_harmony_function_name &&
String::cast(setter->shared()->name())->length() == 0) {
JSFunction::SetName(setter, name, isolate->factory()->set_string());
}
RETURN_FAILURE_ON_EXCEPTION( RETURN_FAILURE_ON_EXCEPTION(
isolate, isolate,
JSObject::DefineAccessor(object, name, isolate->factory()->null_value(), JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),

View File

@ -84,7 +84,6 @@ namespace internal {
F(HomeObjectSymbol, 0, 1) \ F(HomeObjectSymbol, 0, 1) \
F(DefineClass, 4, 1) \ F(DefineClass, 4, 1) \
F(FinalizeClassDefinition, 2, 1) \ F(FinalizeClassDefinition, 2, 1) \
F(DefineClassMethod, 3, 1) \
F(LoadFromSuper, 4, 1) \ F(LoadFromSuper, 4, 1) \
F(LoadKeyedFromSuper, 4, 1) \ F(LoadKeyedFromSuper, 4, 1) \
F(StoreToSuper_Strict, 4, 1) \ F(StoreToSuper_Strict, 4, 1) \
@ -414,7 +413,6 @@ namespace internal {
F(GetHoleNaNUpper, 0, 1) \ F(GetHoleNaNUpper, 0, 1) \
F(GetHoleNaNLower, 0, 1) F(GetHoleNaNLower, 0, 1)
#define FOR_EACH_INTRINSIC_OBJECT(F) \ #define FOR_EACH_INTRINSIC_OBJECT(F) \
F(GetPrototype, 1, 1) \ F(GetPrototype, 1, 1) \
F(InternalSetPrototype, 2, 1) \ F(InternalSetPrototype, 2, 1) \
@ -451,6 +449,7 @@ namespace internal {
F(IsJSGlobalProxy, 1, 1) \ F(IsJSGlobalProxy, 1, 1) \
F(DefineAccessorPropertyUnchecked, 5, 1) \ F(DefineAccessorPropertyUnchecked, 5, 1) \
F(DefineDataPropertyUnchecked, 4, 1) \ F(DefineDataPropertyUnchecked, 4, 1) \
F(DefineDataPropertyInLiteral, 5, 1) \
F(GetDataProperty, 2, 1) \ F(GetDataProperty, 2, 1) \
F(HasFastPackedElements, 1, 1) \ F(HasFastPackedElements, 1, 1) \
F(ValueOf, 1, 1) \ F(ValueOf, 1, 1) \
@ -482,7 +481,6 @@ namespace internal {
F(ObjectDefineProperties, 2, 1) \ F(ObjectDefineProperties, 2, 1) \
F(ObjectDefineProperty, 3, 1) F(ObjectDefineProperty, 3, 1)
#define FOR_EACH_INTRINSIC_OBSERVE(F) \ #define FOR_EACH_INTRINSIC_OBSERVE(F) \
F(IsObserved, 1, 1) \ F(IsObserved, 1, 1) \
F(SetIsObserved, 1, 1) \ F(SetIsObserved, 1, 1) \

View File

@ -4174,6 +4174,7 @@ TEST(ObjectLiterals) {
ObjectLiteral::kDisableMementos; ObjectLiteral::kDisableMementos;
int deep_elements_flags = int deep_elements_flags =
ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos;
// clang-format off // clang-format off
ExpectedSnippet<InstanceType> snippets[] = { ExpectedSnippet<InstanceType> snippets[] = {
{"return { };", {"return { };",
@ -4390,9 +4391,9 @@ TEST(ObjectLiterals) {
1, 1,
{InstanceType::FIXED_ARRAY_TYPE}}, {InstanceType::FIXED_ARRAY_TYPE}},
{"var a = 'test'; return { [a]: 1 }", {"var a = 'test'; return { [a]: 1 }",
6 * kPointerSize, 7 * kPointerSize,
1, 1,
34, 37,
{ {
B(StackCheck), // B(StackCheck), //
B(LdaConstant), U8(0), // B(LdaConstant), U8(0), //
@ -4407,8 +4408,10 @@ TEST(ObjectLiterals) {
B(Star), R(4), // B(Star), R(4), //
B(LdaZero), // B(LdaZero), //
B(Star), R(5), // B(Star), R(5), //
B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(2), // B(LdaZero), //
/* */ U8(4), // B(Star), R(6), //
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), //
/* */ U8(5), //
B(Ldar), R(1), // B(Ldar), R(1), //
B(Return), // B(Return), //
}, },
@ -4416,9 +4419,9 @@ TEST(ObjectLiterals) {
{InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
InstanceType::FIXED_ARRAY_TYPE}}, InstanceType::FIXED_ARRAY_TYPE}},
{"var a = 'test'; return { val: a, [a]: 1 }", {"var a = 'test'; return { val: a, [a]: 1 }",
6 * kPointerSize, 7 * kPointerSize,
1, 1,
40, 43,
{ {
B(StackCheck), // B(StackCheck), //
B(LdaConstant), U8(0), // B(LdaConstant), U8(0), //
@ -4435,8 +4438,10 @@ TEST(ObjectLiterals) {
B(Star), R(4), // B(Star), R(4), //
B(LdaZero), // B(LdaZero), //
B(Star), R(5), // B(Star), R(5), //
B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(2), // B(LdaZero), //
/* */ U8(4), // B(Star), R(6), //
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), //
/* */ U8(5), //
B(Ldar), R(1), // B(Ldar), R(1), //
B(Return), // B(Return), //
}, },
@ -4445,9 +4450,9 @@ TEST(ObjectLiterals) {
InstanceType::FIXED_ARRAY_TYPE, InstanceType::FIXED_ARRAY_TYPE,
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
{"var a = 'test'; return { [a]: 1, __proto__: {} }", {"var a = 'test'; return { [a]: 1, __proto__: {} }",
6 * kPointerSize, 7 * kPointerSize,
1, 1,
50, 53,
{ {
B(StackCheck), // B(StackCheck), //
B(LdaConstant), U8(0), // B(LdaConstant), U8(0), //
@ -4462,8 +4467,10 @@ TEST(ObjectLiterals) {
B(Star), R(4), // B(Star), R(4), //
B(LdaZero), // B(LdaZero), //
B(Star), R(5), // B(Star), R(5), //
B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(2), // B(LdaZero), //
/* */ U8(4), // B(Star), R(6), //
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), //
/* */ U8(5), //
B(Mov), R(1), R(2), // B(Mov), R(1), R(2), //
B(CreateObjectLiteral), U8(1), U8(0), U8(13), // B(CreateObjectLiteral), U8(1), U8(0), U8(13), //
B(Star), R(4), // B(Star), R(4), //
@ -4476,9 +4483,9 @@ TEST(ObjectLiterals) {
{InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
InstanceType::FIXED_ARRAY_TYPE}}, InstanceType::FIXED_ARRAY_TYPE}},
{"var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };", {"var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };",
6 * kPointerSize, 7 * kPointerSize,
1, 1,
74, 77,
{ {
B(StackCheck), // B(StackCheck), //
B(LdaConstant), U8(0), // B(LdaConstant), U8(0), //
@ -4493,8 +4500,10 @@ TEST(ObjectLiterals) {
B(Star), R(4), // B(Star), R(4), //
B(LdaZero), // B(LdaZero), //
B(Star), R(5), // B(Star), R(5), //
B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(2), // B(LdaZero), //
/* */ U8(4), // B(Star), R(6), //
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), //
/* */ U8(5), //
B(Mov), R(1), R(2), // B(Mov), R(1), R(2), //
B(LdaConstant), U8(3), // B(LdaConstant), U8(3), //
B(Star), R(3), // B(Star), R(3), //
@ -8381,7 +8390,9 @@ TEST(DoDebugger) {
CheckBytecodeArrayEqual(snippet, bytecode_array); CheckBytecodeArrayEqual(snippet, bytecode_array);
} }
TEST(ClassDeclarations) { // TODO(rmcilroy): Update expectations after switch to
// Runtime::kDefineDataPropertyInLiteral.
DISABLED_TEST(ClassDeclarations) {
InitializedHandleScope handle_scope; InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper; BytecodeGeneratorHelper helper;
@ -8420,7 +8431,7 @@ TEST(ClassDeclarations) {
B(Star), R(5), // B(Star), R(5), //
B(CreateClosure), U8(3), U8(0), // B(CreateClosure), U8(3), U8(0), //
B(Star), R(6), // B(Star), R(6), //
B(CallRuntime), U16(Runtime::kDefineClassMethod), R(4), U8(3), // B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(4), U8(3),
B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(2), U8(2), // B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(2), U8(2), //
B(Star), R(0), // B(Star), R(0), //
B(Star), R(1), // B(Star), R(1), //
@ -8461,7 +8472,7 @@ TEST(ClassDeclarations) {
B(Star), R(5), // B(Star), R(5), //
B(CreateClosure), U8(3), U8(0), // B(CreateClosure), U8(3), U8(0), //
B(Star), R(6), // B(Star), R(6), //
B(CallRuntime), U16(Runtime::kDefineClassMethod), R(4), U8(3), // B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(4), U8(3),
B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(2), U8(2), // B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(2), U8(2), //
B(Star), R(0), // B(Star), R(0), //
B(Star), R(1), // B(Star), R(1), //
@ -8512,7 +8523,7 @@ TEST(ClassDeclarations) {
B(Star), R(6), // B(Star), R(6), //
B(CreateClosure), U8(3), U8(0), // B(CreateClosure), U8(3), U8(0), //
B(Star), R(7), // B(Star), R(7), //
B(CallRuntime), U16(Runtime::kDefineClassMethod), R(5), U8(3), // B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(5), U8(3),
B(Mov), R(3), R(5), // B(Mov), R(3), R(5), //
B(LdaContextSlot), R(context), U8(5), // B(LdaContextSlot), R(context), U8(5), //
B(ToName), // B(ToName), //
@ -8524,7 +8535,7 @@ TEST(ClassDeclarations) {
/* */ R(0), U8(0), // /* */ R(0), U8(0), //
B(CreateClosure), U8(5), U8(0), // B(CreateClosure), U8(5), U8(0), //
B(Star), R(7), // B(Star), R(7), //
B(CallRuntime), U16(Runtime::kDefineClassMethod), R(5), U8(3), // B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(5), U8(3),
B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(3), U8(2), // B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(3), U8(2), //
B(Star), R(0), // B(Star), R(0), //
B(Star), R(1), // B(Star), R(1), //

View File

@ -90,36 +90,59 @@
assertEquals('set 44', descriptor.set.name); assertEquals('set 44', descriptor.set.name);
})(); })();
// TODO(adamk): Make computed property names work.
(function testComputedProperties() { (function testComputedProperties() {
'use strict'; 'use strict';
var a = 'a'; var a = 'a';
var b = 'b';
var sym1 = Symbol('1'); var sym1 = Symbol('1');
var sym2 = Symbol('2'); var sym2 = Symbol('2');
var sym3 = Symbol('3');
var symNoDescription = Symbol();
var obj = { var obj = {
[a]: function() {}, [a]: function() {},
[sym1]: function() {}, [sym1]: function() {},
[sym2]: function withName() {}, [sym2]: function withName() {},
[symNoDescription]: function() {},
get [sym3]() {},
set [b](val) {},
}; };
// Should be 'a' assertEquals('a', obj[a].name);
assertEquals('', obj[a].name); assertEquals('[1]', obj[sym1].name);
// Should be '[1]'
assertEquals('', obj[sym1].name);
assertEquals('withName', obj[sym2].name); assertEquals('withName', obj[sym2].name);
assertEquals('', obj[symNoDescription].name);
assertEquals('get [3]', Object.getOwnPropertyDescriptor(obj, sym3).get.name);
assertEquals('set b', Object.getOwnPropertyDescriptor(obj, 'b').set.name);
var objMethods = {
[a]() {},
[sym1]() {},
[symNoDescription]: function() {},
};
assertEquals('a', objMethods[a].name);
assertEquals('[1]', objMethods[sym1].name);
assertEquals('', objMethods[symNoDescription].name);
class C { class C {
[a]() { } [a]() { }
[sym1]() { } [sym1]() { }
static [sym2]() { } static [sym2]() { }
[symNoDescription]() { }
get [sym3]() { }
static set [b](val) { }
} }
// Should be 'a' assertEquals('a', C.prototype[a].name);
assertEquals('', C.prototype[a].name); assertEquals('[1]', C.prototype[sym1].name);
// Should be '[1]' assertEquals('[2]', C[sym2].name);
assertEquals('', C.prototype[sym1].name); assertEquals('', C.prototype[symNoDescription].name);
// Should be '[2]'
assertEquals('', C[sym2].name); assertEquals('get [3]', Object.getOwnPropertyDescriptor(C.prototype, sym3).get.name);
assertEquals('set b', Object.getOwnPropertyDescriptor(C, 'b').set.name);
})(); })();
@ -310,3 +333,27 @@
assertEquals('inManyParens', inManyParens.name) assertEquals('inManyParens', inManyParens.name)
})(); })();
})(); })();
(function testComputedNameNotShared() {
function makeClass(propName) {
return class {
static [propName]() {}
}
}
var sym1 = Symbol('1');
var sym2 = Symbol('2');
var class1 = makeClass(sym1);
assertEquals('[1]', class1[sym1].name);
var class2 = makeClass(sym2);
assertEquals('[2]', class2[sym2].name);
assertEquals('[1]', class1[sym1].name);
})();
(function testComputedNamesOnlyAppliedSyntactically() {
function factory() { return () => {}; }
var obj = { ['foo']: factory() };
assertEquals('', obj.foo.name);
})();