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 2954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2965 bool has_pending_exception; | 2965 bool has_pending_exception; |
2966 Handle<Object> argv[] = { value }; | 2966 Handle<Object> argv[] = { value }; |
2967 Execution::Call( | 2967 Execution::Call( |
2968 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); | 2968 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); |
2969 // Check for pending exception and return the result. | 2969 // Check for pending exception and return the result. |
2970 if (has_pending_exception) return Handle<Object>(); | 2970 if (has_pending_exception) return Handle<Object>(); |
2971 return value; | 2971 return value; |
2972 } | 2972 } |
2973 | 2973 |
2974 | 2974 |
2975 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( | 2975 Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
| 2976 Handle<JSObject> object, |
2976 uint32_t index, | 2977 uint32_t index, |
2977 Object* value, | 2978 Handle<Object> value, |
2978 bool* found, | 2979 bool* found, |
2979 StrictModeFlag strict_mode) { | 2980 StrictModeFlag strict_mode) { |
2980 Heap* heap = GetHeap(); | 2981 Isolate *isolate = object->GetIsolate(); |
2981 for (Object* pt = GetPrototype(); | 2982 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); |
2982 pt != heap->null_value(); | 2983 !proto->IsNull(); |
2983 pt = pt->GetPrototype(GetIsolate())) { | 2984 proto = handle(proto->GetPrototype(isolate), isolate)) { |
2984 if (pt->IsJSProxy()) { | 2985 if (proto->IsJSProxy()) { |
2985 Isolate* isolate = GetIsolate(); | 2986 return JSProxy::SetPropertyViaPrototypesWithHandler( |
2986 HandleScope scope(isolate); | 2987 Handle<JSProxy>::cast(proto), |
2987 Handle<JSProxy> proxy(JSProxy::cast(pt)); | 2988 object, |
2988 Handle<JSObject> self(this, isolate); | 2989 isolate->factory()->Uint32ToString(index), // name |
2989 Handle<String> name = isolate->factory()->Uint32ToString(index); | 2990 value, |
2990 Handle<Object> value_handle(value, isolate); | 2991 NONE, |
2991 Handle<Object> result = JSProxy::SetPropertyViaPrototypesWithHandler( | 2992 strict_mode, |
2992 proxy, self, name, value_handle, NONE, strict_mode, found); | 2993 found); |
2993 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
2994 return *result; | |
2995 } | 2994 } |
2996 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 2995 Handle<JSObject> js_proto = Handle<JSObject>::cast(proto); |
| 2996 if (!js_proto->HasDictionaryElements()) { |
2997 continue; | 2997 continue; |
2998 } | 2998 } |
2999 SeededNumberDictionary* dictionary = | 2999 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); |
3000 JSObject::cast(pt)->element_dictionary(); | |
3001 int entry = dictionary->FindEntry(index); | 3000 int entry = dictionary->FindEntry(index); |
3002 if (entry != SeededNumberDictionary::kNotFound) { | 3001 if (entry != SeededNumberDictionary::kNotFound) { |
3003 PropertyDetails details = dictionary->DetailsAt(entry); | 3002 PropertyDetails details = dictionary->DetailsAt(entry); |
3004 if (details.type() == CALLBACKS) { | 3003 if (details.type() == CALLBACKS) { |
3005 *found = true; | 3004 *found = true; |
3006 Isolate* isolate = GetIsolate(); | |
3007 HandleScope scope(isolate); | |
3008 Handle<JSObject> self(this, isolate); | |
3009 Handle<Object> structure(dictionary->ValueAt(entry), isolate); | 3005 Handle<Object> structure(dictionary->ValueAt(entry), isolate); |
3010 Handle<Object> value_handle(value, isolate); | 3006 return SetElementWithCallback(object, structure, index, value, js_proto, |
3011 Handle<JSObject> holder(JSObject::cast(pt)); | 3007 strict_mode); |
3012 Handle<Object> result = SetElementWithCallback( | |
3013 self, structure, index, value_handle, holder, strict_mode); | |
3014 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
3015 return *result; | |
3016 } | 3008 } |
3017 } | 3009 } |
3018 } | 3010 } |
3019 *found = false; | 3011 *found = false; |
3020 return heap->the_hole_value(); | 3012 return isolate->factory()->the_hole_value(); |
3021 } | 3013 } |
3022 | 3014 |
3023 | 3015 |
3024 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, | 3016 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, |
3025 Handle<Name> name, | 3017 Handle<Name> name, |
3026 Handle<Object> value, | 3018 Handle<Object> value, |
3027 PropertyAttributes attributes, | 3019 PropertyAttributes attributes, |
3028 StrictModeFlag strict_mode, | 3020 StrictModeFlag strict_mode, |
3029 bool* done) { | 3021 bool* done) { |
3030 Isolate* isolate = object->GetIsolate(); | 3022 Isolate* isolate = object->GetIsolate(); |
(...skipping 3224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6255 Handle<Object> structure, | 6247 Handle<Object> structure, |
6256 PropertyAttributes attributes) { | 6248 PropertyAttributes attributes) { |
6257 Heap* heap = object->GetHeap(); | 6249 Heap* heap = object->GetHeap(); |
6258 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6250 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
6259 | 6251 |
6260 // Normalize elements to make this operation simple. | 6252 // Normalize elements to make this operation simple. |
6261 bool had_dictionary_elements = object->HasDictionaryElements(); | 6253 bool had_dictionary_elements = object->HasDictionaryElements(); |
6262 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6254 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
6263 ASSERT(object->HasDictionaryElements() || | 6255 ASSERT(object->HasDictionaryElements() || |
6264 object->HasDictionaryArgumentsElements()); | 6256 object->HasDictionaryArgumentsElements()); |
6265 | |
6266 // Update the dictionary with the new CALLBACKS property. | 6257 // Update the dictionary with the new CALLBACKS property. |
6267 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | 6258 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, |
6268 details); | 6259 details); |
6269 dictionary->set_requires_slow_elements(); | 6260 dictionary->set_requires_slow_elements(); |
6270 | 6261 |
6271 // Update the dictionary backing store on the object. | 6262 // Update the dictionary backing store on the object. |
6272 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { | 6263 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { |
6273 // Also delete any parameter alias. | 6264 // Also delete any parameter alias. |
6274 // | 6265 // |
6275 // TODO(kmillikin): when deleting the last parameter alias we could | 6266 // TODO(kmillikin): when deleting the last parameter alias we could |
(...skipping 4933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11209 | 11200 |
11210 PrintF(out, "RelocInfo (size = %d)\n", relocation_size()); | 11201 PrintF(out, "RelocInfo (size = %d)\n", relocation_size()); |
11211 for (RelocIterator it(this); !it.done(); it.next()) { | 11202 for (RelocIterator it(this); !it.done(); it.next()) { |
11212 it.rinfo()->Print(GetIsolate(), out); | 11203 it.rinfo()->Print(GetIsolate(), out); |
11213 } | 11204 } |
11214 PrintF(out, "\n"); | 11205 PrintF(out, "\n"); |
11215 } | 11206 } |
11216 #endif // ENABLE_DISASSEMBLER | 11207 #endif // ENABLE_DISASSEMBLER |
11217 | 11208 |
11218 | 11209 |
| 11210 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength( |
| 11211 Handle<JSObject> object, |
| 11212 int capacity, |
| 11213 int length, |
| 11214 SetFastElementsCapacitySmiMode smi_mode) { |
| 11215 CALL_HEAP_FUNCTION( |
| 11216 object->GetIsolate(), |
| 11217 object->SetFastElementsCapacityAndLength(capacity, length, smi_mode), |
| 11218 FixedArray); |
| 11219 } |
| 11220 |
| 11221 |
11219 MaybeObject* JSObject::SetFastElementsCapacityAndLength( | 11222 MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
11220 int capacity, | 11223 int capacity, |
11221 int length, | 11224 int length, |
11222 SetFastElementsCapacitySmiMode smi_mode) { | 11225 SetFastElementsCapacitySmiMode smi_mode) { |
11223 Heap* heap = GetHeap(); | 11226 Heap* heap = GetHeap(); |
11224 // We should never end in here with a pixel or external array. | 11227 // We should never end in here with a pixel or external array. |
11225 ASSERT(!HasExternalArrayElements()); | 11228 ASSERT(!HasExternalArrayElements()); |
11226 ASSERT(!map()->is_observed()); | 11229 ASSERT(!map()->is_observed()); |
11227 | 11230 |
11228 // Allocate a new fast elements backing store. | 11231 // Allocate a new fast elements backing store. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11295 FLAG_weak_embedded_maps_in_optimized_code; | 11298 FLAG_weak_embedded_maps_in_optimized_code; |
11296 } | 11299 } |
11297 | 11300 |
11298 if (object->IsJSObject()) { | 11301 if (object->IsJSObject()) { |
11299 return FLAG_weak_embedded_objects_in_optimized_code; | 11302 return FLAG_weak_embedded_objects_in_optimized_code; |
11300 } | 11303 } |
11301 | 11304 |
11302 return false; | 11305 return false; |
11303 } | 11306 } |
11304 | 11307 |
| 11308 |
| 11309 void JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object, |
| 11310 int capacity, |
| 11311 int length) { |
| 11312 CALL_HEAP_FUNCTION_VOID( |
| 11313 object->GetIsolate(), |
| 11314 object->SetFastDoubleElementsCapacityAndLength(capacity, length)); |
| 11315 } |
| 11316 |
| 11317 |
11305 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( | 11318 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( |
11306 int capacity, | 11319 int capacity, |
11307 int length) { | 11320 int length) { |
11308 Heap* heap = GetHeap(); | 11321 Heap* heap = GetHeap(); |
11309 // We should never end in here with a pixel or external array. | 11322 // We should never end in here with a pixel or external array. |
11310 ASSERT(!HasExternalArrayElements()); | 11323 ASSERT(!HasExternalArrayElements()); |
11311 ASSERT(!map()->is_observed()); | 11324 ASSERT(!map()->is_observed()); |
11312 | 11325 |
11313 FixedArrayBase* elems; | 11326 FixedArrayBase* elems; |
11314 { MaybeObject* maybe_obj = | 11327 { MaybeObject* maybe_obj = |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11932 return JSObject::cast(proto)->GetLocalElementAccessorPair(index); | 11945 return JSObject::cast(proto)->GetLocalElementAccessorPair(index); |
11933 } | 11946 } |
11934 | 11947 |
11935 // Check for lookup interceptor. | 11948 // Check for lookup interceptor. |
11936 if (HasIndexedInterceptor()) return NULL; | 11949 if (HasIndexedInterceptor()) return NULL; |
11937 | 11950 |
11938 return GetElementsAccessor()->GetAccessorPair(this, this, index); | 11951 return GetElementsAccessor()->GetAccessorPair(this, this, index); |
11939 } | 11952 } |
11940 | 11953 |
11941 | 11954 |
11942 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 11955 Handle<Object> JSObject::SetElementWithInterceptor( |
11943 Object* value, | 11956 Handle<JSObject> object, |
11944 PropertyAttributes attributes, | 11957 uint32_t index, |
11945 StrictModeFlag strict_mode, | 11958 Handle<Object> value, |
11946 bool check_prototype, | 11959 PropertyAttributes attributes, |
11947 SetPropertyMode set_mode) { | 11960 StrictModeFlag strict_mode, |
11948 Isolate* isolate = GetIsolate(); | 11961 bool check_prototype, |
11949 HandleScope scope(isolate); | 11962 SetPropertyMode set_mode) { |
| 11963 Isolate* isolate = object->GetIsolate(); |
11950 | 11964 |
11951 // Make sure that the top context does not change when doing | 11965 // Make sure that the top context does not change when doing |
11952 // callbacks or interceptor calls. | 11966 // callbacks or interceptor calls. |
11953 AssertNoContextChange ncc(isolate); | 11967 AssertNoContextChange ncc(isolate); |
11954 | 11968 |
11955 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 11969 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); |
11956 Handle<JSObject> this_handle(this); | |
11957 Handle<Object> value_handle(value, isolate); | |
11958 if (!interceptor->setter()->IsUndefined()) { | 11970 if (!interceptor->setter()->IsUndefined()) { |
11959 v8::IndexedPropertySetterCallback setter = | 11971 v8::IndexedPropertySetterCallback setter = |
11960 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); | 11972 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); |
11961 LOG(isolate, | 11973 LOG(isolate, |
11962 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 11974 ApiIndexedPropertyAccess("interceptor-indexed-set", *object, index)); |
11963 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); | 11975 PropertyCallbackArguments args(isolate, interceptor->data(), *object, |
| 11976 *object); |
11964 v8::Handle<v8::Value> result = | 11977 v8::Handle<v8::Value> result = |
11965 args.Call(setter, index, v8::Utils::ToLocal(value_handle)); | 11978 args.Call(setter, index, v8::Utils::ToLocal(value)); |
11966 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 11979 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
11967 if (!result.IsEmpty()) return *value_handle; | 11980 if (!result.IsEmpty()) return value; |
11968 } | 11981 } |
11969 MaybeObject* raw_result = | 11982 |
11970 this_handle->SetElementWithoutInterceptor(index, | 11983 return SetElementWithoutInterceptor(object, index, value, attributes, |
11971 *value_handle, | 11984 strict_mode, |
11972 attributes, | 11985 check_prototype, |
11973 strict_mode, | 11986 set_mode); |
11974 check_prototype, | |
11975 set_mode); | |
11976 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | |
11977 return raw_result; | |
11978 } | 11987 } |
11979 | 11988 |
11980 | 11989 |
11981 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 11990 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
11982 Object* structure, | 11991 Object* structure, |
11983 uint32_t index, | 11992 uint32_t index, |
11984 Object* holder) { | 11993 Object* holder) { |
11985 Isolate* isolate = GetIsolate(); | 11994 Isolate* isolate = GetIsolate(); |
11986 ASSERT(!structure->IsForeign()); | 11995 ASSERT(!structure->IsForeign()); |
11987 | 11996 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12115 return false; | 12124 return false; |
12116 } | 12125 } |
12117 FixedArray* arguments = FixedArray::cast(elements->get(1)); | 12126 FixedArray* arguments = FixedArray::cast(elements->get(1)); |
12118 return arguments->IsDictionary(); | 12127 return arguments->IsDictionary(); |
12119 } | 12128 } |
12120 | 12129 |
12121 | 12130 |
12122 // Adding n elements in fast case is O(n*n). | 12131 // Adding n elements in fast case is O(n*n). |
12123 // Note: revisit design to have dual undefined values to capture absent | 12132 // Note: revisit design to have dual undefined values to capture absent |
12124 // elements. | 12133 // elements. |
12125 MaybeObject* JSObject::SetFastElement(uint32_t index, | 12134 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object, |
12126 Object* value, | 12135 uint32_t index, |
12127 StrictModeFlag strict_mode, | 12136 Handle<Object> value, |
12128 bool check_prototype) { | 12137 StrictModeFlag strict_mode, |
12129 ASSERT(HasFastSmiOrObjectElements() || | 12138 bool check_prototype) { |
12130 HasFastArgumentsElements()); | 12139 ASSERT(object->HasFastSmiOrObjectElements() || |
| 12140 object->HasFastArgumentsElements()); |
| 12141 |
| 12142 Isolate* isolate = object->GetIsolate(); |
12131 | 12143 |
12132 // Array optimizations rely on the prototype lookups of Array objects always | 12144 // Array optimizations rely on the prototype lookups of Array objects always |
12133 // returning undefined. If there is a store to the initial prototype object, | 12145 // returning undefined. If there is a store to the initial prototype object, |
12134 // make sure all of these optimizations are invalidated. | 12146 // make sure all of these optimizations are invalidated. |
12135 Isolate* isolate(GetIsolate()); | 12147 if (isolate->is_initial_object_prototype(*object) || |
12136 if (isolate->is_initial_object_prototype(this) || | 12148 isolate->is_initial_array_prototype(*object)) { |
12137 isolate->is_initial_array_prototype(this)) { | 12149 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, |
12138 HandleScope scope(GetIsolate()); | |
12139 map()->dependent_code()->DeoptimizeDependentCodeGroup( | |
12140 GetIsolate(), | |
12141 DependentCode::kElementsCantBeAddedGroup); | 12150 DependentCode::kElementsCantBeAddedGroup); |
12142 } | 12151 } |
12143 | 12152 |
12144 FixedArray* backing_store = FixedArray::cast(elements()); | 12153 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); |
12145 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { | 12154 if (backing_store->map() == |
12146 backing_store = FixedArray::cast(backing_store->get(1)); | 12155 isolate->heap()->non_strict_arguments_elements_map()) { |
| 12156 backing_store = handle(FixedArray::cast(backing_store->get(1))); |
12147 } else { | 12157 } else { |
12148 MaybeObject* maybe = EnsureWritableFastElements(); | 12158 backing_store = EnsureWritableFastElements(object); |
12149 if (!maybe->To(&backing_store)) return maybe; | |
12150 } | 12159 } |
12151 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | 12160 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
12152 | 12161 |
12153 if (check_prototype && | 12162 if (check_prototype && |
12154 (index >= capacity || backing_store->get(index)->IsTheHole())) { | 12163 (index >= capacity || backing_store->get(index)->IsTheHole())) { |
12155 bool found; | 12164 bool found; |
12156 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 12165 Handle<Object> result = SetElementWithCallbackSetterInPrototypes( |
12157 value, | 12166 object, index, value, &found, strict_mode); |
12158 &found, | |
12159 strict_mode); | |
12160 if (found) return result; | 12167 if (found) return result; |
12161 } | 12168 } |
12162 | 12169 |
12163 uint32_t new_capacity = capacity; | 12170 uint32_t new_capacity = capacity; |
12164 // Check if the length property of this object needs to be updated. | 12171 // Check if the length property of this object needs to be updated. |
12165 uint32_t array_length = 0; | 12172 uint32_t array_length = 0; |
12166 bool must_update_array_length = false; | 12173 bool must_update_array_length = false; |
12167 bool introduces_holes = true; | 12174 bool introduces_holes = true; |
12168 if (IsJSArray()) { | 12175 if (object->IsJSArray()) { |
12169 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 12176 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); |
12170 introduces_holes = index > array_length; | 12177 introduces_holes = index > array_length; |
12171 if (index >= array_length) { | 12178 if (index >= array_length) { |
12172 must_update_array_length = true; | 12179 must_update_array_length = true; |
12173 array_length = index + 1; | 12180 array_length = index + 1; |
12174 } | 12181 } |
12175 } else { | 12182 } else { |
12176 introduces_holes = index >= capacity; | 12183 introduces_holes = index >= capacity; |
12177 } | 12184 } |
12178 | 12185 |
12179 // If the array is growing, and it's not growth by a single element at the | 12186 // If the array is growing, and it's not growth by a single element at the |
12180 // end, make sure that the ElementsKind is HOLEY. | 12187 // end, make sure that the ElementsKind is HOLEY. |
12181 ElementsKind elements_kind = GetElementsKind(); | 12188 ElementsKind elements_kind = object->GetElementsKind(); |
12182 if (introduces_holes && | 12189 if (introduces_holes && |
12183 IsFastElementsKind(elements_kind) && | 12190 IsFastElementsKind(elements_kind) && |
12184 !IsFastHoleyElementsKind(elements_kind)) { | 12191 !IsFastHoleyElementsKind(elements_kind)) { |
12185 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); | 12192 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); |
12186 MaybeObject* maybe = TransitionElementsKind(transitioned_kind); | 12193 TransitionElementsKind(object, transitioned_kind); |
12187 if (maybe->IsFailure()) return maybe; | |
12188 } | 12194 } |
12189 | 12195 |
12190 // Check if the capacity of the backing store needs to be increased, or if | 12196 // Check if the capacity of the backing store needs to be increased, or if |
12191 // a transition to slow elements is necessary. | 12197 // a transition to slow elements is necessary. |
12192 if (index >= capacity) { | 12198 if (index >= capacity) { |
12193 bool convert_to_slow = true; | 12199 bool convert_to_slow = true; |
12194 if ((index - capacity) < kMaxGap) { | 12200 if ((index - capacity) < kMaxGap) { |
12195 new_capacity = NewElementsCapacity(index + 1); | 12201 new_capacity = NewElementsCapacity(index + 1); |
12196 ASSERT(new_capacity > index); | 12202 ASSERT(new_capacity > index); |
12197 if (!ShouldConvertToSlowElements(new_capacity)) { | 12203 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
12198 convert_to_slow = false; | 12204 convert_to_slow = false; |
12199 } | 12205 } |
12200 } | 12206 } |
12201 if (convert_to_slow) { | 12207 if (convert_to_slow) { |
12202 MaybeObject* result = NormalizeElements(); | 12208 NormalizeElements(object); |
12203 if (result->IsFailure()) return result; | 12209 return SetDictionaryElement(object, index, value, NONE, strict_mode, |
12204 return SetDictionaryElement(index, value, NONE, strict_mode, | |
12205 check_prototype); | 12210 check_prototype); |
12206 } | 12211 } |
12207 } | 12212 } |
12208 // Convert to fast double elements if appropriate. | 12213 // Convert to fast double elements if appropriate. |
12209 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { | 12214 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { |
12210 // Consider fixing the boilerplate as well if we have one. | 12215 // Consider fixing the boilerplate as well if we have one. |
12211 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) | 12216 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) |
12212 ? FAST_HOLEY_DOUBLE_ELEMENTS | 12217 ? FAST_HOLEY_DOUBLE_ELEMENTS |
12213 : FAST_DOUBLE_ELEMENTS; | 12218 : FAST_DOUBLE_ELEMENTS; |
12214 | 12219 |
12215 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12220 UpdateAllocationSite(object, to_kind); |
12216 if (maybe_failure->IsFailure()) return maybe_failure; | |
12217 | 12221 |
12218 MaybeObject* maybe = | 12222 SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length); |
12219 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); | 12223 FixedDoubleArray::cast(object->elements())->set(index, value->Number()); |
12220 if (maybe->IsFailure()) return maybe; | 12224 object->ValidateElements(); |
12221 FixedDoubleArray::cast(elements())->set(index, value->Number()); | |
12222 ValidateElements(); | |
12223 return value; | 12225 return value; |
12224 } | 12226 } |
12225 // Change elements kind from Smi-only to generic FAST if necessary. | 12227 // Change elements kind from Smi-only to generic FAST if necessary. |
12226 if (HasFastSmiElements() && !value->IsSmi()) { | 12228 if (object->HasFastSmiElements() && !value->IsSmi()) { |
12227 Map* new_map; | 12229 ElementsKind kind = object->HasFastHoleyElements() |
12228 ElementsKind kind = HasFastHoleyElements() | |
12229 ? FAST_HOLEY_ELEMENTS | 12230 ? FAST_HOLEY_ELEMENTS |
12230 : FAST_ELEMENTS; | 12231 : FAST_ELEMENTS; |
12231 | 12232 |
12232 MaybeObject* maybe_failure = UpdateAllocationSite(kind); | 12233 UpdateAllocationSite(object, kind); |
12233 if (maybe_failure->IsFailure()) return maybe_failure; | 12234 object->set_map(*GetElementsTransitionMap(object, kind)); |
12234 | 12235 ASSERT(IsFastObjectElementsKind(object->GetElementsKind())); |
12235 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), | |
12236 kind); | |
12237 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
12238 | |
12239 set_map(new_map); | |
12240 } | 12236 } |
12241 // Increase backing store capacity if that's been decided previously. | 12237 // Increase backing store capacity if that's been decided previously. |
12242 if (new_capacity != capacity) { | 12238 if (new_capacity != capacity) { |
12243 FixedArray* new_elements; | |
12244 SetFastElementsCapacitySmiMode smi_mode = | 12239 SetFastElementsCapacitySmiMode smi_mode = |
12245 value->IsSmi() && HasFastSmiElements() | 12240 value->IsSmi() && object->HasFastSmiElements() |
12246 ? kAllowSmiElements | 12241 ? kAllowSmiElements |
12247 : kDontAllowSmiElements; | 12242 : kDontAllowSmiElements; |
12248 { MaybeObject* maybe = | 12243 Handle<FixedArray> new_elements = |
12249 SetFastElementsCapacityAndLength(new_capacity, | 12244 SetFastElementsCapacityAndLength(object, new_capacity, array_length, |
12250 array_length, | 12245 smi_mode); |
12251 smi_mode); | 12246 new_elements->set(index, *value); |
12252 if (!maybe->To(&new_elements)) return maybe; | 12247 object->ValidateElements(); |
12253 } | |
12254 new_elements->set(index, value); | |
12255 ValidateElements(); | |
12256 return value; | 12248 return value; |
12257 } | 12249 } |
12258 | 12250 |
12259 // Finally, set the new element and length. | 12251 // Finally, set the new element and length. |
12260 ASSERT(elements()->IsFixedArray()); | 12252 ASSERT(object->elements()->IsFixedArray()); |
12261 backing_store->set(index, value); | 12253 backing_store->set(index, *value); |
12262 if (must_update_array_length) { | 12254 if (must_update_array_length) { |
12263 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); | 12255 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); |
12264 } | 12256 } |
12265 return value; | 12257 return value; |
12266 } | 12258 } |
12267 | 12259 |
12268 | 12260 |
12269 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, | 12261 Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object, |
12270 Object* value_raw, | 12262 uint32_t index, |
12271 PropertyAttributes attributes, | 12263 Handle<Object> value, |
12272 StrictModeFlag strict_mode, | 12264 PropertyAttributes attributes, |
12273 bool check_prototype, | 12265 StrictModeFlag strict_mode, |
12274 SetPropertyMode set_mode) { | 12266 bool check_prototype, |
12275 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 12267 SetPropertyMode set_mode) { |
12276 Isolate* isolate = GetIsolate(); | 12268 ASSERT(object->HasDictionaryElements() || |
12277 Heap* heap = isolate->heap(); | 12269 object->HasDictionaryArgumentsElements()); |
12278 Handle<JSObject> self(this); | 12270 Isolate* isolate = object->GetIsolate(); |
12279 Handle<Object> value(value_raw, isolate); | |
12280 | 12271 |
12281 // Insert element in the dictionary. | 12272 // Insert element in the dictionary. |
12282 Handle<FixedArray> elements(FixedArray::cast(this->elements())); | 12273 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
12283 bool is_arguments = | 12274 bool is_arguments = |
12284 (elements->map() == heap->non_strict_arguments_elements_map()); | 12275 (elements->map() == isolate->heap()->non_strict_arguments_elements_map()); |
12285 Handle<SeededNumberDictionary> dictionary(is_arguments | 12276 Handle<SeededNumberDictionary> dictionary(is_arguments |
12286 ? SeededNumberDictionary::cast(elements->get(1)) | 12277 ? SeededNumberDictionary::cast(elements->get(1)) |
12287 : SeededNumberDictionary::cast(*elements)); | 12278 : SeededNumberDictionary::cast(*elements)); |
12288 | 12279 |
12289 int entry = dictionary->FindEntry(index); | 12280 int entry = dictionary->FindEntry(index); |
12290 if (entry != SeededNumberDictionary::kNotFound) { | 12281 if (entry != SeededNumberDictionary::kNotFound) { |
12291 Handle<Object> element(dictionary->ValueAt(entry), isolate); | 12282 Handle<Object> element(dictionary->ValueAt(entry), isolate); |
12292 PropertyDetails details = dictionary->DetailsAt(entry); | 12283 PropertyDetails details = dictionary->DetailsAt(entry); |
12293 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { | 12284 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { |
12294 Handle<Object> result = SetElementWithCallback(self, element, index, | 12285 return SetElementWithCallback(object, element, index, value, object, |
12295 value, self, strict_mode); | 12286 strict_mode); |
12296 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
12297 return *result; | |
12298 } else { | 12287 } else { |
12299 dictionary->UpdateMaxNumberKey(index); | 12288 dictionary->UpdateMaxNumberKey(index); |
12300 // If a value has not been initialized we allow writing to it even if it | 12289 // If a value has not been initialized we allow writing to it even if it |
12301 // is read-only (a declared const that has not been initialized). If a | 12290 // is read-only (a declared const that has not been initialized). If a |
12302 // value is being defined we skip attribute checks completely. | 12291 // value is being defined we skip attribute checks completely. |
12303 if (set_mode == DEFINE_PROPERTY) { | 12292 if (set_mode == DEFINE_PROPERTY) { |
12304 details = PropertyDetails( | 12293 details = PropertyDetails( |
12305 attributes, NORMAL, details.dictionary_index()); | 12294 attributes, NORMAL, details.dictionary_index()); |
12306 dictionary->DetailsAtPut(entry, details); | 12295 dictionary->DetailsAtPut(entry, details); |
12307 } else if (details.IsReadOnly() && !element->IsTheHole()) { | 12296 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
12308 if (strict_mode == kNonStrictMode) { | 12297 if (strict_mode == kNonStrictMode) { |
12309 return isolate->heap()->undefined_value(); | 12298 return isolate->factory()->undefined_value(); |
12310 } else { | 12299 } else { |
12311 Handle<Object> holder(this, isolate); | |
12312 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12300 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12313 Handle<Object> args[2] = { number, holder }; | 12301 Handle<Object> args[2] = { number, object }; |
12314 Handle<Object> error = | 12302 Handle<Object> error = |
12315 isolate->factory()->NewTypeError("strict_read_only_property", | 12303 isolate->factory()->NewTypeError("strict_read_only_property", |
12316 HandleVector(args, 2)); | 12304 HandleVector(args, 2)); |
12317 return isolate->Throw(*error); | 12305 isolate->Throw(*error); |
| 12306 return Handle<Object>(); |
12318 } | 12307 } |
12319 } | 12308 } |
12320 // Elements of the arguments object in slow mode might be slow aliases. | 12309 // Elements of the arguments object in slow mode might be slow aliases. |
12321 if (is_arguments && element->IsAliasedArgumentsEntry()) { | 12310 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
12322 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*element); | 12311 Handle<AliasedArgumentsEntry> entry = |
12323 Context* context = Context::cast(elements->get(0)); | 12312 Handle<AliasedArgumentsEntry>::cast(element); |
| 12313 Handle<Context> context(Context::cast(elements->get(0))); |
12324 int context_index = entry->aliased_context_slot(); | 12314 int context_index = entry->aliased_context_slot(); |
12325 ASSERT(!context->get(context_index)->IsTheHole()); | 12315 ASSERT(!context->get(context_index)->IsTheHole()); |
12326 context->set(context_index, *value); | 12316 context->set(context_index, *value); |
12327 // For elements that are still writable we keep slow aliasing. | 12317 // For elements that are still writable we keep slow aliasing. |
12328 if (!details.IsReadOnly()) value = element; | 12318 if (!details.IsReadOnly()) value = element; |
12329 } | 12319 } |
12330 dictionary->ValueAtPut(entry, *value); | 12320 dictionary->ValueAtPut(entry, *value); |
12331 } | 12321 } |
12332 } else { | 12322 } else { |
12333 // Index not already used. Look for an accessor in the prototype chain. | 12323 // Index not already used. Look for an accessor in the prototype chain. |
12334 // Can cause GC! | 12324 // Can cause GC! |
12335 if (check_prototype) { | 12325 if (check_prototype) { |
12336 bool found; | 12326 bool found; |
12337 MaybeObject* result = SetElementWithCallbackSetterInPrototypes( | 12327 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, |
12338 index, *value, &found, strict_mode); | 12328 index, value, &found, strict_mode); |
12339 if (found) return result; | 12329 if (found) return result; |
12340 } | 12330 } |
| 12331 |
12341 // When we set the is_extensible flag to false we always force the | 12332 // When we set the is_extensible flag to false we always force the |
12342 // element into dictionary mode (and force them to stay there). | 12333 // element into dictionary mode (and force them to stay there). |
12343 if (!self->map()->is_extensible()) { | 12334 if (!object->map()->is_extensible()) { |
12344 if (strict_mode == kNonStrictMode) { | 12335 if (strict_mode == kNonStrictMode) { |
12345 return isolate->heap()->undefined_value(); | 12336 return isolate->factory()->undefined_value(); |
12346 } else { | 12337 } else { |
12347 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12338 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12348 Handle<String> name = isolate->factory()->NumberToString(number); | 12339 Handle<String> name = isolate->factory()->NumberToString(number); |
12349 Handle<Object> args[1] = { name }; | 12340 Handle<Object> args[1] = { name }; |
12350 Handle<Object> error = | 12341 Handle<Object> error = |
12351 isolate->factory()->NewTypeError("object_not_extensible", | 12342 isolate->factory()->NewTypeError("object_not_extensible", |
12352 HandleVector(args, 1)); | 12343 HandleVector(args, 1)); |
12353 return isolate->Throw(*error); | 12344 isolate->Throw(*error); |
| 12345 return Handle<Object>(); |
12354 } | 12346 } |
12355 } | 12347 } |
12356 FixedArrayBase* new_dictionary; | 12348 |
12357 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 12349 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
12358 MaybeObject* maybe = dictionary->AddNumberEntry(index, *value, details); | 12350 Handle<SeededNumberDictionary> new_dictionary = |
12359 if (!maybe->To(&new_dictionary)) return maybe; | 12351 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, |
12360 if (*dictionary != SeededNumberDictionary::cast(new_dictionary)) { | 12352 details); |
| 12353 if (*dictionary != *new_dictionary) { |
12361 if (is_arguments) { | 12354 if (is_arguments) { |
12362 elements->set(1, new_dictionary); | 12355 elements->set(1, *new_dictionary); |
12363 } else { | 12356 } else { |
12364 self->set_elements(new_dictionary); | 12357 object->set_elements(*new_dictionary); |
12365 } | 12358 } |
12366 dictionary = | 12359 dictionary = new_dictionary; |
12367 handle(SeededNumberDictionary::cast(new_dictionary), isolate); | |
12368 } | 12360 } |
12369 } | 12361 } |
12370 | 12362 |
12371 // Update the array length if this JSObject is an array. | 12363 // Update the array length if this JSObject is an array. |
12372 if (self->IsJSArray()) { | 12364 if (object->IsJSArray()) { |
12373 MaybeObject* result = | 12365 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index, |
12374 JSArray::cast(*self)->JSArrayUpdateLengthFromIndex(index, *value); | 12366 value); |
12375 if (result->IsFailure()) return result; | |
12376 } | 12367 } |
12377 | 12368 |
12378 // Attempt to put this object back in fast case. | 12369 // Attempt to put this object back in fast case. |
12379 if (self->ShouldConvertToFastElements()) { | 12370 if (object->ShouldConvertToFastElements()) { |
12380 uint32_t new_length = 0; | 12371 uint32_t new_length = 0; |
12381 if (self->IsJSArray()) { | 12372 if (object->IsJSArray()) { |
12382 CHECK(JSArray::cast(*self)->length()->ToArrayIndex(&new_length)); | 12373 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&new_length)); |
12383 } else { | 12374 } else { |
12384 new_length = dictionary->max_number_key() + 1; | 12375 new_length = dictionary->max_number_key() + 1; |
12385 } | 12376 } |
12386 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays | 12377 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays |
12387 ? kAllowSmiElements | 12378 ? kAllowSmiElements |
12388 : kDontAllowSmiElements; | 12379 : kDontAllowSmiElements; |
12389 bool has_smi_only_elements = false; | 12380 bool has_smi_only_elements = false; |
12390 bool should_convert_to_fast_double_elements = | 12381 bool should_convert_to_fast_double_elements = |
12391 self->ShouldConvertToFastDoubleElements(&has_smi_only_elements); | 12382 object->ShouldConvertToFastDoubleElements(&has_smi_only_elements); |
12392 if (has_smi_only_elements) { | 12383 if (has_smi_only_elements) { |
12393 smi_mode = kForceSmiElements; | 12384 smi_mode = kForceSmiElements; |
12394 } | 12385 } |
12395 MaybeObject* result = should_convert_to_fast_double_elements | 12386 |
12396 ? self->SetFastDoubleElementsCapacityAndLength(new_length, new_length) | 12387 if (should_convert_to_fast_double_elements) { |
12397 : self->SetFastElementsCapacityAndLength( | 12388 SetFastDoubleElementsCapacityAndLength(object, new_length, new_length); |
12398 new_length, new_length, smi_mode); | 12389 } else { |
12399 self->ValidateElements(); | 12390 SetFastElementsCapacityAndLength(object, new_length, new_length, |
12400 if (result->IsFailure()) return result; | 12391 smi_mode); |
| 12392 } |
| 12393 object->ValidateElements(); |
12401 #ifdef DEBUG | 12394 #ifdef DEBUG |
12402 if (FLAG_trace_normalization) { | 12395 if (FLAG_trace_normalization) { |
12403 PrintF("Object elements are fast case again:\n"); | 12396 PrintF("Object elements are fast case again:\n"); |
12404 Print(); | 12397 object->Print(); |
12405 } | 12398 } |
12406 #endif | 12399 #endif |
12407 } | 12400 } |
12408 return *value; | 12401 return value; |
12409 } | 12402 } |
12410 | 12403 |
12411 | 12404 Handle<Object> JSObject::SetFastDoubleElement( |
12412 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( | 12405 Handle<JSObject> object, |
12413 uint32_t index, | 12406 uint32_t index, |
12414 Object* value, | 12407 Handle<Object> value, |
12415 StrictModeFlag strict_mode, | 12408 StrictModeFlag strict_mode, |
12416 bool check_prototype) { | 12409 bool check_prototype) { |
12417 ASSERT(HasFastDoubleElements()); | 12410 ASSERT(object->HasFastDoubleElements()); |
12418 | 12411 |
12419 FixedArrayBase* base_elms = FixedArrayBase::cast(elements()); | 12412 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); |
12420 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); | 12413 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); |
12421 | 12414 |
12422 // If storing to an element that isn't in the array, pass the store request | 12415 // If storing to an element that isn't in the array, pass the store request |
12423 // up the prototype chain before storing in the receiver's elements. | 12416 // up the prototype chain before storing in the receiver's elements. |
12424 if (check_prototype && | 12417 if (check_prototype && |
12425 (index >= elms_length || | 12418 (index >= elms_length || |
12426 FixedDoubleArray::cast(base_elms)->is_the_hole(index))) { | 12419 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) { |
12427 bool found; | 12420 bool found; |
12428 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 12421 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, |
12429 value, | 12422 index, value, &found, strict_mode); |
12430 &found, | |
12431 strict_mode); | |
12432 if (found) return result; | 12423 if (found) return result; |
12433 } | 12424 } |
12434 | 12425 |
12435 // If the value object is not a heap number, switch to fast elements and try | 12426 // If the value object is not a heap number, switch to fast elements and try |
12436 // again. | 12427 // again. |
12437 bool value_is_smi = value->IsSmi(); | 12428 bool value_is_smi = value->IsSmi(); |
12438 bool introduces_holes = true; | 12429 bool introduces_holes = true; |
12439 uint32_t length = elms_length; | 12430 uint32_t length = elms_length; |
12440 if (IsJSArray()) { | 12431 if (object->IsJSArray()) { |
12441 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); | 12432 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length)); |
12442 introduces_holes = index > length; | 12433 introduces_holes = index > length; |
12443 } else { | 12434 } else { |
12444 introduces_holes = index >= elms_length; | 12435 introduces_holes = index >= elms_length; |
12445 } | 12436 } |
12446 | 12437 |
12447 if (!value->IsNumber()) { | 12438 if (!value->IsNumber()) { |
12448 MaybeObject* maybe_obj = SetFastElementsCapacityAndLength( | 12439 SetFastElementsCapacityAndLength(object, elms_length, length, |
12449 elms_length, | 12440 kDontAllowSmiElements); |
12450 length, | 12441 Handle<Object> result = SetFastElement(object, index, value, strict_mode, |
12451 kDontAllowSmiElements); | 12442 check_prototype); |
12452 if (maybe_obj->IsFailure()) return maybe_obj; | 12443 RETURN_IF_EMPTY_HANDLE_VALUE(object->GetIsolate(), result, |
12453 maybe_obj = SetFastElement(index, value, strict_mode, check_prototype); | 12444 Handle<Object>()); |
12454 if (maybe_obj->IsFailure()) return maybe_obj; | 12445 object->ValidateElements(); |
12455 ValidateElements(); | 12446 return result; |
12456 return maybe_obj; | |
12457 } | 12447 } |
12458 | 12448 |
12459 double double_value = value_is_smi | 12449 double double_value = value_is_smi |
12460 ? static_cast<double>(Smi::cast(value)->value()) | 12450 ? static_cast<double>(Handle<Smi>::cast(value)->value()) |
12461 : HeapNumber::cast(value)->value(); | 12451 : Handle<HeapNumber>::cast(value)->value(); |
12462 | 12452 |
12463 // If the array is growing, and it's not growth by a single element at the | 12453 // If the array is growing, and it's not growth by a single element at the |
12464 // end, make sure that the ElementsKind is HOLEY. | 12454 // end, make sure that the ElementsKind is HOLEY. |
12465 ElementsKind elements_kind = GetElementsKind(); | 12455 ElementsKind elements_kind = object->GetElementsKind(); |
12466 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) { | 12456 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) { |
12467 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); | 12457 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); |
12468 MaybeObject* maybe = TransitionElementsKind(transitioned_kind); | 12458 TransitionElementsKind(object, transitioned_kind); |
12469 if (maybe->IsFailure()) return maybe; | |
12470 } | 12459 } |
12471 | 12460 |
12472 // Check whether there is extra space in the fixed array. | 12461 // Check whether there is extra space in the fixed array. |
12473 if (index < elms_length) { | 12462 if (index < elms_length) { |
12474 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); | 12463 Handle<FixedDoubleArray> elms(FixedDoubleArray::cast(object->elements())); |
12475 elms->set(index, double_value); | 12464 elms->set(index, double_value); |
12476 if (IsJSArray()) { | 12465 if (object->IsJSArray()) { |
12477 // Update the length of the array if needed. | 12466 // Update the length of the array if needed. |
12478 uint32_t array_length = 0; | 12467 uint32_t array_length = 0; |
12479 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 12468 CHECK( |
| 12469 Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); |
12480 if (index >= array_length) { | 12470 if (index >= array_length) { |
12481 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | 12471 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1)); |
12482 } | 12472 } |
12483 } | 12473 } |
12484 return value; | 12474 return value; |
12485 } | 12475 } |
12486 | 12476 |
12487 // Allow gap in fast case. | 12477 // Allow gap in fast case. |
12488 if ((index - elms_length) < kMaxGap) { | 12478 if ((index - elms_length) < kMaxGap) { |
12489 // Try allocating extra space. | 12479 // Try allocating extra space. |
12490 int new_capacity = NewElementsCapacity(index+1); | 12480 int new_capacity = NewElementsCapacity(index+1); |
12491 if (!ShouldConvertToSlowElements(new_capacity)) { | 12481 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
12492 ASSERT(static_cast<uint32_t>(new_capacity) > index); | 12482 ASSERT(static_cast<uint32_t>(new_capacity) > index); |
12493 MaybeObject* maybe_obj = | 12483 SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1); |
12494 SetFastDoubleElementsCapacityAndLength(new_capacity, index + 1); | 12484 FixedDoubleArray::cast(object->elements())->set(index, double_value); |
12495 if (maybe_obj->IsFailure()) return maybe_obj; | 12485 object->ValidateElements(); |
12496 FixedDoubleArray::cast(elements())->set(index, double_value); | |
12497 ValidateElements(); | |
12498 return value; | 12486 return value; |
12499 } | 12487 } |
12500 } | 12488 } |
12501 | 12489 |
12502 // Otherwise default to slow case. | 12490 // Otherwise default to slow case. |
12503 ASSERT(HasFastDoubleElements()); | 12491 ASSERT(object->HasFastDoubleElements()); |
12504 ASSERT(map()->has_fast_double_elements()); | 12492 ASSERT(object->map()->has_fast_double_elements()); |
12505 ASSERT(elements()->IsFixedDoubleArray()); | 12493 ASSERT(object->elements()->IsFixedDoubleArray()); |
12506 Object* obj; | 12494 |
12507 { MaybeObject* maybe_obj = NormalizeElements(); | 12495 NormalizeElements(object); |
12508 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12496 ASSERT(object->HasDictionaryElements()); |
12509 } | 12497 return SetElement(object, index, value, NONE, strict_mode, check_prototype); |
12510 ASSERT(HasDictionaryElements()); | |
12511 return SetElement(index, value, NONE, strict_mode, check_prototype); | |
12512 } | 12498 } |
12513 | 12499 |
12514 | 12500 |
12515 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, | 12501 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, |
12516 uint32_t index, | 12502 uint32_t index, |
12517 Handle<Object> value, | 12503 Handle<Object> value, |
12518 PropertyAttributes attributes, | 12504 PropertyAttributes attributes, |
12519 StrictModeFlag strict_mode) { | 12505 StrictModeFlag strict_mode) { |
12520 if (object->IsJSProxy()) { | 12506 if (object->IsJSProxy()) { |
12521 return JSProxy::SetElementWithHandler( | 12507 return JSProxy::SetElementWithHandler( |
12522 Handle<JSProxy>::cast(object), object, index, value, strict_mode); | 12508 Handle<JSProxy>::cast(object), object, index, value, strict_mode); |
12523 } | 12509 } |
12524 return JSObject::SetElement( | 12510 return JSObject::SetElement( |
12525 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); | 12511 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); |
12526 } | 12512 } |
12527 | 12513 |
12528 | 12514 |
12529 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, | 12515 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, |
12530 uint32_t index, | 12516 uint32_t index, |
12531 Handle<Object> value, | 12517 Handle<Object> value, |
12532 StrictModeFlag strict_mode) { | 12518 StrictModeFlag strict_mode) { |
12533 ASSERT(!object->HasExternalArrayElements()); | 12519 ASSERT(!object->HasExternalArrayElements()); |
12534 CALL_HEAP_FUNCTION( | 12520 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); |
12535 object->GetIsolate(), | |
12536 object->SetElement(index, *value, NONE, strict_mode, false), | |
12537 Object); | |
12538 } | 12521 } |
12539 | 12522 |
12540 | 12523 |
12541 Handle<Object> JSObject::SetElement(Handle<JSObject> object, | 12524 Handle<Object> JSObject::SetElement(Handle<JSObject> object, |
12542 uint32_t index, | 12525 uint32_t index, |
12543 Handle<Object> value, | 12526 Handle<Object> value, |
12544 PropertyAttributes attr, | 12527 PropertyAttributes attributes, |
12545 StrictModeFlag strict_mode, | 12528 StrictModeFlag strict_mode, |
12546 bool check_prototype, | 12529 bool check_prototype, |
12547 SetPropertyMode set_mode) { | 12530 SetPropertyMode set_mode) { |
| 12531 Isolate* isolate = object->GetIsolate(); |
| 12532 |
12548 if (object->HasExternalArrayElements()) { | 12533 if (object->HasExternalArrayElements()) { |
12549 if (!value->IsNumber() && !value->IsUndefined()) { | 12534 if (!value->IsNumber() && !value->IsUndefined()) { |
12550 bool has_exception; | 12535 bool has_exception; |
12551 Handle<Object> number = | 12536 Handle<Object> number = |
12552 Execution::ToNumber(object->GetIsolate(), value, &has_exception); | 12537 Execution::ToNumber(isolate, value, &has_exception); |
12553 if (has_exception) return Handle<Object>(); | 12538 if (has_exception) return Handle<Object>(); |
12554 value = number; | 12539 value = number; |
12555 } | 12540 } |
12556 } | 12541 } |
12557 CALL_HEAP_FUNCTION( | |
12558 object->GetIsolate(), | |
12559 object->SetElement(index, *value, attr, strict_mode, check_prototype, | |
12560 set_mode), | |
12561 Object); | |
12562 } | |
12563 | |
12564 | |
12565 MaybeObject* JSObject::SetElement(uint32_t index, | |
12566 Object* value_raw, | |
12567 PropertyAttributes attributes, | |
12568 StrictModeFlag strict_mode, | |
12569 bool check_prototype, | |
12570 SetPropertyMode set_mode) { | |
12571 Isolate* isolate = GetIsolate(); | |
12572 | 12542 |
12573 // Check access rights if needed. | 12543 // Check access rights if needed. |
12574 if (IsAccessCheckNeeded()) { | 12544 if (object->IsAccessCheckNeeded()) { |
12575 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 12545 if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_SET)) { |
12576 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 12546 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); |
12577 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 12547 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
12578 return value_raw; | 12548 return value; |
12579 } | 12549 } |
12580 } | 12550 } |
12581 | 12551 |
12582 if (IsJSGlobalProxy()) { | 12552 if (object->IsJSGlobalProxy()) { |
12583 Object* proto = GetPrototype(); | 12553 Handle<Object> proto(object->GetPrototype(), isolate); |
12584 if (proto->IsNull()) return value_raw; | 12554 if (proto->IsNull()) return value; |
12585 ASSERT(proto->IsJSGlobalObject()); | 12555 ASSERT(proto->IsJSGlobalObject()); |
12586 return JSObject::cast(proto)->SetElement(index, | 12556 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
12587 value_raw, | 12557 strict_mode, |
12588 attributes, | 12558 check_prototype, |
12589 strict_mode, | 12559 set_mode); |
12590 check_prototype, | |
12591 set_mode); | |
12592 } | 12560 } |
12593 | 12561 |
12594 // Don't allow element properties to be redefined for external arrays. | 12562 // Don't allow element properties to be redefined for external arrays. |
12595 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { | 12563 if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { |
12596 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12564 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12597 Handle<Object> args[] = { handle(this, isolate), number }; | 12565 Handle<Object> args[] = { object, number }; |
12598 Handle<Object> error = isolate->factory()->NewTypeError( | 12566 Handle<Object> error = isolate->factory()->NewTypeError( |
12599 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12567 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
12600 return isolate->Throw(*error); | 12568 isolate->Throw(*error); |
| 12569 return Handle<Object>(); |
12601 } | 12570 } |
12602 | 12571 |
12603 // Normalize the elements to enable attributes on the property. | 12572 // Normalize the elements to enable attributes on the property. |
12604 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12573 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
12605 SeededNumberDictionary* dictionary; | 12574 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
12606 MaybeObject* maybe_object = NormalizeElements(); | |
12607 if (!maybe_object->To(&dictionary)) return maybe_object; | |
12608 // Make sure that we never go back to fast case. | 12575 // Make sure that we never go back to fast case. |
12609 dictionary->set_requires_slow_elements(); | 12576 dictionary->set_requires_slow_elements(); |
12610 } | 12577 } |
12611 | 12578 |
12612 if (!(FLAG_harmony_observation && map()->is_observed())) { | 12579 if (!(FLAG_harmony_observation && object->map()->is_observed())) { |
12613 return HasIndexedInterceptor() | 12580 return object->HasIndexedInterceptor() |
12614 ? SetElementWithInterceptor( | 12581 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, |
12615 index, value_raw, attributes, strict_mode, check_prototype, set_mode) | 12582 check_prototype, |
12616 : SetElementWithoutInterceptor( | 12583 set_mode) |
12617 index, value_raw, attributes, strict_mode, check_prototype, set_mode); | 12584 : SetElementWithoutInterceptor(object, index, value, attributes, |
12618 } | 12585 strict_mode, |
12619 | 12586 check_prototype, |
12620 // From here on, everything has to be handlified. | 12587 set_mode); |
12621 Handle<JSObject> self(this); | 12588 } |
12622 Handle<Object> value(value_raw, isolate); | 12589 |
12623 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index); | 12590 PropertyAttributes old_attributes = object->GetLocalElementAttribute(index); |
12624 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 12591 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
12625 Handle<Object> old_length_handle; | 12592 Handle<Object> old_length_handle; |
12626 Handle<Object> new_length_handle; | 12593 Handle<Object> new_length_handle; |
12627 | 12594 |
12628 if (old_attributes != ABSENT) { | 12595 if (old_attributes != ABSENT) { |
12629 if (self->GetLocalElementAccessorPair(index) == NULL) | 12596 if (object->GetLocalElementAccessorPair(index) == NULL) |
12630 old_value = Object::GetElement(isolate, self, index); | 12597 old_value = Object::GetElement(isolate, object, index); |
12631 } else if (self->IsJSArray()) { | 12598 } else if (object->IsJSArray()) { |
12632 // Store old array length in case adding an element grows the array. | 12599 // Store old array length in case adding an element grows the array. |
12633 old_length_handle = handle(Handle<JSArray>::cast(self)->length(), isolate); | 12600 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
| 12601 isolate); |
12634 } | 12602 } |
12635 | 12603 |
12636 // Check for lookup interceptor | 12604 // Check for lookup interceptor |
12637 MaybeObject* result = self->HasIndexedInterceptor() | 12605 Handle<Object> result = object->HasIndexedInterceptor() |
12638 ? self->SetElementWithInterceptor( | 12606 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, |
12639 index, *value, attributes, strict_mode, check_prototype, set_mode) | 12607 check_prototype, |
12640 : self->SetElementWithoutInterceptor( | 12608 set_mode) |
12641 index, *value, attributes, strict_mode, check_prototype, set_mode); | 12609 : SetElementWithoutInterceptor(object, index, value, attributes, |
12642 | 12610 strict_mode, |
12643 Handle<Object> hresult; | 12611 check_prototype, |
12644 if (!result->ToHandle(&hresult, isolate)) return result; | 12612 set_mode); |
| 12613 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>()); |
12645 | 12614 |
12646 Handle<String> name = isolate->factory()->Uint32ToString(index); | 12615 Handle<String> name = isolate->factory()->Uint32ToString(index); |
12647 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index); | 12616 PropertyAttributes new_attributes = object->GetLocalElementAttribute(index); |
12648 if (old_attributes == ABSENT) { | 12617 if (old_attributes == ABSENT) { |
12649 if (self->IsJSArray() && | 12618 if (object->IsJSArray() && |
12650 !old_length_handle->SameValue(Handle<JSArray>::cast(self)->length())) { | 12619 !old_length_handle->SameValue( |
12651 new_length_handle = handle(Handle<JSArray>::cast(self)->length(), | 12620 Handle<JSArray>::cast(object)->length())) { |
| 12621 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
12652 isolate); | 12622 isolate); |
12653 uint32_t old_length = 0; | 12623 uint32_t old_length = 0; |
12654 uint32_t new_length = 0; | 12624 uint32_t new_length = 0; |
12655 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 12625 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
12656 CHECK(new_length_handle->ToArrayIndex(&new_length)); | 12626 CHECK(new_length_handle->ToArrayIndex(&new_length)); |
12657 | 12627 |
12658 BeginPerformSplice(Handle<JSArray>::cast(self)); | 12628 BeginPerformSplice(Handle<JSArray>::cast(object)); |
12659 EnqueueChangeRecord(self, "add", name, old_value); | 12629 EnqueueChangeRecord(object, "add", name, old_value); |
12660 EnqueueChangeRecord(self, "update", isolate->factory()->length_string(), | 12630 EnqueueChangeRecord(object, "update", isolate->factory()->length_string(), |
12661 old_length_handle); | 12631 old_length_handle); |
12662 EndPerformSplice(Handle<JSArray>::cast(self)); | 12632 EndPerformSplice(Handle<JSArray>::cast(object)); |
12663 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12633 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
12664 EnqueueSpliceRecord(Handle<JSArray>::cast(self), old_length, deleted, | 12634 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, |
12665 new_length - old_length); | 12635 new_length - old_length); |
12666 } else { | 12636 } else { |
12667 EnqueueChangeRecord(self, "add", name, old_value); | 12637 EnqueueChangeRecord(object, "add", name, old_value); |
12668 } | 12638 } |
12669 } else if (old_value->IsTheHole()) { | 12639 } else if (old_value->IsTheHole()) { |
12670 EnqueueChangeRecord(self, "reconfigure", name, old_value); | 12640 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
12671 } else { | 12641 } else { |
12672 Handle<Object> new_value = Object::GetElement(isolate, self, index); | 12642 Handle<Object> new_value = Object::GetElement(isolate, object, index); |
12673 bool value_changed = !old_value->SameValue(*new_value); | 12643 bool value_changed = !old_value->SameValue(*new_value); |
12674 if (old_attributes != new_attributes) { | 12644 if (old_attributes != new_attributes) { |
12675 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | 12645 if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
12676 EnqueueChangeRecord(self, "reconfigure", name, old_value); | 12646 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
12677 } else if (value_changed) { | 12647 } else if (value_changed) { |
12678 EnqueueChangeRecord(self, "update", name, old_value); | 12648 EnqueueChangeRecord(object, "update", name, old_value); |
12679 } | 12649 } |
12680 } | 12650 } |
12681 | 12651 |
12682 return *hresult; | 12652 return result; |
12683 } | 12653 } |
12684 | 12654 |
12685 | 12655 |
12686 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 12656 Handle<Object> JSObject::SetElementWithoutInterceptor( |
12687 Object* value, | 12657 Handle<JSObject> object, |
12688 PropertyAttributes attr, | 12658 uint32_t index, |
12689 StrictModeFlag strict_mode, | 12659 Handle<Object> value, |
12690 bool check_prototype, | 12660 PropertyAttributes attributes, |
12691 SetPropertyMode set_mode) { | 12661 StrictModeFlag strict_mode, |
12692 ASSERT(HasDictionaryElements() || | 12662 bool check_prototype, |
12693 HasDictionaryArgumentsElements() || | 12663 SetPropertyMode set_mode) { |
12694 (attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); | 12664 ASSERT(object->HasDictionaryElements() || |
12695 Isolate* isolate = GetIsolate(); | 12665 object->HasDictionaryArgumentsElements() || |
| 12666 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); |
| 12667 Isolate* isolate = object->GetIsolate(); |
12696 if (FLAG_trace_external_array_abuse && | 12668 if (FLAG_trace_external_array_abuse && |
12697 IsExternalArrayElementsKind(GetElementsKind())) { | 12669 IsExternalArrayElementsKind(object->GetElementsKind())) { |
12698 CheckArrayAbuse(this, "external elements write", index); | 12670 CheckArrayAbuse(*object, "external elements write", index); |
12699 } | 12671 } |
12700 if (FLAG_trace_js_array_abuse && | 12672 if (FLAG_trace_js_array_abuse && |
12701 !IsExternalArrayElementsKind(GetElementsKind())) { | 12673 !IsExternalArrayElementsKind(object->GetElementsKind())) { |
12702 if (IsJSArray()) { | 12674 if (object->IsJSArray()) { |
12703 CheckArrayAbuse(this, "elements write", index, true); | 12675 CheckArrayAbuse(*object, "elements write", index, true); |
12704 } | 12676 } |
12705 } | 12677 } |
12706 switch (GetElementsKind()) { | 12678 switch (object->GetElementsKind()) { |
12707 case FAST_SMI_ELEMENTS: | 12679 case FAST_SMI_ELEMENTS: |
12708 case FAST_ELEMENTS: | 12680 case FAST_ELEMENTS: |
12709 case FAST_HOLEY_SMI_ELEMENTS: | 12681 case FAST_HOLEY_SMI_ELEMENTS: |
12710 case FAST_HOLEY_ELEMENTS: | 12682 case FAST_HOLEY_ELEMENTS: |
12711 return SetFastElement(index, value, strict_mode, check_prototype); | 12683 return SetFastElement(object, index, value, strict_mode, check_prototype); |
12712 case FAST_DOUBLE_ELEMENTS: | 12684 case FAST_DOUBLE_ELEMENTS: |
12713 case FAST_HOLEY_DOUBLE_ELEMENTS: | 12685 case FAST_HOLEY_DOUBLE_ELEMENTS: |
12714 return SetFastDoubleElement(index, value, strict_mode, check_prototype); | 12686 return SetFastDoubleElement(object, index, value, strict_mode, |
| 12687 check_prototype); |
12715 case EXTERNAL_PIXEL_ELEMENTS: { | 12688 case EXTERNAL_PIXEL_ELEMENTS: { |
12716 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 12689 ExternalPixelArray* pixels = ExternalPixelArray::cast(object->elements()); |
12717 return pixels->SetValue(index, value); | 12690 return handle(pixels->SetValue(index, *value), isolate); |
12718 } | 12691 } |
12719 case EXTERNAL_BYTE_ELEMENTS: { | 12692 case EXTERNAL_BYTE_ELEMENTS: { |
12720 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 12693 Handle<ExternalByteArray> array( |
12721 return array->SetValue(index, value); | 12694 ExternalByteArray::cast(object->elements())); |
| 12695 return ExternalByteArray::SetValue(array, index, value); |
12722 } | 12696 } |
12723 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 12697 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
12724 ExternalUnsignedByteArray* array = | 12698 Handle<ExternalUnsignedByteArray> array( |
12725 ExternalUnsignedByteArray::cast(elements()); | 12699 ExternalUnsignedByteArray::cast(object->elements())); |
12726 return array->SetValue(index, value); | 12700 return ExternalUnsignedByteArray::SetValue(array, index, value); |
12727 } | 12701 } |
12728 case EXTERNAL_SHORT_ELEMENTS: { | 12702 case EXTERNAL_SHORT_ELEMENTS: { |
12729 ExternalShortArray* array = ExternalShortArray::cast(elements()); | 12703 Handle<ExternalShortArray> array(ExternalShortArray::cast( |
12730 return array->SetValue(index, value); | 12704 object->elements())); |
| 12705 return ExternalShortArray::SetValue(array, index, value); |
12731 } | 12706 } |
12732 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { | 12707 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { |
12733 ExternalUnsignedShortArray* array = | 12708 Handle<ExternalUnsignedShortArray> array( |
12734 ExternalUnsignedShortArray::cast(elements()); | 12709 ExternalUnsignedShortArray::cast(object->elements())); |
12735 return array->SetValue(index, value); | 12710 return ExternalUnsignedShortArray::SetValue(array, index, value); |
12736 } | 12711 } |
12737 case EXTERNAL_INT_ELEMENTS: { | 12712 case EXTERNAL_INT_ELEMENTS: { |
12738 ExternalIntArray* array = ExternalIntArray::cast(elements()); | 12713 Handle<ExternalIntArray> array( |
12739 return array->SetValue(index, value); | 12714 ExternalIntArray::cast(object->elements())); |
| 12715 return ExternalIntArray::SetValue(array, index, value); |
12740 } | 12716 } |
12741 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 12717 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
12742 ExternalUnsignedIntArray* array = | 12718 Handle<ExternalUnsignedIntArray> array( |
12743 ExternalUnsignedIntArray::cast(elements()); | 12719 ExternalUnsignedIntArray::cast(object->elements())); |
12744 return array->SetValue(index, value); | 12720 return ExternalUnsignedIntArray::SetValue(array, index, value); |
12745 } | 12721 } |
12746 case EXTERNAL_FLOAT_ELEMENTS: { | 12722 case EXTERNAL_FLOAT_ELEMENTS: { |
12747 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); | 12723 Handle<ExternalFloatArray> array( |
12748 return array->SetValue(index, value); | 12724 ExternalFloatArray::cast(object->elements())); |
| 12725 return ExternalFloatArray::SetValue(array, index, value); |
12749 } | 12726 } |
12750 case EXTERNAL_DOUBLE_ELEMENTS: { | 12727 case EXTERNAL_DOUBLE_ELEMENTS: { |
12751 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); | 12728 Handle<ExternalDoubleArray> array( |
12752 return array->SetValue(index, value); | 12729 ExternalDoubleArray::cast(object->elements())); |
| 12730 return ExternalDoubleArray::SetValue(array, index, value); |
12753 } | 12731 } |
12754 case DICTIONARY_ELEMENTS: | 12732 case DICTIONARY_ELEMENTS: |
12755 return SetDictionaryElement(index, value, attr, strict_mode, | 12733 return SetDictionaryElement(object, index, value, attributes, strict_mode, |
12756 check_prototype, set_mode); | 12734 check_prototype, |
| 12735 set_mode); |
12757 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 12736 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
12758 FixedArray* parameter_map = FixedArray::cast(elements()); | 12737 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
12759 uint32_t length = parameter_map->length(); | 12738 uint32_t length = parameter_map->length(); |
12760 Object* probe = | 12739 Handle<Object> probe = index < length - 2 ? |
12761 (index < length - 2) ? parameter_map->get(index + 2) : NULL; | 12740 Handle<Object>(parameter_map->get(index + 2), isolate) : |
12762 if (probe != NULL && !probe->IsTheHole()) { | 12741 Handle<Object>(); |
12763 Context* context = Context::cast(parameter_map->get(0)); | 12742 if (!probe.is_null() && !probe->IsTheHole()) { |
12764 int context_index = Smi::cast(probe)->value(); | 12743 Handle<Context> context(Context::cast(parameter_map->get(0))); |
| 12744 int context_index = Handle<Smi>::cast(probe)->value(); |
12765 ASSERT(!context->get(context_index)->IsTheHole()); | 12745 ASSERT(!context->get(context_index)->IsTheHole()); |
12766 context->set(context_index, value); | 12746 context->set(context_index, *value); |
12767 // Redefining attributes of an aliased element destroys fast aliasing. | 12747 // Redefining attributes of an aliased element destroys fast aliasing. |
12768 if (set_mode == SET_PROPERTY || attr == NONE) return value; | 12748 if (set_mode == SET_PROPERTY || attributes == NONE) return value; |
12769 parameter_map->set_the_hole(index + 2); | 12749 parameter_map->set_the_hole(index + 2); |
12770 // For elements that are still writable we re-establish slow aliasing. | 12750 // For elements that are still writable we re-establish slow aliasing. |
12771 if ((attr & READ_ONLY) == 0) { | 12751 if ((attributes & READ_ONLY) == 0) { |
12772 MaybeObject* maybe_entry = | 12752 value = Handle<Object>::cast( |
12773 isolate->heap()->AllocateAliasedArgumentsEntry(context_index); | 12753 isolate->factory()->NewAliasedArgumentsEntry(context_index)); |
12774 if (!maybe_entry->ToObject(&value)) return maybe_entry; | |
12775 } | 12754 } |
12776 } | 12755 } |
12777 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 12756 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
12778 if (arguments->IsDictionary()) { | 12757 if (arguments->IsDictionary()) { |
12779 return SetDictionaryElement(index, value, attr, strict_mode, | 12758 return SetDictionaryElement(object, index, value, attributes, |
12780 check_prototype, set_mode); | 12759 strict_mode, |
| 12760 check_prototype, |
| 12761 set_mode); |
12781 } else { | 12762 } else { |
12782 return SetFastElement(index, value, strict_mode, check_prototype); | 12763 return SetFastElement(object, index, value, strict_mode, |
| 12764 check_prototype); |
12783 } | 12765 } |
12784 } | 12766 } |
12785 } | 12767 } |
12786 // All possible cases have been handled above. Add a return to avoid the | 12768 // All possible cases have been handled above. Add a return to avoid the |
12787 // complaints from the compiler. | 12769 // complaints from the compiler. |
12788 UNREACHABLE(); | 12770 UNREACHABLE(); |
12789 return isolate->heap()->null_value(); | 12771 return isolate->factory()->null_value(); |
12790 } | 12772 } |
12791 | 12773 |
12792 | 12774 |
12793 void JSObject::TransitionElementsKind(Handle<JSObject> object, | 12775 void JSObject::TransitionElementsKind(Handle<JSObject> object, |
12794 ElementsKind to_kind) { | 12776 ElementsKind to_kind) { |
12795 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), | 12777 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
12796 object->TransitionElementsKind(to_kind)); | 12778 object->TransitionElementsKind(to_kind)); |
12797 } | 12779 } |
12798 | 12780 |
12799 | 12781 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12876 | 12858 |
12877 | 12859 |
12878 void AllocationSite::AddDependentCode(Reason reason, Handle<Code> code) { | 12860 void AllocationSite::AddDependentCode(Reason reason, Handle<Code> code) { |
12879 DependentCode::DependencyGroup group = ToDependencyGroup(reason); | 12861 DependentCode::DependencyGroup group = ToDependencyGroup(reason); |
12880 Handle<DependentCode> codes = DependentCode::Insert( | 12862 Handle<DependentCode> codes = DependentCode::Insert( |
12881 Handle<DependentCode>(dependent_code()), group, code); | 12863 Handle<DependentCode>(dependent_code()), group, code); |
12882 if (*codes != dependent_code()) set_dependent_code(*codes); | 12864 if (*codes != dependent_code()) set_dependent_code(*codes); |
12883 } | 12865 } |
12884 | 12866 |
12885 | 12867 |
| 12868 void JSObject::UpdateAllocationSite(Handle<JSObject> object, |
| 12869 ElementsKind to_kind) { |
| 12870 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
| 12871 object->UpdateAllocationSite(to_kind)); |
| 12872 } |
| 12873 |
| 12874 |
12886 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { | 12875 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { |
12887 if (!FLAG_track_allocation_sites || !IsJSArray()) { | 12876 if (!FLAG_track_allocation_sites || !IsJSArray()) { |
12888 return this; | 12877 return this; |
12889 } | 12878 } |
12890 | 12879 |
12891 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); | 12880 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); |
12892 if (memento == NULL || !memento->IsValid()) { | 12881 if (memento == NULL || !memento->IsValid()) { |
12893 return this; | 12882 return this; |
12894 } | 12883 } |
12895 | 12884 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12981 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { | 12970 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { |
12982 return false; | 12971 return false; |
12983 } | 12972 } |
12984 | 12973 |
12985 // Transitions from HOLEY -> PACKED are not allowed. | 12974 // Transitions from HOLEY -> PACKED are not allowed. |
12986 return !IsFastHoleyElementsKind(from_kind) || | 12975 return !IsFastHoleyElementsKind(from_kind) || |
12987 IsFastHoleyElementsKind(to_kind); | 12976 IsFastHoleyElementsKind(to_kind); |
12988 } | 12977 } |
12989 | 12978 |
12990 | 12979 |
| 12980 void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array, |
| 12981 uint32_t index, |
| 12982 Handle<Object> value) { |
| 12983 CALL_HEAP_FUNCTION_VOID(array->GetIsolate(), |
| 12984 array->JSArrayUpdateLengthFromIndex(index, *value)); |
| 12985 } |
| 12986 |
| 12987 |
12991 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, | 12988 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
12992 Object* value) { | 12989 Object* value) { |
12993 uint32_t old_len = 0; | 12990 uint32_t old_len = 0; |
12994 CHECK(length()->ToArrayIndex(&old_len)); | 12991 CHECK(length()->ToArrayIndex(&old_len)); |
12995 // Check to see if we need to update the length. For now, we make | 12992 // Check to see if we need to update the length. For now, we make |
12996 // sure that the length stays within 32-bits (unsigned). | 12993 // sure that the length stays within 32-bits (unsigned). |
12997 if (index >= old_len && index != 0xffffffff) { | 12994 if (index >= old_len && index != 0xffffffff) { |
12998 Object* len; | 12995 Object* len; |
12999 { MaybeObject* maybe_len = | 12996 { MaybeObject* maybe_len = |
13000 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); | 12997 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13086 // Fall through if packing is not guaranteed. | 13083 // Fall through if packing is not guaranteed. |
13087 case FAST_HOLEY_SMI_ELEMENTS: | 13084 case FAST_HOLEY_SMI_ELEMENTS: |
13088 case FAST_HOLEY_ELEMENTS: | 13085 case FAST_HOLEY_ELEMENTS: |
13089 backing_store = FixedArray::cast(backing_store_base); | 13086 backing_store = FixedArray::cast(backing_store_base); |
13090 *capacity = backing_store->length(); | 13087 *capacity = backing_store->length(); |
13091 for (int i = 0; i < *capacity; ++i) { | 13088 for (int i = 0; i < *capacity; ++i) { |
13092 if (!backing_store->get(i)->IsTheHole()) ++(*used); | 13089 if (!backing_store->get(i)->IsTheHole()) ++(*used); |
13093 } | 13090 } |
13094 break; | 13091 break; |
13095 case DICTIONARY_ELEMENTS: { | 13092 case DICTIONARY_ELEMENTS: { |
13096 SeededNumberDictionary* dictionary = | 13093 SeededNumberDictionary* dictionary = element_dictionary(); |
13097 SeededNumberDictionary::cast(FixedArray::cast(elements())); | |
13098 *capacity = dictionary->Capacity(); | 13094 *capacity = dictionary->Capacity(); |
13099 *used = dictionary->NumberOfElements(); | 13095 *used = dictionary->NumberOfElements(); |
13100 break; | 13096 break; |
13101 } | 13097 } |
13102 case FAST_DOUBLE_ELEMENTS: | 13098 case FAST_DOUBLE_ELEMENTS: |
13103 if (IsJSArray()) { | 13099 if (IsJSArray()) { |
13104 *capacity = backing_store_base->length(); | 13100 *capacity = backing_store_base->length(); |
13105 *used = Smi::cast(JSArray::cast(this)->length())->value(); | 13101 *used = Smi::cast(JSArray::cast(this)->length())->value(); |
13106 break; | 13102 break; |
13107 } | 13103 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13186 SeededNumberDictionary::kEntrySize; | 13182 SeededNumberDictionary::kEntrySize; |
13187 return 2 * dictionary_size >= array_size; | 13183 return 2 * dictionary_size >= array_size; |
13188 } | 13184 } |
13189 | 13185 |
13190 | 13186 |
13191 bool JSObject::ShouldConvertToFastDoubleElements( | 13187 bool JSObject::ShouldConvertToFastDoubleElements( |
13192 bool* has_smi_only_elements) { | 13188 bool* has_smi_only_elements) { |
13193 *has_smi_only_elements = false; | 13189 *has_smi_only_elements = false; |
13194 if (FLAG_unbox_double_arrays) { | 13190 if (FLAG_unbox_double_arrays) { |
13195 ASSERT(HasDictionaryElements()); | 13191 ASSERT(HasDictionaryElements()); |
13196 SeededNumberDictionary* dictionary = | 13192 SeededNumberDictionary* dictionary = element_dictionary(); |
13197 SeededNumberDictionary::cast(elements()); | |
13198 bool found_double = false; | 13193 bool found_double = false; |
13199 for (int i = 0; i < dictionary->Capacity(); i++) { | 13194 for (int i = 0; i < dictionary->Capacity(); i++) { |
13200 Object* key = dictionary->KeyAt(i); | 13195 Object* key = dictionary->KeyAt(i); |
13201 if (key->IsNumber()) { | 13196 if (key->IsNumber()) { |
13202 Object* value = dictionary->ValueAt(i); | 13197 Object* value = dictionary->ValueAt(i); |
13203 if (!value->IsNumber()) return false; | 13198 if (!value->IsNumber()) return false; |
13204 if (!value->IsSmi()) { | 13199 if (!value->IsSmi()) { |
13205 found_double = true; | 13200 found_double = true; |
13206 } | 13201 } |
13207 } | 13202 } |
(...skipping 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14565 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); | 14560 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); |
14566 dict->CopyValuesTo(*fast_elements); | 14561 dict->CopyValuesTo(*fast_elements); |
14567 object->ValidateElements(); | 14562 object->ValidateElements(); |
14568 | 14563 |
14569 object->set_map_and_elements(*new_map, *fast_elements); | 14564 object->set_map_and_elements(*new_map, *fast_elements); |
14570 } else if (object->HasExternalArrayElements()) { | 14565 } else if (object->HasExternalArrayElements()) { |
14571 // External arrays cannot have holes or undefined elements. | 14566 // External arrays cannot have holes or undefined elements. |
14572 return handle(Smi::FromInt( | 14567 return handle(Smi::FromInt( |
14573 ExternalArray::cast(object->elements())->length()), isolate); | 14568 ExternalArray::cast(object->elements())->length()), isolate); |
14574 } else if (!object->HasFastDoubleElements()) { | 14569 } else if (!object->HasFastDoubleElements()) { |
14575 JSObject::EnsureWritableFastElements(object); | 14570 EnsureWritableFastElements(object); |
14576 } | 14571 } |
14577 ASSERT(object->HasFastSmiOrObjectElements() || | 14572 ASSERT(object->HasFastSmiOrObjectElements() || |
14578 object->HasFastDoubleElements()); | 14573 object->HasFastDoubleElements()); |
14579 | 14574 |
14580 // Collect holes at the end, undefined before that and the rest at the | 14575 // Collect holes at the end, undefined before that and the rest at the |
14581 // start, and return the number of non-hole, non-undefined values. | 14576 // start, and return the number of non-hole, non-undefined values. |
14582 | 14577 |
14583 Handle<FixedArrayBase> elements_base(object->elements()); | 14578 Handle<FixedArrayBase> elements_base(object->elements()); |
14584 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); | 14579 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); |
14585 if (limit > elements_length) { | 14580 if (limit > elements_length) { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14772 // Clamp undefined to zero (default). All other types have been | 14767 // Clamp undefined to zero (default). All other types have been |
14773 // converted to a number type further up in the call chain. | 14768 // converted to a number type further up in the call chain. |
14774 ASSERT(value->IsUndefined()); | 14769 ASSERT(value->IsUndefined()); |
14775 } | 14770 } |
14776 receiver->set(index, cast_value); | 14771 receiver->set(index, cast_value); |
14777 } | 14772 } |
14778 return heap->NumberFromInt32(cast_value); | 14773 return heap->NumberFromInt32(cast_value); |
14779 } | 14774 } |
14780 | 14775 |
14781 | 14776 |
| 14777 Handle<Object> ExternalByteArray::SetValue(Handle<ExternalByteArray> array, |
| 14778 uint32_t index, |
| 14779 Handle<Object> value) { |
| 14780 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14781 array->SetValue(index, *value), |
| 14782 Object); |
| 14783 } |
| 14784 |
| 14785 |
14782 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { | 14786 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { |
14783 return ExternalArrayIntSetter<ExternalByteArray, int8_t> | 14787 return ExternalArrayIntSetter<ExternalByteArray, int8_t> |
14784 (GetHeap(), this, index, value); | 14788 (GetHeap(), this, index, value); |
14785 } | 14789 } |
14786 | 14790 |
14787 | 14791 |
| 14792 Handle<Object> ExternalUnsignedByteArray::SetValue( |
| 14793 Handle<ExternalUnsignedByteArray> array, |
| 14794 uint32_t index, |
| 14795 Handle<Object> value) { |
| 14796 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14797 array->SetValue(index, *value), |
| 14798 Object); |
| 14799 } |
| 14800 |
| 14801 |
14788 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, | 14802 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, |
14789 Object* value) { | 14803 Object* value) { |
14790 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> | 14804 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> |
14791 (GetHeap(), this, index, value); | 14805 (GetHeap(), this, index, value); |
14792 } | 14806 } |
14793 | 14807 |
14794 | 14808 |
| 14809 Handle<Object> ExternalShortArray::SetValue( |
| 14810 Handle<ExternalShortArray> array, |
| 14811 uint32_t index, |
| 14812 Handle<Object> value) { |
| 14813 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14814 array->SetValue(index, *value), |
| 14815 Object); |
| 14816 } |
| 14817 |
| 14818 |
14795 MaybeObject* ExternalShortArray::SetValue(uint32_t index, | 14819 MaybeObject* ExternalShortArray::SetValue(uint32_t index, |
14796 Object* value) { | 14820 Object* value) { |
14797 return ExternalArrayIntSetter<ExternalShortArray, int16_t> | 14821 return ExternalArrayIntSetter<ExternalShortArray, int16_t> |
14798 (GetHeap(), this, index, value); | 14822 (GetHeap(), this, index, value); |
14799 } | 14823 } |
14800 | 14824 |
14801 | 14825 |
| 14826 Handle<Object> ExternalUnsignedShortArray::SetValue( |
| 14827 Handle<ExternalUnsignedShortArray> array, |
| 14828 uint32_t index, |
| 14829 Handle<Object> value) { |
| 14830 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14831 array->SetValue(index, *value), |
| 14832 Object); |
| 14833 } |
| 14834 |
| 14835 |
14802 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, | 14836 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, |
14803 Object* value) { | 14837 Object* value) { |
14804 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> | 14838 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> |
14805 (GetHeap(), this, index, value); | 14839 (GetHeap(), this, index, value); |
14806 } | 14840 } |
14807 | 14841 |
14808 | 14842 |
| 14843 Handle<Object> ExternalIntArray::SetValue(Handle<ExternalIntArray> array, |
| 14844 uint32_t index, |
| 14845 Handle<Object> value) { |
| 14846 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14847 array->SetValue(index, *value), |
| 14848 Object); |
| 14849 } |
| 14850 |
| 14851 |
14809 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { | 14852 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { |
14810 return ExternalArrayIntSetter<ExternalIntArray, int32_t> | 14853 return ExternalArrayIntSetter<ExternalIntArray, int32_t> |
14811 (GetHeap(), this, index, value); | 14854 (GetHeap(), this, index, value); |
14812 } | 14855 } |
14813 | 14856 |
14814 | 14857 |
| 14858 Handle<Object> ExternalUnsignedIntArray::SetValue( |
| 14859 Handle<ExternalUnsignedIntArray> array, |
| 14860 uint32_t index, |
| 14861 Handle<Object> value) { |
| 14862 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14863 array->SetValue(index, *value), |
| 14864 Object); |
| 14865 } |
| 14866 |
| 14867 |
14815 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { | 14868 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { |
14816 uint32_t cast_value = 0; | 14869 uint32_t cast_value = 0; |
14817 Heap* heap = GetHeap(); | 14870 Heap* heap = GetHeap(); |
14818 if (index < static_cast<uint32_t>(length())) { | 14871 if (index < static_cast<uint32_t>(length())) { |
14819 if (value->IsSmi()) { | 14872 if (value->IsSmi()) { |
14820 int int_value = Smi::cast(value)->value(); | 14873 int int_value = Smi::cast(value)->value(); |
14821 cast_value = static_cast<uint32_t>(int_value); | 14874 cast_value = static_cast<uint32_t>(int_value); |
14822 } else if (value->IsHeapNumber()) { | 14875 } else if (value->IsHeapNumber()) { |
14823 double double_value = HeapNumber::cast(value)->value(); | 14876 double double_value = HeapNumber::cast(value)->value(); |
14824 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); | 14877 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); |
14825 } else { | 14878 } else { |
14826 // Clamp undefined to zero (default). All other types have been | 14879 // Clamp undefined to zero (default). All other types have been |
14827 // converted to a number type further up in the call chain. | 14880 // converted to a number type further up in the call chain. |
14828 ASSERT(value->IsUndefined()); | 14881 ASSERT(value->IsUndefined()); |
14829 } | 14882 } |
14830 set(index, cast_value); | 14883 set(index, cast_value); |
14831 } | 14884 } |
14832 return heap->NumberFromUint32(cast_value); | 14885 return heap->NumberFromUint32(cast_value); |
14833 } | 14886 } |
14834 | 14887 |
14835 | 14888 |
| 14889 Handle<Object> ExternalFloatArray::SetValue(Handle<ExternalFloatArray> array, |
| 14890 uint32_t index, |
| 14891 Handle<Object> value) { |
| 14892 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14893 array->SetValue(index, *value), |
| 14894 Object); |
| 14895 } |
| 14896 |
| 14897 |
14836 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { | 14898 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { |
14837 float cast_value = static_cast<float>(OS::nan_value()); | 14899 float cast_value = static_cast<float>(OS::nan_value()); |
14838 Heap* heap = GetHeap(); | 14900 Heap* heap = GetHeap(); |
14839 if (index < static_cast<uint32_t>(length())) { | 14901 if (index < static_cast<uint32_t>(length())) { |
14840 if (value->IsSmi()) { | 14902 if (value->IsSmi()) { |
14841 int int_value = Smi::cast(value)->value(); | 14903 int int_value = Smi::cast(value)->value(); |
14842 cast_value = static_cast<float>(int_value); | 14904 cast_value = static_cast<float>(int_value); |
14843 } else if (value->IsHeapNumber()) { | 14905 } else if (value->IsHeapNumber()) { |
14844 double double_value = HeapNumber::cast(value)->value(); | 14906 double double_value = HeapNumber::cast(value)->value(); |
14845 cast_value = static_cast<float>(double_value); | 14907 cast_value = static_cast<float>(double_value); |
14846 } else { | 14908 } else { |
14847 // Clamp undefined to NaN (default). All other types have been | 14909 // Clamp undefined to NaN (default). All other types have been |
14848 // converted to a number type further up in the call chain. | 14910 // converted to a number type further up in the call chain. |
14849 ASSERT(value->IsUndefined()); | 14911 ASSERT(value->IsUndefined()); |
14850 } | 14912 } |
14851 set(index, cast_value); | 14913 set(index, cast_value); |
14852 } | 14914 } |
14853 return heap->AllocateHeapNumber(cast_value); | 14915 return heap->AllocateHeapNumber(cast_value); |
14854 } | 14916 } |
14855 | 14917 |
14856 | 14918 |
| 14919 Handle<Object> ExternalDoubleArray::SetValue(Handle<ExternalDoubleArray> array, |
| 14920 uint32_t index, |
| 14921 Handle<Object> value) { |
| 14922 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14923 array->SetValue(index, *value), |
| 14924 Object); |
| 14925 } |
| 14926 |
| 14927 |
14857 MaybeObject* ExternalDoubleArray::SetValue(uint32_t index, Object* value) { | 14928 MaybeObject* ExternalDoubleArray::SetValue(uint32_t index, Object* value) { |
14858 double double_value = OS::nan_value(); | 14929 double double_value = OS::nan_value(); |
14859 Heap* heap = GetHeap(); | 14930 Heap* heap = GetHeap(); |
14860 if (index < static_cast<uint32_t>(length())) { | 14931 if (index < static_cast<uint32_t>(length())) { |
14861 if (value->IsSmi()) { | 14932 if (value->IsSmi()) { |
14862 int int_value = Smi::cast(value)->value(); | 14933 int int_value = Smi::cast(value)->value(); |
14863 double_value = static_cast<double>(int_value); | 14934 double_value = static_cast<double>(int_value); |
14864 } else if (value->IsHeapNumber()) { | 14935 } else if (value->IsHeapNumber()) { |
14865 double_value = HeapNumber::cast(value)->value(); | 14936 double_value = HeapNumber::cast(value)->value(); |
14866 } else { | 14937 } else { |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15468 return; | 15539 return; |
15469 } | 15540 } |
15470 // Update max key value. | 15541 // Update max key value. |
15471 Object* max_index_object = get(kMaxNumberKeyIndex); | 15542 Object* max_index_object = get(kMaxNumberKeyIndex); |
15472 if (!max_index_object->IsSmi() || max_number_key() < key) { | 15543 if (!max_index_object->IsSmi() || max_number_key() < key) { |
15473 FixedArray::set(kMaxNumberKeyIndex, | 15544 FixedArray::set(kMaxNumberKeyIndex, |
15474 Smi::FromInt(key << kRequiresSlowElementsTagSize)); | 15545 Smi::FromInt(key << kRequiresSlowElementsTagSize)); |
15475 } | 15546 } |
15476 } | 15547 } |
15477 | 15548 |
| 15549 Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry( |
| 15550 Handle<SeededNumberDictionary> dictionary, |
| 15551 uint32_t key, |
| 15552 Handle<Object> value, |
| 15553 PropertyDetails details) { |
| 15554 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 15555 dictionary->AddNumberEntry(key, *value, details), |
| 15556 SeededNumberDictionary); |
| 15557 } |
15478 | 15558 |
15479 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key, | 15559 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key, |
15480 Object* value, | 15560 Object* value, |
15481 PropertyDetails details) { | 15561 PropertyDetails details) { |
15482 UpdateMaxNumberKey(key); | 15562 UpdateMaxNumberKey(key); |
15483 SLOW_ASSERT(this->FindEntry(key) == kNotFound); | 15563 SLOW_ASSERT(this->FindEntry(key) == kNotFound); |
15484 return Add(key, value, details); | 15564 return Add(key, value, details); |
15485 } | 15565 } |
15486 | 15566 |
15487 | 15567 |
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16563 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16643 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16564 static const char* error_messages_[] = { | 16644 static const char* error_messages_[] = { |
16565 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16645 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16566 }; | 16646 }; |
16567 #undef ERROR_MESSAGES_TEXTS | 16647 #undef ERROR_MESSAGES_TEXTS |
16568 return error_messages_[reason]; | 16648 return error_messages_[reason]; |
16569 } | 16649 } |
16570 | 16650 |
16571 | 16651 |
16572 } } // namespace v8::internal | 16652 } } // namespace v8::internal |
OLD | NEW |