| 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 | 
|---|