| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 | 568 |
| 569 Handle<Object> argv[] = { value }; | 569 Handle<Object> argv[] = { value }; |
| 570 RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver, | 570 RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver, |
| 571 ARRAY_SIZE(argv), argv, true), | 571 ARRAY_SIZE(argv), argv, true), |
| 572 Object); | 572 Object); |
| 573 return value; | 573 return value; |
| 574 } | 574 } |
| 575 | 575 |
| 576 | 576 |
| 577 static bool FindAllCanReadHolder(LookupIterator* it) { | 577 static bool FindAllCanReadHolder(LookupIterator* it) { |
| 578 it->skip_interceptor(); | |
| 579 it->skip_access_check(); | |
| 580 for (; it->IsFound(); it->Next()) { | 578 for (; it->IsFound(); it->Next()) { |
| 581 if (it->state() == LookupIterator::PROPERTY && | 579 if (it->state() == LookupIterator::PROPERTY && |
| 582 it->HasProperty() && | 580 it->HasProperty() && |
| 583 it->property_kind() == LookupIterator::ACCESSOR) { | 581 it->property_kind() == LookupIterator::ACCESSOR) { |
| 584 Handle<Object> accessors = it->GetAccessors(); | 582 Handle<Object> accessors = it->GetAccessors(); |
| 585 if (accessors->IsAccessorInfo()) { | 583 if (accessors->IsAccessorInfo()) { |
| 586 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; | 584 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; |
| 587 } | 585 } |
| 588 } | 586 } |
| 589 } | 587 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 611 if (FindAllCanReadHolder(it)) | 609 if (FindAllCanReadHolder(it)) |
| 612 return maybe(it->property_details().attributes()); | 610 return maybe(it->property_details().attributes()); |
| 613 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS); | 611 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS); |
| 614 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), | 612 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), |
| 615 Maybe<PropertyAttributes>()); | 613 Maybe<PropertyAttributes>()); |
| 616 return maybe(ABSENT); | 614 return maybe(ABSENT); |
| 617 } | 615 } |
| 618 | 616 |
| 619 | 617 |
| 620 static bool FindAllCanWriteHolder(LookupIterator* it) { | 618 static bool FindAllCanWriteHolder(LookupIterator* it) { |
| 621 it->skip_interceptor(); | |
| 622 it->skip_access_check(); | |
| 623 for (; it->IsFound(); it->Next()) { | 619 for (; it->IsFound(); it->Next()) { |
| 624 if (it->state() == LookupIterator::PROPERTY && it->HasProperty() && | 620 if (it->state() == LookupIterator::PROPERTY && it->HasProperty() && |
| 625 it->property_kind() == LookupIterator::ACCESSOR) { | 621 it->property_kind() == LookupIterator::ACCESSOR) { |
| 626 Handle<Object> accessors = it->GetAccessors(); | 622 Handle<Object> accessors = it->GetAccessors(); |
| 627 if (accessors->IsAccessorInfo()) { | 623 if (accessors->IsAccessorInfo()) { |
| 628 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; | 624 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; |
| 629 } | 625 } |
| 630 } | 626 } |
| 631 } | 627 } |
| 632 return false; | 628 return false; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 if (object->IsGlobalObject()) { | 664 if (object->IsGlobalObject()) { |
| 669 value = handle(Handle<PropertyCell>::cast(value)->value(), isolate); | 665 value = handle(Handle<PropertyCell>::cast(value)->value(), isolate); |
| 670 DCHECK(!value->IsTheHole()); | 666 DCHECK(!value->IsTheHole()); |
| 671 } | 667 } |
| 672 DCHECK(!value->IsPropertyCell() && !value->IsCell()); | 668 DCHECK(!value->IsPropertyCell() && !value->IsCell()); |
| 673 return value; | 669 return value; |
| 674 } | 670 } |
| 675 | 671 |
| 676 | 672 |
| 677 void JSObject::SetNormalizedProperty(Handle<JSObject> object, | 673 void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
| 678 const LookupResult* result, | |
| 679 Handle<Object> value) { | |
| 680 DCHECK(!object->HasFastProperties()); | |
| 681 NameDictionary* property_dictionary = object->property_dictionary(); | |
| 682 if (object->IsGlobalObject()) { | |
| 683 Handle<PropertyCell> cell(PropertyCell::cast( | |
| 684 property_dictionary->ValueAt(result->GetDictionaryEntry()))); | |
| 685 PropertyCell::SetValueInferType(cell, value); | |
| 686 } else { | |
| 687 property_dictionary->ValueAtPut(result->GetDictionaryEntry(), *value); | |
| 688 } | |
| 689 } | |
| 690 | |
| 691 | |
| 692 void JSObject::SetNormalizedProperty(Handle<JSObject> object, | |
| 693 Handle<Name> name, | 674 Handle<Name> name, |
| 694 Handle<Object> value, | 675 Handle<Object> value, |
| 695 PropertyDetails details) { | 676 PropertyDetails details) { |
| 696 DCHECK(!object->HasFastProperties()); | 677 DCHECK(!object->HasFastProperties()); |
| 697 Handle<NameDictionary> property_dictionary(object->property_dictionary()); | 678 Handle<NameDictionary> property_dictionary(object->property_dictionary()); |
| 698 | 679 |
| 699 if (!name->IsUniqueName()) { | 680 if (!name->IsUniqueName()) { |
| 700 name = object->GetIsolate()->factory()->InternalizeString( | 681 name = object->GetIsolate()->factory()->InternalizeString( |
| 701 Handle<String>::cast(name)); | 682 Handle<String>::cast(name)); |
| 702 } | 683 } |
| (...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { | 1797 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { |
| 1817 return MaybeHandle<Map>(); | 1798 return MaybeHandle<Map>(); |
| 1818 } | 1799 } |
| 1819 | 1800 |
| 1820 // Allocate new instance descriptors with (name, constant) added. | 1801 // Allocate new instance descriptors with (name, constant) added. |
| 1821 ConstantDescriptor new_constant_desc(name, constant, attributes); | 1802 ConstantDescriptor new_constant_desc(name, constant, attributes); |
| 1822 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); | 1803 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); |
| 1823 } | 1804 } |
| 1824 | 1805 |
| 1825 | 1806 |
| 1826 void JSObject::AddFastProperty(Handle<JSObject> object, | |
| 1827 Handle<Name> name, | |
| 1828 Handle<Object> value, | |
| 1829 PropertyAttributes attributes, | |
| 1830 StoreFromKeyed store_mode, | |
| 1831 TransitionFlag flag) { | |
| 1832 DCHECK(!object->IsJSGlobalProxy()); | |
| 1833 | |
| 1834 MaybeHandle<Map> maybe_map; | |
| 1835 if (value->IsJSFunction()) { | |
| 1836 maybe_map = Map::CopyWithConstant( | |
| 1837 handle(object->map()), name, value, attributes, flag); | |
| 1838 } else if (!object->map()->TooManyFastProperties(store_mode)) { | |
| 1839 Isolate* isolate = object->GetIsolate(); | |
| 1840 Representation representation = value->OptimalRepresentation(); | |
| 1841 maybe_map = Map::CopyWithField( | |
| 1842 handle(object->map(), isolate), name, | |
| 1843 value->OptimalType(isolate, representation), | |
| 1844 attributes, representation, flag); | |
| 1845 } | |
| 1846 | |
| 1847 Handle<Map> new_map; | |
| 1848 if (!maybe_map.ToHandle(&new_map)) { | |
| 1849 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | |
| 1850 return; | |
| 1851 } | |
| 1852 | |
| 1853 JSObject::MigrateToNewProperty(object, new_map, value); | |
| 1854 } | |
| 1855 | |
| 1856 | |
| 1857 void JSObject::AddSlowProperty(Handle<JSObject> object, | 1807 void JSObject::AddSlowProperty(Handle<JSObject> object, |
| 1858 Handle<Name> name, | 1808 Handle<Name> name, |
| 1859 Handle<Object> value, | 1809 Handle<Object> value, |
| 1860 PropertyAttributes attributes) { | 1810 PropertyAttributes attributes) { |
| 1861 DCHECK(!object->HasFastProperties()); | 1811 DCHECK(!object->HasFastProperties()); |
| 1862 Isolate* isolate = object->GetIsolate(); | 1812 Isolate* isolate = object->GetIsolate(); |
| 1863 Handle<NameDictionary> dict(object->property_dictionary()); | 1813 Handle<NameDictionary> dict(object->property_dictionary()); |
| 1864 if (object->IsGlobalObject()) { | 1814 if (object->IsGlobalObject()) { |
| 1865 // In case name is an orphaned property reuse the cell. | 1815 // In case name is an orphaned property reuse the cell. |
| 1866 int entry = dict->FindEntry(name); | 1816 int entry = dict->FindEntry(name); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1879 PropertyCell::SetValueInferType(cell, value); | 1829 PropertyCell::SetValueInferType(cell, value); |
| 1880 value = cell; | 1830 value = cell; |
| 1881 } | 1831 } |
| 1882 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 1832 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
| 1883 Handle<NameDictionary> result = | 1833 Handle<NameDictionary> result = |
| 1884 NameDictionary::Add(dict, name, value, details); | 1834 NameDictionary::Add(dict, name, value, details); |
| 1885 if (*dict != *result) object->set_properties(*result); | 1835 if (*dict != *result) object->set_properties(*result); |
| 1886 } | 1836 } |
| 1887 | 1837 |
| 1888 | 1838 |
| 1889 MaybeHandle<Object> JSObject::AddPropertyInternal( | |
| 1890 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, | |
| 1891 PropertyAttributes attributes, JSReceiver::StoreFromKeyed store_mode, | |
| 1892 ExtensibilityCheck extensibility_check, TransitionFlag transition_flag) { | |
| 1893 DCHECK(!object->IsJSGlobalProxy()); | |
| 1894 Isolate* isolate = object->GetIsolate(); | |
| 1895 | |
| 1896 if (!name->IsUniqueName()) { | |
| 1897 name = isolate->factory()->InternalizeString( | |
| 1898 Handle<String>::cast(name)); | |
| 1899 } | |
| 1900 | |
| 1901 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | |
| 1902 !object->map()->is_extensible()) { | |
| 1903 Handle<Object> args[1] = {name}; | |
| 1904 Handle<Object> error = isolate->factory()->NewTypeError( | |
| 1905 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | |
| 1906 return isolate->Throw<Object>(error); | |
| 1907 } | |
| 1908 | |
| 1909 if (object->HasFastProperties()) { | |
| 1910 AddFastProperty(object, name, value, attributes, store_mode, | |
| 1911 transition_flag); | |
| 1912 } | |
| 1913 | |
| 1914 if (!object->HasFastProperties()) { | |
| 1915 AddSlowProperty(object, name, value, attributes); | |
| 1916 } | |
| 1917 | |
| 1918 if (object->map()->is_observed() && | |
| 1919 *name != isolate->heap()->hidden_string()) { | |
| 1920 Handle<Object> old_value = isolate->factory()->the_hole_value(); | |
| 1921 EnqueueChangeRecord(object, "add", name, old_value); | |
| 1922 } | |
| 1923 | |
| 1924 return value; | |
| 1925 } | |
| 1926 | |
| 1927 | |
| 1928 Context* JSObject::GetCreationContext() { | 1839 Context* JSObject::GetCreationContext() { |
| 1929 Object* constructor = this->map()->constructor(); | 1840 Object* constructor = this->map()->constructor(); |
| 1930 JSFunction* function; | 1841 JSFunction* function; |
| 1931 if (!constructor->IsJSFunction()) { | 1842 if (!constructor->IsJSFunction()) { |
| 1932 // Functions have null as a constructor, | 1843 // Functions have null as a constructor, |
| 1933 // but any JSFunction knows its context immediately. | 1844 // but any JSFunction knows its context immediately. |
| 1934 function = JSFunction::cast(this); | 1845 function = JSFunction::cast(this); |
| 1935 } else { | 1846 } else { |
| 1936 function = JSFunction::cast(constructor); | 1847 function = JSFunction::cast(constructor); |
| 1937 } | 1848 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1952 Handle<Object> args[] = { type, object, name, old_value }; | 1863 Handle<Object> args[] = { type, object, name, old_value }; |
| 1953 int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4; | 1864 int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4; |
| 1954 | 1865 |
| 1955 Execution::Call(isolate, | 1866 Execution::Call(isolate, |
| 1956 Handle<JSFunction>(isolate->observers_notify_change()), | 1867 Handle<JSFunction>(isolate->observers_notify_change()), |
| 1957 isolate->factory()->undefined_value(), | 1868 isolate->factory()->undefined_value(), |
| 1958 argc, args).Assert(); | 1869 argc, args).Assert(); |
| 1959 } | 1870 } |
| 1960 | 1871 |
| 1961 | 1872 |
| 1962 static void ReplaceSlowProperty(Handle<JSObject> object, | |
| 1963 Handle<Name> name, | |
| 1964 Handle<Object> value, | |
| 1965 PropertyAttributes attributes) { | |
| 1966 NameDictionary* dictionary = object->property_dictionary(); | |
| 1967 int old_index = dictionary->FindEntry(name); | |
| 1968 int new_enumeration_index = 0; // 0 means "Use the next available index." | |
| 1969 if (old_index != -1) { | |
| 1970 // All calls to ReplaceSlowProperty have had all transitions removed. | |
| 1971 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); | |
| 1972 } | |
| 1973 | |
| 1974 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); | |
| 1975 JSObject::SetNormalizedProperty(object, name, value, new_details); | |
| 1976 } | |
| 1977 | |
| 1978 | |
| 1979 const char* Representation::Mnemonic() const { | 1873 const char* Representation::Mnemonic() const { |
| 1980 switch (kind_) { | 1874 switch (kind_) { |
| 1981 case kNone: return "v"; | 1875 case kNone: return "v"; |
| 1982 case kTagged: return "t"; | 1876 case kTagged: return "t"; |
| 1983 case kSmi: return "s"; | 1877 case kSmi: return "s"; |
| 1984 case kDouble: return "d"; | 1878 case kDouble: return "d"; |
| 1985 case kInteger32: return "i"; | 1879 case kInteger32: return "i"; |
| 1986 case kHeapObject: return "h"; | 1880 case kHeapObject: return "h"; |
| 1987 case kExternal: return "x"; | 1881 case kExternal: return "x"; |
| 1988 default: | 1882 default: |
| (...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3022 return SetDataProperty(it, value); | 2916 return SetDataProperty(it, value); |
| 3023 } | 2917 } |
| 3024 } | 2918 } |
| 3025 done = true; | 2919 done = true; |
| 3026 break; | 2920 break; |
| 3027 } | 2921 } |
| 3028 | 2922 |
| 3029 if (done) break; | 2923 if (done) break; |
| 3030 } | 2924 } |
| 3031 | 2925 |
| 3032 return AddDataProperty(it, value, NONE, strict_mode, store_mode); | 2926 return AddDataProperty(it, value, NONE, strict_mode, store_mode, |
| 2927 PERFORM_EXTENSIBILITY_CHECK); |
| 3033 } | 2928 } |
| 3034 | 2929 |
| 3035 | 2930 |
| 3036 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it, | 2931 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it, |
| 3037 Handle<Object> value, | 2932 Handle<Object> value, |
| 3038 StrictMode strict_mode) { | 2933 StrictMode strict_mode) { |
| 3039 if (strict_mode != STRICT) return value; | 2934 if (strict_mode != STRICT) return value; |
| 3040 | 2935 |
| 3041 Handle<Object> args[] = {it->name(), it->GetReceiver()}; | 2936 Handle<Object> args[] = {it->name(), it->GetReceiver()}; |
| 3042 Handle<Object> error = it->factory()->NewTypeError( | 2937 Handle<Object> error = it->factory()->NewTypeError( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3077 } | 2972 } |
| 3078 | 2973 |
| 3079 return value; | 2974 return value; |
| 3080 } | 2975 } |
| 3081 | 2976 |
| 3082 | 2977 |
| 3083 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, | 2978 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, |
| 3084 Handle<Object> value, | 2979 Handle<Object> value, |
| 3085 PropertyAttributes attributes, | 2980 PropertyAttributes attributes, |
| 3086 StrictMode strict_mode, | 2981 StrictMode strict_mode, |
| 3087 StoreFromKeyed store_mode) { | 2982 StoreFromKeyed store_mode, |
| 2983 ExtensibilityCheck check) { |
| 3088 DCHECK(!it->GetReceiver()->IsJSProxy()); | 2984 DCHECK(!it->GetReceiver()->IsJSProxy()); |
| 3089 if (!it->GetReceiver()->IsJSObject()) { | 2985 if (!it->GetReceiver()->IsJSObject()) { |
| 3090 // TODO(verwaest): Throw a TypeError with a more specific message. | 2986 // TODO(verwaest): Throw a TypeError with a more specific message. |
| 3091 return WriteToReadOnlyProperty(it, value, strict_mode); | 2987 return WriteToReadOnlyProperty(it, value, strict_mode); |
| 3092 } | 2988 } |
| 3093 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 2989 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
| 3094 | 2990 |
| 3095 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) | 2991 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) |
| 3096 // instead. If the prototype is Null, the proxy is detached. | 2992 // instead. If the prototype is Null, the proxy is detached. |
| 3097 if (receiver->IsJSGlobalProxy()) { | 2993 if (receiver->IsJSGlobalProxy()) { |
| 3098 // Trying to assign to a detached proxy. | 2994 // Trying to assign to a detached proxy. |
| 3099 PrototypeIterator iter(it->isolate(), receiver); | 2995 PrototypeIterator iter(it->isolate(), receiver); |
| 3100 if (iter.IsAtEnd()) return value; | 2996 if (iter.IsAtEnd()) return value; |
| 3101 receiver = | 2997 receiver = |
| 3102 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); | 2998 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 3103 } | 2999 } |
| 3104 | 3000 |
| 3105 if (!receiver->map()->is_extensible()) { | 3001 if (check == PERFORM_EXTENSIBILITY_CHECK && |
| 3002 !receiver->map()->is_extensible()) { |
| 3106 if (strict_mode == SLOPPY) return value; | 3003 if (strict_mode == SLOPPY) return value; |
| 3107 | 3004 |
| 3108 Handle<Object> args[1] = {it->name()}; | 3005 Handle<Object> args[1] = {it->name()}; |
| 3109 Handle<Object> error = it->factory()->NewTypeError( | 3006 Handle<Object> error = it->factory()->NewTypeError( |
| 3110 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | 3007 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); |
| 3111 return it->isolate()->Throw<Object>(error); | 3008 return it->isolate()->Throw<Object>(error); |
| 3112 } | 3009 } |
| 3113 | 3010 |
| 3114 // Possibly migrate to the most up-to-date map that will be able to store | 3011 // Possibly migrate to the most up-to-date map that will be able to store |
| 3115 // |value| under it->name() with |attributes|. | 3012 // |value| under it->name() with |attributes|. |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3936 return false; | 3833 return false; |
| 3937 } | 3834 } |
| 3938 JSObject::MigrateToMap(object, new_map); | 3835 JSObject::MigrateToMap(object, new_map); |
| 3939 if (FLAG_trace_migration) { | 3836 if (FLAG_trace_migration) { |
| 3940 object->PrintInstanceMigration(stdout, *original_map, object->map()); | 3837 object->PrintInstanceMigration(stdout, *original_map, object->map()); |
| 3941 } | 3838 } |
| 3942 return true; | 3839 return true; |
| 3943 } | 3840 } |
| 3944 | 3841 |
| 3945 | 3842 |
| 3946 MaybeHandle<Object> JSObject::SetPropertyUsingTransition( | |
| 3947 Handle<JSObject> object, | |
| 3948 LookupResult* lookup, | |
| 3949 Handle<Name> name, | |
| 3950 Handle<Object> value, | |
| 3951 PropertyAttributes attributes) { | |
| 3952 Handle<Map> transition_map(lookup->GetTransitionTarget()); | |
| 3953 int descriptor = transition_map->LastAdded(); | |
| 3954 | |
| 3955 Handle<DescriptorArray> descriptors(transition_map->instance_descriptors()); | |
| 3956 PropertyDetails details = descriptors->GetDetails(descriptor); | |
| 3957 | |
| 3958 if (details.type() == CALLBACKS || attributes != details.attributes()) { | |
| 3959 // AddPropertyInternal will either normalize the object, or create a new | |
| 3960 // fast copy of the map. If we get a fast copy of the map, all field | |
| 3961 // representations will be tagged since the transition is omitted. | |
| 3962 return JSObject::AddPropertyInternal( | |
| 3963 object, name, value, attributes, | |
| 3964 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | |
| 3965 JSReceiver::OMIT_EXTENSIBILITY_CHECK, OMIT_TRANSITION); | |
| 3966 } | |
| 3967 | |
| 3968 // Keep the target CONSTANT if the same value is stored. | |
| 3969 // TODO(verwaest): Also support keeping the placeholder | |
| 3970 // (value->IsUninitialized) as constant. | |
| 3971 if (!lookup->CanHoldValue(value)) { | |
| 3972 Representation field_representation = value->OptimalRepresentation(); | |
| 3973 Handle<HeapType> field_type = value->OptimalType( | |
| 3974 lookup->isolate(), field_representation); | |
| 3975 transition_map = Map::GeneralizeRepresentation( | |
| 3976 transition_map, descriptor, | |
| 3977 field_representation, field_type, FORCE_FIELD); | |
| 3978 } | |
| 3979 | |
| 3980 JSObject::MigrateToNewProperty(object, transition_map, value); | |
| 3981 return value; | |
| 3982 } | |
| 3983 | |
| 3984 | |
| 3985 void JSObject::MigrateToNewProperty(Handle<JSObject> object, | 3843 void JSObject::MigrateToNewProperty(Handle<JSObject> object, |
| 3986 Handle<Map> map, | 3844 Handle<Map> map, |
| 3987 Handle<Object> value) { | 3845 Handle<Object> value) { |
| 3988 JSObject::MigrateToMap(object, map); | 3846 JSObject::MigrateToMap(object, map); |
| 3989 if (map->GetLastDescriptorDetails().type() != FIELD) return; | 3847 if (map->GetLastDescriptorDetails().type() != FIELD) return; |
| 3990 object->WriteToField(map->LastAdded(), *value); | 3848 object->WriteToField(map->LastAdded(), *value); |
| 3991 } | 3849 } |
| 3992 | 3850 |
| 3993 | 3851 |
| 3994 void JSObject::WriteToField(int descriptor, Object* value) { | 3852 void JSObject::WriteToField(int descriptor, Object* value) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4005 if (value->IsUninitialized()) return; | 3863 if (value->IsUninitialized()) return; |
| 4006 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); | 3864 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); |
| 4007 DCHECK(box->IsMutableHeapNumber()); | 3865 DCHECK(box->IsMutableHeapNumber()); |
| 4008 box->set_value(value->Number()); | 3866 box->set_value(value->Number()); |
| 4009 } else { | 3867 } else { |
| 4010 FastPropertyAtPut(index, value); | 3868 FastPropertyAtPut(index, value); |
| 4011 } | 3869 } |
| 4012 } | 3870 } |
| 4013 | 3871 |
| 4014 | 3872 |
| 4015 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { | |
| 4016 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { | |
| 4017 Representation field_representation = value->OptimalRepresentation(); | |
| 4018 Handle<HeapType> field_type = value->OptimalType( | |
| 4019 lookup->isolate(), field_representation); | |
| 4020 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), | |
| 4021 lookup->GetDescriptorIndex(), | |
| 4022 field_representation, field_type); | |
| 4023 } | |
| 4024 lookup->holder()->WriteToField(lookup->GetDescriptorIndex(), *value); | |
| 4025 } | |
| 4026 | |
| 4027 | |
| 4028 void JSObject::ConvertAndSetOwnProperty(LookupResult* lookup, | |
| 4029 Handle<Name> name, | |
| 4030 Handle<Object> value, | |
| 4031 PropertyAttributes attributes) { | |
| 4032 Handle<JSObject> object(lookup->holder()); | |
| 4033 if (object->map()->TooManyFastProperties(Object::MAY_BE_STORE_FROM_KEYED)) { | |
| 4034 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | |
| 4035 } else if (object->map()->is_prototype_map()) { | |
| 4036 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0); | |
| 4037 } | |
| 4038 | |
| 4039 if (!object->HasFastProperties()) { | |
| 4040 ReplaceSlowProperty(object, name, value, attributes); | |
| 4041 ReoptimizeIfPrototype(object); | |
| 4042 return; | |
| 4043 } | |
| 4044 | |
| 4045 int descriptor_index = lookup->GetDescriptorIndex(); | |
| 4046 if (lookup->GetAttributes() == attributes) { | |
| 4047 JSObject::GeneralizeFieldRepresentation(object, descriptor_index, | |
| 4048 Representation::Tagged(), | |
| 4049 HeapType::Any(lookup->isolate())); | |
| 4050 } else { | |
| 4051 Handle<Map> old_map(object->map()); | |
| 4052 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, | |
| 4053 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); | |
| 4054 JSObject::MigrateToMap(object, new_map); | |
| 4055 } | |
| 4056 | |
| 4057 object->WriteToField(descriptor_index, *value); | |
| 4058 } | |
| 4059 | |
| 4060 | |
| 4061 void JSObject::SetPropertyToFieldWithAttributes(LookupResult* lookup, | |
| 4062 Handle<Name> name, | |
| 4063 Handle<Object> value, | |
| 4064 PropertyAttributes attributes) { | |
| 4065 if (lookup->GetAttributes() == attributes) { | |
| 4066 if (value->IsUninitialized()) return; | |
| 4067 SetPropertyToField(lookup, value); | |
| 4068 } else { | |
| 4069 ConvertAndSetOwnProperty(lookup, name, value, attributes); | |
| 4070 } | |
| 4071 } | |
| 4072 | |
| 4073 | |
| 4074 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, | 3873 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, |
| 4075 Handle<Object> value, | 3874 Handle<Object> value, |
| 4076 PropertyAttributes attributes) { | 3875 PropertyAttributes attributes) { |
| 4077 #ifdef DEBUG | 3876 #ifdef DEBUG |
| 4078 uint32_t index; | 3877 uint32_t index; |
| 4079 DCHECK(!object->IsJSProxy()); | 3878 DCHECK(!object->IsJSProxy()); |
| 4080 DCHECK(!name->AsArrayIndex(&index)); | 3879 DCHECK(!name->AsArrayIndex(&index)); |
| 4081 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); | 3880 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); |
| 4082 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it); | 3881 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it); |
| 4083 DCHECK(maybe.has_value); | 3882 DCHECK(maybe.has_value); |
| 4084 DCHECK(!it.IsFound()); | 3883 DCHECK(!it.IsFound()); |
| 4085 DCHECK(object->map()->is_extensible()); | 3884 DCHECK(object->map()->is_extensible()); |
| 4086 #endif | 3885 #endif |
| 4087 SetOwnPropertyIgnoreAttributes(object, name, value, attributes, | 3886 SetOwnPropertyIgnoreAttributes(object, name, value, attributes, |
| 4088 OMIT_EXTENSIBILITY_CHECK).Check(); | 3887 OMIT_EXTENSIBILITY_CHECK).Check(); |
| 4089 } | 3888 } |
| 4090 | 3889 |
| 4091 | 3890 |
| 4092 // Reconfigures a property to a data property with attributes, even if it is not | 3891 // Reconfigures a property to a data property with attributes, even if it is not |
| 4093 // reconfigurable. | 3892 // reconfigurable. |
| 4094 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( | 3893 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( |
| 4095 Handle<JSObject> object, | 3894 Handle<JSObject> object, |
| 4096 Handle<Name> name, | 3895 Handle<Name> name, |
| 4097 Handle<Object> value, | 3896 Handle<Object> value, |
| 4098 PropertyAttributes attributes, | 3897 PropertyAttributes attributes, |
| 4099 ExtensibilityCheck extensibility_check, | 3898 ExtensibilityCheck extensibility_check, |
| 4100 StoreFromKeyed store_from_keyed, | 3899 StoreFromKeyed store_from_keyed, |
| 4101 ExecutableAccessorInfoHandling handling) { | 3900 ExecutableAccessorInfoHandling handling) { |
| 4102 DCHECK(!value->IsTheHole()); | 3901 DCHECK(!value->IsTheHole()); |
| 4103 Isolate* isolate = object->GetIsolate(); | 3902 LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN_ACCESS); |
| 3903 bool is_observed = object->map()->is_observed() && |
| 3904 *name != it.isolate()->heap()->hidden_string(); |
| 3905 for (; it.IsFound(); it.Next()) { |
| 3906 switch (it.state()) { |
| 3907 case LookupIterator::NOT_FOUND: |
| 3908 case LookupIterator::JSPROXY: |
| 3909 case LookupIterator::INTERCEPTOR: |
| 3910 UNREACHABLE(); |
| 4104 | 3911 |
| 4105 // Make sure that the top context does not change when doing callbacks or | 3912 case LookupIterator::ACCESS_CHECK: |
| 4106 // interceptor calls. | 3913 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 4107 AssertNoContextChange ncc(isolate); | 3914 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); |
| 4108 | |
| 4109 LookupResult lookup(isolate); | |
| 4110 object->LookupOwn(name, &lookup, true); | |
| 4111 if (!lookup.IsFound()) { | |
| 4112 object->map()->LookupTransition(*object, *name, &lookup); | |
| 4113 } | |
| 4114 | |
| 4115 // Check access rights if needed. | |
| 4116 if (object->IsAccessCheckNeeded()) { | |
| 4117 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | |
| 4118 LookupIterator it(object, name, LookupIterator::CHECK_OWN); | |
| 4119 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); | |
| 4120 } | |
| 4121 } | |
| 4122 | |
| 4123 if (object->IsJSGlobalProxy()) { | |
| 4124 PrototypeIterator iter(isolate, object); | |
| 4125 if (iter.IsAtEnd()) return value; | |
| 4126 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | |
| 4127 return SetOwnPropertyIgnoreAttributes( | |
| 4128 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), name, | |
| 4129 value, attributes, extensibility_check); | |
| 4130 } | |
| 4131 | |
| 4132 if (lookup.IsInterceptor() || | |
| 4133 (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) { | |
| 4134 object->LookupOwnRealNamedProperty(name, &lookup); | |
| 4135 } | |
| 4136 | |
| 4137 // Check for accessor in prototype chain removed here in clone. | |
| 4138 if (!lookup.IsFound()) { | |
| 4139 object->map()->LookupTransition(*object, *name, &lookup); | |
| 4140 TransitionFlag flag = lookup.IsFound() | |
| 4141 ? OMIT_TRANSITION : INSERT_TRANSITION; | |
| 4142 // Neither properties nor transitions found. | |
| 4143 return AddPropertyInternal(object, name, value, attributes, | |
| 4144 store_from_keyed, extensibility_check, flag); | |
| 4145 } | |
| 4146 | |
| 4147 Handle<Object> old_value = isolate->factory()->the_hole_value(); | |
| 4148 PropertyAttributes old_attributes = ABSENT; | |
| 4149 bool is_observed = object->map()->is_observed() && | |
| 4150 *name != isolate->heap()->hidden_string(); | |
| 4151 if (is_observed && lookup.IsProperty()) { | |
| 4152 if (lookup.IsDataProperty()) { | |
| 4153 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); | |
| 4154 } | |
| 4155 old_attributes = lookup.GetAttributes(); | |
| 4156 } | |
| 4157 | |
| 4158 bool executed_set_prototype = false; | |
| 4159 | |
| 4160 // Check of IsReadOnly removed from here in clone. | |
| 4161 if (lookup.IsTransition()) { | |
| 4162 Handle<Object> result; | |
| 4163 ASSIGN_RETURN_ON_EXCEPTION( | |
| 4164 isolate, result, | |
| 4165 SetPropertyUsingTransition( | |
| 4166 handle(lookup.holder()), &lookup, name, value, attributes), | |
| 4167 Object); | |
| 4168 } else { | |
| 4169 switch (lookup.type()) { | |
| 4170 case NORMAL: | |
| 4171 ReplaceSlowProperty(object, name, value, attributes); | |
| 4172 break; | |
| 4173 case FIELD: | |
| 4174 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); | |
| 4175 break; | |
| 4176 case CONSTANT: | |
| 4177 // Only replace the constant if necessary. | |
| 4178 if (lookup.GetAttributes() != attributes || | |
| 4179 *value != lookup.GetConstant()) { | |
| 4180 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); | |
| 4181 } | 3915 } |
| 4182 break; | 3916 break; |
| 4183 case CALLBACKS: | |
| 4184 { | |
| 4185 Handle<Object> callback(lookup.GetCallbackObject(), isolate); | |
| 4186 if (callback->IsExecutableAccessorInfo() && | |
| 4187 handling == DONT_FORCE_FIELD) { | |
| 4188 Handle<Object> result; | |
| 4189 ASSIGN_RETURN_ON_EXCEPTION( | |
| 4190 isolate, result, JSObject::SetPropertyWithAccessor( | |
| 4191 object, name, value, handle(lookup.holder()), | |
| 4192 callback, STRICT), | |
| 4193 Object); | |
| 4194 | 3917 |
| 4195 if (attributes != lookup.GetAttributes()) { | 3918 case LookupIterator::PROPERTY: { |
| 4196 Handle<ExecutableAccessorInfo> new_data = | 3919 if (!it.HasProperty()) break; |
| 4197 Accessors::CloneAccessor( | 3920 if (it.HolderIsNonGlobalHiddenPrototype()) break; |
| 4198 isolate, Handle<ExecutableAccessorInfo>::cast(callback)); | 3921 PropertyDetails details = it.property_details(); |
| 4199 new_data->set_property_attributes(attributes); | 3922 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); |
| 4200 if (attributes & READ_ONLY) { | 3923 switch (it.property_kind()) { |
| 4201 // This way we don't have to introduce a lookup to the setter, | 3924 case LookupIterator::ACCESSOR: { |
| 4202 // simply make it unavailable to reflect the attributes. | 3925 // Ensure the context isn't changed after calling into accessors. |
| 4203 new_data->clear_setter(); | 3926 AssertNoContextChange ncc(it.isolate()); |
| 3927 |
| 3928 Handle<Object> accessors = it.GetAccessors(); |
| 3929 |
| 3930 if (is_observed && accessors->IsAccessorInfo()) { |
| 3931 ASSIGN_RETURN_ON_EXCEPTION( |
| 3932 it.isolate(), old_value, |
| 3933 GetPropertyWithAccessor(it.GetReceiver(), it.name(), |
| 3934 it.GetHolder<JSObject>(), accessors), |
| 3935 Object); |
| 4204 } | 3936 } |
| 4205 | 3937 |
| 4206 SetPropertyCallback(object, name, new_data, attributes); | 3938 // Special handling for ExecutableAccessorInfo, which behaves like a |
| 3939 // data property. |
| 3940 if (handling == DONT_FORCE_FIELD && |
| 3941 accessors->IsExecutableAccessorInfo()) { |
| 3942 Handle<Object> result; |
| 3943 ASSIGN_RETURN_ON_EXCEPTION( |
| 3944 it.isolate(), result, |
| 3945 JSObject::SetPropertyWithAccessor( |
| 3946 it.GetReceiver(), it.name(), value, |
| 3947 it.GetHolder<JSObject>(), accessors, STRICT), |
| 3948 Object); |
| 3949 DCHECK(result->SameValue(*value)); |
| 3950 |
| 3951 if (details.attributes() == attributes) { |
| 3952 // Regular property update if the attributes match. |
| 3953 if (is_observed && !old_value->SameValue(*value)) { |
| 3954 // If we are setting the prototype of a function and are |
| 3955 // observed, don't send change records because the prototype |
| 3956 // handles that itself. |
| 3957 if (!object->IsJSFunction() || |
| 3958 !Name::Equals(it.isolate()->factory()->prototype_string(), |
| 3959 name) || |
| 3960 !Handle<JSFunction>::cast(object) |
| 3961 ->should_have_prototype()) { |
| 3962 EnqueueChangeRecord(object, "update", name, old_value); |
| 3963 } |
| 3964 } |
| 3965 return value; |
| 3966 } |
| 3967 |
| 3968 // Reconfigure the accessor if attributes mismatch. |
| 3969 Handle<ExecutableAccessorInfo> new_data = |
| 3970 Accessors::CloneAccessor( |
| 3971 it.isolate(), |
| 3972 Handle<ExecutableAccessorInfo>::cast(accessors)); |
| 3973 new_data->set_property_attributes(attributes); |
| 3974 // By clearing the setter we don't have to introduce a lookup to |
| 3975 // the setter, simply make it unavailable to reflect the |
| 3976 // attributes. |
| 3977 if (attributes & READ_ONLY) new_data->clear_setter(); |
| 3978 SetPropertyCallback(object, name, new_data, attributes); |
| 3979 if (is_observed) { |
| 3980 if (old_value->SameValue(*value)) { |
| 3981 old_value = it.isolate()->factory()->the_hole_value(); |
| 3982 } |
| 3983 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 3984 } |
| 3985 return value; |
| 3986 } |
| 3987 |
| 3988 // Regular accessor. Reconfigure to data property. |
| 3989 break; |
| 4207 } | 3990 } |
| 4208 if (is_observed) { | 3991 |
| 4209 // If we are setting the prototype of a function and are observed, | 3992 case LookupIterator::DATA: |
| 4210 // don't send change records because the prototype handles that | 3993 // Regular property update if the attributes match. |
| 4211 // itself. | 3994 if (details.attributes() == attributes) { |
| 4212 executed_set_prototype = object->IsJSFunction() && | 3995 return SetDataProperty(&it, value); |
| 4213 String::Equals(isolate->factory()->prototype_string(), | 3996 } |
| 4214 Handle<String>::cast(name)) && | 3997 // Reconfigure the data property if the attributes mismatch. |
| 4215 Handle<JSFunction>::cast(object)->should_have_prototype(); | 3998 if (is_observed) old_value = it.GetDataValue(); |
| 3999 } |
| 4000 |
| 4001 it.ReconfigureDataProperty(value, attributes); |
| 4002 it.PrepareForDataProperty(value); |
| 4003 it.WriteDataValue(value); |
| 4004 |
| 4005 if (is_observed) { |
| 4006 if (old_value->SameValue(*value)) { |
| 4007 old_value = it.isolate()->factory()->the_hole_value(); |
| 4216 } | 4008 } |
| 4217 } else { | 4009 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 4218 ConvertAndSetOwnProperty(&lookup, name, value, attributes); | |
| 4219 } | 4010 } |
| 4220 break; | |
| 4221 } | |
| 4222 case NONEXISTENT: | |
| 4223 case HANDLER: | |
| 4224 case INTERCEPTOR: | |
| 4225 UNREACHABLE(); | |
| 4226 } | |
| 4227 } | |
| 4228 | 4011 |
| 4229 if (is_observed && !executed_set_prototype) { | 4012 return value; |
| 4230 if (lookup.IsTransition()) { | |
| 4231 EnqueueChangeRecord(object, "add", name, old_value); | |
| 4232 } else if (old_value->IsTheHole()) { | |
| 4233 EnqueueChangeRecord(object, "reconfigure", name, old_value); | |
| 4234 } else { | |
| 4235 LookupResult new_lookup(isolate); | |
| 4236 object->LookupOwn(name, &new_lookup, true); | |
| 4237 bool value_changed = false; | |
| 4238 if (new_lookup.IsDataProperty()) { | |
| 4239 Handle<Object> new_value = | |
| 4240 Object::GetPropertyOrElement(object, name).ToHandleChecked(); | |
| 4241 value_changed = !old_value->SameValue(*new_value); | |
| 4242 } | |
| 4243 if (new_lookup.GetAttributes() != old_attributes) { | |
| 4244 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | |
| 4245 EnqueueChangeRecord(object, "reconfigure", name, old_value); | |
| 4246 } else if (value_changed) { | |
| 4247 EnqueueChangeRecord(object, "update", name, old_value); | |
| 4248 } | 4013 } |
| 4249 } | 4014 } |
| 4250 } | 4015 } |
| 4251 | 4016 |
| 4252 return value; | 4017 return AddDataProperty(&it, value, attributes, STRICT, store_from_keyed, |
| 4018 extensibility_check); |
| 4253 } | 4019 } |
| 4254 | 4020 |
| 4255 | 4021 |
| 4256 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( | 4022 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
| 4257 Handle<JSObject> holder, | 4023 Handle<JSObject> holder, |
| 4258 Handle<Object> receiver, | 4024 Handle<Object> receiver, |
| 4259 Handle<Name> name) { | 4025 Handle<Name> name) { |
| 4260 // TODO(rossberg): Support symbols in the API. | 4026 // TODO(rossberg): Support symbols in the API. |
| 4261 if (name->IsSymbol()) return maybe(ABSENT); | 4027 if (name->IsSymbol()) return maybe(ABSENT); |
| 4262 | 4028 |
| (...skipping 3124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7387 | 7153 |
| 7388 Handle<Map> result; | 7154 Handle<Map> result; |
| 7389 if (!maybe_map.ToHandle(&result)) { | 7155 if (!maybe_map.ToHandle(&result)) { |
| 7390 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES); | 7156 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES); |
| 7391 } | 7157 } |
| 7392 | 7158 |
| 7393 return result; | 7159 return result; |
| 7394 } | 7160 } |
| 7395 | 7161 |
| 7396 | 7162 |
| 7163 Handle<Map> Map::ReconfigureDataProperty(Handle<Map> map, int descriptor, |
| 7164 PropertyAttributes attributes) { |
| 7165 // Dictionaries have to be reconfigured in-place. |
| 7166 DCHECK(!map->is_dictionary_map()); |
| 7167 |
| 7168 // For now, give up on transitioning and just create a unique map. |
| 7169 // TODO(verwaest/ishell): Cache transitions with different attributes. |
| 7170 return CopyGeneralizeAllRepresentations(map, descriptor, FORCE_FIELD, |
| 7171 attributes, "attributes mismatch"); |
| 7172 } |
| 7173 |
| 7174 |
| 7397 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, | 7175 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, |
| 7398 Descriptor* descriptor, | 7176 Descriptor* descriptor, |
| 7399 TransitionFlag flag) { | 7177 TransitionFlag flag) { |
| 7400 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 7178 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 7401 | 7179 |
| 7402 // Ensure the key is unique. | 7180 // Ensure the key is unique. |
| 7403 descriptor->KeyToUniqueName(); | 7181 descriptor->KeyToUniqueName(); |
| 7404 | 7182 |
| 7405 if (flag == INSERT_TRANSITION && | 7183 if (flag == INSERT_TRANSITION && |
| 7406 map->owns_descriptors() && | 7184 map->owns_descriptors() && |
| (...skipping 9522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16929 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16707 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16930 static const char* error_messages_[] = { | 16708 static const char* error_messages_[] = { |
| 16931 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16709 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16932 }; | 16710 }; |
| 16933 #undef ERROR_MESSAGES_TEXTS | 16711 #undef ERROR_MESSAGES_TEXTS |
| 16934 return error_messages_[reason]; | 16712 return error_messages_[reason]; |
| 16935 } | 16713 } |
| 16936 | 16714 |
| 16937 | 16715 |
| 16938 } } // namespace v8::internal | 16716 } } // namespace v8::internal |
| OLD | NEW |