Index: src/compiler/ast-graph-builder.cc |
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc |
index 161a33a10d4ac8663c2e57e81b99a737b8468cfc..13c26370717032f75201aed394bcccca6e5f65c9 100644 |
--- a/src/compiler/ast-graph-builder.cc |
+++ b/src/compiler/ast-graph-builder.cc |
@@ -1614,6 +1614,13 @@ void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { |
OutputFrameStateCombine::Push()); |
environment()->Push(prototype); |
+ Node* needs_name; |
+ bool check_name = !expr->has_name_static_property() && |
+ !expr->constructor()->raw_name()->IsEmpty(); |
+ if (check_name) { |
+ needs_name = jsgraph()->TrueConstant(); |
+ } |
+ |
// Create nodes to store method values into the literal. |
for (int i = 0; i < expr->properties()->length(); i++) { |
ClassLiteral::Property* property = expr->properties()->at(i); |
@@ -1623,11 +1630,38 @@ void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { |
Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i)); |
environment()->Push(name); |
- // The static prototype property is read only. We handle the non computed |
- // property name case in the parser. Since this is the only case where we |
- // need to check for an own read only property we special case this so we do |
- // not need to do this for every property. |
if (property->is_static() && property->is_computed_name()) { |
+ // Check for a static property called "name". The non computed property |
+ // name is handled in the parser. |
+ if (check_name) { |
+ IfBuilder needs_name_is_false(this); |
+ Node* needs_name_is_false_cond = |
+ NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
+ needs_name, jsgraph()->FalseConstant()); |
+ needs_name_is_false.If(needs_name_is_false_cond, BranchHint::kFalse); |
+ needs_name_is_false.Then(); |
+ needs_name_is_false.Else(); |
+ { |
+ IfBuilder has_name(this); |
+ Node* name_string = |
+ jsgraph()->Constant(isolate()->factory()->name_string()); |
+ Node* has_name_cond = |
+ NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
+ name, name_string); |
+ has_name.If(has_name_cond, BranchHint::kFalse); |
+ has_name.Then(); |
+ needs_name = jsgraph()->FalseConstant(); |
+ has_name.Else(); |
+ has_name.End(); |
+ } |
+ needs_name_is_false.End(); |
+ } |
+ |
+ // The static prototype property is read only. We handle the non computed |
+ // property name case in the parser. Since this is the only case where we |
+ // need to check for an own read only property we special case this so we |
+ // do |
+ // not need to do this for every property. |
Node* check = BuildThrowIfStaticPrototype(environment()->Pop(), |
expr->GetIdForProperty(i)); |
environment()->Push(check); |
@@ -1672,8 +1706,29 @@ void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { |
} |
} |
- // Set the constructor to have fast properties. |
prototype = environment()->Pop(); |
+ |
+ // Install a "name" property if missing. |
+ if (check_name) { |
+ IfBuilder install_name(this); |
+ Node* install_name_cond = |
+ NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
+ needs_name, jsgraph()->TrueConstant()); |
+ install_name.If(install_name_cond, BranchHint::kTrue); |
+ install_name.Then(); |
+ { |
+ literal = environment()->Pop(); |
+ const Operator* op = |
+ javascript()->CallRuntime(Runtime::kInstallClassNameAccessor); |
+ literal = NewNode(op, literal); |
+ PrepareFrameState(literal, BailoutId::None()); |
+ environment()->Push(literal); |
+ } |
+ install_name.Else(); |
+ install_name.End(); |
+ } |
+ |
+ // Set the constructor to have fast properties. |
literal = environment()->Pop(); |
const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties); |
literal = NewNode(op, literal); |