| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 } | 1909 } |
| 1910 } | 1910 } |
| 1911 return true; | 1911 return true; |
| 1912 } | 1912 } |
| 1913 | 1913 |
| 1914 | 1914 |
| 1915 MaybeObject* JSObject::AddFastProperty(Name* name, | 1915 MaybeObject* JSObject::AddFastProperty(Name* name, |
| 1916 Object* value, | 1916 Object* value, |
| 1917 PropertyAttributes attributes, | 1917 PropertyAttributes attributes, |
| 1918 StoreFromKeyed store_mode, | 1918 StoreFromKeyed store_mode, |
| 1919 ValueType value_type) { | 1919 ValueType value_type, |
| 1920 TransitionFlag flag) { |
| 1920 ASSERT(!IsJSGlobalProxy()); | 1921 ASSERT(!IsJSGlobalProxy()); |
| 1921 ASSERT(DescriptorArray::kNotFound == | 1922 ASSERT(DescriptorArray::kNotFound == |
| 1922 map()->instance_descriptors()->Search( | 1923 map()->instance_descriptors()->Search( |
| 1923 name, map()->NumberOfOwnDescriptors())); | 1924 name, map()->NumberOfOwnDescriptors())); |
| 1924 | 1925 |
| 1925 // Normalize the object if the name is an actual name (not the | 1926 // Normalize the object if the name is an actual name (not the |
| 1926 // hidden strings) and is not a real identifier. | 1927 // hidden strings) and is not a real identifier. |
| 1927 // Normalize the object if it will have too many fast properties. | 1928 // Normalize the object if it will have too many fast properties. |
| 1928 Isolate* isolate = GetHeap()->isolate(); | 1929 Isolate* isolate = GetHeap()->isolate(); |
| 1929 if ((!name->IsSymbol() && !IsIdentifier(isolate->unicode_cache(), name) | 1930 if ((!name->IsSymbol() && |
| 1930 && name != isolate->heap()->hidden_string()) || | 1931 !IsIdentifier(isolate->unicode_cache(), name) && |
| 1931 (map()->unused_property_fields() == 0 && | 1932 name != isolate->heap()->hidden_string()) || |
| 1932 TooManyFastProperties(properties()->length(), store_mode))) { | 1933 TooManyFastProperties(store_mode)) { |
| 1933 Object* obj; | 1934 MaybeObject* maybe_failure = |
| 1934 MaybeObject* maybe_obj = | |
| 1935 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1935 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1936 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1936 if (maybe_failure->IsFailure()) return maybe_failure; |
| 1937 | |
| 1938 return AddSlowProperty(name, value, attributes); | 1937 return AddSlowProperty(name, value, attributes); |
| 1939 } | 1938 } |
| 1940 | 1939 |
| 1941 // Compute the new index for new field. | 1940 // Compute the new index for new field. |
| 1942 int index = map()->NextFreePropertyIndex(); | 1941 int index = map()->NextFreePropertyIndex(); |
| 1943 | 1942 |
| 1944 // Allocate new instance descriptors with (name, index) added | 1943 // Allocate new instance descriptors with (name, index) added |
| 1945 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; | 1944 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
| 1946 Representation representation = value->OptimalRepresentation(value_type); | 1945 Representation representation = value->OptimalRepresentation(value_type); |
| 1947 | 1946 |
| 1948 FieldDescriptor new_field(name, index, attributes, representation); | 1947 FieldDescriptor new_field(name, index, attributes, representation); |
| 1949 | 1948 |
| 1950 ASSERT(index < map()->inobject_properties() || | 1949 ASSERT(index < map()->inobject_properties() || |
| 1951 (index - map()->inobject_properties()) < properties()->length() || | 1950 (index - map()->inobject_properties()) < properties()->length() || |
| 1952 map()->unused_property_fields() == 0); | 1951 map()->unused_property_fields() == 0); |
| 1953 | 1952 |
| 1954 FixedArray* values = NULL; | 1953 FixedArray* values = NULL; |
| 1955 | 1954 |
| 1956 // TODO(verwaest): Merge with AddFastPropertyUsingMap. | 1955 // TODO(verwaest): Merge with AddFastPropertyUsingMap. |
| 1957 if (map()->unused_property_fields() == 0) { | 1956 if (map()->unused_property_fields() == 0) { |
| 1958 // Make room for the new value | 1957 // Make room for the new value |
| 1959 MaybeObject* maybe_values = | 1958 MaybeObject* maybe_values = |
| 1960 properties()->CopySize(properties()->length() + kFieldsAdded); | 1959 properties()->CopySize(properties()->length() + kFieldsAdded); |
| 1961 if (!maybe_values->To(&values)) return maybe_values; | 1960 if (!maybe_values->To(&values)) return maybe_values; |
| 1962 } | 1961 } |
| 1963 | 1962 |
| 1964 TransitionFlag flag = INSERT_TRANSITION; | |
| 1965 | |
| 1966 Heap* heap = isolate->heap(); | 1963 Heap* heap = isolate->heap(); |
| 1967 | 1964 |
| 1968 Object* storage; | 1965 Object* storage; |
| 1969 MaybeObject* maybe_storage = | 1966 MaybeObject* maybe_storage = |
| 1970 value->AllocateNewStorageFor(heap, representation); | 1967 value->AllocateNewStorageFor(heap, representation); |
| 1971 if (!maybe_storage->To(&storage)) return maybe_storage; | 1968 if (!maybe_storage->To(&storage)) return maybe_storage; |
| 1972 | 1969 |
| 1973 // Note that Map::CopyAddDescriptor has side-effects, the new map is already | 1970 // Note that Map::CopyAddDescriptor has side-effects, the new map is already |
| 1974 // inserted in the transition tree. No more allocations that might fail are | 1971 // inserted in the transition tree. No more allocations that might fail are |
| 1975 // allowed after this point. | 1972 // allowed after this point. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1988 set_map(new_map); | 1985 set_map(new_map); |
| 1989 | 1986 |
| 1990 FastPropertyAtPut(index, storage); | 1987 FastPropertyAtPut(index, storage); |
| 1991 return value; | 1988 return value; |
| 1992 } | 1989 } |
| 1993 | 1990 |
| 1994 | 1991 |
| 1995 MaybeObject* JSObject::AddConstantProperty( | 1992 MaybeObject* JSObject::AddConstantProperty( |
| 1996 Name* name, | 1993 Name* name, |
| 1997 Object* constant, | 1994 Object* constant, |
| 1998 PropertyAttributes attributes) { | 1995 PropertyAttributes attributes, |
| 1996 TransitionFlag initial_flag) { |
| 1999 // Allocate new instance descriptors with (name, constant) added | 1997 // Allocate new instance descriptors with (name, constant) added |
| 2000 ConstantDescriptor d(name, constant, attributes); | 1998 ConstantDescriptor d(name, constant, attributes); |
| 2001 | 1999 |
| 2002 TransitionFlag flag = | 2000 TransitionFlag flag = |
| 2003 // Do not add transitions to global objects. | 2001 // Do not add transitions to global objects. |
| 2004 (IsGlobalObject() || | 2002 (IsGlobalObject() || |
| 2005 // Don't add transitions to special properties with non-trivial | 2003 // Don't add transitions to special properties with non-trivial |
| 2006 // attributes. | 2004 // attributes. |
| 2007 attributes != NONE) | 2005 attributes != NONE) |
| 2008 ? OMIT_TRANSITION | 2006 ? OMIT_TRANSITION |
| 2009 : INSERT_TRANSITION; | 2007 : initial_flag; |
| 2010 | 2008 |
| 2011 Map* new_map; | 2009 Map* new_map; |
| 2012 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); | 2010 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); |
| 2013 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 2011 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 2014 | 2012 |
| 2015 set_map(new_map); | 2013 set_map(new_map); |
| 2016 return constant; | 2014 return constant; |
| 2017 } | 2015 } |
| 2018 | 2016 |
| 2019 | 2017 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2059 } | 2057 } |
| 2060 | 2058 |
| 2061 | 2059 |
| 2062 MaybeObject* JSObject::AddProperty(Name* name, | 2060 MaybeObject* JSObject::AddProperty(Name* name, |
| 2063 Object* value, | 2061 Object* value, |
| 2064 PropertyAttributes attributes, | 2062 PropertyAttributes attributes, |
| 2065 StrictModeFlag strict_mode, | 2063 StrictModeFlag strict_mode, |
| 2066 JSReceiver::StoreFromKeyed store_mode, | 2064 JSReceiver::StoreFromKeyed store_mode, |
| 2067 ExtensibilityCheck extensibility_check, | 2065 ExtensibilityCheck extensibility_check, |
| 2068 ValueType value_type, | 2066 ValueType value_type, |
| 2069 StoreMode mode) { | 2067 StoreMode mode, |
| 2068 TransitionFlag transition_flag) { |
| 2070 ASSERT(!IsJSGlobalProxy()); | 2069 ASSERT(!IsJSGlobalProxy()); |
| 2071 Map* map_of_this = map(); | 2070 Map* map_of_this = map(); |
| 2072 Heap* heap = GetHeap(); | 2071 Heap* heap = GetHeap(); |
| 2073 Isolate* isolate = heap->isolate(); | 2072 Isolate* isolate = heap->isolate(); |
| 2074 MaybeObject* result; | 2073 MaybeObject* result; |
| 2075 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 2074 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
| 2076 !map_of_this->is_extensible()) { | 2075 !map_of_this->is_extensible()) { |
| 2077 if (strict_mode == kNonStrictMode) { | 2076 if (strict_mode == kNonStrictMode) { |
| 2078 return value; | 2077 return value; |
| 2079 } else { | 2078 } else { |
| 2080 Handle<Object> args[1] = {Handle<Name>(name)}; | 2079 Handle<Object> args[1] = {Handle<Name>(name)}; |
| 2081 return isolate->Throw( | 2080 return isolate->Throw( |
| 2082 *isolate->factory()->NewTypeError("object_not_extensible", | 2081 *isolate->factory()->NewTypeError("object_not_extensible", |
| 2083 HandleVector(args, 1))); | 2082 HandleVector(args, 1))); |
| 2084 } | 2083 } |
| 2085 } | 2084 } |
| 2086 | 2085 |
| 2087 if (HasFastProperties()) { | 2086 if (HasFastProperties()) { |
| 2088 // Ensure the descriptor array does not get too big. | 2087 // Ensure the descriptor array does not get too big. |
| 2089 if (map_of_this->NumberOfOwnDescriptors() < | 2088 if (map_of_this->NumberOfOwnDescriptors() < |
| 2090 DescriptorArray::kMaxNumberOfDescriptors) { | 2089 DescriptorArray::kMaxNumberOfDescriptors) { |
| 2091 // TODO(verwaest): Support other constants. | 2090 // TODO(verwaest): Support other constants. |
| 2092 // if (mode == ALLOW_AS_CONSTANT && | 2091 // if (mode == ALLOW_AS_CONSTANT && |
| 2093 // !value->IsTheHole() && | 2092 // !value->IsTheHole() && |
| 2094 // !value->IsConsString()) { | 2093 // !value->IsConsString()) { |
| 2095 if (value->IsJSFunction()) { | 2094 if (value->IsJSFunction()) { |
| 2096 result = AddConstantProperty(name, value, attributes); | 2095 result = AddConstantProperty(name, value, attributes, transition_flag); |
| 2097 } else { | 2096 } else { |
| 2098 result = AddFastProperty( | 2097 result = AddFastProperty( |
| 2099 name, value, attributes, store_mode, value_type); | 2098 name, value, attributes, store_mode, value_type, transition_flag); |
| 2100 } | 2099 } |
| 2101 } else { | 2100 } else { |
| 2102 // Normalize the object to prevent very large instance descriptors. | 2101 // Normalize the object to prevent very large instance descriptors. |
| 2103 // This eliminates unwanted N^2 allocation and lookup behavior. | 2102 // This eliminates unwanted N^2 allocation and lookup behavior. |
| 2104 Object* obj; | 2103 Object* obj; |
| 2105 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2104 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2106 if (!maybe->To(&obj)) return maybe; | 2105 if (!maybe->To(&obj)) return maybe; |
| 2107 result = AddSlowProperty(name, value, attributes); | 2106 result = AddSlowProperty(name, value, attributes); |
| 2108 } | 2107 } |
| 2109 } else { | 2108 } else { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2193 if (old_index != -1) { | 2192 if (old_index != -1) { |
| 2194 // All calls to ReplaceSlowProperty have had all transitions removed. | 2193 // All calls to ReplaceSlowProperty have had all transitions removed. |
| 2195 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); | 2194 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); |
| 2196 } | 2195 } |
| 2197 | 2196 |
| 2198 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); | 2197 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); |
| 2199 return SetNormalizedProperty(name, value, new_details); | 2198 return SetNormalizedProperty(name, value, new_details); |
| 2200 } | 2199 } |
| 2201 | 2200 |
| 2202 | 2201 |
| 2203 MaybeObject* JSObject::ConvertDescriptorToField(Name* name, | |
| 2204 Object* new_value, | |
| 2205 PropertyAttributes attributes, | |
| 2206 TransitionFlag flag) { | |
| 2207 if (map()->unused_property_fields() == 0 && | |
| 2208 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { | |
| 2209 Object* obj; | |
| 2210 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | |
| 2211 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 2212 return ReplaceSlowProperty(name, new_value, attributes); | |
| 2213 } | |
| 2214 | |
| 2215 Representation representation = IsJSContextExtensionObject() | |
| 2216 ? Representation::Tagged() : new_value->OptimalRepresentation(); | |
| 2217 int index = map()->NextFreePropertyIndex(); | |
| 2218 FieldDescriptor new_field(name, index, attributes, representation); | |
| 2219 | |
| 2220 // Make a new map for the object. | |
| 2221 Map* new_map; | |
| 2222 MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field, flag); | |
| 2223 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
| 2224 | |
| 2225 // Make new properties array if necessary. | |
| 2226 FixedArray* new_properties = NULL; | |
| 2227 int new_unused_property_fields = map()->unused_property_fields() - 1; | |
| 2228 if (map()->unused_property_fields() == 0) { | |
| 2229 new_unused_property_fields = kFieldsAdded - 1; | |
| 2230 MaybeObject* maybe_new_properties = | |
| 2231 properties()->CopySize(properties()->length() + kFieldsAdded); | |
| 2232 if (!maybe_new_properties->To(&new_properties)) return maybe_new_properties; | |
| 2233 } | |
| 2234 | |
| 2235 Heap* heap = GetHeap(); | |
| 2236 Object* storage; | |
| 2237 MaybeObject* maybe_storage = | |
| 2238 new_value->AllocateNewStorageFor(heap, representation); | |
| 2239 if (!maybe_storage->To(&storage)) return maybe_storage; | |
| 2240 | |
| 2241 // Update pointers to commit changes. | |
| 2242 // Object points to the new map. | |
| 2243 new_map->set_unused_property_fields(new_unused_property_fields); | |
| 2244 set_map(new_map); | |
| 2245 if (new_properties != NULL) { | |
| 2246 set_properties(new_properties); | |
| 2247 } | |
| 2248 FastPropertyAtPut(index, storage); | |
| 2249 return new_value; | |
| 2250 } | |
| 2251 | |
| 2252 | |
| 2253 const char* Representation::Mnemonic() const { | 2202 const char* Representation::Mnemonic() const { |
| 2254 switch (kind_) { | 2203 switch (kind_) { |
| 2255 case kNone: return "v"; | 2204 case kNone: return "v"; |
| 2256 case kTagged: return "t"; | 2205 case kTagged: return "t"; |
| 2257 case kSmi: return "s"; | 2206 case kSmi: return "s"; |
| 2258 case kDouble: return "d"; | 2207 case kDouble: return "d"; |
| 2259 case kInteger32: return "i"; | 2208 case kInteger32: return "i"; |
| 2260 case kHeapObject: return "h"; | 2209 case kHeapObject: return "h"; |
| 2261 case kExternal: return "x"; | 2210 case kExternal: return "x"; |
| 2262 default: | 2211 default: |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2389 if (!maybe_array->To(&array)) return maybe_array; | 2338 if (!maybe_array->To(&array)) return maybe_array; |
| 2390 | 2339 |
| 2391 DescriptorArray* old_descriptors = old_map->instance_descriptors(); | 2340 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
| 2392 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 2341 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
| 2393 int descriptors = new_map->NumberOfOwnDescriptors(); | 2342 int descriptors = new_map->NumberOfOwnDescriptors(); |
| 2394 | 2343 |
| 2395 for (int i = 0; i < descriptors; i++) { | 2344 for (int i = 0; i < descriptors; i++) { |
| 2396 PropertyDetails details = new_descriptors->GetDetails(i); | 2345 PropertyDetails details = new_descriptors->GetDetails(i); |
| 2397 if (details.type() != FIELD) continue; | 2346 if (details.type() != FIELD) continue; |
| 2398 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2347 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2348 if (old_details.type() == CALLBACKS) { |
| 2349 ASSERT(details.representation().IsTagged()); |
| 2350 continue; |
| 2351 } |
| 2399 ASSERT(old_details.type() == CONSTANT || | 2352 ASSERT(old_details.type() == CONSTANT || |
| 2400 old_details.type() == FIELD); | 2353 old_details.type() == FIELD); |
| 2401 Object* value = old_details.type() == CONSTANT | 2354 Object* value = old_details.type() == CONSTANT |
| 2402 ? old_descriptors->GetValue(i) | 2355 ? old_descriptors->GetValue(i) |
| 2403 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); | 2356 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); |
| 2404 if (FLAG_track_double_fields && | 2357 if (FLAG_track_double_fields && |
| 2405 !old_details.representation().IsDouble() && | 2358 !old_details.representation().IsDouble() && |
| 2406 details.representation().IsDouble()) { | 2359 details.representation().IsDouble()) { |
| 2407 if (old_details.representation().IsNone()) value = Smi::FromInt(0); | 2360 if (old_details.representation().IsNone()) value = Smi::FromInt(0); |
| 2408 // Objects must be allocated in the old object space, since the | 2361 // Objects must be allocated in the old object space, since the |
| (...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3789 Handle<Name> name, | 3742 Handle<Name> name, |
| 3790 Handle<Object> value, | 3743 Handle<Object> value, |
| 3791 PropertyAttributes attributes) { | 3744 PropertyAttributes attributes) { |
| 3792 Map* transition_map = lookup->GetTransitionTarget(); | 3745 Map* transition_map = lookup->GetTransitionTarget(); |
| 3793 int descriptor = transition_map->LastAdded(); | 3746 int descriptor = transition_map->LastAdded(); |
| 3794 | 3747 |
| 3795 DescriptorArray* descriptors = transition_map->instance_descriptors(); | 3748 DescriptorArray* descriptors = transition_map->instance_descriptors(); |
| 3796 PropertyDetails details = descriptors->GetDetails(descriptor); | 3749 PropertyDetails details = descriptors->GetDetails(descriptor); |
| 3797 | 3750 |
| 3798 if (details.type() == CALLBACKS || attributes != details.attributes()) { | 3751 if (details.type() == CALLBACKS || attributes != details.attributes()) { |
| 3799 return lookup->holder()->ConvertDescriptorToField( | 3752 // AddProperty will either normalize the object, or create a new fast copy |
| 3800 *name, *value, attributes); | 3753 // of the map. If we get a fast copy of the map, all field representations |
| 3754 // will be tagged since the transition is omitted. |
| 3755 return lookup->holder()->AddProperty( |
| 3756 *name, *value, attributes, kNonStrictMode, |
| 3757 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
| 3758 JSReceiver::OMIT_EXTENSIBILITY_CHECK, |
| 3759 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); |
| 3801 } | 3760 } |
| 3802 | 3761 |
| 3803 // Keep the target CONSTANT if the same value is stored. | 3762 // Keep the target CONSTANT if the same value is stored. |
| 3804 // TODO(verwaest): Also support keeping the placeholder | 3763 // TODO(verwaest): Also support keeping the placeholder |
| 3805 // (value->IsUninitialized) as constant. | 3764 // (value->IsUninitialized) as constant. |
| 3806 if (details.type() == CONSTANT && | 3765 if (details.type() == CONSTANT && |
| 3807 descriptors->GetValue(descriptor) == *value) { | 3766 descriptors->GetValue(descriptor) == *value) { |
| 3808 lookup->holder()->set_map(transition_map); | 3767 lookup->holder()->set_map(transition_map); |
| 3809 return *value; | 3768 return *value; |
| 3810 } | 3769 } |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4015 ValueType value_type, | 3974 ValueType value_type, |
| 4016 StoreMode mode) { | 3975 StoreMode mode) { |
| 4017 CALL_HEAP_FUNCTION( | 3976 CALL_HEAP_FUNCTION( |
| 4018 object->GetIsolate(), | 3977 object->GetIsolate(), |
| 4019 object->SetLocalPropertyIgnoreAttributes( | 3978 object->SetLocalPropertyIgnoreAttributes( |
| 4020 *key, *value, attributes, value_type, mode), | 3979 *key, *value, attributes, value_type, mode), |
| 4021 Object); | 3980 Object); |
| 4022 } | 3981 } |
| 4023 | 3982 |
| 4024 | 3983 |
| 3984 static MaybeObject* ConvertAndSetLocalProperty( |
| 3985 LookupResult* lookup, |
| 3986 Name* name, |
| 3987 Object* value, |
| 3988 PropertyAttributes attributes) { |
| 3989 JSObject* object = lookup->holder(); |
| 3990 if (object->TooManyFastProperties()) { |
| 3991 MaybeObject* maybe_failure = object->NormalizeProperties( |
| 3992 CLEAR_INOBJECT_PROPERTIES, 0); |
| 3993 if (maybe_failure->IsFailure()) return maybe_failure; |
| 3994 } |
| 3995 |
| 3996 if (!object->HasFastProperties()) { |
| 3997 return object->ReplaceSlowProperty(name, value, attributes); |
| 3998 } |
| 3999 |
| 4000 int descriptor_index = lookup->GetDescriptorIndex(); |
| 4001 MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation( |
| 4002 descriptor_index, Representation::Tagged(), FORCE_FIELD); |
| 4003 if (maybe_failure->IsFailure()) return maybe_failure; |
| 4004 |
| 4005 DescriptorArray* descriptors = object->map()->instance_descriptors(); |
| 4006 int index = descriptors->GetDetails(descriptor_index).field_index(); |
| 4007 object->FastPropertyAtPut(index, value); |
| 4008 return value; |
| 4009 } |
| 4010 |
| 4011 |
| 4025 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( | 4012 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| 4026 Name* name_raw, | 4013 Name* name_raw, |
| 4027 Object* value_raw, | 4014 Object* value_raw, |
| 4028 PropertyAttributes attributes, | 4015 PropertyAttributes attributes, |
| 4029 ValueType value_type, | 4016 ValueType value_type, |
| 4030 StoreMode mode, | 4017 StoreMode mode, |
| 4031 ExtensibilityCheck extensibility_check) { | 4018 ExtensibilityCheck extensibility_check) { |
| 4032 // Make sure that the top context does not change when doing callbacks or | 4019 // Make sure that the top context does not change when doing callbacks or |
| 4033 // interceptor calls. | 4020 // interceptor calls. |
| 4034 AssertNoContextChange ncc; | 4021 AssertNoContextChange ncc; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4093 case FIELD: | 4080 case FIELD: |
| 4094 if (value->IsUninitialized()) break; | 4081 if (value->IsUninitialized()) break; |
| 4095 result = SetPropertyToField(&lookup, name, value); | 4082 result = SetPropertyToField(&lookup, name, value); |
| 4096 break; | 4083 break; |
| 4097 case CONSTANT: | 4084 case CONSTANT: |
| 4098 // Only replace the constant if necessary. | 4085 // Only replace the constant if necessary. |
| 4099 if (*value == lookup.GetConstant()) return *value; | 4086 if (*value == lookup.GetConstant()) return *value; |
| 4100 if (value->IsUninitialized()) break; | 4087 if (value->IsUninitialized()) break; |
| 4101 result = SetPropertyToField(&lookup, name, value); | 4088 result = SetPropertyToField(&lookup, name, value); |
| 4102 break; | 4089 break; |
| 4090 case INTERCEPTOR: |
| 4091 self->LocalLookupRealNamedProperty(*name, &lookup); |
| 4092 if (lookup.IsFound()) { |
| 4093 if (lookup.IsPropertyCallbacks()) { |
| 4094 result = ConvertAndSetLocalProperty( |
| 4095 &lookup, *name, *value, attributes); |
| 4096 } else if (lookup.IsNormal()) { |
| 4097 result = self->ReplaceSlowProperty(*name, *value, attributes); |
| 4098 } else { |
| 4099 result = SetPropertyToField(&lookup, name, value); |
| 4100 } |
| 4101 } else { |
| 4102 result = self->AddProperty( |
| 4103 *name, *value, attributes, kNonStrictMode, MAY_BE_STORE_FROM_KEYED, |
| 4104 extensibility_check, value_type, mode); |
| 4105 } |
| 4106 break; |
| 4103 case CALLBACKS: | 4107 case CALLBACKS: |
| 4104 case INTERCEPTOR: | 4108 result = ConvertAndSetLocalProperty(&lookup, *name, *value, attributes); |
| 4105 // Override callback in clone | |
| 4106 result = self->ConvertDescriptorToField(*name, *value, attributes); | |
| 4107 break; | 4109 break; |
| 4108 case TRANSITION: | 4110 case TRANSITION: |
| 4109 result = SetPropertyUsingTransition(&lookup, name, value, attributes); | 4111 result = SetPropertyUsingTransition(&lookup, name, value, attributes); |
| 4110 break; | 4112 break; |
| 4111 case HANDLER: | 4113 case HANDLER: |
| 4112 case NONEXISTENT: | 4114 case NONEXISTENT: |
| 4113 UNREACHABLE(); | 4115 UNREACHABLE(); |
| 4114 } | 4116 } |
| 4115 | 4117 |
| 4116 Handle<Object> hresult; | 4118 Handle<Object> hresult; |
| (...skipping 11835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15952 #define ERROR_MESSAGES_TEXTS(C, T) T, | 15954 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 15953 static const char* error_messages_[] = { | 15955 static const char* error_messages_[] = { |
| 15954 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 15956 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 15955 }; | 15957 }; |
| 15956 #undef ERROR_MESSAGES_TEXTS | 15958 #undef ERROR_MESSAGES_TEXTS |
| 15957 return error_messages_[reason]; | 15959 return error_messages_[reason]; |
| 15958 } | 15960 } |
| 15959 | 15961 |
| 15960 | 15962 |
| 15961 } } // namespace v8::internal | 15963 } } // namespace v8::internal |
| OLD | NEW |