Skip to content

Commit 224b659

Browse files
TimothyGuV8 LUCI CQ
authored and
V8 LUCI CQ
committed
Install class "name" accessor before methods
tc39/ecma262#1490 changed the spec so that the "name" property of a class should be installed after "length" but before "prototype". This CL adapts accordingly. After this change, there is now no need for the separate code path to set the "name" accessor at runtime. Delete the relevant runtime code as well. Bug: v8:8771 Change-Id: I8f809b45bf209c899cf5df76d0ebf6d9a45a6d4e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2974772 Commit-Queue: Timothy Gu <[email protected]> Reviewed-by: Marja Hölttä <[email protected]> Cr-Commit-Position: refs/heads/master@{#75340}
1 parent 250a648 commit 224b659

File tree

8 files changed

+38
-91
lines changed

8 files changed

+38
-91
lines changed

src/ast/ast.h

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,9 +2453,6 @@ class ClassLiteral final : public Expression {
24532453
ZonePtrList<Property>* private_members() const { return private_members_; }
24542454
int start_position() const { return position(); }
24552455
int end_position() const { return end_position_; }
2456-
bool has_name_static_property() const {
2457-
return HasNameStaticProperty::decode(bit_field_);
2458-
}
24592456
bool has_static_computed_names() const {
24602457
return HasStaticComputedNames::decode(bit_field_);
24612458
}
@@ -2491,9 +2488,9 @@ class ClassLiteral final : public Expression {
24912488
FunctionLiteral* static_initializer,
24922489
FunctionLiteral* instance_members_initializer_function,
24932490
int start_position, int end_position,
2494-
bool has_name_static_property, bool has_static_computed_names,
2495-
bool is_anonymous, bool has_private_methods,
2496-
Variable* home_object, Variable* static_home_object)
2491+
bool has_static_computed_names, bool is_anonymous,
2492+
bool has_private_methods, Variable* home_object,
2493+
Variable* static_home_object)
24972494
: Expression(start_position, kClassLiteral),
24982495
end_position_(end_position),
24992496
scope_(scope),
@@ -2506,8 +2503,7 @@ class ClassLiteral final : public Expression {
25062503
instance_members_initializer_function),
25072504
home_object_(home_object),
25082505
static_home_object_(static_home_object) {
2509-
bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) |
2510-
HasStaticComputedNames::encode(has_static_computed_names) |
2506+
bit_field_ |= HasStaticComputedNames::encode(has_static_computed_names) |
25112507
IsAnonymousExpression::encode(is_anonymous) |
25122508
HasPrivateMethods::encode(has_private_methods);
25132509
}
@@ -2520,8 +2516,7 @@ class ClassLiteral final : public Expression {
25202516
ZonePtrList<Property>* private_members_;
25212517
FunctionLiteral* static_initializer_;
25222518
FunctionLiteral* instance_members_initializer_function_;
2523-
using HasNameStaticProperty = Expression::NextBitField<bool, 1>;
2524-
using HasStaticComputedNames = HasNameStaticProperty::Next<bool, 1>;
2519+
using HasStaticComputedNames = Expression::NextBitField<bool, 1>;
25252520
using IsAnonymousExpression = HasStaticComputedNames::Next<bool, 1>;
25262521
using HasPrivateMethods = IsAnonymousExpression::Next<bool, 1>;
25272522
Variable* home_object_;
@@ -3251,16 +3246,14 @@ class AstNodeFactory final {
32513246
ZonePtrList<ClassLiteral::Property>* private_members,
32523247
FunctionLiteral* static_initializer,
32533248
FunctionLiteral* instance_members_initializer_function,
3254-
int start_position, int end_position, bool has_name_static_property,
3255-
bool has_static_computed_names, bool is_anonymous,
3256-
bool has_private_methods, Variable* home_object,
3249+
int start_position, int end_position, bool has_static_computed_names,
3250+
bool is_anonymous, bool has_private_methods, Variable* home_object,
32573251
Variable* static_home_object) {
32583252
return zone_->New<ClassLiteral>(
32593253
scope, extends, constructor, public_members, private_members,
32603254
static_initializer, instance_members_initializer_function,
3261-
start_position, end_position, has_name_static_property,
3262-
has_static_computed_names, is_anonymous, has_private_methods,
3263-
home_object, static_home_object);
3255+
start_position, end_position, has_static_computed_names, is_anonymous,
3256+
has_private_methods, home_object, static_home_object);
32643257
}
32653258

32663259
NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,

