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 |