Commit 324ab707 authored by verwaest's avatar verwaest Committed by Commit bot

For non-prototype objects constructed using base==new.target, use the cached...

For non-prototype objects constructed using base==new.target, use the cached constructor to render the name.

BUG=chromium:563791
LOG=y

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

Cr-Commit-Position: refs/heads/master@{#32556}
parent fa7a07c3
...@@ -2084,6 +2084,7 @@ AllocationResult Heap::AllocateMap(InstanceType instance_type, ...@@ -2084,6 +2084,7 @@ AllocationResult Heap::AllocateMap(InstanceType instance_type,
Map::Counter::encode(Map::kRetainingCounterStart); Map::Counter::encode(Map::kRetainingCounterStart);
map->set_bit_field3(bit_field3); map->set_bit_field3(bit_field3);
map->set_elements_kind(elements_kind); map->set_elements_kind(elements_kind);
map->set_new_target_is_base(true);
return map; return map;
} }
......
...@@ -4750,6 +4750,14 @@ bool Map::is_strong() { ...@@ -4750,6 +4750,14 @@ bool Map::is_strong() {
} }
void Map::set_new_target_is_base(bool value) {
set_bit_field3(NewTargetIsBase::update(bit_field3(), value));
}
bool Map::new_target_is_base() { return NewTargetIsBase::decode(bit_field3()); }
void Map::set_counter(int value) { void Map::set_counter(int value) {
set_bit_field3(Counter::update(bit_field3(), value)); set_bit_field3(Counter::update(bit_field3(), value));
} }
......
...@@ -2293,6 +2293,25 @@ String* JSReceiver::class_name() { ...@@ -2293,6 +2293,25 @@ String* JSReceiver::class_name() {
// static // static
Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) { Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
Isolate* isolate = receiver->GetIsolate(); Isolate* isolate = receiver->GetIsolate();
// If the object was instantiated simply with base == new.target, the
// constructor on the map provides the most accurate name.
// Don't provide the info for prototypes, since their constructors are
// reclaimed and replaced by Object in OptimizeAsPrototype.
if (!receiver->IsJSProxy() && receiver->map()->new_target_is_base() &&
!receiver->map()->is_prototype_map()) {
Object* maybe_constructor = receiver->map()->GetConstructor();
if (maybe_constructor->IsJSFunction()) {
JSFunction* constructor = JSFunction::cast(maybe_constructor);
String* name = String::cast(constructor->shared()->name());
if (name->length() == 0) name = constructor->shared()->inferred_name();
if (name->length() != 0 &&
!name->Equals(isolate->heap()->Object_string())) {
return handle(name, isolate);
}
}
}
if (FLAG_harmony_tostring) { if (FLAG_harmony_tostring) {
Handle<Object> maybe_tag = JSReceiver::GetDataProperty( Handle<Object> maybe_tag = JSReceiver::GetDataProperty(
receiver, isolate->factory()->to_string_tag_symbol()); receiver, isolate->factory()->to_string_tag_symbol());
...@@ -2309,14 +2328,8 @@ Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) { ...@@ -2309,14 +2328,8 @@ Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
if (maybe_constructor->IsJSFunction()) { if (maybe_constructor->IsJSFunction()) {
JSFunction* constructor = JSFunction::cast(*maybe_constructor); JSFunction* constructor = JSFunction::cast(*maybe_constructor);
String* name = String::cast(constructor->shared()->name()); String* name = String::cast(constructor->shared()->name());
if (name->length() > 0) { if (name->length() == 0) name = constructor->shared()->inferred_name();
result = handle(name, isolate); if (name->length() > 0) result = handle(name, isolate);
} else {
String* inferred_name = constructor->shared()->inferred_name();
if (inferred_name->length() > 0) {
result = handle(inferred_name, isolate);
}
}
} }
return result.is_identical_to(isolate->factory()->Object_string()) return result.is_identical_to(isolate->factory()->Object_string())
...@@ -12577,6 +12590,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate, ...@@ -12577,6 +12590,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
isolate, prototype, isolate, prototype,
JSReceiver::GetProperty(new_target_proxy, prototype_string), Map); JSReceiver::GetProperty(new_target_proxy, prototype_string), Map);
Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
map->set_new_target_is_base(false);
if (!prototype->IsJSReceiver()) { if (!prototype->IsJSReceiver()) {
Handle<Context> context; Handle<Context> context;
...@@ -12628,6 +12642,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate, ...@@ -12628,6 +12642,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
Handle<Map> map = Handle<Map> map =
Map::CopyInitialMap(constructor_initial_map, instance_size, Map::CopyInitialMap(constructor_initial_map, instance_size,
in_object_properties, unused_property_fields); in_object_properties, unused_property_fields);
map->set_new_target_is_base(false);
JSFunction::SetInitialMap(new_target_function, map, prototype); JSFunction::SetInitialMap(new_target_function, map, prototype);
map->SetConstructor(*constructor); map->SetConstructor(*constructor);
...@@ -12650,6 +12665,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate, ...@@ -12650,6 +12665,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
} }
Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
map->set_new_target_is_base(false);
DCHECK(prototype->IsJSReceiver()); DCHECK(prototype->IsJSReceiver());
if (map->prototype() != *prototype) { if (map->prototype() != *prototype) {
Map::SetPrototype(map, prototype, FAST_PROTOTYPE); Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
......
...@@ -5488,7 +5488,7 @@ class Map: public HeapObject { ...@@ -5488,7 +5488,7 @@ class Map: public HeapObject {
class IsUnstable : public BitField<bool, 24, 1> {}; class IsUnstable : public BitField<bool, 24, 1> {};
class IsMigrationTarget : public BitField<bool, 25, 1> {}; class IsMigrationTarget : public BitField<bool, 25, 1> {};
class IsStrong : public BitField<bool, 26, 1> {}; class IsStrong : public BitField<bool, 26, 1> {};
// Bit 27 is free. class NewTargetIsBase : public BitField<bool, 27, 1> {};
// Keep this bit field at the very end for better code in // Keep this bit field at the very end for better code in
// Builtins::kJSConstructStubGeneric stub. // Builtins::kJSConstructStubGeneric stub.
...@@ -5594,6 +5594,8 @@ class Map: public HeapObject { ...@@ -5594,6 +5594,8 @@ class Map: public HeapObject {
inline void set_is_strong(); inline void set_is_strong();
inline bool is_strong(); inline bool is_strong();
inline void set_new_target_is_base(bool value);
inline bool new_target_is_base();
inline void set_is_extensible(bool value); inline void set_is_extensible(bool value);
inline bool is_extensible(); inline bool is_extensible();
inline void set_is_prototype_map(bool value); inline void set_is_prototype_map(bool value);
......
...@@ -6,5 +6,5 @@ var error; ...@@ -6,5 +6,5 @@ var error;
try { reference_error(); } catch (e) { error = e; } try { reference_error(); } catch (e) { error = e; }
toString = error.toString; toString = error.toString;
error.__proto__ = []; error.__proto__ = [];
assertEquals("Array: reference_error is not defined", assertEquals("ReferenceError: reference_error is not defined",
toString.call(error)); toString.call(error));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment