Chromium Code Reviews| 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 |