Install "name" property on anonymous classes

This is a normative PR that reached consensus at the June 2019 TC39:
https://github.com/tc39/test262/pull/2299

Bug: v8:9646
Change-Id: I8cb927b9e9231dfb71ebf47171205a096350e38b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2360905
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69460}
This commit is contained in:
Shu-yu Guo 2020-08-17 18:44:41 -07:00 committed by Commit Bot
parent 65d28a7fe4
commit 048761aa0f
8 changed files with 28 additions and 46 deletions

View File

@ -95,14 +95,8 @@ void ObjectBoilerplateDescription::set_backing_store_size(
OBJECT_CONSTRUCTORS_IMPL(ClassBoilerplate, FixedArray)
CAST_ACCESSOR(ClassBoilerplate)
BIT_FIELD_ACCESSORS(ClassBoilerplate, flags, install_class_name_accessor,
ClassBoilerplate::Flags::InstallClassNameAccessorBit)
BIT_FIELD_ACCESSORS(ClassBoilerplate, flags, arguments_count,
ClassBoilerplate::Flags::ArgumentsCountBits)
SMI_ACCESSORS(ClassBoilerplate, flags,
FixedArray::OffsetOfElementAt(kFlagsIndex))
SMI_ACCESSORS(ClassBoilerplate, arguments_count,
FixedArray::OffsetOfElementAt(kArgumentsCountIndex))
ACCESSORS(ClassBoilerplate, static_properties_template, Object,
FixedArray::OffsetOfElementAt(kClassPropertiesTemplateIndex))

View File

@ -551,32 +551,24 @@ Handle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate(
}
}
// Add name accessor to the class object if necessary.
bool install_class_name_accessor = false;
// All classes, even anonymous ones, have a name accessor. If static_desc is
// in dictionary mode, the name accessor is installed at runtime in
// DefineClass.
if (!expr->has_name_static_property() &&
expr->constructor()->has_shared_name()) {
if (static_desc.HasDictionaryProperties()) {
// Install class name accessor if necessary during class literal
// instantiation.
install_class_name_accessor = true;
} else {
// Set class name accessor if the "name" method was not added yet.
PropertyAttributes attribs =
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
static_desc.AddConstant(isolate, factory->name_string(),
factory->function_name_accessor(), attribs);
}
!static_desc.HasDictionaryProperties()) {
// Set class name accessor if the "name" method was not added yet.
PropertyAttributes attribs =
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
static_desc.AddConstant(isolate, factory->name_string(),
factory->function_name_accessor(), attribs);
}
static_desc.Finalize(isolate);
instance_desc.Finalize(isolate);
Handle<ClassBoilerplate> class_boilerplate = Handle<ClassBoilerplate>::cast(
factory->NewFixedArray(kBoileplateLength, AllocationType::kOld));
factory->NewFixedArray(kBoilerplateLength, AllocationType::kOld));
class_boilerplate->set_flags(0);
class_boilerplate->set_install_class_name_accessor(
install_class_name_accessor);
class_boilerplate->set_arguments_count(dynamic_argument_index);
class_boilerplate->set_static_properties_template(

View File

@ -77,14 +77,6 @@ class ClassBoilerplate : public FixedArray {
public:
enum ValueKind { kData, kGetter, kSetter };
struct Flags {
#define FLAGS_BIT_FIELDS(V, _) \
V(InstallClassNameAccessorBit, bool, 1, _) \
V(ArgumentsCountBits, int, 30, _)
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS
};
struct ComputedEntryFlags {
#define COMPUTED_ENTRY_BIT_FIELDS(V, _) \
V(ValueKindBits, ValueKind, 2, _) \
@ -133,14 +125,14 @@ class ClassBoilerplate : public FixedArray {
ClassLiteral* expr);
enum {
kFlagsIndex,
kArgumentsCountIndex,
kClassPropertiesTemplateIndex,
kClassElementsTemplateIndex,
kClassComputedPropertiesIndex,
kPrototypePropertiesTemplateIndex,
kPrototypeElementsTemplateIndex,
kPrototypeComputedPropertiesIndex,
kBoileplateLength // last element
kBoilerplateLength // last element
};
private:

View File

@ -537,7 +537,7 @@ bool InitClassPrototype(Isolate* isolate,
map->set_may_have_interesting_symbols(true);
map->set_construction_counter(Map::kNoSlackTracking);
// We care about name property only for class constructor.
// Class prototypes do not have a name accessor.
const bool install_name_accessor = false;
return AddDescriptorsByTemplate(
@ -592,8 +592,8 @@ bool InitClassConstructor(
map->set_may_have_interesting_symbols(true);
map->set_construction_counter(Map::kNoSlackTracking);
bool install_name_accessor =
class_boilerplate->install_class_name_accessor() != 0;
// All class constructors have a name accessor.
const bool install_name_accessor = true;
return AddDescriptorsByTemplate(
isolate, map, properties_dictionary_template,

View File

@ -36,8 +36,11 @@
literal = { __proto__: class {} };
assertEquals('', literal.__proto__.name);
assertEquals(
undefined, Object.getOwnPropertyDescriptor(literal.__proto__, 'name'));
var nameDescr = Object.getOwnPropertyDescriptor(literal.__proto__, 'name');
assertEquals('', nameDescr.value);
assertFalse(nameDescr.writable);
assertFalse(nameDescr.enumerable);
assertTrue(nameDescr.configurable);
literal = { __proto__: class F {} };
assertEquals('F', literal.__proto__.name);

View File

@ -394,7 +394,7 @@
})();
(function testClassNameOrder() {
assertEquals(['length', 'prototype'], Object.getOwnPropertyNames(class {}));
assertEquals(['length', 'prototype', 'name'], Object.getOwnPropertyNames(class {}));
var tmp = {'': class {}};
var Tmp = tmp[''];

View File

@ -44,7 +44,8 @@
};
// Anonymous classes do not have a "name" property by default.
assertSame(undefined, Object.getOwnPropertyDescriptor(class {}, 'name'));
descriptor.value = '';
assertEquals(descriptor, Object.getOwnPropertyDescriptor(class {}, 'name'));
descriptor.value = 'C';
assertEquals(descriptor, Object.getOwnPropertyDescriptor(class C {}, 'name'));
@ -55,8 +56,9 @@
let b = { __proto__: class {} };
assertSame('', b.__proto__.name);
assertSame(
undefined, Object.getOwnPropertyDescriptor(b.__proto__, 'name'));
descriptor.value = '';
assertEquals(
descriptor, Object.getOwnPropertyDescriptor(b.__proto__, 'name'));
let c = { fn: class F {} };
assertSame('F', c.fn.name);

View File

@ -504,7 +504,6 @@
# https://bugs.chromium.org/p/v8/issues/detail?id=9646
'built-ins/ThrowTypeError/name': [FAIL],
'language/expressions/class/name': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=9742
'intl402/Locale/getters': [FAIL],