src/objects/literal-objects.cc

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,13 @@ void AddToDictionaryTemplate(IsolateT* isolate, Handle<Dictionary> dictionary,
276276
existing_value.IsAccessorInfo());
277277
DCHECK_IMPLIES(!existing_value.IsSmi(),
278278
AccessorInfo::cast(existing_value).name() ==
279-
*isolate->factory()->length_string());
279+
*isolate->factory()->length_string() ||
280+
AccessorInfo::cast(existing_value).name() ==
281+
*isolate->factory()->name_string());
280282
if (!existing_value.IsSmi() || Smi::ToInt(existing_value) < key_index) {
281283
// Overwrite existing value because it was defined before the computed
282-
// one (AccessorInfo "length" property is always defined before).
284+
// one (AccessorInfo "length" and "name" properties are always defined
285+
// before).
283286
PropertyDetails details(
284287
kData, DONT_ENUM, PropertyDetails::kConstIfDictConstnessTracking,
285288
enum_order_existing);
@@ -625,6 +628,14 @@ Handle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate(
625628
static_desc.AddConstant(isolate, factory->length_string(),
626629
factory->function_length_accessor(), attribs);
627630
}
631+
{
632+
// Add name_accessor.
633+
// All classes, even anonymous ones, have a name accessor.
634+
PropertyAttributes attribs =
635+
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
636+
static_desc.AddConstant(isolate, factory->name_string(),
637+
factory->function_name_accessor(), attribs);
638+
}
628639
{
629640
// Add prototype_accessor.
630641
PropertyAttributes attribs =
@@ -698,18 +709,6 @@ Handle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate(
698709
}
699710
}
700711

701-
// All classes, even anonymous ones, have a name accessor. If static_desc is
702-
// in dictionary mode, the name accessor is installed at runtime in
703-
// DefineClass.
704-
if (!expr->has_name_static_property() &&
705-
!static_desc.HasDictionaryProperties()) {
706-
// Set class name accessor if the "name" method was not added yet.
707-
PropertyAttributes attribs =
708-
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
709-
static_desc.AddConstant(isolate, factory->name_string(),
710-
factory->function_name_accessor(), attribs);
711-
}
712-
713712
static_desc.Finalize(isolate);
714713
instance_desc.Finalize(isolate);
715714

src/parsing/parser-base.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,6 @@ class ParserBase {
595595
instance_fields(parser->impl()->NewClassPropertyList(4)),
596596
constructor(parser->impl()->NullExpression()),
597597
has_seen_constructor(false),
598-
has_name_static_property(false),
599598
has_static_computed_names(false),
600599
has_static_elements(false),
601600
has_static_private_methods(false),
@@ -615,7 +614,6 @@ class ParserBase {
615614
FunctionLiteralT constructor;
616615

617616
bool has_seen_constructor;
618-
bool has_name_static_property;
619617
bool has_static_computed_names;
620618
bool has_static_elements;
621619
bool has_static_private_methods;
@@ -2316,11 +2314,6 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassInfo* class_info,
23162314
name_expression = ParseProperty(prop_info);
23172315
}
23182316

2319-
if (!class_info->has_name_static_property && prop_info->is_static &&
2320-
impl()->IsName(prop_info->name)) {
2321-
class_info->has_name_static_property = true;
2322-
}
2323-
23242317
switch (prop_info->kind) {
23252318
case ParsePropertyKind::kAssign:
23262319
case ParsePropertyKind::kClassField:

src/parsing/parser.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,7 +3132,6 @@ FunctionLiteral* Parser::CreateInitializerFunction(
31323132
// - proxy
31333133
// - extends
31343134
// - properties
3135-
// - has_name_static_property
31363135
// - has_static_computed_names
31373136
Expression* Parser::RewriteClassLiteral(ClassScope* block_scope,
31383137
const AstRawString* name,
@@ -3183,7 +3182,6 @@ Expression* Parser::RewriteClassLiteral(ClassScope* block_scope,
31833182
block_scope, class_info->extends, class_info->constructor,
31843183
class_info->public_members, class_info->private_members,
31853184
static_initializer, instance_members_initializer_function, pos, end_pos,
3186-
class_info->has_name_static_property,
31873185
class_info->has_static_computed_names, class_info->is_anonymous,
31883186
class_info->has_private_methods, class_info->home_object_variable,
31893187
class_info->static_home_object_variable);

src/runtime/runtime-classes.cc

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -202,19 +202,12 @@ Handle<Dictionary> ShallowCopyDictionaryTemplate(
202202

203203
template <typename Dictionary>
204204
bool SubstituteValues(Isolate* isolate, Handle<Dictionary> dictionary,
205-
RuntimeArguments& args,
206-
bool* install_name_accessor = nullptr) {
207-
Handle<Name> name_string = isolate->factory()->name_string();
208-
205+
RuntimeArguments& args) {
209206
// Replace all indices with proper methods.
210207
ReadOnlyRoots roots(isolate);
211208
for (InternalIndex i : dictionary->IterateEntries()) {
212209
Object maybe_key = dictionary->KeyAt(i);
213210
if (!Dictionary::IsKey(roots, maybe_key)) continue;
214-
if (install_name_accessor && *install_name_accessor &&
215-
(maybe_key == *name_string)) {
216-
*install_name_accessor = false;
217-
}
218211
Handle<Object> key(maybe_key, isolate);
219212
Handle<Object> value(dictionary->ValueAt(i), isolate);
220213
if (value->IsAccessorPair()) {
@@ -400,7 +393,7 @@ bool AddDescriptorsByTemplate(
400393
Handle<Dictionary> properties_dictionary_template,
401394
Handle<NumberDictionary> elements_dictionary_template,
402395
Handle<FixedArray> computed_properties, Handle<JSObject> receiver,
403-
bool install_name_accessor, RuntimeArguments& args) {
396+
RuntimeArguments& args) {
404397
int computed_properties_length = computed_properties->length();
405398

406399
// Shallow-copy properties template.
@@ -438,20 +431,9 @@ bool AddDescriptorsByTemplate(
438431
}
439432

440433
// Replace all indices with proper methods.
441-
if (!SubstituteValues<Dictionary>(isolate, properties_dictionary, args,
442-
&install_name_accessor)) {
434+
if (!SubstituteValues<Dictionary>(isolate, properties_dictionary, args)) {
443435
return false;
444436
}
445-
if (install_name_accessor) {
446-
PropertyAttributes attribs =
447-
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
448-
PropertyDetails details(kAccessor, attribs,
449-
PropertyDetails::kConstIfDictConstnessTracking);
450-
Handle<Dictionary> dict = ToHandle(Dictionary::Add(
451-
isolate, properties_dictionary, isolate->factory()->name_string(),
452-
isolate->factory()->function_name_accessor(), details));
453-
CHECK_EQ(*dict, *properties_dictionary);
454-
}
455437

456438
UpdateProtectors(isolate, receiver, properties_dictionary);
457439

@@ -520,23 +502,18 @@ bool InitClassPrototype(Isolate* isolate,
520502
map->set_may_have_interesting_symbols(true);
521503
map->set_construction_counter(Map::kNoSlackTracking);
522504

523-
// Class prototypes do not have a name accessor.
524-
const bool install_name_accessor = false;
525-
526505
if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
527506
Handle<SwissNameDictionary> properties_dictionary_template =
528507
Handle<SwissNameDictionary>::cast(properties_template);
529508
return AddDescriptorsByTemplate(
530509
isolate, map, properties_dictionary_template,
531-
elements_dictionary_template, computed_properties, prototype,
532-
install_name_accessor, args);
510+
elements_dictionary_template, computed_properties, prototype, args);
533511
} else {
534512
Handle<NameDictionary> properties_dictionary_template =
535513
Handle<NameDictionary>::cast(properties_template);
536514
return AddDescriptorsByTemplate(
537515
isolate, map, properties_dictionary_template,
538-
elements_dictionary_template, computed_properties, prototype,
539-
install_name_accessor, args);
516+
elements_dictionary_template, computed_properties, prototype, args);
540517
}
541518
}
542519
}
@@ -582,24 +559,19 @@ bool InitClassConstructor(Isolate* isolate,
582559
map->set_may_have_interesting_symbols(true);
583560
map->set_construction_counter(Map::kNoSlackTracking);
584561

585-
// All class constructors have a name accessor.
586-
const bool install_name_accessor = true;
587-
588562
if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
589563
Handle<SwissNameDictionary> properties_dictionary_template =
590564
Handle<SwissNameDictionary>::cast(properties_template);
591565

592566
return AddDescriptorsByTemplate(
593567
isolate, map, properties_dictionary_template,
594-
elements_dictionary_template, computed_properties, constructor,
595-
install_name_accessor, args);
568+
elements_dictionary_template, computed_properties, constructor, args);
596569
} else {
597570
Handle<NameDictionary> properties_dictionary_template =
598571
Handle<NameDictionary>::cast(properties_template);
599572
return AddDescriptorsByTemplate(
600573
isolate, map, properties_dictionary_template,
601-
elements_dictionary_template, computed_properties, constructor,
602-
install_name_accessor, args);
574+
elements_dictionary_template, computed_properties, constructor, args);
603575
}
604576
}
605577
}

test/mjsunit/es6/computed-property-names-classes.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,7 @@ function ID(x) {
7878
assertEquals('C', C.c());
7979
assertEquals('D', C.d());
8080
assertArrayEquals([], Object.keys(C));
81-
// TODO(arv): It is not clear that we are adding the "standard" properties
82-
// in the right order. As far as I can tell the spec adds them in alphabetical
83-
// order.
84-
assertArrayEquals(['length', 'prototype', 'a', 'b', 'c', 'd', 'name'],
81+
assertArrayEquals(['length', 'name', 'prototype', 'a', 'b', 'c', 'd'],
8582
Object.getOwnPropertyNames(C));
8683
})();
8784

@@ -99,7 +96,7 @@ function ID(x) {
9996
assertEquals('D', C[2]());
10097
// Array indexes first.
10198
assertArrayEquals([], Object.keys(C));
102-
assertArrayEquals(['1', '2', 'length', 'prototype', 'a', 'c', 'name'],
99+
assertArrayEquals(['1', '2', 'length', 'name', 'prototype', 'a', 'c'],
103100
Object.getOwnPropertyNames(C));
104101
})();
105102

@@ -118,7 +115,7 @@ function ID(x) {
118115
assertEquals('C', C.c());
119116
assertEquals('D', C[sym2]());
120117
assertArrayEquals([], Object.keys(C));
121-
assertArrayEquals(['length', 'prototype', 'a', 'c', 'name'],
118+
assertArrayEquals(['length', 'name', 'prototype', 'a', 'c'],
122119
Object.getOwnPropertyNames(C));
123120
assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(C));
124121
})();

test/mjsunit/es6/function-name.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -394,25 +394,25 @@
394394
})();
395395

396396
(function testClassNameOrder() {
397-
assertEquals(['length', 'prototype', 'name'], Object.getOwnPropertyNames(class {}));
397+
assertEquals(['length', 'name', 'prototype'], Object.getOwnPropertyNames(class {}));
398398

399399
var tmp = {'': class {}};
400400
var Tmp = tmp[''];
401-
assertEquals(['length', 'prototype', 'name'], Object.getOwnPropertyNames(Tmp));
401+
assertEquals(['length', 'name', 'prototype'], Object.getOwnPropertyNames(Tmp));
402402

403403
var name = () => '';
404404
var tmp = {[name()]: class {}};
405405
var Tmp = tmp[name()];
406-
assertEquals(['length', 'prototype', 'name'], Object.getOwnPropertyNames(Tmp));
406+
assertEquals(['length', 'name', 'prototype'], Object.getOwnPropertyNames(Tmp));
407407

408408
class A { }
409-
assertEquals(['length', 'prototype', 'name'], Object.getOwnPropertyNames(A));
409+
assertEquals(['length', 'name', 'prototype'], Object.getOwnPropertyNames(A));
410410

411411
class B { static foo() { } }
412-
assertEquals(['length', 'prototype', 'foo', 'name'], Object.getOwnPropertyNames(B));
412+
assertEquals(['length', 'name', 'prototype', 'foo'], Object.getOwnPropertyNames(B));
413413

414414
class C { static name() { } static foo() { } }
415-
assertEquals(['length', 'prototype', 'name', 'foo'], Object.getOwnPropertyNames(C));
415+
assertEquals(['length', 'name', 'prototype', 'foo'], Object.getOwnPropertyNames(C));
416416
})();
417417

418418
(function testStaticName() {

test/test262/test262.status

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@
7171
# https://code.google.com/p/v8/issues/detail?id=10958
7272
'language/module-code/eval-gtbndng-indirect-faux-assertion': [FAIL],
7373

74-
# https://code.google.com/p/v8/issues/detail?id=8771
75-
'language/computed-property-names/class/static/method-number': [FAIL],
76-
'language/computed-property-names/class/static/method-string': [FAIL],
77-
'language/computed-property-names/class/static/method-symbol': [FAIL],
78-
7974
# https://bugs.chromium.org/p/v8/issues/detail?id=4895
8075
# Some TypedArray methods throw due to the same bug, from Get
8176
'built-ins/TypedArray/prototype/every/callbackfn-detachbuffer': [FAIL],

0 commit comments

Comments
 (0)