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 2948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2959 bool has_pending_exception; | 2959 bool has_pending_exception; |
2960 Handle<Object> argv[] = { value }; | 2960 Handle<Object> argv[] = { value }; |
2961 Execution::Call( | 2961 Execution::Call( |
2962 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); | 2962 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); |
2963 // Check for pending exception and return the result. | 2963 // Check for pending exception and return the result. |
2964 if (has_pending_exception) return Handle<Object>(); | 2964 if (has_pending_exception) return Handle<Object>(); |
2965 return value; | 2965 return value; |
2966 } | 2966 } |
2967 | 2967 |
2968 | 2968 |
2969 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( | 2969 Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
2970 Handle<JSObject> object, | |
2970 uint32_t index, | 2971 uint32_t index, |
2971 Object* value, | 2972 Handle<Object> value, |
2972 bool* found, | 2973 bool* found, |
2973 StrictModeFlag strict_mode) { | 2974 StrictModeFlag strict_mode) { |
2974 Heap* heap = GetHeap(); | 2975 Isolate *isolate = object->GetIsolate(); |
2975 for (Object* pt = GetPrototype(); | 2976 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); |
2976 pt != heap->null_value(); | 2977 !proto->IsNull(); |
2977 pt = pt->GetPrototype(GetIsolate())) { | 2978 proto = handle(proto->GetPrototype(isolate), isolate)) { |
2978 if (pt->IsJSProxy()) { | 2979 if (proto->IsJSProxy()) { |
2979 Isolate* isolate = GetIsolate(); | 2980 return JSProxy::SetPropertyViaPrototypesWithHandler( |
2980 HandleScope scope(isolate); | 2981 Handle<JSProxy>::cast(proto), |
2981 Handle<JSProxy> proxy(JSProxy::cast(pt)); | 2982 object, |
2982 Handle<JSObject> self(this, isolate); | 2983 isolate->factory()->Uint32ToString(index), // name |
2983 Handle<String> name = isolate->factory()->Uint32ToString(index); | 2984 value, |
2984 Handle<Object> value_handle(value, isolate); | 2985 NONE, |
2985 Handle<Object> result = JSProxy::SetPropertyViaPrototypesWithHandler( | 2986 strict_mode, |
2986 proxy, self, name, value_handle, NONE, strict_mode, found); | 2987 found); |
2987 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
2988 return *result; | |
2989 } | 2988 } |
2990 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 2989 Handle<JSObject> js_proto = Handle<JSObject>::cast(proto); |
2990 if (!js_proto->HasDictionaryElements()) { | |
2991 continue; | 2991 continue; |
2992 } | 2992 } |
2993 SeededNumberDictionary* dictionary = | 2993 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); |
2994 JSObject::cast(pt)->element_dictionary(); | |
2995 int entry = dictionary->FindEntry(index); | 2994 int entry = dictionary->FindEntry(index); |
2996 if (entry != SeededNumberDictionary::kNotFound) { | 2995 if (entry != SeededNumberDictionary::kNotFound) { |
2997 PropertyDetails details = dictionary->DetailsAt(entry); | 2996 PropertyDetails details = dictionary->DetailsAt(entry); |
2998 if (details.type() == CALLBACKS) { | 2997 if (details.type() == CALLBACKS) { |
2999 *found = true; | 2998 *found = true; |
3000 Isolate* isolate = GetIsolate(); | |
3001 HandleScope scope(isolate); | |
3002 Handle<JSObject> self(this, isolate); | |
3003 Handle<Object> structure(dictionary->ValueAt(entry), isolate); | 2999 Handle<Object> structure(dictionary->ValueAt(entry), isolate); |
3004 Handle<Object> value_handle(value, isolate); | 3000 return SetElementWithCallback(object, structure, index, value, js_proto, |
3005 Handle<JSObject> holder(JSObject::cast(pt)); | 3001 strict_mode); |
3006 Handle<Object> result = SetElementWithCallback( | |
3007 self, structure, index, value_handle, holder, strict_mode); | |
3008 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
3009 return *result; | |
3010 } | 3002 } |
3011 } | 3003 } |
3012 } | 3004 } |
3013 *found = false; | 3005 *found = false; |
3014 return heap->the_hole_value(); | 3006 return isolate->factory()->the_hole_value(); |
3015 } | 3007 } |
3016 | 3008 |
3017 | 3009 |
3018 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, | 3010 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, |
3019 Handle<Name> name, | 3011 Handle<Name> name, |
3020 Handle<Object> value, | 3012 Handle<Object> value, |
3021 PropertyAttributes attributes, | 3013 PropertyAttributes attributes, |
3022 StrictModeFlag strict_mode, | 3014 StrictModeFlag strict_mode, |
3023 bool* done) { | 3015 bool* done) { |
3024 Isolate* isolate = object->GetIsolate(); | 3016 Isolate* isolate = object->GetIsolate(); |
(...skipping 3224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6249 Handle<Object> structure, | 6241 Handle<Object> structure, |
6250 PropertyAttributes attributes) { | 6242 PropertyAttributes attributes) { |
6251 Heap* heap = object->GetHeap(); | 6243 Heap* heap = object->GetHeap(); |
6252 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6244 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
6253 | 6245 |
6254 // Normalize elements to make this operation simple. | 6246 // Normalize elements to make this operation simple. |
6255 bool had_dictionary_elements = object->HasDictionaryElements(); | 6247 bool had_dictionary_elements = object->HasDictionaryElements(); |
6256 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6248 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
6257 ASSERT(object->HasDictionaryElements() || | 6249 ASSERT(object->HasDictionaryElements() || |
6258 object->HasDictionaryArgumentsElements()); | 6250 object->HasDictionaryArgumentsElements()); |
6259 | |
6260 // Update the dictionary with the new CALLBACKS property. | 6251 // Update the dictionary with the new CALLBACKS property. |
6261 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | 6252 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, |
6262 details); | 6253 details); |
6263 dictionary->set_requires_slow_elements(); | 6254 dictionary->set_requires_slow_elements(); |
6264 | 6255 |
6265 // Update the dictionary backing store on the object. | 6256 // Update the dictionary backing store on the object. |
6266 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { | 6257 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { |
6267 // Also delete any parameter alias. | 6258 // Also delete any parameter alias. |
6268 // | 6259 // |
6269 // TODO(kmillikin): when deleting the last parameter alias we could | 6260 // TODO(kmillikin): when deleting the last parameter alias we could |
(...skipping 4937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11207 | 11198 |
11208 PrintF(out, "RelocInfo (size = %d)\n", relocation_size()); | 11199 PrintF(out, "RelocInfo (size = %d)\n", relocation_size()); |
11209 for (RelocIterator it(this); !it.done(); it.next()) { | 11200 for (RelocIterator it(this); !it.done(); it.next()) { |
11210 it.rinfo()->Print(GetIsolate(), out); | 11201 it.rinfo()->Print(GetIsolate(), out); |
11211 } | 11202 } |
11212 PrintF(out, "\n"); | 11203 PrintF(out, "\n"); |
11213 } | 11204 } |
11214 #endif // ENABLE_DISASSEMBLER | 11205 #endif // ENABLE_DISASSEMBLER |
11215 | 11206 |
11216 | 11207 |
11208 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength( | |
11209 Handle<JSObject> object, | |
11210 int capacity, | |
11211 int length, | |
11212 SetFastElementsCapacitySmiMode smi_mode) { | |
11213 CALL_HEAP_FUNCTION( | |
11214 object->GetIsolate(), | |
Michael Starzinger
2013/11/13 12:24:45
nit: Indentation is off.
rafaelw
2013/11/13 20:56:47
Done.
| |
11215 object->SetFastElementsCapacityAndLength(capacity, length, smi_mode), | |
11216 FixedArray); | |
11217 } | |
11218 | |
11219 | |
11217 MaybeObject* JSObject::SetFastElementsCapacityAndLength( | 11220 MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
11218 int capacity, | 11221 int capacity, |
11219 int length, | 11222 int length, |
11220 SetFastElementsCapacitySmiMode smi_mode) { | 11223 SetFastElementsCapacitySmiMode smi_mode) { |
11221 Heap* heap = GetHeap(); | 11224 Heap* heap = GetHeap(); |
11222 // We should never end in here with a pixel or external array. | 11225 // We should never end in here with a pixel or external array. |
11223 ASSERT(!HasExternalArrayElements()); | 11226 ASSERT(!HasExternalArrayElements()); |
11224 ASSERT(!map()->is_observed()); | 11227 ASSERT(!map()->is_observed()); |
11225 | 11228 |
11226 // Allocate a new fast elements backing store. | 11229 // Allocate a new fast elements backing store. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11293 FLAG_weak_embedded_maps_in_optimized_code; | 11296 FLAG_weak_embedded_maps_in_optimized_code; |
11294 } | 11297 } |
11295 | 11298 |
11296 if (object->IsJSObject()) { | 11299 if (object->IsJSObject()) { |
11297 return FLAG_weak_embedded_objects_in_optimized_code; | 11300 return FLAG_weak_embedded_objects_in_optimized_code; |
11298 } | 11301 } |
11299 | 11302 |
11300 return false; | 11303 return false; |
11301 } | 11304 } |
11302 | 11305 |
11306 | |
11307 void JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object, | |
11308 int capacity, | |
11309 int length) { | |
11310 CALL_HEAP_FUNCTION_VOID( | |
11311 object->GetIsolate(), | |
11312 object->SetFastDoubleElementsCapacityAndLength(capacity, length)); | |
11313 } | |
11314 | |
11315 | |
11303 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( | 11316 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( |
11304 int capacity, | 11317 int capacity, |
11305 int length) { | 11318 int length) { |
11306 Heap* heap = GetHeap(); | 11319 Heap* heap = GetHeap(); |
11307 // We should never end in here with a pixel or external array. | 11320 // We should never end in here with a pixel or external array. |
11308 ASSERT(!HasExternalArrayElements()); | 11321 ASSERT(!HasExternalArrayElements()); |
11309 ASSERT(!map()->is_observed()); | 11322 ASSERT(!map()->is_observed()); |
11310 | 11323 |
11311 FixedArrayBase* elems; | 11324 FixedArrayBase* elems; |
11312 { MaybeObject* maybe_obj = | 11325 { MaybeObject* maybe_obj = |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11929 return JSObject::cast(proto)->GetLocalElementAccessorPair(index); | 11942 return JSObject::cast(proto)->GetLocalElementAccessorPair(index); |
11930 } | 11943 } |
11931 | 11944 |
11932 // Check for lookup interceptor. | 11945 // Check for lookup interceptor. |
11933 if (HasIndexedInterceptor()) return NULL; | 11946 if (HasIndexedInterceptor()) return NULL; |
11934 | 11947 |
11935 return GetElementsAccessor()->GetAccessorPair(this, this, index); | 11948 return GetElementsAccessor()->GetAccessorPair(this, this, index); |
11936 } | 11949 } |
11937 | 11950 |
11938 | 11951 |
11939 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 11952 Handle<Object> JSObject::SetElementWithInterceptor( |
11940 Object* value, | 11953 Handle<JSObject> object, |
11941 PropertyAttributes attributes, | 11954 uint32_t index, |
11942 StrictModeFlag strict_mode, | 11955 Handle<Object> value, |
11943 bool check_prototype, | 11956 PropertyAttributes attributes, |
11944 SetPropertyMode set_mode) { | 11957 StrictModeFlag strict_mode, |
11945 Isolate* isolate = GetIsolate(); | 11958 bool check_prototype, |
11946 HandleScope scope(isolate); | 11959 SetPropertyMode set_mode) { |
11960 Isolate* isolate = object->GetIsolate(); | |
11947 | 11961 |
11948 // Make sure that the top context does not change when doing | 11962 // Make sure that the top context does not change when doing |
11949 // callbacks or interceptor calls. | 11963 // callbacks or interceptor calls. |
11950 AssertNoContextChange ncc(isolate); | 11964 AssertNoContextChange ncc(isolate); |
11951 | 11965 |
11952 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 11966 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); |
11953 Handle<JSObject> this_handle(this); | |
11954 Handle<Object> value_handle(value, isolate); | |
11955 if (!interceptor->setter()->IsUndefined()) { | 11967 if (!interceptor->setter()->IsUndefined()) { |
11956 v8::IndexedPropertySetterCallback setter = | 11968 v8::IndexedPropertySetterCallback setter = |
11957 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); | 11969 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); |
11958 LOG(isolate, | 11970 LOG(isolate, |
11959 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 11971 ApiIndexedPropertyAccess("interceptor-indexed-set", *object, index)); |
11960 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); | 11972 PropertyCallbackArguments args(isolate, interceptor->data(), *object, |
11973 *object); | |
11961 v8::Handle<v8::Value> result = | 11974 v8::Handle<v8::Value> result = |
11962 args.Call(setter, index, v8::Utils::ToLocal(value_handle)); | 11975 args.Call(setter, index, v8::Utils::ToLocal(value)); |
11963 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 11976 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
11964 if (!result.IsEmpty()) return *value_handle; | 11977 if (!result.IsEmpty()) return value; |
11965 } | 11978 } |
11966 MaybeObject* raw_result = | 11979 |
11967 this_handle->SetElementWithoutInterceptor(index, | 11980 return SetElementWithoutInterceptor(object, index, value, attributes, |
11968 *value_handle, | 11981 strict_mode, |
11969 attributes, | 11982 check_prototype, |
11970 strict_mode, | 11983 set_mode); |
11971 check_prototype, | |
11972 set_mode); | |
11973 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | |
11974 return raw_result; | |
11975 } | 11984 } |
11976 | 11985 |
11977 | 11986 |
11978 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 11987 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
11979 Object* structure, | 11988 Object* structure, |
11980 uint32_t index, | 11989 uint32_t index, |
11981 Object* holder) { | 11990 Object* holder) { |
11982 Isolate* isolate = GetIsolate(); | 11991 Isolate* isolate = GetIsolate(); |
11983 ASSERT(!structure->IsForeign()); | 11992 ASSERT(!structure->IsForeign()); |
11984 | 11993 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12112 return false; | 12121 return false; |
12113 } | 12122 } |
12114 FixedArray* arguments = FixedArray::cast(elements->get(1)); | 12123 FixedArray* arguments = FixedArray::cast(elements->get(1)); |
12115 return arguments->IsDictionary(); | 12124 return arguments->IsDictionary(); |
12116 } | 12125 } |
12117 | 12126 |
12118 | 12127 |
12119 // Adding n elements in fast case is O(n*n). | 12128 // Adding n elements in fast case is O(n*n). |
12120 // Note: revisit design to have dual undefined values to capture absent | 12129 // Note: revisit design to have dual undefined values to capture absent |
12121 // elements. | 12130 // elements. |
12122 MaybeObject* JSObject::SetFastElement(uint32_t index, | 12131 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object, |
12123 Object* value, | 12132 uint32_t index, |
12124 StrictModeFlag strict_mode, | 12133 Handle<Object> value, |
12125 bool check_prototype) { | 12134 StrictModeFlag strict_mode, |
12126 ASSERT(HasFastSmiOrObjectElements() || | 12135 bool check_prototype) { |
12127 HasFastArgumentsElements()); | 12136 ASSERT(object->HasFastSmiOrObjectElements() || |
12137 object->HasFastArgumentsElements()); | |
12138 | |
12139 Isolate* isolate = object->GetIsolate(); | |
12128 | 12140 |
12129 // Array optimizations rely on the prototype lookups of Array objects always | 12141 // Array optimizations rely on the prototype lookups of Array objects always |
12130 // returning undefined. If there is a store to the initial prototype object, | 12142 // returning undefined. If there is a store to the initial prototype object, |
12131 // make sure all of these optimizations are invalidated. | 12143 // make sure all of these optimizations are invalidated. |
12132 Isolate* isolate(GetIsolate()); | 12144 if (isolate->is_initial_object_prototype(*object) || |
12133 if (isolate->is_initial_object_prototype(this) || | 12145 isolate->is_initial_array_prototype(*object)) { |
12134 isolate->is_initial_array_prototype(this)) { | 12146 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, |
12135 HandleScope scope(GetIsolate()); | |
12136 map()->dependent_code()->DeoptimizeDependentCodeGroup( | |
12137 GetIsolate(), | |
12138 DependentCode::kElementsCantBeAddedGroup); | 12147 DependentCode::kElementsCantBeAddedGroup); |
12139 } | 12148 } |
12140 | 12149 |
12141 FixedArray* backing_store = FixedArray::cast(elements()); | 12150 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); |
12142 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { | 12151 if (backing_store->map() == |
12143 backing_store = FixedArray::cast(backing_store->get(1)); | 12152 isolate->heap()->non_strict_arguments_elements_map()) { |
12153 backing_store = handle(FixedArray::cast(backing_store->get(1))); | |
12144 } else { | 12154 } else { |
12145 MaybeObject* maybe = EnsureWritableFastElements(); | 12155 backing_store = EnsureWritableFastElements(object); |
12146 if (!maybe->To(&backing_store)) return maybe; | |
12147 } | 12156 } |
12148 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | 12157 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
12149 | 12158 |
12150 if (check_prototype && | 12159 if (check_prototype && |
12151 (index >= capacity || backing_store->get(index)->IsTheHole())) { | 12160 (index >= capacity || backing_store->get(index)->IsTheHole())) { |
12152 bool found; | 12161 bool found; |
12153 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 12162 Handle<Object> result = SetElementWithCallbackSetterInPrototypes( |
12154 value, | 12163 object, index, value, &found, strict_mode); |
12155 &found, | |
12156 strict_mode); | |
12157 if (found) return result; | 12164 if (found) return result; |
12158 } | 12165 } |
12159 | 12166 |
12160 uint32_t new_capacity = capacity; | 12167 uint32_t new_capacity = capacity; |
12161 // Check if the length property of this object needs to be updated. | 12168 // Check if the length property of this object needs to be updated. |
12162 uint32_t array_length = 0; | 12169 uint32_t array_length = 0; |
12163 bool must_update_array_length = false; | 12170 bool must_update_array_length = false; |
12164 bool introduces_holes = true; | 12171 bool introduces_holes = true; |
12165 if (IsJSArray()) { | 12172 if (object->IsJSArray()) { |
12166 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 12173 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); |
12167 introduces_holes = index > array_length; | 12174 introduces_holes = index > array_length; |
12168 if (index >= array_length) { | 12175 if (index >= array_length) { |
12169 must_update_array_length = true; | 12176 must_update_array_length = true; |
12170 array_length = index + 1; | 12177 array_length = index + 1; |
12171 } | 12178 } |
12172 } else { | 12179 } else { |
12173 introduces_holes = index >= capacity; | 12180 introduces_holes = index >= capacity; |
12174 } | 12181 } |
12175 | 12182 |
12176 // If the array is growing, and it's not growth by a single element at the | 12183 // If the array is growing, and it's not growth by a single element at the |
12177 // end, make sure that the ElementsKind is HOLEY. | 12184 // end, make sure that the ElementsKind is HOLEY. |
12178 ElementsKind elements_kind = GetElementsKind(); | 12185 ElementsKind elements_kind = object->GetElementsKind(); |
12179 if (introduces_holes && | 12186 if (introduces_holes && |
12180 IsFastElementsKind(elements_kind) && | 12187 IsFastElementsKind(elements_kind) && |
12181 !IsFastHoleyElementsKind(elements_kind)) { | 12188 !IsFastHoleyElementsKind(elements_kind)) { |
12182 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); | 12189 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); |
12183 MaybeObject* maybe = TransitionElementsKind(transitioned_kind); | 12190 TransitionElementsKind(object, transitioned_kind); |
12184 if (maybe->IsFailure()) return maybe; | |
12185 } | 12191 } |
12186 | 12192 |
12187 // Check if the capacity of the backing store needs to be increased, or if | 12193 // Check if the capacity of the backing store needs to be increased, or if |
12188 // a transition to slow elements is necessary. | 12194 // a transition to slow elements is necessary. |
12189 if (index >= capacity) { | 12195 if (index >= capacity) { |
12190 bool convert_to_slow = true; | 12196 bool convert_to_slow = true; |
12191 if ((index - capacity) < kMaxGap) { | 12197 if ((index - capacity) < kMaxGap) { |
12192 new_capacity = NewElementsCapacity(index + 1); | 12198 new_capacity = NewElementsCapacity(index + 1); |
12193 ASSERT(new_capacity > index); | 12199 ASSERT(new_capacity > index); |
12194 if (!ShouldConvertToSlowElements(new_capacity)) { | 12200 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
12195 convert_to_slow = false; | 12201 convert_to_slow = false; |
12196 } | 12202 } |
12197 } | 12203 } |
12198 if (convert_to_slow) { | 12204 if (convert_to_slow) { |
12199 MaybeObject* result = NormalizeElements(); | 12205 NormalizeElements(object); |
12200 if (result->IsFailure()) return result; | 12206 return SetDictionaryElement(object, index, value, NONE, strict_mode, |
12201 return SetDictionaryElement(index, value, NONE, strict_mode, | |
12202 check_prototype); | 12207 check_prototype); |
12203 } | 12208 } |
12204 } | 12209 } |
12205 // Convert to fast double elements if appropriate. | 12210 // Convert to fast double elements if appropriate. |
12206 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { | 12211 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { |
12207 // Consider fixing the boilerplate as well if we have one. | 12212 // Consider fixing the boilerplate as well if we have one. |
12208 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) | 12213 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) |
12209 ? FAST_HOLEY_DOUBLE_ELEMENTS | 12214 ? FAST_HOLEY_DOUBLE_ELEMENTS |
12210 : FAST_DOUBLE_ELEMENTS; | 12215 : FAST_DOUBLE_ELEMENTS; |
12211 | 12216 |
12212 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12217 UpdateAllocationSite(object, to_kind); |
12213 if (maybe_failure->IsFailure()) return maybe_failure; | |
12214 | 12218 |
12215 MaybeObject* maybe = | 12219 SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length); |
12216 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); | 12220 FixedDoubleArray::cast(object->elements())->set(index, value->Number()); |
12217 if (maybe->IsFailure()) return maybe; | 12221 object->ValidateElements(); |
12218 FixedDoubleArray::cast(elements())->set(index, value->Number()); | |
12219 ValidateElements(); | |
12220 return value; | 12222 return value; |
12221 } | 12223 } |
12222 // Change elements kind from Smi-only to generic FAST if necessary. | 12224 // Change elements kind from Smi-only to generic FAST if necessary. |
12223 if (HasFastSmiElements() && !value->IsSmi()) { | 12225 if (object->HasFastSmiElements() && !value->IsSmi()) { |
12224 Map* new_map; | 12226 ElementsKind kind = object->HasFastHoleyElements() |
12225 ElementsKind kind = HasFastHoleyElements() | |
12226 ? FAST_HOLEY_ELEMENTS | 12227 ? FAST_HOLEY_ELEMENTS |
12227 : FAST_ELEMENTS; | 12228 : FAST_ELEMENTS; |
12228 | 12229 |
12229 MaybeObject* maybe_failure = UpdateAllocationSite(kind); | 12230 UpdateAllocationSite(object, kind); |
12230 if (maybe_failure->IsFailure()) return maybe_failure; | 12231 object->set_map(*GetElementsTransitionMap(object, kind)); |
12231 | 12232 ASSERT(IsFastObjectElementsKind(object->GetElementsKind())); |
12232 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), | |
12233 kind); | |
12234 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
12235 | |
12236 set_map(new_map); | |
12237 } | 12233 } |
12238 // Increase backing store capacity if that's been decided previously. | 12234 // Increase backing store capacity if that's been decided previously. |
12239 if (new_capacity != capacity) { | 12235 if (new_capacity != capacity) { |
12240 FixedArray* new_elements; | |
12241 SetFastElementsCapacitySmiMode smi_mode = | 12236 SetFastElementsCapacitySmiMode smi_mode = |
12242 value->IsSmi() && HasFastSmiElements() | 12237 value->IsSmi() && object->HasFastSmiElements() |
12243 ? kAllowSmiElements | 12238 ? kAllowSmiElements |
12244 : kDontAllowSmiElements; | 12239 : kDontAllowSmiElements; |
12245 { MaybeObject* maybe = | 12240 Handle<FixedArray> new_elements = |
12246 SetFastElementsCapacityAndLength(new_capacity, | 12241 SetFastElementsCapacityAndLength(object, new_capacity, array_length, |
12247 array_length, | 12242 smi_mode); |
12248 smi_mode); | 12243 new_elements->set(index, *value); |
12249 if (!maybe->To(&new_elements)) return maybe; | 12244 object->ValidateElements(); |
12250 } | |
12251 new_elements->set(index, value); | |
12252 ValidateElements(); | |
12253 return value; | 12245 return value; |
12254 } | 12246 } |
12255 | 12247 |
12256 // Finally, set the new element and length. | 12248 // Finally, set the new element and length. |
12257 ASSERT(elements()->IsFixedArray()); | 12249 ASSERT(object->elements()->IsFixedArray()); |
12258 backing_store->set(index, value); | 12250 backing_store->set(index, *value); |
12259 if (must_update_array_length) { | 12251 if (must_update_array_length) { |
12260 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); | 12252 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); |
12261 } | 12253 } |
12262 return value; | 12254 return value; |
12263 } | 12255 } |
12264 | 12256 |
12265 | 12257 |
12266 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, | 12258 Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object, |
12267 Object* value_raw, | 12259 uint32_t index, |
12268 PropertyAttributes attributes, | 12260 Handle<Object> value, |
12269 StrictModeFlag strict_mode, | 12261 PropertyAttributes attributes, |
12270 bool check_prototype, | 12262 StrictModeFlag strict_mode, |
12271 SetPropertyMode set_mode) { | 12263 bool check_prototype, |
12272 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 12264 SetPropertyMode set_mode) { |
12273 Isolate* isolate = GetIsolate(); | 12265 ASSERT(object->HasDictionaryElements() || |
12274 Heap* heap = isolate->heap(); | 12266 object->HasDictionaryArgumentsElements()); |
12275 Handle<JSObject> self(this); | 12267 Isolate* isolate = object->GetIsolate(); |
12276 Handle<Object> value(value_raw, isolate); | |
12277 | 12268 |
12278 // Insert element in the dictionary. | 12269 // Insert element in the dictionary. |
12279 Handle<FixedArray> elements(FixedArray::cast(this->elements())); | 12270 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
12280 bool is_arguments = | 12271 bool is_arguments = |
12281 (elements->map() == heap->non_strict_arguments_elements_map()); | 12272 (elements->map() == isolate->heap()->non_strict_arguments_elements_map()); |
12282 Handle<SeededNumberDictionary> dictionary(is_arguments | 12273 Handle<SeededNumberDictionary> dictionary(is_arguments |
12283 ? SeededNumberDictionary::cast(elements->get(1)) | 12274 ? SeededNumberDictionary::cast(elements->get(1)) |
12284 : SeededNumberDictionary::cast(*elements)); | 12275 : SeededNumberDictionary::cast(*elements)); |
12285 | 12276 |
12286 int entry = dictionary->FindEntry(index); | 12277 int entry = dictionary->FindEntry(index); |
12287 if (entry != SeededNumberDictionary::kNotFound) { | 12278 if (entry != SeededNumberDictionary::kNotFound) { |
12288 Handle<Object> element(dictionary->ValueAt(entry), isolate); | 12279 Handle<Object> element(dictionary->ValueAt(entry), isolate); |
12289 PropertyDetails details = dictionary->DetailsAt(entry); | 12280 PropertyDetails details = dictionary->DetailsAt(entry); |
12290 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { | 12281 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { |
12291 Handle<Object> result = SetElementWithCallback(self, element, index, | 12282 return SetElementWithCallback(object, element, index, value, object, |
12292 value, self, strict_mode); | 12283 strict_mode); |
12293 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
12294 return *result; | |
12295 } else { | 12284 } else { |
12296 dictionary->UpdateMaxNumberKey(index); | 12285 dictionary->UpdateMaxNumberKey(index); |
12297 // If a value has not been initialized we allow writing to it even if it | 12286 // If a value has not been initialized we allow writing to it even if it |
12298 // is read-only (a declared const that has not been initialized). If a | 12287 // is read-only (a declared const that has not been initialized). If a |
12299 // value is being defined we skip attribute checks completely. | 12288 // value is being defined we skip attribute checks completely. |
12300 if (set_mode == DEFINE_PROPERTY) { | 12289 if (set_mode == DEFINE_PROPERTY) { |
12301 details = PropertyDetails( | 12290 details = PropertyDetails( |
12302 attributes, NORMAL, details.dictionary_index()); | 12291 attributes, NORMAL, details.dictionary_index()); |
12303 dictionary->DetailsAtPut(entry, details); | 12292 dictionary->DetailsAtPut(entry, details); |
12304 } else if (details.IsReadOnly() && !element->IsTheHole()) { | 12293 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
12305 if (strict_mode == kNonStrictMode) { | 12294 if (strict_mode == kNonStrictMode) { |
12306 return isolate->heap()->undefined_value(); | 12295 return isolate->factory()->undefined_value(); |
12307 } else { | 12296 } else { |
12308 Handle<Object> holder(this, isolate); | |
12309 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12297 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12310 Handle<Object> args[2] = { number, holder }; | 12298 Handle<Object> args[2] = { number, object }; |
12311 Handle<Object> error = | 12299 Handle<Object> error = |
12312 isolate->factory()->NewTypeError("strict_read_only_property", | 12300 isolate->factory()->NewTypeError("strict_read_only_property", |
12313 HandleVector(args, 2)); | 12301 HandleVector(args, 2)); |
12314 return isolate->Throw(*error); | 12302 isolate->Throw(*error); |
12303 return Handle<Object>(); | |
12315 } | 12304 } |
12316 } | 12305 } |
12317 // Elements of the arguments object in slow mode might be slow aliases. | 12306 // Elements of the arguments object in slow mode might be slow aliases. |
12318 if (is_arguments && element->IsAliasedArgumentsEntry()) { | 12307 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
12319 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*element); | 12308 Handle<AliasedArgumentsEntry> entry = |
12320 Context* context = Context::cast(elements->get(0)); | 12309 Handle<AliasedArgumentsEntry>::cast(element); |
12310 Handle<Context> context(Context::cast(elements->get(0))); | |
12321 int context_index = entry->aliased_context_slot(); | 12311 int context_index = entry->aliased_context_slot(); |
12322 ASSERT(!context->get(context_index)->IsTheHole()); | 12312 ASSERT(!context->get(context_index)->IsTheHole()); |
12323 context->set(context_index, *value); | 12313 context->set(context_index, *value); |
12324 // For elements that are still writable we keep slow aliasing. | 12314 // For elements that are still writable we keep slow aliasing. |
12325 if (!details.IsReadOnly()) value = element; | 12315 if (!details.IsReadOnly()) value = element; |
12326 } | 12316 } |
12327 dictionary->ValueAtPut(entry, *value); | 12317 dictionary->ValueAtPut(entry, *value); |
12328 } | 12318 } |
12329 } else { | 12319 } else { |
12330 // Index not already used. Look for an accessor in the prototype chain. | 12320 // Index not already used. Look for an accessor in the prototype chain. |
12331 // Can cause GC! | 12321 // Can cause GC! |
12332 if (check_prototype) { | 12322 if (check_prototype) { |
12333 bool found; | 12323 bool found; |
12334 MaybeObject* result = SetElementWithCallbackSetterInPrototypes( | 12324 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, |
12335 index, *value, &found, strict_mode); | 12325 index, value, &found, strict_mode); |
12336 if (found) return result; | 12326 if (found) return result; |
12337 } | 12327 } |
12328 | |
12338 // When we set the is_extensible flag to false we always force the | 12329 // When we set the is_extensible flag to false we always force the |
12339 // element into dictionary mode (and force them to stay there). | 12330 // element into dictionary mode (and force them to stay there). |
12340 if (!self->map()->is_extensible()) { | 12331 if (!object->map()->is_extensible()) { |
12341 if (strict_mode == kNonStrictMode) { | 12332 if (strict_mode == kNonStrictMode) { |
12342 return isolate->heap()->undefined_value(); | 12333 return isolate->factory()->undefined_value(); |
12343 } else { | 12334 } else { |
12344 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12335 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12345 Handle<String> name = isolate->factory()->NumberToString(number); | 12336 Handle<String> name = isolate->factory()->NumberToString(number); |
12346 Handle<Object> args[1] = { name }; | 12337 Handle<Object> args[1] = { name }; |
12347 Handle<Object> error = | 12338 Handle<Object> error = |
12348 isolate->factory()->NewTypeError("object_not_extensible", | 12339 isolate->factory()->NewTypeError("object_not_extensible", |
12349 HandleVector(args, 1)); | 12340 HandleVector(args, 1)); |
12350 return isolate->Throw(*error); | 12341 isolate->Throw(*error); |
12342 return Handle<Object>(); | |
12351 } | 12343 } |
12352 } | 12344 } |
12353 FixedArrayBase* new_dictionary; | 12345 Handle<SeededNumberDictionary> new_dictionary; |
Michael Starzinger
2013/11/13 12:24:45
nit: Let's merge the declaration of "new_dictionar
rafaelw
2013/11/13 20:56:47
Done.
| |
12354 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 12346 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
12355 MaybeObject* maybe = dictionary->AddNumberEntry(index, *value, details); | 12347 new_dictionary = SeededNumberDictionary::AddNumberEntry(dictionary, index, |
12356 if (!maybe->To(&new_dictionary)) return maybe; | 12348 value, |
12357 if (*dictionary != SeededNumberDictionary::cast(new_dictionary)) { | 12349 details); |
12350 if (*dictionary != *new_dictionary) { | |
12358 if (is_arguments) { | 12351 if (is_arguments) { |
12359 elements->set(1, new_dictionary); | 12352 elements->set(1, *new_dictionary); |
12360 } else { | 12353 } else { |
12361 self->set_elements(new_dictionary); | 12354 object->set_elements(*new_dictionary); |
12362 } | 12355 } |
12363 dictionary = | 12356 dictionary = new_dictionary; |
12364 handle(SeededNumberDictionary::cast(new_dictionary), isolate); | |
12365 } | 12357 } |
12366 } | 12358 } |
12367 | 12359 |
12368 // Update the array length if this JSObject is an array. | 12360 // Update the array length if this JSObject is an array. |
12369 if (self->IsJSArray()) { | 12361 if (object->IsJSArray()) { |
12370 MaybeObject* result = | 12362 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index, |
12371 JSArray::cast(*self)->JSArrayUpdateLengthFromIndex(index, *value); | 12363 value); |
12372 if (result->IsFailure()) return result; | |
12373 } | 12364 } |
12374 | 12365 |
12375 // Attempt to put this object back in fast case. | 12366 // Attempt to put this object back in fast case. |
12376 if (self->ShouldConvertToFastElements()) { | 12367 if (object->ShouldConvertToFastElements()) { |
12377 uint32_t new_length = 0; | 12368 uint32_t new_length = 0; |
12378 if (self->IsJSArray()) { | 12369 if (object->IsJSArray()) { |
12379 CHECK(JSArray::cast(*self)->length()->ToArrayIndex(&new_length)); | 12370 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&new_length)); |
12380 } else { | 12371 } else { |
12381 new_length = dictionary->max_number_key() + 1; | 12372 new_length = dictionary->max_number_key() + 1; |
12382 } | 12373 } |
12383 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays | 12374 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays |
12384 ? kAllowSmiElements | 12375 ? kAllowSmiElements |
12385 : kDontAllowSmiElements; | 12376 : kDontAllowSmiElements; |
12386 bool has_smi_only_elements = false; | 12377 bool has_smi_only_elements = false; |
12387 bool should_convert_to_fast_double_elements = | 12378 bool should_convert_to_fast_double_elements = |
12388 self->ShouldConvertToFastDoubleElements(&has_smi_only_elements); | 12379 object->ShouldConvertToFastDoubleElements(&has_smi_only_elements); |
12389 if (has_smi_only_elements) { | 12380 if (has_smi_only_elements) { |
12390 smi_mode = kForceSmiElements; | 12381 smi_mode = kForceSmiElements; |
12391 } | 12382 } |
12392 MaybeObject* result = should_convert_to_fast_double_elements | 12383 |
12393 ? self->SetFastDoubleElementsCapacityAndLength(new_length, new_length) | 12384 if (should_convert_to_fast_double_elements) { |
12394 : self->SetFastElementsCapacityAndLength( | 12385 SetFastDoubleElementsCapacityAndLength(object, new_length, new_length); |
12395 new_length, new_length, smi_mode); | 12386 } else { |
12396 self->ValidateElements(); | 12387 SetFastElementsCapacityAndLength(object, new_length, new_length, |
12397 if (result->IsFailure()) return result; | 12388 smi_mode); |
12389 } | |
12390 object->ValidateElements(); | |
12398 #ifdef DEBUG | 12391 #ifdef DEBUG |
12399 if (FLAG_trace_normalization) { | 12392 if (FLAG_trace_normalization) { |
12400 PrintF("Object elements are fast case again:\n"); | 12393 PrintF("Object elements are fast case again:\n"); |
12401 Print(); | 12394 object->Print(); |
12402 } | 12395 } |
12403 #endif | 12396 #endif |
12404 } | 12397 } |
12405 return *value; | 12398 return value; |
12406 } | 12399 } |
12407 | 12400 |
12408 | 12401 Handle<Object> JSObject::SetFastDoubleElement( |
12409 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( | 12402 Handle<JSObject> object, |
12410 uint32_t index, | 12403 uint32_t index, |
12411 Object* value, | 12404 Handle<Object> value, |
12412 StrictModeFlag strict_mode, | 12405 StrictModeFlag strict_mode, |
12413 bool check_prototype) { | 12406 bool check_prototype) { |
12414 ASSERT(HasFastDoubleElements()); | 12407 ASSERT(object->HasFastDoubleElements()); |
12415 | 12408 |
12416 FixedArrayBase* base_elms = FixedArrayBase::cast(elements()); | 12409 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); |
12417 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); | 12410 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); |
12418 | 12411 |
12419 // If storing to an element that isn't in the array, pass the store request | 12412 // If storing to an element that isn't in the array, pass the store request |
12420 // up the prototype chain before storing in the receiver's elements. | 12413 // up the prototype chain before storing in the receiver's elements. |
12421 if (check_prototype && | 12414 if (check_prototype && |
12422 (index >= elms_length || | 12415 (index >= elms_length || |
12423 FixedDoubleArray::cast(base_elms)->is_the_hole(index))) { | 12416 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) { |
12424 bool found; | 12417 bool found; |
12425 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 12418 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, |
12426 value, | 12419 index, value, &found, strict_mode); |
12427 &found, | |
12428 strict_mode); | |
12429 if (found) return result; | 12420 if (found) return result; |
12430 } | 12421 } |
12431 | 12422 |
12432 // If the value object is not a heap number, switch to fast elements and try | 12423 // If the value object is not a heap number, switch to fast elements and try |
12433 // again. | 12424 // again. |
12434 bool value_is_smi = value->IsSmi(); | 12425 bool value_is_smi = value->IsSmi(); |
12435 bool introduces_holes = true; | 12426 bool introduces_holes = true; |
12436 uint32_t length = elms_length; | 12427 uint32_t length = elms_length; |
12437 if (IsJSArray()) { | 12428 if (object->IsJSArray()) { |
12438 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); | 12429 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length)); |
12439 introduces_holes = index > length; | 12430 introduces_holes = index > length; |
12440 } else { | 12431 } else { |
12441 introduces_holes = index >= elms_length; | 12432 introduces_holes = index >= elms_length; |
12442 } | 12433 } |
12443 | 12434 |
12444 if (!value->IsNumber()) { | 12435 if (!value->IsNumber()) { |
12445 MaybeObject* maybe_obj = SetFastElementsCapacityAndLength( | 12436 SetFastElementsCapacityAndLength(object, elms_length, length, |
12446 elms_length, | 12437 kDontAllowSmiElements); |
12447 length, | 12438 Handle<Object> result = SetFastElement(object, index, value, strict_mode, |
12448 kDontAllowSmiElements); | 12439 check_prototype); |
12449 if (maybe_obj->IsFailure()) return maybe_obj; | 12440 RETURN_IF_EMPTY_HANDLE_VALUE(object->GetIsolate(), result, |
12450 maybe_obj = SetFastElement(index, value, strict_mode, check_prototype); | 12441 Handle<Object>()); |
12451 if (maybe_obj->IsFailure()) return maybe_obj; | 12442 object->ValidateElements(); |
12452 ValidateElements(); | 12443 return result; |
12453 return maybe_obj; | |
12454 } | 12444 } |
12455 | 12445 |
12456 double double_value = value_is_smi | 12446 double double_value = value_is_smi |
12457 ? static_cast<double>(Smi::cast(value)->value()) | 12447 ? static_cast<double>(Handle<Smi>::cast(value)->value()) |
12458 : HeapNumber::cast(value)->value(); | 12448 : Handle<HeapNumber>::cast(value)->value(); |
12459 | 12449 |
12460 // If the array is growing, and it's not growth by a single element at the | 12450 // If the array is growing, and it's not growth by a single element at the |
12461 // end, make sure that the ElementsKind is HOLEY. | 12451 // end, make sure that the ElementsKind is HOLEY. |
12462 ElementsKind elements_kind = GetElementsKind(); | 12452 ElementsKind elements_kind = object->GetElementsKind(); |
12463 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) { | 12453 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) { |
12464 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); | 12454 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); |
12465 MaybeObject* maybe = TransitionElementsKind(transitioned_kind); | 12455 TransitionElementsKind(object, transitioned_kind); |
12466 if (maybe->IsFailure()) return maybe; | |
12467 } | 12456 } |
12468 | 12457 |
12469 // Check whether there is extra space in the fixed array. | 12458 // Check whether there is extra space in the fixed array. |
12470 if (index < elms_length) { | 12459 if (index < elms_length) { |
12471 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); | 12460 Handle<FixedDoubleArray> elms(FixedDoubleArray::cast(object->elements())); |
12472 elms->set(index, double_value); | 12461 elms->set(index, double_value); |
12473 if (IsJSArray()) { | 12462 if (object->IsJSArray()) { |
12474 // Update the length of the array if needed. | 12463 // Update the length of the array if needed. |
12475 uint32_t array_length = 0; | 12464 uint32_t array_length = 0; |
12476 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 12465 CHECK( |
12466 Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); | |
12477 if (index >= array_length) { | 12467 if (index >= array_length) { |
12478 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | 12468 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1)); |
12479 } | 12469 } |
12480 } | 12470 } |
12481 return value; | 12471 return value; |
12482 } | 12472 } |
12483 | 12473 |
12484 // Allow gap in fast case. | 12474 // Allow gap in fast case. |
12485 if ((index - elms_length) < kMaxGap) { | 12475 if ((index - elms_length) < kMaxGap) { |
12486 // Try allocating extra space. | 12476 // Try allocating extra space. |
12487 int new_capacity = NewElementsCapacity(index+1); | 12477 int new_capacity = NewElementsCapacity(index+1); |
12488 if (!ShouldConvertToSlowElements(new_capacity)) { | 12478 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
12489 ASSERT(static_cast<uint32_t>(new_capacity) > index); | 12479 ASSERT(static_cast<uint32_t>(new_capacity) > index); |
12490 MaybeObject* maybe_obj = | 12480 SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1); |
12491 SetFastDoubleElementsCapacityAndLength(new_capacity, index + 1); | 12481 FixedDoubleArray::cast(object->elements())->set(index, double_value); |
12492 if (maybe_obj->IsFailure()) return maybe_obj; | 12482 object->ValidateElements(); |
12493 FixedDoubleArray::cast(elements())->set(index, double_value); | |
12494 ValidateElements(); | |
12495 return value; | 12483 return value; |
12496 } | 12484 } |
12497 } | 12485 } |
12498 | 12486 |
12499 // Otherwise default to slow case. | 12487 // Otherwise default to slow case. |
12500 ASSERT(HasFastDoubleElements()); | 12488 ASSERT(object->HasFastDoubleElements()); |
12501 ASSERT(map()->has_fast_double_elements()); | 12489 ASSERT(object->map()->has_fast_double_elements()); |
12502 ASSERT(elements()->IsFixedDoubleArray()); | 12490 ASSERT(object->elements()->IsFixedDoubleArray()); |
12503 Object* obj; | 12491 |
12504 { MaybeObject* maybe_obj = NormalizeElements(); | 12492 NormalizeElements(object); |
12505 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12493 ASSERT(object->HasDictionaryElements()); |
12506 } | 12494 return SetElement(object, index, value, NONE, strict_mode, check_prototype); |
12507 ASSERT(HasDictionaryElements()); | |
12508 return SetElement(index, value, NONE, strict_mode, check_prototype); | |
12509 } | 12495 } |
12510 | 12496 |
12511 | 12497 |
12512 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, | 12498 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, |
12513 uint32_t index, | 12499 uint32_t index, |
12514 Handle<Object> value, | 12500 Handle<Object> value, |
12515 PropertyAttributes attributes, | 12501 PropertyAttributes attributes, |
12516 StrictModeFlag strict_mode) { | 12502 StrictModeFlag strict_mode) { |
12517 if (object->IsJSProxy()) { | 12503 if (object->IsJSProxy()) { |
12518 return JSProxy::SetElementWithHandler( | 12504 return JSProxy::SetElementWithHandler( |
12519 Handle<JSProxy>::cast(object), object, index, value, strict_mode); | 12505 Handle<JSProxy>::cast(object), object, index, value, strict_mode); |
12520 } | 12506 } |
12521 return JSObject::SetElement( | 12507 return JSObject::SetElement( |
12522 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); | 12508 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); |
12523 } | 12509 } |
12524 | 12510 |
12525 | 12511 |
12526 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, | 12512 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, |
12527 uint32_t index, | 12513 uint32_t index, |
12528 Handle<Object> value, | 12514 Handle<Object> value, |
12529 StrictModeFlag strict_mode) { | 12515 StrictModeFlag strict_mode) { |
12530 ASSERT(!object->HasExternalArrayElements()); | 12516 ASSERT(!object->HasExternalArrayElements()); |
12531 CALL_HEAP_FUNCTION( | 12517 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); |
12532 object->GetIsolate(), | |
12533 object->SetElement(index, *value, NONE, strict_mode, false), | |
12534 Object); | |
12535 } | 12518 } |
12536 | 12519 |
12537 | 12520 |
12538 Handle<Object> JSObject::SetElement(Handle<JSObject> object, | 12521 Handle<Object> JSObject::SetElement(Handle<JSObject> object, |
12539 uint32_t index, | 12522 uint32_t index, |
12540 Handle<Object> value, | 12523 Handle<Object> value, |
12541 PropertyAttributes attr, | 12524 PropertyAttributes attributes, |
12542 StrictModeFlag strict_mode, | 12525 StrictModeFlag strict_mode, |
12543 bool check_prototype, | 12526 bool check_prototype, |
12544 SetPropertyMode set_mode) { | 12527 SetPropertyMode set_mode) { |
12528 Isolate* isolate = object->GetIsolate(); | |
12529 | |
12545 if (object->HasExternalArrayElements()) { | 12530 if (object->HasExternalArrayElements()) { |
12546 if (!value->IsNumber() && !value->IsUndefined()) { | 12531 if (!value->IsNumber() && !value->IsUndefined()) { |
12547 bool has_exception; | 12532 bool has_exception; |
12548 Handle<Object> number = | 12533 Handle<Object> number = |
12549 Execution::ToNumber(object->GetIsolate(), value, &has_exception); | 12534 Execution::ToNumber(isolate, value, &has_exception); |
12550 if (has_exception) return Handle<Object>(); | 12535 if (has_exception) return Handle<Object>(); |
12551 value = number; | 12536 value = number; |
12552 } | 12537 } |
12553 } | 12538 } |
12554 CALL_HEAP_FUNCTION( | |
12555 object->GetIsolate(), | |
12556 object->SetElement(index, *value, attr, strict_mode, check_prototype, | |
12557 set_mode), | |
12558 Object); | |
12559 } | |
12560 | |
12561 | |
12562 MaybeObject* JSObject::SetElement(uint32_t index, | |
12563 Object* value_raw, | |
12564 PropertyAttributes attributes, | |
12565 StrictModeFlag strict_mode, | |
12566 bool check_prototype, | |
12567 SetPropertyMode set_mode) { | |
12568 Isolate* isolate = GetIsolate(); | |
12569 | 12539 |
12570 // Check access rights if needed. | 12540 // Check access rights if needed. |
12571 if (IsAccessCheckNeeded()) { | 12541 if (object->IsAccessCheckNeeded()) { |
12572 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 12542 if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_SET)) { |
12573 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 12543 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); |
12574 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 12544 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
12575 return value_raw; | 12545 return value; |
12576 } | 12546 } |
12577 } | 12547 } |
12578 | 12548 |
12579 if (IsJSGlobalProxy()) { | 12549 if (object->IsJSGlobalProxy()) { |
12580 Object* proto = GetPrototype(); | 12550 Handle<Object> proto(object->GetPrototype(), isolate); |
12581 if (proto->IsNull()) return value_raw; | 12551 if (proto->IsNull()) return value; |
12582 ASSERT(proto->IsJSGlobalObject()); | 12552 ASSERT(proto->IsJSGlobalObject()); |
12583 return JSObject::cast(proto)->SetElement(index, | 12553 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
12584 value_raw, | 12554 strict_mode, |
12585 attributes, | 12555 check_prototype, |
12586 strict_mode, | 12556 set_mode); |
12587 check_prototype, | |
12588 set_mode); | |
12589 } | 12557 } |
12590 | 12558 |
12591 // Don't allow element properties to be redefined for external arrays. | 12559 // Don't allow element properties to be redefined for external arrays. |
12592 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { | 12560 if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { |
12593 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12561 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12594 Handle<Object> args[] = { handle(this, isolate), number }; | 12562 Handle<Object> args[] = { object, number }; |
12595 Handle<Object> error = isolate->factory()->NewTypeError( | 12563 Handle<Object> error = isolate->factory()->NewTypeError( |
12596 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12564 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
12597 return isolate->Throw(*error); | 12565 isolate->Throw(*error); |
12566 return Handle<Object>(); | |
12598 } | 12567 } |
12599 | 12568 |
12600 // Normalize the elements to enable attributes on the property. | 12569 // Normalize the elements to enable attributes on the property. |
12601 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12570 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
12602 SeededNumberDictionary* dictionary; | 12571 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
12603 MaybeObject* maybe_object = NormalizeElements(); | |
12604 if (!maybe_object->To(&dictionary)) return maybe_object; | |
12605 // Make sure that we never go back to fast case. | 12572 // Make sure that we never go back to fast case. |
12606 dictionary->set_requires_slow_elements(); | 12573 dictionary->set_requires_slow_elements(); |
12607 } | 12574 } |
12608 | 12575 |
12609 if (!(FLAG_harmony_observation && map()->is_observed())) { | 12576 if (!(FLAG_harmony_observation && object->map()->is_observed())) { |
12610 return HasIndexedInterceptor() | 12577 return object->HasIndexedInterceptor() |
12611 ? SetElementWithInterceptor( | 12578 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, |
12612 index, value_raw, attributes, strict_mode, check_prototype, set_mode) | 12579 check_prototype, |
12613 : SetElementWithoutInterceptor( | 12580 set_mode) |
12614 index, value_raw, attributes, strict_mode, check_prototype, set_mode); | 12581 : SetElementWithoutInterceptor(object, index, value, attributes, |
12615 } | 12582 strict_mode, |
12616 | 12583 check_prototype, |
12617 // From here on, everything has to be handlified. | 12584 set_mode); |
12618 Handle<JSObject> self(this); | 12585 } |
12619 Handle<Object> value(value_raw, isolate); | 12586 |
12620 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index); | 12587 PropertyAttributes old_attributes = object->GetLocalElementAttribute(index); |
12621 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 12588 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
12622 Handle<Object> old_length_handle; | 12589 Handle<Object> old_length_handle; |
12623 Handle<Object> new_length_handle; | 12590 Handle<Object> new_length_handle; |
12624 | 12591 |
12625 if (old_attributes != ABSENT) { | 12592 if (old_attributes != ABSENT) { |
12626 if (self->GetLocalElementAccessorPair(index) == NULL) | 12593 if (object->GetLocalElementAccessorPair(index) == NULL) |
12627 old_value = Object::GetElement(isolate, self, index); | 12594 old_value = Object::GetElement(isolate, object, index); |
12628 } else if (self->IsJSArray()) { | 12595 } else if (object->IsJSArray()) { |
12629 // Store old array length in case adding an element grows the array. | 12596 // Store old array length in case adding an element grows the array. |
12630 old_length_handle = handle(Handle<JSArray>::cast(self)->length(), isolate); | 12597 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
12598 isolate); | |
12631 } | 12599 } |
12632 | 12600 |
12633 // Check for lookup interceptor | 12601 // Check for lookup interceptor |
12634 MaybeObject* result = self->HasIndexedInterceptor() | 12602 Handle<Object> result = object->HasIndexedInterceptor() |
12635 ? self->SetElementWithInterceptor( | 12603 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, |
12636 index, *value, attributes, strict_mode, check_prototype, set_mode) | 12604 check_prototype, |
12637 : self->SetElementWithoutInterceptor( | 12605 set_mode) |
12638 index, *value, attributes, strict_mode, check_prototype, set_mode); | 12606 : SetElementWithoutInterceptor(object, index, value, attributes, |
12639 | 12607 strict_mode, |
12640 Handle<Object> hresult; | 12608 check_prototype, |
12641 if (!result->ToHandle(&hresult, isolate)) return result; | 12609 set_mode); |
12610 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>()); | |
12642 | 12611 |
12643 Handle<String> name = isolate->factory()->Uint32ToString(index); | 12612 Handle<String> name = isolate->factory()->Uint32ToString(index); |
12644 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index); | 12613 PropertyAttributes new_attributes = object->GetLocalElementAttribute(index); |
12645 if (old_attributes == ABSENT) { | 12614 if (old_attributes == ABSENT) { |
12646 if (self->IsJSArray() && | 12615 if (object->IsJSArray() && |
12647 !old_length_handle->SameValue(Handle<JSArray>::cast(self)->length())) { | 12616 !old_length_handle->SameValue( |
12648 new_length_handle = handle(Handle<JSArray>::cast(self)->length(), | 12617 Handle<JSArray>::cast(object)->length())) { |
12618 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), | |
12649 isolate); | 12619 isolate); |
12650 uint32_t old_length = 0; | 12620 uint32_t old_length = 0; |
12651 uint32_t new_length = 0; | 12621 uint32_t new_length = 0; |
12652 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 12622 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
12653 CHECK(new_length_handle->ToArrayIndex(&new_length)); | 12623 CHECK(new_length_handle->ToArrayIndex(&new_length)); |
12654 | 12624 |
12655 BeginPerformSplice(Handle<JSArray>::cast(self)); | 12625 BeginPerformSplice(Handle<JSArray>::cast(object)); |
12656 EnqueueChangeRecord(self, "add", name, old_value); | 12626 EnqueueChangeRecord(object, "add", name, old_value); |
12657 EnqueueChangeRecord(self, "update", isolate->factory()->length_string(), | 12627 EnqueueChangeRecord(object, "update", isolate->factory()->length_string(), |
12658 old_length_handle); | 12628 old_length_handle); |
12659 EndPerformSplice(Handle<JSArray>::cast(self)); | 12629 EndPerformSplice(Handle<JSArray>::cast(object)); |
12660 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12630 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
12661 EnqueueSpliceRecord(Handle<JSArray>::cast(self), old_length, deleted, | 12631 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, |
12662 new_length - old_length); | 12632 new_length - old_length); |
12663 } else { | 12633 } else { |
12664 EnqueueChangeRecord(self, "add", name, old_value); | 12634 EnqueueChangeRecord(object, "add", name, old_value); |
12665 } | 12635 } |
12666 } else if (old_value->IsTheHole()) { | 12636 } else if (old_value->IsTheHole()) { |
12667 EnqueueChangeRecord(self, "reconfigure", name, old_value); | 12637 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
12668 } else { | 12638 } else { |
12669 Handle<Object> new_value = Object::GetElement(isolate, self, index); | 12639 Handle<Object> new_value = Object::GetElement(isolate, object, index); |
12670 bool value_changed = !old_value->SameValue(*new_value); | 12640 bool value_changed = !old_value->SameValue(*new_value); |
12671 if (old_attributes != new_attributes) { | 12641 if (old_attributes != new_attributes) { |
12672 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | 12642 if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
12673 EnqueueChangeRecord(self, "reconfigure", name, old_value); | 12643 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
12674 } else if (value_changed) { | 12644 } else if (value_changed) { |
12675 EnqueueChangeRecord(self, "update", name, old_value); | 12645 EnqueueChangeRecord(object, "update", name, old_value); |
12676 } | 12646 } |
12677 } | 12647 } |
12678 | 12648 |
12679 return *hresult; | 12649 return result; |
12680 } | 12650 } |
12681 | 12651 |
12682 | 12652 |
12683 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 12653 Handle<Object> JSObject::SetElementWithoutInterceptor( |
12684 Object* value, | 12654 Handle<JSObject> object, |
12685 PropertyAttributes attr, | 12655 uint32_t index, |
12686 StrictModeFlag strict_mode, | 12656 Handle<Object> value, |
12687 bool check_prototype, | 12657 PropertyAttributes attributes, |
12688 SetPropertyMode set_mode) { | 12658 StrictModeFlag strict_mode, |
12689 ASSERT(HasDictionaryElements() || | 12659 bool check_prototype, |
12690 HasDictionaryArgumentsElements() || | 12660 SetPropertyMode set_mode) { |
12691 (attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); | 12661 ASSERT(object->HasDictionaryElements() || |
12692 Isolate* isolate = GetIsolate(); | 12662 object->HasDictionaryArgumentsElements() || |
12663 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); | |
12664 Isolate* isolate = object->GetIsolate(); | |
12693 if (FLAG_trace_external_array_abuse && | 12665 if (FLAG_trace_external_array_abuse && |
12694 IsExternalArrayElementsKind(GetElementsKind())) { | 12666 IsExternalArrayElementsKind(object->GetElementsKind())) { |
12695 CheckArrayAbuse(this, "external elements write", index); | 12667 CheckArrayAbuse(*object, "external elements write", index); |
12696 } | 12668 } |
12697 if (FLAG_trace_js_array_abuse && | 12669 if (FLAG_trace_js_array_abuse && |
12698 !IsExternalArrayElementsKind(GetElementsKind())) { | 12670 !IsExternalArrayElementsKind(object->GetElementsKind())) { |
12699 if (IsJSArray()) { | 12671 if (object->IsJSArray()) { |
12700 CheckArrayAbuse(this, "elements write", index, true); | 12672 CheckArrayAbuse(*object, "elements write", index, true); |
12701 } | 12673 } |
12702 } | 12674 } |
12703 switch (GetElementsKind()) { | 12675 switch (object->GetElementsKind()) { |
12704 case FAST_SMI_ELEMENTS: | 12676 case FAST_SMI_ELEMENTS: |
12705 case FAST_ELEMENTS: | 12677 case FAST_ELEMENTS: |
12706 case FAST_HOLEY_SMI_ELEMENTS: | 12678 case FAST_HOLEY_SMI_ELEMENTS: |
12707 case FAST_HOLEY_ELEMENTS: | 12679 case FAST_HOLEY_ELEMENTS: |
12708 return SetFastElement(index, value, strict_mode, check_prototype); | 12680 return SetFastElement(object, index, value, strict_mode, check_prototype); |
12709 case FAST_DOUBLE_ELEMENTS: | 12681 case FAST_DOUBLE_ELEMENTS: |
12710 case FAST_HOLEY_DOUBLE_ELEMENTS: | 12682 case FAST_HOLEY_DOUBLE_ELEMENTS: |
12711 return SetFastDoubleElement(index, value, strict_mode, check_prototype); | 12683 return SetFastDoubleElement(object, index, value, strict_mode, |
12684 check_prototype); | |
12712 case EXTERNAL_PIXEL_ELEMENTS: { | 12685 case EXTERNAL_PIXEL_ELEMENTS: { |
12713 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 12686 ExternalPixelArray* pixels = ExternalPixelArray::cast(object->elements()); |
12714 return pixels->SetValue(index, value); | 12687 return handle(pixels->SetValue(index, *value), isolate); |
12715 } | 12688 } |
12716 case EXTERNAL_BYTE_ELEMENTS: { | 12689 case EXTERNAL_BYTE_ELEMENTS: { |
12717 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 12690 Handle<ExternalByteArray> array( |
12718 return array->SetValue(index, value); | 12691 ExternalByteArray::cast(object->elements())); |
12692 return ExternalByteArray::SetValue(array, index, value); | |
12719 } | 12693 } |
12720 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 12694 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
12721 ExternalUnsignedByteArray* array = | 12695 Handle<ExternalUnsignedByteArray> array( |
12722 ExternalUnsignedByteArray::cast(elements()); | 12696 ExternalUnsignedByteArray::cast(object->elements())); |
12723 return array->SetValue(index, value); | 12697 return ExternalUnsignedByteArray::SetValue(array, index, value); |
12724 } | 12698 } |
12725 case EXTERNAL_SHORT_ELEMENTS: { | 12699 case EXTERNAL_SHORT_ELEMENTS: { |
12726 ExternalShortArray* array = ExternalShortArray::cast(elements()); | 12700 Handle<ExternalShortArray> array(ExternalShortArray::cast( |
12727 return array->SetValue(index, value); | 12701 object->elements())); |
12702 return ExternalShortArray::SetValue(array, index, value); | |
12728 } | 12703 } |
12729 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { | 12704 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { |
12730 ExternalUnsignedShortArray* array = | 12705 Handle<ExternalUnsignedShortArray> array( |
12731 ExternalUnsignedShortArray::cast(elements()); | 12706 ExternalUnsignedShortArray::cast(object->elements())); |
12732 return array->SetValue(index, value); | 12707 return ExternalUnsignedShortArray::SetValue(array, index, value); |
12733 } | 12708 } |
12734 case EXTERNAL_INT_ELEMENTS: { | 12709 case EXTERNAL_INT_ELEMENTS: { |
12735 ExternalIntArray* array = ExternalIntArray::cast(elements()); | 12710 Handle<ExternalIntArray> array( |
12736 return array->SetValue(index, value); | 12711 ExternalIntArray::cast(object->elements())); |
12712 return ExternalIntArray::SetValue(array, index, value); | |
12737 } | 12713 } |
12738 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 12714 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
12739 ExternalUnsignedIntArray* array = | 12715 Handle<ExternalUnsignedIntArray> array( |
12740 ExternalUnsignedIntArray::cast(elements()); | 12716 ExternalUnsignedIntArray::cast(object->elements())); |
12741 return array->SetValue(index, value); | 12717 return ExternalUnsignedIntArray::SetValue(array, index, value); |
12742 } | 12718 } |
12743 case EXTERNAL_FLOAT_ELEMENTS: { | 12719 case EXTERNAL_FLOAT_ELEMENTS: { |
12744 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); | 12720 Handle<ExternalFloatArray> array( |
12745 return array->SetValue(index, value); | 12721 ExternalFloatArray::cast(object->elements())); |
12722 return ExternalFloatArray::SetValue(array, index, value); | |
12746 } | 12723 } |
12747 case EXTERNAL_DOUBLE_ELEMENTS: { | 12724 case EXTERNAL_DOUBLE_ELEMENTS: { |
12748 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); | 12725 Handle<ExternalDoubleArray> array( |
12749 return array->SetValue(index, value); | 12726 ExternalDoubleArray::cast(object->elements())); |
12727 return ExternalDoubleArray::SetValue(array, index, value); | |
12750 } | 12728 } |
12751 case DICTIONARY_ELEMENTS: | 12729 case DICTIONARY_ELEMENTS: |
12752 return SetDictionaryElement(index, value, attr, strict_mode, | 12730 return SetDictionaryElement(object, index, value, attributes, strict_mode, |
12753 check_prototype, set_mode); | 12731 check_prototype, |
12732 set_mode); | |
12754 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 12733 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
12755 FixedArray* parameter_map = FixedArray::cast(elements()); | 12734 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
12756 uint32_t length = parameter_map->length(); | 12735 uint32_t length = parameter_map->length(); |
12757 Object* probe = | 12736 Handle<Object> probe = index < length - 2 ? |
12758 (index < length - 2) ? parameter_map->get(index + 2) : NULL; | 12737 Handle<Object>(parameter_map->get(index + 2), isolate) : |
12759 if (probe != NULL && !probe->IsTheHole()) { | 12738 Handle<Object>(); |
12760 Context* context = Context::cast(parameter_map->get(0)); | 12739 if (!probe.is_null() && !probe->IsTheHole()) { |
12761 int context_index = Smi::cast(probe)->value(); | 12740 Handle<Context> context(Context::cast(parameter_map->get(0))); |
12741 int context_index = Handle<Smi>::cast(probe)->value(); | |
12762 ASSERT(!context->get(context_index)->IsTheHole()); | 12742 ASSERT(!context->get(context_index)->IsTheHole()); |
12763 context->set(context_index, value); | 12743 context->set(context_index, *value); |
12764 // Redefining attributes of an aliased element destroys fast aliasing. | 12744 // Redefining attributes of an aliased element destroys fast aliasing. |
12765 if (set_mode == SET_PROPERTY || attr == NONE) return value; | 12745 if (set_mode == SET_PROPERTY || attributes == NONE) return value; |
12766 parameter_map->set_the_hole(index + 2); | 12746 parameter_map->set_the_hole(index + 2); |
12767 // For elements that are still writable we re-establish slow aliasing. | 12747 // For elements that are still writable we re-establish slow aliasing. |
12768 if ((attr & READ_ONLY) == 0) { | 12748 if ((attributes & READ_ONLY) == 0) { |
12769 MaybeObject* maybe_entry = | 12749 value = Handle<Object>::cast( |
12770 isolate->heap()->AllocateAliasedArgumentsEntry(context_index); | 12750 isolate->factory()->NewAliasedArgumentsEntry(context_index)); |
12771 if (!maybe_entry->ToObject(&value)) return maybe_entry; | |
12772 } | 12751 } |
12773 } | 12752 } |
12774 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 12753 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
12775 if (arguments->IsDictionary()) { | 12754 if (arguments->IsDictionary()) { |
12776 return SetDictionaryElement(index, value, attr, strict_mode, | 12755 return SetDictionaryElement(object, index, value, attributes, |
12777 check_prototype, set_mode); | 12756 strict_mode, |
12757 check_prototype, | |
12758 set_mode); | |
12778 } else { | 12759 } else { |
12779 return SetFastElement(index, value, strict_mode, check_prototype); | 12760 return SetFastElement(object, index, value, strict_mode, |
12761 check_prototype); | |
12780 } | 12762 } |
12781 } | 12763 } |
12782 } | 12764 } |
12783 // All possible cases have been handled above. Add a return to avoid the | 12765 // All possible cases have been handled above. Add a return to avoid the |
12784 // complaints from the compiler. | 12766 // complaints from the compiler. |
12785 UNREACHABLE(); | 12767 UNREACHABLE(); |
12786 return isolate->heap()->null_value(); | 12768 return isolate->factory()->null_value(); |
12787 } | 12769 } |
12788 | 12770 |
12789 | 12771 |
12790 void JSObject::TransitionElementsKind(Handle<JSObject> object, | 12772 void JSObject::TransitionElementsKind(Handle<JSObject> object, |
12791 ElementsKind to_kind) { | 12773 ElementsKind to_kind) { |
12792 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), | 12774 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
12793 object->TransitionElementsKind(to_kind)); | 12775 object->TransitionElementsKind(to_kind)); |
12794 } | 12776 } |
12795 | 12777 |
12796 | 12778 |
12797 bool AllocationSite::IsNestedSite() { | 12779 bool AllocationSite::IsNestedSite() { |
12798 ASSERT(FLAG_trace_track_allocation_sites); | 12780 ASSERT(FLAG_trace_track_allocation_sites); |
12799 Object* current = GetHeap()->allocation_sites_list(); | 12781 Object* current = GetHeap()->allocation_sites_list(); |
12800 while (current != NULL && current->IsAllocationSite()) { | 12782 while (current != NULL && current->IsAllocationSite()) { |
12801 AllocationSite* current_site = AllocationSite::cast(current); | 12783 AllocationSite* current_site = AllocationSite::cast(current); |
12802 if (current_site->nested_site() == this) { | 12784 if (current_site->nested_site() == this) { |
12803 return true; | 12785 return true; |
12804 } | 12786 } |
12805 current = current_site->weak_next(); | 12787 current = current_site->weak_next(); |
12806 } | 12788 } |
12807 return false; | 12789 return false; |
12808 } | 12790 } |
12809 | 12791 |
12810 | 12792 |
12793 void JSObject::UpdateAllocationSite(Handle<JSObject> object, | |
12794 ElementsKind to_kind) { | |
12795 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), | |
12796 object->UpdateAllocationSite(to_kind)); | |
12797 } | |
12798 | |
12799 | |
12811 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { | 12800 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { |
12812 if (!FLAG_track_allocation_sites || !IsJSArray()) { | 12801 if (!FLAG_track_allocation_sites || !IsJSArray()) { |
12813 return this; | 12802 return this; |
12814 } | 12803 } |
12815 | 12804 |
12816 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); | 12805 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); |
12817 if (memento == NULL || !memento->IsValid()) { | 12806 if (memento == NULL || !memento->IsValid()) { |
12818 return this; | 12807 return this; |
12819 } | 12808 } |
12820 | 12809 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12948 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { | 12937 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { |
12949 return false; | 12938 return false; |
12950 } | 12939 } |
12951 | 12940 |
12952 // Transitions from HOLEY -> PACKED are not allowed. | 12941 // Transitions from HOLEY -> PACKED are not allowed. |
12953 return !IsFastHoleyElementsKind(from_kind) || | 12942 return !IsFastHoleyElementsKind(from_kind) || |
12954 IsFastHoleyElementsKind(to_kind); | 12943 IsFastHoleyElementsKind(to_kind); |
12955 } | 12944 } |
12956 | 12945 |
12957 | 12946 |
12947 void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array, | |
12948 uint32_t index, | |
12949 Handle<Object> value) { | |
12950 CALL_HEAP_FUNCTION_VOID(array->GetIsolate(), | |
12951 array->JSArrayUpdateLengthFromIndex(index, *value)); | |
12952 } | |
12953 | |
12954 | |
12958 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, | 12955 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
12959 Object* value) { | 12956 Object* value) { |
12960 uint32_t old_len = 0; | 12957 uint32_t old_len = 0; |
12961 CHECK(length()->ToArrayIndex(&old_len)); | 12958 CHECK(length()->ToArrayIndex(&old_len)); |
12962 // Check to see if we need to update the length. For now, we make | 12959 // Check to see if we need to update the length. For now, we make |
12963 // sure that the length stays within 32-bits (unsigned). | 12960 // sure that the length stays within 32-bits (unsigned). |
12964 if (index >= old_len && index != 0xffffffff) { | 12961 if (index >= old_len && index != 0xffffffff) { |
12965 Object* len; | 12962 Object* len; |
12966 { MaybeObject* maybe_len = | 12963 { MaybeObject* maybe_len = |
12967 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); | 12964 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13053 // Fall through if packing is not guaranteed. | 13050 // Fall through if packing is not guaranteed. |
13054 case FAST_HOLEY_SMI_ELEMENTS: | 13051 case FAST_HOLEY_SMI_ELEMENTS: |
13055 case FAST_HOLEY_ELEMENTS: | 13052 case FAST_HOLEY_ELEMENTS: |
13056 backing_store = FixedArray::cast(backing_store_base); | 13053 backing_store = FixedArray::cast(backing_store_base); |
13057 *capacity = backing_store->length(); | 13054 *capacity = backing_store->length(); |
13058 for (int i = 0; i < *capacity; ++i) { | 13055 for (int i = 0; i < *capacity; ++i) { |
13059 if (!backing_store->get(i)->IsTheHole()) ++(*used); | 13056 if (!backing_store->get(i)->IsTheHole()) ++(*used); |
13060 } | 13057 } |
13061 break; | 13058 break; |
13062 case DICTIONARY_ELEMENTS: { | 13059 case DICTIONARY_ELEMENTS: { |
13063 SeededNumberDictionary* dictionary = | 13060 SeededNumberDictionary* dictionary = element_dictionary(); |
13064 SeededNumberDictionary::cast(FixedArray::cast(elements())); | |
13065 *capacity = dictionary->Capacity(); | 13061 *capacity = dictionary->Capacity(); |
13066 *used = dictionary->NumberOfElements(); | 13062 *used = dictionary->NumberOfElements(); |
13067 break; | 13063 break; |
13068 } | 13064 } |
13069 case FAST_DOUBLE_ELEMENTS: | 13065 case FAST_DOUBLE_ELEMENTS: |
13070 if (IsJSArray()) { | 13066 if (IsJSArray()) { |
13071 *capacity = backing_store_base->length(); | 13067 *capacity = backing_store_base->length(); |
13072 *used = Smi::cast(JSArray::cast(this)->length())->value(); | 13068 *used = Smi::cast(JSArray::cast(this)->length())->value(); |
13073 break; | 13069 break; |
13074 } | 13070 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13153 SeededNumberDictionary::kEntrySize; | 13149 SeededNumberDictionary::kEntrySize; |
13154 return 2 * dictionary_size >= array_size; | 13150 return 2 * dictionary_size >= array_size; |
13155 } | 13151 } |
13156 | 13152 |
13157 | 13153 |
13158 bool JSObject::ShouldConvertToFastDoubleElements( | 13154 bool JSObject::ShouldConvertToFastDoubleElements( |
13159 bool* has_smi_only_elements) { | 13155 bool* has_smi_only_elements) { |
13160 *has_smi_only_elements = false; | 13156 *has_smi_only_elements = false; |
13161 if (FLAG_unbox_double_arrays) { | 13157 if (FLAG_unbox_double_arrays) { |
13162 ASSERT(HasDictionaryElements()); | 13158 ASSERT(HasDictionaryElements()); |
13163 SeededNumberDictionary* dictionary = | 13159 SeededNumberDictionary* dictionary = element_dictionary(); |
13164 SeededNumberDictionary::cast(elements()); | |
13165 bool found_double = false; | 13160 bool found_double = false; |
13166 for (int i = 0; i < dictionary->Capacity(); i++) { | 13161 for (int i = 0; i < dictionary->Capacity(); i++) { |
13167 Object* key = dictionary->KeyAt(i); | 13162 Object* key = dictionary->KeyAt(i); |
13168 if (key->IsNumber()) { | 13163 if (key->IsNumber()) { |
13169 Object* value = dictionary->ValueAt(i); | 13164 Object* value = dictionary->ValueAt(i); |
13170 if (!value->IsNumber()) return false; | 13165 if (!value->IsNumber()) return false; |
13171 if (!value->IsSmi()) { | 13166 if (!value->IsSmi()) { |
13172 found_double = true; | 13167 found_double = true; |
13173 } | 13168 } |
13174 } | 13169 } |
(...skipping 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14532 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); | 14527 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); |
14533 dict->CopyValuesTo(*fast_elements); | 14528 dict->CopyValuesTo(*fast_elements); |
14534 object->ValidateElements(); | 14529 object->ValidateElements(); |
14535 | 14530 |
14536 object->set_map_and_elements(*new_map, *fast_elements); | 14531 object->set_map_and_elements(*new_map, *fast_elements); |
14537 } else if (object->HasExternalArrayElements()) { | 14532 } else if (object->HasExternalArrayElements()) { |
14538 // External arrays cannot have holes or undefined elements. | 14533 // External arrays cannot have holes or undefined elements. |
14539 return handle(Smi::FromInt( | 14534 return handle(Smi::FromInt( |
14540 ExternalArray::cast(object->elements())->length()), isolate); | 14535 ExternalArray::cast(object->elements())->length()), isolate); |
14541 } else if (!object->HasFastDoubleElements()) { | 14536 } else if (!object->HasFastDoubleElements()) { |
14542 JSObject::EnsureWritableFastElements(object); | 14537 EnsureWritableFastElements(object); |
14543 } | 14538 } |
14544 ASSERT(object->HasFastSmiOrObjectElements() || | 14539 ASSERT(object->HasFastSmiOrObjectElements() || |
14545 object->HasFastDoubleElements()); | 14540 object->HasFastDoubleElements()); |
14546 | 14541 |
14547 // Collect holes at the end, undefined before that and the rest at the | 14542 // Collect holes at the end, undefined before that and the rest at the |
14548 // start, and return the number of non-hole, non-undefined values. | 14543 // start, and return the number of non-hole, non-undefined values. |
14549 | 14544 |
14550 Handle<FixedArrayBase> elements_base(object->elements()); | 14545 Handle<FixedArrayBase> elements_base(object->elements()); |
14551 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); | 14546 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); |
14552 if (limit > elements_length) { | 14547 if (limit > elements_length) { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14739 // Clamp undefined to zero (default). All other types have been | 14734 // Clamp undefined to zero (default). All other types have been |
14740 // converted to a number type further up in the call chain. | 14735 // converted to a number type further up in the call chain. |
14741 ASSERT(value->IsUndefined()); | 14736 ASSERT(value->IsUndefined()); |
14742 } | 14737 } |
14743 receiver->set(index, cast_value); | 14738 receiver->set(index, cast_value); |
14744 } | 14739 } |
14745 return heap->NumberFromInt32(cast_value); | 14740 return heap->NumberFromInt32(cast_value); |
14746 } | 14741 } |
14747 | 14742 |
14748 | 14743 |
14744 Handle<Object> ExternalByteArray::SetValue(Handle<ExternalByteArray> array, | |
14745 uint32_t index, | |
14746 Handle<Object> value) { | |
14747 CALL_HEAP_FUNCTION(array->GetIsolate(), | |
14748 array->SetValue(index, *value), | |
14749 Object); | |
14750 } | |
14751 | |
14752 | |
14749 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { | 14753 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { |
14750 return ExternalArrayIntSetter<ExternalByteArray, int8_t> | 14754 return ExternalArrayIntSetter<ExternalByteArray, int8_t> |
14751 (GetHeap(), this, index, value); | 14755 (GetHeap(), this, index, value); |
14752 } | 14756 } |
14753 | 14757 |
14754 | 14758 |
14759 Handle<Object> ExternalUnsignedByteArray::SetValue( | |
14760 Handle<ExternalUnsignedByteArray> array, | |
14761 uint32_t index, | |
14762 Handle<Object> value) { | |
14763 CALL_HEAP_FUNCTION(array->GetIsolate(), | |
14764 array->SetValue(index, *value), | |
14765 Object); | |
14766 } | |
14767 | |
14768 | |
14755 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, | 14769 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, |
14756 Object* value) { | 14770 Object* value) { |
14757 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> | 14771 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> |
14758 (GetHeap(), this, index, value); | 14772 (GetHeap(), this, index, value); |
14759 } | 14773 } |
14760 | 14774 |
14761 | 14775 |
14776 Handle<Object> ExternalShortArray::SetValue( | |
14777 Handle<ExternalShortArray> 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 | |
14762 MaybeObject* ExternalShortArray::SetValue(uint32_t index, | 14786 MaybeObject* ExternalShortArray::SetValue(uint32_t index, |
14763 Object* value) { | 14787 Object* value) { |
14764 return ExternalArrayIntSetter<ExternalShortArray, int16_t> | 14788 return ExternalArrayIntSetter<ExternalShortArray, int16_t> |
14765 (GetHeap(), this, index, value); | 14789 (GetHeap(), this, index, value); |
14766 } | 14790 } |
14767 | 14791 |
14768 | 14792 |
14793 Handle<Object> ExternalUnsignedShortArray::SetValue( | |
14794 Handle<ExternalUnsignedShortArray> array, | |
14795 uint32_t index, | |
14796 Handle<Object> value) { | |
14797 CALL_HEAP_FUNCTION(array->GetIsolate(), | |
14798 array->SetValue(index, *value), | |
14799 Object); | |
14800 } | |
14801 | |
14802 | |
14769 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, | 14803 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, |
14770 Object* value) { | 14804 Object* value) { |
14771 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> | 14805 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> |
14772 (GetHeap(), this, index, value); | 14806 (GetHeap(), this, index, value); |
14773 } | 14807 } |
14774 | 14808 |
14775 | 14809 |
14810 Handle<Object> ExternalIntArray::SetValue(Handle<ExternalIntArray> 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 | |
14776 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { | 14819 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { |
14777 return ExternalArrayIntSetter<ExternalIntArray, int32_t> | 14820 return ExternalArrayIntSetter<ExternalIntArray, int32_t> |
14778 (GetHeap(), this, index, value); | 14821 (GetHeap(), this, index, value); |
14779 } | 14822 } |
14780 | 14823 |
14781 | 14824 |
14825 Handle<Object> ExternalUnsignedIntArray::SetValue( | |
14826 Handle<ExternalUnsignedIntArray> array, | |
14827 uint32_t index, | |
14828 Handle<Object> value) { | |
14829 CALL_HEAP_FUNCTION(array->GetIsolate(), | |
14830 array->SetValue(index, *value), | |
14831 Object); | |
14832 } | |
14833 | |
14834 | |
14782 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { | 14835 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { |
14783 uint32_t cast_value = 0; | 14836 uint32_t cast_value = 0; |
14784 Heap* heap = GetHeap(); | 14837 Heap* heap = GetHeap(); |
14785 if (index < static_cast<uint32_t>(length())) { | 14838 if (index < static_cast<uint32_t>(length())) { |
14786 if (value->IsSmi()) { | 14839 if (value->IsSmi()) { |
14787 int int_value = Smi::cast(value)->value(); | 14840 int int_value = Smi::cast(value)->value(); |
14788 cast_value = static_cast<uint32_t>(int_value); | 14841 cast_value = static_cast<uint32_t>(int_value); |
14789 } else if (value->IsHeapNumber()) { | 14842 } else if (value->IsHeapNumber()) { |
14790 double double_value = HeapNumber::cast(value)->value(); | 14843 double double_value = HeapNumber::cast(value)->value(); |
14791 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); | 14844 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); |
14792 } else { | 14845 } else { |
14793 // Clamp undefined to zero (default). All other types have been | 14846 // Clamp undefined to zero (default). All other types have been |
14794 // converted to a number type further up in the call chain. | 14847 // converted to a number type further up in the call chain. |
14795 ASSERT(value->IsUndefined()); | 14848 ASSERT(value->IsUndefined()); |
14796 } | 14849 } |
14797 set(index, cast_value); | 14850 set(index, cast_value); |
14798 } | 14851 } |
14799 return heap->NumberFromUint32(cast_value); | 14852 return heap->NumberFromUint32(cast_value); |
14800 } | 14853 } |
14801 | 14854 |
14802 | 14855 |
14856 Handle<Object> ExternalFloatArray::SetValue(Handle<ExternalFloatArray> array, | |
14857 uint32_t index, | |
14858 Handle<Object> value) { | |
14859 CALL_HEAP_FUNCTION(array->GetIsolate(), | |
14860 array->SetValue(index, *value), | |
14861 Object); | |
14862 } | |
14863 | |
14864 | |
14803 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { | 14865 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { |
14804 float cast_value = static_cast<float>(OS::nan_value()); | 14866 float cast_value = static_cast<float>(OS::nan_value()); |
14805 Heap* heap = GetHeap(); | 14867 Heap* heap = GetHeap(); |
14806 if (index < static_cast<uint32_t>(length())) { | 14868 if (index < static_cast<uint32_t>(length())) { |
14807 if (value->IsSmi()) { | 14869 if (value->IsSmi()) { |
14808 int int_value = Smi::cast(value)->value(); | 14870 int int_value = Smi::cast(value)->value(); |
14809 cast_value = static_cast<float>(int_value); | 14871 cast_value = static_cast<float>(int_value); |
14810 } else if (value->IsHeapNumber()) { | 14872 } else if (value->IsHeapNumber()) { |
14811 double double_value = HeapNumber::cast(value)->value(); | 14873 double double_value = HeapNumber::cast(value)->value(); |
14812 cast_value = static_cast<float>(double_value); | 14874 cast_value = static_cast<float>(double_value); |
14813 } else { | 14875 } else { |
14814 // Clamp undefined to NaN (default). All other types have been | 14876 // Clamp undefined to NaN (default). All other types have been |
14815 // converted to a number type further up in the call chain. | 14877 // converted to a number type further up in the call chain. |
14816 ASSERT(value->IsUndefined()); | 14878 ASSERT(value->IsUndefined()); |
14817 } | 14879 } |
14818 set(index, cast_value); | 14880 set(index, cast_value); |
14819 } | 14881 } |
14820 return heap->AllocateHeapNumber(cast_value); | 14882 return heap->AllocateHeapNumber(cast_value); |
14821 } | 14883 } |
14822 | 14884 |
14823 | 14885 |
14886 Handle<Object> ExternalDoubleArray::SetValue(Handle<ExternalDoubleArray> array, | |
14887 uint32_t index, | |
14888 Handle<Object> value) { | |
14889 CALL_HEAP_FUNCTION(array->GetIsolate(), | |
14890 array->SetValue(index, *value), | |
14891 Object); | |
14892 } | |
14893 | |
14894 | |
14824 MaybeObject* ExternalDoubleArray::SetValue(uint32_t index, Object* value) { | 14895 MaybeObject* ExternalDoubleArray::SetValue(uint32_t index, Object* value) { |
14825 double double_value = OS::nan_value(); | 14896 double double_value = OS::nan_value(); |
14826 Heap* heap = GetHeap(); | 14897 Heap* heap = GetHeap(); |
14827 if (index < static_cast<uint32_t>(length())) { | 14898 if (index < static_cast<uint32_t>(length())) { |
14828 if (value->IsSmi()) { | 14899 if (value->IsSmi()) { |
14829 int int_value = Smi::cast(value)->value(); | 14900 int int_value = Smi::cast(value)->value(); |
14830 double_value = static_cast<double>(int_value); | 14901 double_value = static_cast<double>(int_value); |
14831 } else if (value->IsHeapNumber()) { | 14902 } else if (value->IsHeapNumber()) { |
14832 double_value = HeapNumber::cast(value)->value(); | 14903 double_value = HeapNumber::cast(value)->value(); |
14833 } else { | 14904 } else { |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15435 return; | 15506 return; |
15436 } | 15507 } |
15437 // Update max key value. | 15508 // Update max key value. |
15438 Object* max_index_object = get(kMaxNumberKeyIndex); | 15509 Object* max_index_object = get(kMaxNumberKeyIndex); |
15439 if (!max_index_object->IsSmi() || max_number_key() < key) { | 15510 if (!max_index_object->IsSmi() || max_number_key() < key) { |
15440 FixedArray::set(kMaxNumberKeyIndex, | 15511 FixedArray::set(kMaxNumberKeyIndex, |
15441 Smi::FromInt(key << kRequiresSlowElementsTagSize)); | 15512 Smi::FromInt(key << kRequiresSlowElementsTagSize)); |
15442 } | 15513 } |
15443 } | 15514 } |
15444 | 15515 |
15516 Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry( | |
15517 Handle<SeededNumberDictionary> dictionary, | |
15518 uint32_t key, | |
15519 Handle<Object> value, | |
15520 PropertyDetails details) { | |
15521 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | |
15522 dictionary->AddNumberEntry(key, *value, details), | |
15523 SeededNumberDictionary); | |
15524 } | |
15445 | 15525 |
15446 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key, | 15526 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key, |
15447 Object* value, | 15527 Object* value, |
15448 PropertyDetails details) { | 15528 PropertyDetails details) { |
15449 UpdateMaxNumberKey(key); | 15529 UpdateMaxNumberKey(key); |
15450 SLOW_ASSERT(this->FindEntry(key) == kNotFound); | 15530 SLOW_ASSERT(this->FindEntry(key) == kNotFound); |
15451 return Add(key, value, details); | 15531 return Add(key, value, details); |
15452 } | 15532 } |
15453 | 15533 |
15454 | 15534 |
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16530 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16610 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16531 static const char* error_messages_[] = { | 16611 static const char* error_messages_[] = { |
16532 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16612 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16533 }; | 16613 }; |
16534 #undef ERROR_MESSAGES_TEXTS | 16614 #undef ERROR_MESSAGES_TEXTS |
16535 return error_messages_[reason]; | 16615 return error_messages_[reason]; |
16536 } | 16616 } |
16537 | 16617 |
16538 | 16618 |
16539 } } // namespace v8::internal | 16619 } } // namespace v8::internal |
OLD | NEW |