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,
Map::Counter::encode(Map::kRetainingCounterStart);
map->set_bit_field3(bit_field3);
map->set_elements_kind(elements_kind);
map->set_new_target_is_base(true);
return map;
}
......
......@@ -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) {
set_bit_field3(Counter::update(bit_field3(), value));
}
......
......@@ -2293,6 +2293,25 @@ String* JSReceiver::class_name() {
// static
Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
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) {
Handle<Object> maybe_tag = JSReceiver::GetDataProperty(
receiver, isolate->factory()->to_string_tag_symbol());
......@@ -2309,14 +2328,8 @@ Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
if (maybe_constructor->IsJSFunction()) {
JSFunction* constructor = JSFunction::cast(*maybe_constructor);
String* name = String::cast(constructor->shared()->name());
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);
}
}
if (name->length() == 0) name = constructor->shared()->inferred_name();
if (name->length() > 0) result = handle(name, isolate);
}
return result.is_identical_to(isolate->factory()->Object_string())
......@@ -12577,6 +12590,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
isolate, prototype,
JSReceiver::GetProperty(new_target_proxy, prototype_string), Map);
Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
map->set_new_target_is_base(false);
if (!prototype->IsJSReceiver()) {
Handle<Context> context;
......@@ -12628,6 +12642,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
Handle<Map> map =
Map::CopyInitialMap(constructor_initial_map, instance_size,
in_object_properties, unused_property_fields);
map->set_new_target_is_base(false);
JSFunction::SetInitialMap(new_target_function, map, prototype);
map->SetConstructor(*constructor);
......@@ -12650,6 +12665,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
}
Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
map->set_new_target_is_base(false);
DCHECK(prototype->IsJSReceiver());
if (map->prototype() != *prototype) {
Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
......
......@@ -5488,7 +5488,7 @@ class Map: public HeapObject {
class IsUnstable : public BitField<bool, 24, 1> {};
class IsMigrationTarget : public BitField<bool, 25, 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
// Builtins::kJSConstructStubGeneric stub.
......@@ -5594,6 +5594,8 @@ class Map: public HeapObject {
inline void set_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 bool is_extensible();
inline void set_is_prototype_map(bool value);
......
......@@ -6,5 +6,5 @@ var error;
try { reference_error(); } catch (e) { error = e; }
toString = error.toString;
error.__proto__ = [];
assertEquals("Array: reference_error is not defined",
assertEquals("ReferenceError: reference_error is not defined",
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