Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: src/objects.cc

Issue 2080243003: Use instance type in Object.prototype.toString(). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add TODO comment about checking IsArray() before reading toStringTag. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-body-descriptors-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 2512 matching lines...) Expand 10 before | Expand all | Expand 10 after
2523 Object* maybe_constructor = map()->GetConstructor(); 2523 Object* maybe_constructor = map()->GetConstructor();
2524 if (maybe_constructor->IsJSFunction()) { 2524 if (maybe_constructor->IsJSFunction()) {
2525 JSFunction* constructor = JSFunction::cast(maybe_constructor); 2525 JSFunction* constructor = JSFunction::cast(maybe_constructor);
2526 return String::cast(constructor->shared()->instance_class_name()); 2526 return String::cast(constructor->shared()->instance_class_name());
2527 } 2527 }
2528 // If the constructor is not present, return "Object". 2528 // If the constructor is not present, return "Object".
2529 return GetHeap()->Object_string(); 2529 return GetHeap()->Object_string();
2530 } 2530 }
2531 2531
2532 2532
2533 MaybeHandle<String> JSReceiver::BuiltinStringTag(Handle<JSReceiver> object) {
2534 Maybe<bool> is_array = Object::IsArray(object);
2535 MAYBE_RETURN(is_array, MaybeHandle<String>());
2536 Isolate* const isolate = object->GetIsolate();
2537 if (is_array.FromJust()) {
2538 return isolate->factory()->Array_string();
2539 }
2540
2541 // TODO(adamk): According to ES2015, we should return "Function" when
2542 // object has a [[Call]] internal method (corresponds to IsCallable).
2543 // But this is well cemented in layout tests and might cause webbreakage.
2544 // if (object->IsCallable()) {
2545 // return isolate->factory()->Function_string();
2546 // }
2547 // TODO(adamk): class_name() is expensive, replace with instance type
2548 // checks where possible.
2549
2550 InstanceType instance_type = object->map()->instance_type();
2551 switch (instance_type) {
2552 case JS_PROXY_TYPE:
2553 case JS_SPECIAL_API_OBJECT_TYPE:
2554 case JS_API_OBJECT_TYPE:
2555 case JS_VALUE_TYPE:
2556 case JS_DATE_TYPE:
2557 // Arguments and Error objects have type JS_OBJECT_TYPE
2558 case JS_OBJECT_TYPE:
2559 case JS_REGEXP_TYPE:
2560 case JS_BOUND_FUNCTION_TYPE:
2561 case JS_FUNCTION_TYPE:
2562 return handle(object->class_name(), isolate);
2563 default:
2564 return isolate->factory()->Object_string();
2565 }
2566 }
2567
2568
2569 // static 2533 // static
2570 Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) { 2534 Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
2571 Isolate* isolate = receiver->GetIsolate(); 2535 Isolate* isolate = receiver->GetIsolate();
2572 2536
2573 // If the object was instantiated simply with base == new.target, the 2537 // If the object was instantiated simply with base == new.target, the
2574 // constructor on the map provides the most accurate name. 2538 // constructor on the map provides the most accurate name.
2575 // Don't provide the info for prototypes, since their constructors are 2539 // Don't provide the info for prototypes, since their constructors are
2576 // reclaimed and replaced by Object in OptimizeAsPrototype. 2540 // reclaimed and replaced by Object in OptimizeAsPrototype.
2577 if (!receiver->IsJSProxy() && receiver->map()->new_target_is_base() && 2541 if (!receiver->IsJSProxy() && receiver->map()->new_target_is_base() &&
2578 !receiver->map()->is_prototype_map()) { 2542 !receiver->map()->is_prototype_map()) {
(...skipping 9723 matching lines...) Expand 10 before | Expand all | Expand 10 after
12302 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 12266 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
12303 case JS_DATA_VIEW_TYPE: 12267 case JS_DATA_VIEW_TYPE:
12304 case JS_DATE_TYPE: 12268 case JS_DATE_TYPE:
12305 case JS_FUNCTION_TYPE: 12269 case JS_FUNCTION_TYPE:
12306 case JS_GENERATOR_OBJECT_TYPE: 12270 case JS_GENERATOR_OBJECT_TYPE:
12307 case JS_MAP_ITERATOR_TYPE: 12271 case JS_MAP_ITERATOR_TYPE:
12308 case JS_MAP_TYPE: 12272 case JS_MAP_TYPE:
12309 case JS_MESSAGE_OBJECT_TYPE: 12273 case JS_MESSAGE_OBJECT_TYPE:
12310 case JS_MODULE_TYPE: 12274 case JS_MODULE_TYPE:
12311 case JS_OBJECT_TYPE: 12275 case JS_OBJECT_TYPE:
12276 case JS_ERROR_TYPE:
12277 case JS_ARGUMENTS_TYPE:
12312 case JS_PROMISE_TYPE: 12278 case JS_PROMISE_TYPE:
12313 case JS_REGEXP_TYPE: 12279 case JS_REGEXP_TYPE:
12314 case JS_SET_ITERATOR_TYPE: 12280 case JS_SET_ITERATOR_TYPE:
12315 case JS_SET_TYPE: 12281 case JS_SET_TYPE:
12316 case JS_SPECIAL_API_OBJECT_TYPE: 12282 case JS_SPECIAL_API_OBJECT_TYPE:
12317 case JS_TYPED_ARRAY_TYPE: 12283 case JS_TYPED_ARRAY_TYPE:
12318 case JS_VALUE_TYPE: 12284 case JS_VALUE_TYPE:
12319 case JS_WEAK_MAP_TYPE: 12285 case JS_WEAK_MAP_TYPE:
12320 case JS_WEAK_SET_TYPE: 12286 case JS_WEAK_SET_TYPE:
12321 return true; 12287 return true;
(...skipping 3333 matching lines...) Expand 10 before | Expand all | Expand 10 after
15655 15621
15656 Handle<String> tag; 15622 Handle<String> tag;
15657 Handle<Object> to_string_tag; 15623 Handle<Object> to_string_tag;
15658 ASSIGN_RETURN_ON_EXCEPTION( 15624 ASSIGN_RETURN_ON_EXCEPTION(
15659 isolate, to_string_tag, 15625 isolate, to_string_tag,
15660 JSReceiver::GetProperty(receiver, 15626 JSReceiver::GetProperty(receiver,
15661 isolate->factory()->to_string_tag_symbol()), 15627 isolate->factory()->to_string_tag_symbol()),
15662 String); 15628 String);
15663 if (to_string_tag->IsString()) { 15629 if (to_string_tag->IsString()) {
15664 tag = Handle<String>::cast(to_string_tag); 15630 tag = Handle<String>::cast(to_string_tag);
15631 } else {
15632 InstanceType instance_type = receiver->map()->instance_type();
15633
15634 switch (instance_type) {
15635 case JS_API_OBJECT_TYPE:
15636 case JS_SPECIAL_API_OBJECT_TYPE:
15637 tag = handle(receiver->class_name(), isolate);
15638 break;
15639 case JS_ARGUMENTS_TYPE:
15640 return isolate->factory()->arguments_to_string();
15641 case JS_ARRAY_TYPE:
15642 return isolate->factory()->array_to_string();
15643 case JS_BOUND_FUNCTION_TYPE:
15644 case JS_FUNCTION_TYPE:
15645 return isolate->factory()->function_to_string();
15646 case JS_ERROR_TYPE:
15647 return isolate->factory()->error_to_string();
15648 case JS_DATE_TYPE:
15649 return isolate->factory()->date_to_string();
15650 case JS_REGEXP_TYPE:
15651 return isolate->factory()->regexp_to_string();
15652
15653 // TODO(franzih): According to the specification, isArray() must be run
15654 // before get(@@toStringTag). On proxies, isArray() and get() can throw
15655 // if the proxy has been revoked, so we change observable behavior
15656 // by not obeying the correct order.
15657 case JS_PROXY_TYPE: {
15658 Maybe<bool> is_array = Object::IsArray(receiver);
15659 MAYBE_RETURN(is_array, MaybeHandle<String>());
15660 if (is_array.FromJust()) {
15661 return isolate->factory()->array_to_string();
15662 }
15663 if (receiver->IsCallable()) {
15664 return isolate->factory()->function_to_string();
15665 }
15666 return isolate->factory()->object_to_string();
15667 }
15668 case JS_VALUE_TYPE: {
15669 Object* value = JSValue::cast(*receiver)->value();
15670 if (value->IsString()) {
15671 return isolate->factory()->string_to_string();
15672 }
15673 if (value->IsNumber()) {
15674 return isolate->factory()->number_to_string();
15675 }
15676 if (value->IsBoolean()) {
15677 return isolate->factory()->boolean_to_string();
15678 }
15679 if (value->IsSymbol()) {
15680 return isolate->factory()->object_to_string();
15681 }
15682 UNREACHABLE();
15683 tag = handle(receiver->class_name(), isolate);
15684 break;
15685 }
15686 default:
15687 return isolate->factory()->object_to_string();
15688 break;
15689 }
15665 } 15690 }
15666 15691
15667 if (tag.is_null()) {
15668 ASSIGN_RETURN_ON_EXCEPTION(isolate, tag,
15669 JSReceiver::BuiltinStringTag(receiver), String);
15670 }
15671
15672 if (*tag == isolate->heap()->Object_string()) {
15673 return isolate->factory()->object_to_string();
15674 }
15675 if (*tag == isolate->heap()->String_string()) {
15676 return isolate->factory()->string_to_string();
15677 }
15678 if (*tag == isolate->heap()->Array_string()) {
15679 return isolate->factory()->array_to_string();
15680 }
15681 if (*tag == isolate->heap()->Function_string()) {
15682 return isolate->factory()->function_to_string();
15683 }
15684 IncrementalStringBuilder builder(isolate); 15692 IncrementalStringBuilder builder(isolate);
15685 builder.AppendCString("[object "); 15693 builder.AppendCString("[object ");
15686 builder.AppendString(tag); 15694 builder.AppendString(tag);
15687 builder.AppendCharacter(']'); 15695 builder.AppendCharacter(']');
15688 return builder.Finish(); 15696 return builder.Finish();
15689 } 15697 }
15690 15698
15691
15692 const char* Symbol::PrivateSymbolToName() const { 15699 const char* Symbol::PrivateSymbolToName() const {
15693 Heap* heap = GetIsolate()->heap(); 15700 Heap* heap = GetIsolate()->heap();
15694 #define SYMBOL_CHECK_AND_PRINT(name) \ 15701 #define SYMBOL_CHECK_AND_PRINT(name) \
15695 if (this == heap->name()) return #name; 15702 if (this == heap->name()) return #name;
15696 PRIVATE_SYMBOL_LIST(SYMBOL_CHECK_AND_PRINT) 15703 PRIVATE_SYMBOL_LIST(SYMBOL_CHECK_AND_PRINT)
15697 #undef SYMBOL_CHECK_AND_PRINT 15704 #undef SYMBOL_CHECK_AND_PRINT
15698 return "UNKNOWN"; 15705 return "UNKNOWN";
15699 } 15706 }
15700 15707
15701 15708
(...skipping 3149 matching lines...) Expand 10 before | Expand all | Expand 10 after
18851 } else { 18858 } else {
18852 // Old-style generators. 18859 // Old-style generators.
18853 int offset = continuation(); 18860 int offset = continuation();
18854 CHECK(0 <= offset && offset < function()->code()->instruction_size()); 18861 CHECK(0 <= offset && offset < function()->code()->instruction_size());
18855 return function()->code()->SourcePosition(offset); 18862 return function()->code()->SourcePosition(offset);
18856 } 18863 }
18857 } 18864 }
18858 18865
18859 } // namespace internal 18866 } // namespace internal
18860 } // namespace v8 18867 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-body-descriptors-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698