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