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 |