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 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 | 724 |
725 | 725 |
726 Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) { | 726 Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) { |
727 for (; it->IsFound(); it->Next()) { | 727 for (; it->IsFound(); it->Next()) { |
728 switch (it->state()) { | 728 switch (it->state()) { |
729 case LookupIterator::INTERCEPTOR: | 729 case LookupIterator::INTERCEPTOR: |
730 case LookupIterator::NOT_FOUND: | 730 case LookupIterator::NOT_FOUND: |
731 case LookupIterator::TRANSITION: | 731 case LookupIterator::TRANSITION: |
732 UNREACHABLE(); | 732 UNREACHABLE(); |
733 case LookupIterator::ACCESS_CHECK: | 733 case LookupIterator::ACCESS_CHECK: |
734 if (it->HasAccess()) continue; | 734 // Support calling this method without an active context, but refuse |
| 735 // access to access-checked objects in that case. |
| 736 if (it->isolate()->context() != nullptr && it->HasAccess()) continue; |
735 // Fall through. | 737 // Fall through. |
736 case LookupIterator::JSPROXY: | 738 case LookupIterator::JSPROXY: |
737 it->NotFound(); | 739 it->NotFound(); |
738 return it->isolate()->factory()->undefined_value(); | 740 return it->isolate()->factory()->undefined_value(); |
739 case LookupIterator::ACCESSOR: | 741 case LookupIterator::ACCESSOR: |
740 // TODO(verwaest): For now this doesn't call into | 742 // TODO(verwaest): For now this doesn't call into |
741 // ExecutableAccessorInfo, since clients don't need it. Update once | 743 // ExecutableAccessorInfo, since clients don't need it. Update once |
742 // relevant. | 744 // relevant. |
743 it->NotFound(); | 745 it->NotFound(); |
744 return it->isolate()->factory()->undefined_value(); | 746 return it->isolate()->factory()->undefined_value(); |
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1808 JSFunction::cast(native_context->get(constructor_function_index))); | 1810 JSFunction::cast(native_context->get(constructor_function_index))); |
1809 } | 1811 } |
1810 } | 1812 } |
1811 return MaybeHandle<JSFunction>(); | 1813 return MaybeHandle<JSFunction>(); |
1812 } | 1814 } |
1813 | 1815 |
1814 | 1816 |
1815 void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, | 1817 void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, |
1816 PropertyAttributes attributes) { | 1818 PropertyAttributes attributes) { |
1817 OFStream os(file); | 1819 OFStream os(file); |
1818 os << "[reconfiguring "; | 1820 os << "[reconfiguring]"; |
1819 constructor_name()->PrintOn(file); | |
1820 os << "] "; | |
1821 Name* name = instance_descriptors()->GetKey(modify_index); | 1821 Name* name = instance_descriptors()->GetKey(modify_index); |
1822 if (name->IsString()) { | 1822 if (name->IsString()) { |
1823 String::cast(name)->PrintOn(file); | 1823 String::cast(name)->PrintOn(file); |
1824 } else { | 1824 } else { |
1825 os << "{symbol " << static_cast<void*>(name) << "}"; | 1825 os << "{symbol " << static_cast<void*>(name) << "}"; |
1826 } | 1826 } |
1827 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; | 1827 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; |
1828 os << attributes << " ["; | 1828 os << attributes << " ["; |
1829 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 1829 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
1830 os << "]\n"; | 1830 os << "]\n"; |
1831 } | 1831 } |
1832 | 1832 |
1833 | 1833 |
1834 void Map::PrintGeneralization(FILE* file, | 1834 void Map::PrintGeneralization(FILE* file, |
1835 const char* reason, | 1835 const char* reason, |
1836 int modify_index, | 1836 int modify_index, |
1837 int split, | 1837 int split, |
1838 int descriptors, | 1838 int descriptors, |
1839 bool constant_to_field, | 1839 bool constant_to_field, |
1840 Representation old_representation, | 1840 Representation old_representation, |
1841 Representation new_representation, | 1841 Representation new_representation, |
1842 HeapType* old_field_type, | 1842 HeapType* old_field_type, |
1843 HeapType* new_field_type) { | 1843 HeapType* new_field_type) { |
1844 OFStream os(file); | 1844 OFStream os(file); |
1845 os << "[generalizing "; | 1845 os << "[generalizing]"; |
1846 constructor_name()->PrintOn(file); | |
1847 os << "] "; | |
1848 Name* name = instance_descriptors()->GetKey(modify_index); | 1846 Name* name = instance_descriptors()->GetKey(modify_index); |
1849 if (name->IsString()) { | 1847 if (name->IsString()) { |
1850 String::cast(name)->PrintOn(file); | 1848 String::cast(name)->PrintOn(file); |
1851 } else { | 1849 } else { |
1852 os << "{symbol " << static_cast<void*>(name) << "}"; | 1850 os << "{symbol " << static_cast<void*>(name) << "}"; |
1853 } | 1851 } |
1854 os << ":"; | 1852 os << ":"; |
1855 if (constant_to_field) { | 1853 if (constant_to_field) { |
1856 os << "c"; | 1854 os << "c"; |
1857 } else { | 1855 } else { |
(...skipping 11 matching lines...) Expand all Loading... |
1869 } | 1867 } |
1870 os << ") ["; | 1868 os << ") ["; |
1871 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 1869 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
1872 os << "]\n"; | 1870 os << "]\n"; |
1873 } | 1871 } |
1874 | 1872 |
1875 | 1873 |
1876 void JSObject::PrintInstanceMigration(FILE* file, | 1874 void JSObject::PrintInstanceMigration(FILE* file, |
1877 Map* original_map, | 1875 Map* original_map, |
1878 Map* new_map) { | 1876 Map* new_map) { |
1879 PrintF(file, "[migrating "); | 1877 PrintF(file, "[migrating]"); |
1880 map()->constructor_name()->PrintOn(file); | |
1881 PrintF(file, "] "); | |
1882 DescriptorArray* o = original_map->instance_descriptors(); | 1878 DescriptorArray* o = original_map->instance_descriptors(); |
1883 DescriptorArray* n = new_map->instance_descriptors(); | 1879 DescriptorArray* n = new_map->instance_descriptors(); |
1884 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { | 1880 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { |
1885 Representation o_r = o->GetDetails(i).representation(); | 1881 Representation o_r = o->GetDetails(i).representation(); |
1886 Representation n_r = n->GetDetails(i).representation(); | 1882 Representation n_r = n->GetDetails(i).representation(); |
1887 if (!o_r.Equals(n_r)) { | 1883 if (!o_r.Equals(n_r)) { |
1888 String::cast(o->GetKey(i))->PrintOn(file); | 1884 String::cast(o->GetKey(i))->PrintOn(file); |
1889 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); | 1885 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); |
1890 } else if (o->GetDetails(i).type() == DATA_CONSTANT && | 1886 } else if (o->GetDetails(i).type() == DATA_CONSTANT && |
1891 n->GetDetails(i).type() == DATA) { | 1887 n->GetDetails(i).type() == DATA) { |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2223 Object* maybe_constructor = map()->GetConstructor(); | 2219 Object* maybe_constructor = map()->GetConstructor(); |
2224 if (maybe_constructor->IsJSFunction()) { | 2220 if (maybe_constructor->IsJSFunction()) { |
2225 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 2221 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
2226 return String::cast(constructor->shared()->instance_class_name()); | 2222 return String::cast(constructor->shared()->instance_class_name()); |
2227 } | 2223 } |
2228 // If the constructor is not present, return "Object". | 2224 // If the constructor is not present, return "Object". |
2229 return GetHeap()->Object_string(); | 2225 return GetHeap()->Object_string(); |
2230 } | 2226 } |
2231 | 2227 |
2232 | 2228 |
2233 String* Map::constructor_name() { | 2229 // static |
2234 if (is_prototype_map() && prototype_info()->IsPrototypeInfo()) { | 2230 Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) { |
2235 PrototypeInfo* proto_info = PrototypeInfo::cast(prototype_info()); | 2231 Isolate* isolate = receiver->GetIsolate(); |
2236 if (proto_info->constructor_name()->IsString()) { | 2232 if (FLAG_harmony_tostring) { |
2237 return String::cast(proto_info->constructor_name()); | 2233 Handle<Object> maybe_tag = JSReceiver::GetDataProperty( |
| 2234 receiver, isolate->factory()->to_string_tag_symbol()); |
| 2235 if (maybe_tag->IsString()) return Handle<String>::cast(maybe_tag); |
| 2236 } |
| 2237 |
| 2238 PrototypeIterator iter(isolate, receiver); |
| 2239 if (iter.IsAtEnd()) return handle(receiver->class_name()); |
| 2240 Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter); |
| 2241 LookupIterator it(receiver, isolate->factory()->constructor_string(), start, |
| 2242 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); |
| 2243 Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it); |
| 2244 Handle<String> result = isolate->factory()->Object_string(); |
| 2245 if (maybe_constructor->IsJSFunction()) { |
| 2246 JSFunction* constructor = JSFunction::cast(*maybe_constructor); |
| 2247 String* name = String::cast(constructor->shared()->name()); |
| 2248 if (name->length() > 0) { |
| 2249 result = handle(name, isolate); |
| 2250 } else { |
| 2251 String* inferred_name = constructor->shared()->inferred_name(); |
| 2252 if (inferred_name->length() > 0) { |
| 2253 result = handle(inferred_name, isolate); |
| 2254 } |
2238 } | 2255 } |
2239 } | 2256 } |
2240 Object* maybe_constructor = GetConstructor(); | 2257 |
2241 if (maybe_constructor->IsJSFunction()) { | 2258 return result.is_identical_to(isolate->factory()->Object_string()) |
2242 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 2259 ? handle(receiver->class_name()) |
2243 String* name = String::cast(constructor->shared()->name()); | 2260 : result; |
2244 if (name->length() > 0) return name; | |
2245 String* inferred_name = constructor->shared()->inferred_name(); | |
2246 if (inferred_name->length() > 0) return inferred_name; | |
2247 Object* proto = prototype(); | |
2248 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | |
2249 } | |
2250 // TODO(rossberg): what about proxies? | |
2251 // If the constructor is not present, return "Object". | |
2252 return GetHeap()->Object_string(); | |
2253 } | 2261 } |
2254 | 2262 |
2255 | 2263 |
2256 String* JSReceiver::constructor_name() { | |
2257 return map()->constructor_name(); | |
2258 } | |
2259 | |
2260 | |
2261 Context* JSReceiver::GetCreationContext() { | 2264 Context* JSReceiver::GetCreationContext() { |
2262 Object* constructor = map()->GetConstructor(); | 2265 Object* constructor = map()->GetConstructor(); |
2263 JSFunction* function; | 2266 JSFunction* function; |
2264 if (!constructor->IsJSFunction()) { | 2267 if (!constructor->IsJSFunction()) { |
2265 // Functions have null as a constructor, | 2268 // Functions have null as a constructor, |
2266 // but any JSFunction knows its context immediately. | 2269 // but any JSFunction knows its context immediately. |
2267 function = JSFunction::cast(this); | 2270 function = JSFunction::cast(this); |
2268 } else { | 2271 } else { |
2269 function = JSFunction::cast(constructor); | 2272 function = JSFunction::cast(constructor); |
2270 } | 2273 } |
(...skipping 9431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11702 | 11705 |
11703 // Replace the pointer to the exact constructor with the Object function | 11706 // Replace the pointer to the exact constructor with the Object function |
11704 // from the same context if undetectable from JS. This is to avoid keeping | 11707 // from the same context if undetectable from JS. This is to avoid keeping |
11705 // memory alive unnecessarily. | 11708 // memory alive unnecessarily. |
11706 Object* maybe_constructor = object->map()->GetConstructor(); | 11709 Object* maybe_constructor = object->map()->GetConstructor(); |
11707 if (maybe_constructor->IsJSFunction()) { | 11710 if (maybe_constructor->IsJSFunction()) { |
11708 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 11711 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
11709 Isolate* isolate = object->GetIsolate(); | 11712 Isolate* isolate = object->GetIsolate(); |
11710 if (!constructor->shared()->IsApiFunction() && | 11713 if (!constructor->shared()->IsApiFunction() && |
11711 object->class_name() == isolate->heap()->Object_string()) { | 11714 object->class_name() == isolate->heap()->Object_string()) { |
11712 Handle<String> constructor_name(object->constructor_name(), isolate); | |
11713 Context* context = constructor->context()->native_context(); | 11715 Context* context = constructor->context()->native_context(); |
11714 JSFunction* object_function = context->object_function(); | 11716 JSFunction* object_function = context->object_function(); |
11715 object->map()->SetConstructor(object_function); | 11717 object->map()->SetConstructor(object_function); |
11716 Handle<PrototypeInfo> proto_info = | |
11717 Map::GetOrCreatePrototypeInfo(object, isolate); | |
11718 proto_info->set_constructor_name(*constructor_name); | |
11719 } | 11718 } |
11720 } | 11719 } |
11721 } | 11720 } |
11722 } | 11721 } |
11723 | 11722 |
11724 | 11723 |
11725 // static | 11724 // static |
11726 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { | 11725 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { |
11727 if (!object->map()->is_prototype_map()) return; | 11726 if (!object->map()->is_prototype_map()) return; |
11728 OptimizeAsPrototype(object, FAST_PROTOTYPE); | 11727 OptimizeAsPrototype(object, FAST_PROTOTYPE); |
(...skipping 6872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18601 if (cell->value() != *new_value) { | 18600 if (cell->value() != *new_value) { |
18602 cell->set_value(*new_value); | 18601 cell->set_value(*new_value); |
18603 Isolate* isolate = cell->GetIsolate(); | 18602 Isolate* isolate = cell->GetIsolate(); |
18604 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18603 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18605 isolate, DependentCode::kPropertyCellChangedGroup); | 18604 isolate, DependentCode::kPropertyCellChangedGroup); |
18606 } | 18605 } |
18607 } | 18606 } |
18608 | 18607 |
18609 } // namespace internal | 18608 } // namespace internal |
18610 } // namespace v8 | 18609 } // namespace v8 |
OLD | NEW |