OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 2262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2273 return String::cast(constructor->shared()->instance_class_name()); | 2273 return String::cast(constructor->shared()->instance_class_name()); |
2274 } | 2274 } |
2275 // If the constructor is not present, return "Object". | 2275 // If the constructor is not present, return "Object". |
2276 return GetHeap()->Object_string(); | 2276 return GetHeap()->Object_string(); |
2277 } | 2277 } |
2278 | 2278 |
2279 | 2279 |
2280 // static | 2280 // static |
2281 Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) { | 2281 Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) { |
2282 Isolate* isolate = receiver->GetIsolate(); | 2282 Isolate* isolate = receiver->GetIsolate(); |
| 2283 |
| 2284 // If the object was instantiated simply with base == new.target, the |
| 2285 // constructor on the map provides the most accurate name. |
| 2286 // Don't provide the info for prototypes, since their constructors are |
| 2287 // reclaimed and replaced by Object in OptimizeAsPrototype. |
| 2288 if (!receiver->IsJSProxy() && receiver->map()->new_target_is_base() && |
| 2289 !receiver->map()->is_prototype_map()) { |
| 2290 Object* maybe_constructor = receiver->map()->GetConstructor(); |
| 2291 if (maybe_constructor->IsJSFunction()) { |
| 2292 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 2293 String* name = String::cast(constructor->shared()->name()); |
| 2294 if (name->length() == 0) name = constructor->shared()->inferred_name(); |
| 2295 if (name->length() != 0 && |
| 2296 !name->Equals(isolate->heap()->Object_string())) { |
| 2297 return handle(name, isolate); |
| 2298 } |
| 2299 } |
| 2300 } |
| 2301 |
2283 if (FLAG_harmony_tostring) { | 2302 if (FLAG_harmony_tostring) { |
2284 Handle<Object> maybe_tag = JSReceiver::GetDataProperty( | 2303 Handle<Object> maybe_tag = JSReceiver::GetDataProperty( |
2285 receiver, isolate->factory()->to_string_tag_symbol()); | 2304 receiver, isolate->factory()->to_string_tag_symbol()); |
2286 if (maybe_tag->IsString()) return Handle<String>::cast(maybe_tag); | 2305 if (maybe_tag->IsString()) return Handle<String>::cast(maybe_tag); |
2287 } | 2306 } |
2288 | 2307 |
2289 PrototypeIterator iter(isolate, receiver); | 2308 PrototypeIterator iter(isolate, receiver); |
2290 if (iter.IsAtEnd()) return handle(receiver->class_name()); | 2309 if (iter.IsAtEnd()) return handle(receiver->class_name()); |
2291 Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter); | 2310 Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter); |
2292 LookupIterator it(receiver, isolate->factory()->constructor_string(), start, | 2311 LookupIterator it(receiver, isolate->factory()->constructor_string(), start, |
2293 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); | 2312 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); |
2294 Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it); | 2313 Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it); |
2295 Handle<String> result = isolate->factory()->Object_string(); | 2314 Handle<String> result = isolate->factory()->Object_string(); |
2296 if (maybe_constructor->IsJSFunction()) { | 2315 if (maybe_constructor->IsJSFunction()) { |
2297 JSFunction* constructor = JSFunction::cast(*maybe_constructor); | 2316 JSFunction* constructor = JSFunction::cast(*maybe_constructor); |
2298 String* name = String::cast(constructor->shared()->name()); | 2317 String* name = String::cast(constructor->shared()->name()); |
2299 if (name->length() > 0) { | 2318 if (name->length() == 0) name = constructor->shared()->inferred_name(); |
2300 result = handle(name, isolate); | 2319 if (name->length() > 0) result = handle(name, isolate); |
2301 } else { | |
2302 String* inferred_name = constructor->shared()->inferred_name(); | |
2303 if (inferred_name->length() > 0) { | |
2304 result = handle(inferred_name, isolate); | |
2305 } | |
2306 } | |
2307 } | 2320 } |
2308 | 2321 |
2309 return result.is_identical_to(isolate->factory()->Object_string()) | 2322 return result.is_identical_to(isolate->factory()->Object_string()) |
2310 ? handle(receiver->class_name()) | 2323 ? handle(receiver->class_name()) |
2311 : result; | 2324 : result; |
2312 } | 2325 } |
2313 | 2326 |
2314 | 2327 |
2315 Context* JSReceiver::GetCreationContext() { | 2328 Context* JSReceiver::GetCreationContext() { |
2316 Object* constructor = map()->GetConstructor(); | 2329 Object* constructor = map()->GetConstructor(); |
(...skipping 10251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12568 if (*new_target == *constructor) return constructor_initial_map; | 12581 if (*new_target == *constructor) return constructor_initial_map; |
12569 | 12582 |
12570 if (new_target->IsJSProxy()) { | 12583 if (new_target->IsJSProxy()) { |
12571 Handle<JSProxy> new_target_proxy = Handle<JSProxy>::cast(new_target); | 12584 Handle<JSProxy> new_target_proxy = Handle<JSProxy>::cast(new_target); |
12572 Handle<Object> prototype; | 12585 Handle<Object> prototype; |
12573 Handle<String> prototype_string = isolate->factory()->prototype_string(); | 12586 Handle<String> prototype_string = isolate->factory()->prototype_string(); |
12574 ASSIGN_RETURN_ON_EXCEPTION( | 12587 ASSIGN_RETURN_ON_EXCEPTION( |
12575 isolate, prototype, | 12588 isolate, prototype, |
12576 JSReceiver::GetProperty(new_target_proxy, prototype_string), Map); | 12589 JSReceiver::GetProperty(new_target_proxy, prototype_string), Map); |
12577 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); | 12590 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); |
| 12591 map->set_new_target_is_base(false); |
12578 | 12592 |
12579 if (!prototype->IsJSReceiver()) { | 12593 if (!prototype->IsJSReceiver()) { |
12580 Handle<Context> context; | 12594 Handle<Context> context; |
12581 ASSIGN_RETURN_ON_EXCEPTION( | 12595 ASSIGN_RETURN_ON_EXCEPTION( |
12582 isolate, context, JSProxy::GetFunctionRealm(new_target_proxy), Map); | 12596 isolate, context, JSProxy::GetFunctionRealm(new_target_proxy), Map); |
12583 DCHECK(context->IsNativeContext()); | 12597 DCHECK(context->IsNativeContext()); |
12584 // TODO(verwaest): Use the intrinsicDefaultProto instead. | 12598 // TODO(verwaest): Use the intrinsicDefaultProto instead. |
12585 prototype = handle(context->initial_object_prototype(), isolate); | 12599 prototype = handle(context->initial_object_prototype(), isolate); |
12586 } | 12600 } |
12587 | 12601 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12619 constructor_initial_map->unused_property_fields(); | 12633 constructor_initial_map->unused_property_fields(); |
12620 int instance_size; | 12634 int instance_size; |
12621 int in_object_properties; | 12635 int in_object_properties; |
12622 new_target_function->CalculateInstanceSizeForDerivedClass( | 12636 new_target_function->CalculateInstanceSizeForDerivedClass( |
12623 instance_type, internal_fields, &instance_size, &in_object_properties); | 12637 instance_type, internal_fields, &instance_size, &in_object_properties); |
12624 | 12638 |
12625 int unused_property_fields = in_object_properties - pre_allocated; | 12639 int unused_property_fields = in_object_properties - pre_allocated; |
12626 Handle<Map> map = | 12640 Handle<Map> map = |
12627 Map::CopyInitialMap(constructor_initial_map, instance_size, | 12641 Map::CopyInitialMap(constructor_initial_map, instance_size, |
12628 in_object_properties, unused_property_fields); | 12642 in_object_properties, unused_property_fields); |
| 12643 map->set_new_target_is_base(false); |
12629 | 12644 |
12630 JSFunction::SetInitialMap(new_target_function, map, prototype); | 12645 JSFunction::SetInitialMap(new_target_function, map, prototype); |
12631 map->SetConstructor(*constructor); | 12646 map->SetConstructor(*constructor); |
12632 new_target_function->StartInobjectSlackTracking(); | 12647 new_target_function->StartInobjectSlackTracking(); |
12633 return map; | 12648 return map; |
12634 } | 12649 } |
12635 | 12650 |
12636 // Fetch the prototype. | 12651 // Fetch the prototype. |
12637 Handle<Object> prototype; | 12652 Handle<Object> prototype; |
12638 if (new_target_function->map()->has_non_instance_prototype()) { | 12653 if (new_target_function->map()->has_non_instance_prototype()) { |
12639 // TODO(verwaest): In case of non-instance prototype, use the | 12654 // TODO(verwaest): In case of non-instance prototype, use the |
12640 // intrinsicDefaultProto instead. | 12655 // intrinsicDefaultProto instead. |
12641 prototype = handle(new_target_function->context() | 12656 prototype = handle(new_target_function->context() |
12642 ->native_context() | 12657 ->native_context() |
12643 ->initial_object_prototype()); | 12658 ->initial_object_prototype()); |
12644 } else { | 12659 } else { |
12645 // Make sure the prototype is cached on new_target_function. | 12660 // Make sure the prototype is cached on new_target_function. |
12646 EnsureHasInitialMap(new_target_function); | 12661 EnsureHasInitialMap(new_target_function); |
12647 prototype = handle(new_target_function->instance_prototype(), isolate); | 12662 prototype = handle(new_target_function->instance_prototype(), isolate); |
12648 } | 12663 } |
12649 | 12664 |
12650 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); | 12665 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); |
| 12666 map->set_new_target_is_base(false); |
12651 DCHECK(prototype->IsJSReceiver()); | 12667 DCHECK(prototype->IsJSReceiver()); |
12652 if (map->prototype() != *prototype) { | 12668 if (map->prototype() != *prototype) { |
12653 Map::SetPrototype(map, prototype, FAST_PROTOTYPE); | 12669 Map::SetPrototype(map, prototype, FAST_PROTOTYPE); |
12654 } | 12670 } |
12655 map->SetConstructor(*constructor); | 12671 map->SetConstructor(*constructor); |
12656 return map; | 12672 return map; |
12657 } | 12673 } |
12658 | 12674 |
12659 | 12675 |
12660 void JSFunction::PrintName(FILE* out) { | 12676 void JSFunction::PrintName(FILE* out) { |
(...skipping 6394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19055 if (cell->value() != *new_value) { | 19071 if (cell->value() != *new_value) { |
19056 cell->set_value(*new_value); | 19072 cell->set_value(*new_value); |
19057 Isolate* isolate = cell->GetIsolate(); | 19073 Isolate* isolate = cell->GetIsolate(); |
19058 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19074 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19059 isolate, DependentCode::kPropertyCellChangedGroup); | 19075 isolate, DependentCode::kPropertyCellChangedGroup); |
19060 } | 19076 } |
19061 } | 19077 } |
19062 | 19078 |
19063 } // namespace internal | 19079 } // namespace internal |
19064 } // namespace v8 | 19080 } // namespace v8 |
OLD | NEW |