| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 result = DeepCopyBoilerplate(jsObject); | 149 result = DeepCopyBoilerplate(jsObject); |
| 150 if (result->IsFailure()) return result; | 150 if (result->IsFailure()) return result; |
| 151 result = copy->SetProperty(keyString, result, NONE); | 151 result = copy->SetProperty(keyString, result, NONE); |
| 152 if (result->IsFailure()) return result; | 152 if (result->IsFailure()) return result; |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 } | 155 } |
| 156 | 156 |
| 157 // Deep copy local elements. | 157 // Deep copy local elements. |
| 158 // Pixel elements cannot be created using an object literal. | 158 // Pixel elements cannot be created using an object literal. |
| 159 ASSERT(!copy->HasPixelElements()); | 159 ASSERT(!copy->HasPixelElements() && !copy->HasExternalArrayElements()); |
| 160 switch (copy->GetElementsKind()) { | 160 switch (copy->GetElementsKind()) { |
| 161 case JSObject::FAST_ELEMENTS: { | 161 case JSObject::FAST_ELEMENTS: { |
| 162 FixedArray* elements = FixedArray::cast(copy->elements()); | 162 FixedArray* elements = FixedArray::cast(copy->elements()); |
| 163 WriteBarrierMode mode = elements->GetWriteBarrierMode(); | 163 WriteBarrierMode mode = elements->GetWriteBarrierMode(); |
| 164 for (int i = 0; i < elements->length(); i++) { | 164 for (int i = 0; i < elements->length(); i++) { |
| 165 Object* value = elements->get(i); | 165 Object* value = elements->get(i); |
| 166 if (value->IsJSObject()) { | 166 if (value->IsJSObject()) { |
| 167 JSObject* jsObject = JSObject::cast(value); | 167 JSObject* jsObject = JSObject::cast(value); |
| 168 result = DeepCopyBoilerplate(jsObject); | 168 result = DeepCopyBoilerplate(jsObject); |
| 169 if (result->IsFailure()) return result; | 169 if (result->IsFailure()) return result; |
| (...skipping 2403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2573 HandleVector(args, 2)); | 2573 HandleVector(args, 2)); |
| 2574 return Top::Throw(*error); | 2574 return Top::Throw(*error); |
| 2575 } | 2575 } |
| 2576 | 2576 |
| 2577 // Check if the given key is an array index. | 2577 // Check if the given key is an array index. |
| 2578 uint32_t index; | 2578 uint32_t index; |
| 2579 if (Array::IndexFromObject(*key, &index)) { | 2579 if (Array::IndexFromObject(*key, &index)) { |
| 2580 return GetElementOrCharAt(object, index); | 2580 return GetElementOrCharAt(object, index); |
| 2581 } | 2581 } |
| 2582 | 2582 |
| 2583 // If the target object is a JSObject and has an ExternalArray as |
| 2584 // its elements, we need to check for negative indices and report |
| 2585 // exceptions. Indices larger than the array's length will be caught |
| 2586 // elsewhere. |
| 2587 if (key->IsSmi() && Smi::cast(*key)->value() < 0) { |
| 2588 if (object->IsJSObject() && |
| 2589 JSObject::cast(*object)->HasExternalArrayElements()) { |
| 2590 uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value()); |
| 2591 return Top::Throw(*Factory::NewIndexError(index)); |
| 2592 } |
| 2593 } |
| 2594 |
| 2583 // Convert the key to a string - possibly by calling back into JavaScript. | 2595 // Convert the key to a string - possibly by calling back into JavaScript. |
| 2584 Handle<String> name; | 2596 Handle<String> name; |
| 2585 if (key->IsString()) { | 2597 if (key->IsString()) { |
| 2586 name = Handle<String>::cast(key); | 2598 name = Handle<String>::cast(key); |
| 2587 } else { | 2599 } else { |
| 2588 bool has_pending_exception = false; | 2600 bool has_pending_exception = false; |
| 2589 Handle<Object> converted = | 2601 Handle<Object> converted = |
| 2590 Execution::ToString(key, &has_pending_exception); | 2602 Execution::ToString(key, &has_pending_exception); |
| 2591 if (has_pending_exception) return Failure::Exception(); | 2603 if (has_pending_exception) return Failure::Exception(); |
| 2592 name = Handle<String>::cast(converted); | 2604 name = Handle<String>::cast(converted); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2707 // assignments. | 2719 // assignments. |
| 2708 if (js_object->IsStringObjectWithCharacterAt(index)) { | 2720 if (js_object->IsStringObjectWithCharacterAt(index)) { |
| 2709 return *value; | 2721 return *value; |
| 2710 } | 2722 } |
| 2711 | 2723 |
| 2712 Handle<Object> result = SetElement(js_object, index, value); | 2724 Handle<Object> result = SetElement(js_object, index, value); |
| 2713 if (result.is_null()) return Failure::Exception(); | 2725 if (result.is_null()) return Failure::Exception(); |
| 2714 return *value; | 2726 return *value; |
| 2715 } | 2727 } |
| 2716 | 2728 |
| 2729 // If the target object is a JSObject and has an ExternalArray as |
| 2730 // its elements, we need to check for negative indices and report |
| 2731 // exceptions. Indices larger than the array's length will be caught |
| 2732 // elsewhere. |
| 2733 if (key->IsSmi() && Smi::cast(*key)->value() < 0) { |
| 2734 if (object->IsJSObject() && |
| 2735 JSObject::cast(*object)->HasExternalArrayElements()) { |
| 2736 uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value()); |
| 2737 return Top::Throw(*Factory::NewIndexError(index)); |
| 2738 } |
| 2739 } |
| 2740 |
| 2717 if (key->IsString()) { | 2741 if (key->IsString()) { |
| 2718 Handle<Object> result; | 2742 Handle<Object> result; |
| 2719 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 2743 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
| 2720 ASSERT(attr == NONE); | 2744 ASSERT(attr == NONE); |
| 2721 result = SetElement(js_object, index, value); | 2745 result = SetElement(js_object, index, value); |
| 2722 } else { | 2746 } else { |
| 2723 Handle<String> key_string = Handle<String>::cast(key); | 2747 Handle<String> key_string = Handle<String>::cast(key); |
| 2724 key_string->TryFlattenIfNotFlat(); | 2748 key_string->TryFlattenIfNotFlat(); |
| 2725 result = SetProperty(js_object, key_string, value, attr); | 2749 result = SetProperty(js_object, key_string, value, attr); |
| 2726 } | 2750 } |
| (...skipping 2539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5266 } | 5290 } |
| 5267 | 5291 |
| 5268 private: | 5292 private: |
| 5269 Handle<FixedArray> storage_; | 5293 Handle<FixedArray> storage_; |
| 5270 uint32_t index_limit_; | 5294 uint32_t index_limit_; |
| 5271 bool fast_elements_; | 5295 bool fast_elements_; |
| 5272 uint32_t index_offset_; | 5296 uint32_t index_offset_; |
| 5273 }; | 5297 }; |
| 5274 | 5298 |
| 5275 | 5299 |
| 5300 template<class ExternalArrayClass, class ElementType> |
| 5301 static uint32_t IterateExternalArrayElements(Handle<JSObject> receiver, |
| 5302 bool elements_are_ints, |
| 5303 bool elements_are_guaranteed_smis, |
| 5304 uint32_t range, |
| 5305 ArrayConcatVisitor* visitor) { |
| 5306 Handle<ExternalArrayClass> array( |
| 5307 ExternalArrayClass::cast(receiver->elements())); |
| 5308 uint32_t len = Min(static_cast<uint32_t>(array->length()), range); |
| 5309 |
| 5310 if (visitor != NULL) { |
| 5311 if (elements_are_ints) { |
| 5312 if (elements_are_guaranteed_smis) { |
| 5313 for (uint32_t j = 0; j < len; j++) { |
| 5314 Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get(j)))); |
| 5315 visitor->visit(j, e); |
| 5316 } |
| 5317 } else { |
| 5318 for (uint32_t j = 0; j < len; j++) { |
| 5319 int64_t val = static_cast<int64_t>(array->get(j)); |
| 5320 if (Smi::IsValid(static_cast<intptr_t>(val))) { |
| 5321 Handle<Smi> e(Smi::FromInt(static_cast<int>(val))); |
| 5322 visitor->visit(j, e); |
| 5323 } else { |
| 5324 Handle<Object> e( |
| 5325 Heap::AllocateHeapNumber(static_cast<ElementType>(val))); |
| 5326 visitor->visit(j, e); |
| 5327 } |
| 5328 } |
| 5329 } |
| 5330 } else { |
| 5331 for (uint32_t j = 0; j < len; j++) { |
| 5332 Handle<Object> e(Heap::AllocateHeapNumber(array->get(j))); |
| 5333 visitor->visit(j, e); |
| 5334 } |
| 5335 } |
| 5336 } |
| 5337 |
| 5338 return len; |
| 5339 } |
| 5340 |
| 5276 /** | 5341 /** |
| 5277 * A helper function that visits elements of a JSObject. Only elements | 5342 * A helper function that visits elements of a JSObject. Only elements |
| 5278 * whose index between 0 and range (exclusive) are visited. | 5343 * whose index between 0 and range (exclusive) are visited. |
| 5279 * | 5344 * |
| 5280 * If the third parameter, visitor, is not NULL, the visitor is called | 5345 * If the third parameter, visitor, is not NULL, the visitor is called |
| 5281 * with parameters, 'visitor_index_offset + element index' and the element. | 5346 * with parameters, 'visitor_index_offset + element index' and the element. |
| 5282 * | 5347 * |
| 5283 * It returns the number of visisted elements. | 5348 * It returns the number of visisted elements. |
| 5284 */ | 5349 */ |
| 5285 static uint32_t IterateElements(Handle<JSObject> receiver, | 5350 static uint32_t IterateElements(Handle<JSObject> receiver, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 5315 | 5380 |
| 5316 for (uint32_t j = 0; j < len; j++) { | 5381 for (uint32_t j = 0; j < len; j++) { |
| 5317 num_of_elements++; | 5382 num_of_elements++; |
| 5318 if (visitor != NULL) { | 5383 if (visitor != NULL) { |
| 5319 Handle<Smi> e(Smi::FromInt(pixels->get(j))); | 5384 Handle<Smi> e(Smi::FromInt(pixels->get(j))); |
| 5320 visitor->visit(j, e); | 5385 visitor->visit(j, e); |
| 5321 } | 5386 } |
| 5322 } | 5387 } |
| 5323 break; | 5388 break; |
| 5324 } | 5389 } |
| 5390 case JSObject::EXTERNAL_BYTE_ELEMENTS: { |
| 5391 num_of_elements = |
| 5392 IterateExternalArrayElements<ExternalByteArray, int8_t>( |
| 5393 receiver, true, true, range, visitor); |
| 5394 break; |
| 5395 } |
| 5396 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
| 5397 num_of_elements = |
| 5398 IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>( |
| 5399 receiver, true, true, range, visitor); |
| 5400 break; |
| 5401 } |
| 5402 case JSObject::EXTERNAL_SHORT_ELEMENTS: { |
| 5403 num_of_elements = |
| 5404 IterateExternalArrayElements<ExternalShortArray, int16_t>( |
| 5405 receiver, true, true, range, visitor); |
| 5406 break; |
| 5407 } |
| 5408 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { |
| 5409 num_of_elements = |
| 5410 IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>( |
| 5411 receiver, true, true, range, visitor); |
| 5412 break; |
| 5413 } |
| 5414 case JSObject::EXTERNAL_INT_ELEMENTS: { |
| 5415 num_of_elements = |
| 5416 IterateExternalArrayElements<ExternalIntArray, int32_t>( |
| 5417 receiver, true, false, range, visitor); |
| 5418 break; |
| 5419 } |
| 5420 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
| 5421 num_of_elements = |
| 5422 IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>( |
| 5423 receiver, true, false, range, visitor); |
| 5424 break; |
| 5425 } |
| 5426 case JSObject::EXTERNAL_FLOAT_ELEMENTS: { |
| 5427 num_of_elements = |
| 5428 IterateExternalArrayElements<ExternalFloatArray, float>( |
| 5429 receiver, false, false, range, visitor); |
| 5430 break; |
| 5431 } |
| 5325 case JSObject::DICTIONARY_ELEMENTS: { | 5432 case JSObject::DICTIONARY_ELEMENTS: { |
| 5326 Handle<NumberDictionary> dict(receiver->element_dictionary()); | 5433 Handle<NumberDictionary> dict(receiver->element_dictionary()); |
| 5327 uint32_t capacity = dict->Capacity(); | 5434 uint32_t capacity = dict->Capacity(); |
| 5328 for (uint32_t j = 0; j < capacity; j++) { | 5435 for (uint32_t j = 0; j < capacity; j++) { |
| 5329 Handle<Object> k(dict->KeyAt(j)); | 5436 Handle<Object> k(dict->KeyAt(j)); |
| 5330 if (dict->IsKey(*k)) { | 5437 if (dict->IsKey(*k)) { |
| 5331 ASSERT(k->IsNumber()); | 5438 ASSERT(k->IsNumber()); |
| 5332 uint32_t index = static_cast<uint32_t>(k->Number()); | 5439 uint32_t index = static_cast<uint32_t>(k->Number()); |
| 5333 if (index < range) { | 5440 if (index < range) { |
| 5334 num_of_elements++; | 5441 num_of_elements++; |
| (...skipping 2416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7751 } else { | 7858 } else { |
| 7752 // Handle last resort GC and make sure to allow future allocations | 7859 // Handle last resort GC and make sure to allow future allocations |
| 7753 // to grow the heap without causing GCs (if possible). | 7860 // to grow the heap without causing GCs (if possible). |
| 7754 Counters::gc_last_resort_from_js.Increment(); | 7861 Counters::gc_last_resort_from_js.Increment(); |
| 7755 Heap::CollectAllGarbage(false); | 7862 Heap::CollectAllGarbage(false); |
| 7756 } | 7863 } |
| 7757 } | 7864 } |
| 7758 | 7865 |
| 7759 | 7866 |
| 7760 } } // namespace v8::internal | 7867 } } // namespace v8::internal |
| OLD | NEW |