Index: src/interpreter/bytecode-generator.cc |
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
index c67e5d43f706b797a63f5fe9b77257d0fefefe69..db6643fd62dcfcb722aa1be0e8bcbf714c83fd05 100644 |
--- a/src/interpreter/bytecode-generator.cc |
+++ b/src/interpreter/bytecode-generator.cc |
@@ -571,8 +571,8 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) |
generator_state_(), |
loop_depth_(0), |
home_object_symbol_(info->isolate()->factory()->home_object_symbol()), |
- prototype_string_(info->isolate()->factory()->prototype_string()) { |
-} |
+ prototype_string_(info->isolate()->factory()->prototype_string()), |
+ name_string_(info->isolate()->factory()->name_string()) {} |
Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { |
AllocateDeferredConstants(); |
@@ -1382,7 +1382,7 @@ void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { |
VisitClassLiteralForRuntimeDefinition(expr); |
// Load the "prototype" from the constructor. |
- RegisterList args = register_allocator()->NewRegisterList(2); |
+ RegisterList args = register_allocator()->NewRegisterList(3); |
Register literal = args[0]; |
Register prototype = args[1]; |
FeedbackVectorSlot slot = expr->PrototypeSlot(); |
@@ -1391,7 +1391,9 @@ void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { |
.LoadNamedProperty(literal, prototype_string(), feedback_index(slot)) |
.StoreAccumulatorInRegister(prototype); |
- VisitClassLiteralProperties(expr, literal, prototype); |
+ Register needs_name = args[2]; |
rmcilroy
2016/11/28 10:28:59
This shouldn't be allocated in the same RegisterLi
|
+ VisitClassLiteralProperties(expr, literal, prototype, needs_name); |
+ BuildClassLiteralNameProperty(expr, literal, needs_name); |
builder()->CallRuntime(Runtime::kToFastProperties, literal); |
// Assign to class variable. |
if (expr->class_variable_proxy() != nullptr) { |
@@ -1420,7 +1422,8 @@ void BytecodeGenerator::VisitClassLiteralForRuntimeDefinition( |
void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr, |
Register literal, |
- Register prototype) { |
+ Register prototype, |
+ Register needs_name) { |
RegisterAllocationScope register_scope(this); |
RegisterList args = register_allocator()->NewRegisterList(5); |
Register receiver = args[0], key = args[1], value = args[2], attr = args[3], |
@@ -1429,6 +1432,13 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr, |
bool attr_assigned = false; |
Register old_receiver = Register::invalid_value(); |
+ // Initialize has_name_static_property. |
+ bool check_name = !expr->has_name_static_property() && |
Toon Verwaest
2016/11/28 10:40:58
Isn't the general case that we don't have a static
|
+ !expr->constructor()->raw_name()->IsEmpty(); |
+ if (check_name) { |
+ builder()->LoadTrue().StoreAccumulatorInRegister(needs_name); |
+ } |
+ |
// 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); |
@@ -1444,6 +1454,19 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr, |
builder()->ConvertAccumulatorToName(key); |
if (property->is_static() && property->is_computed_name()) { |
+ // Check for a static property called "name". |
+ if (check_name) { |
+ BytecodeLabel has_name; |
+ builder() |
+ ->LoadAccumulatorWithRegister(needs_name) |
+ .JumpIfFalse(&has_name) |
+ .LoadLiteral(name_string()) |
+ .CompareOperation(Token::Value::EQ_STRICT, key) |
+ .LogicalNot() |
+ .StoreAccumulatorInRegister(needs_name) |
+ .Bind(&has_name); |
+ } |
rmcilroy
2016/11/28 10:28:59
I'm not keen on this extra code added to every pro
Toon Verwaest
2016/11/28 10:40:58
I agree, we should just do something more expensiv
|
+ |
// 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 |
@@ -1493,6 +1516,21 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr, |
} |
} |
+void BytecodeGenerator::BuildClassLiteralNameProperty(ClassLiteral* expr, |
+ Register literal, |
+ Register needs_name) { |
+ bool check_name = !expr->has_name_static_property() && |
+ !expr->constructor()->raw_name()->IsEmpty(); |
+ if (check_name) { |
+ BytecodeLabel has_name; |
+ builder() |
+ ->LoadAccumulatorWithRegister(needs_name) |
+ .JumpIfFalse(&has_name) |
+ .CallRuntime(Runtime::kInstallClassNameAccessor, literal) |
+ .Bind(&has_name); |
+ } |
+} |
+ |
void BytecodeGenerator::VisitNativeFunctionLiteral( |
NativeFunctionLiteral* expr) { |
size_t entry = builder()->AllocateConstantPoolEntry(); |