| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // } | 66 // } |
| 67 // | 67 // |
| 68 // This is an example of the Curiously Recurring Template Pattern (see | 68 // This is an example of the Curiously Recurring Template Pattern (see |
| 69 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use | 69 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use |
| 70 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and | 70 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and |
| 71 // specialization of SomeElementsAccessor methods). | 71 // specialization of SomeElementsAccessor methods). |
| 72 template <typename ElementsAccessorSubclass, typename BackingStoreClass> | 72 template <typename ElementsAccessorSubclass, typename BackingStoreClass> |
| 73 class ElementsAccessorBase : public ElementsAccessor { | 73 class ElementsAccessorBase : public ElementsAccessor { |
| 74 protected: | 74 protected: |
| 75 ElementsAccessorBase() { } | 75 ElementsAccessorBase() { } |
| 76 virtual MaybeObject* GetWithReceiver(JSObject* obj, | 76 virtual MaybeObject* Get(FixedArrayBase* backing_store, |
| 77 Object* receiver, | 77 uint32_t key, |
| 78 uint32_t key) { | 78 JSObject* obj, |
| 79 BackingStoreClass* backing_store = BackingStoreClass::cast(obj->elements()); | 79 Object* receiver) { |
| 80 return ElementsAccessorSubclass::Get( |
| 81 BackingStoreClass::cast(backing_store), key, obj, receiver); |
| 82 } |
| 83 |
| 84 static MaybeObject* Get(BackingStoreClass* backing_store, |
| 85 uint32_t key, |
| 86 JSObject* obj, |
| 87 Object* receiver) { |
| 80 if (key < ElementsAccessorSubclass::GetCapacity(backing_store)) { | 88 if (key < ElementsAccessorSubclass::GetCapacity(backing_store)) { |
| 81 return backing_store->get(key); | 89 return backing_store->get(key); |
| 82 } | 90 } |
| 83 return obj->GetHeap()->the_hole_value(); | 91 return backing_store->GetHeap()->the_hole_value(); |
| 84 } | 92 } |
| 85 | 93 |
| 86 virtual MaybeObject* Delete(JSObject* obj, | 94 virtual MaybeObject* Delete(JSObject* obj, |
| 87 uint32_t key, | 95 uint32_t key, |
| 88 JSReceiver::DeleteMode mode) = 0; | 96 JSReceiver::DeleteMode mode) = 0; |
| 89 | 97 |
| 90 virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from, | 98 virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from, |
| 91 FixedArray* to) { | 99 FixedArray* to, |
| 100 JSObject* holder, |
| 101 Object* receiver) { |
| 92 int len0 = to->length(); | 102 int len0 = to->length(); |
| 93 #ifdef DEBUG | 103 #ifdef DEBUG |
| 94 if (FLAG_enable_slow_asserts) { | 104 if (FLAG_enable_slow_asserts) { |
| 95 for (int i = 0; i < len0; i++) { | 105 for (int i = 0; i < len0; i++) { |
| 96 ASSERT(!to->get(i)->IsTheHole()); | 106 ASSERT(!to->get(i)->IsTheHole()); |
| 97 } | 107 } |
| 98 } | 108 } |
| 99 #endif | 109 #endif |
| 100 BackingStoreClass* backing_store = BackingStoreClass::cast(from); | 110 BackingStoreClass* backing_store = BackingStoreClass::cast(from); |
| 101 uint32_t len1 = ElementsAccessorSubclass::GetCapacity(backing_store); | 111 uint32_t len1 = ElementsAccessorSubclass::GetCapacity(backing_store); |
| 102 | 112 |
| 103 // Optimize if 'other' is empty. | 113 // Optimize if 'other' is empty. |
| 104 // We cannot optimize if 'this' is empty, as other may have holes. | 114 // We cannot optimize if 'this' is empty, as other may have holes. |
| 105 if (len1 == 0) return to; | 115 if (len1 == 0) return to; |
| 106 | 116 |
| 107 // Compute how many elements are not in other. | 117 // Compute how many elements are not in other. |
| 108 int extra = 0; | 118 int extra = 0; |
| 109 for (uint32_t y = 0; y < len1; y++) { | 119 for (uint32_t y = 0; y < len1; y++) { |
| 110 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, y)) { | 120 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, |
| 121 y, |
| 122 holder, |
| 123 receiver)) { |
| 111 uint32_t key = | 124 uint32_t key = |
| 112 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); | 125 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); |
| 113 MaybeObject* maybe_value = | 126 MaybeObject* maybe_value = |
| 114 ElementsAccessorSubclass::GetElement(backing_store, key); | 127 ElementsAccessorSubclass::Get(backing_store, key, holder, receiver); |
| 115 Object* value; | 128 Object* value; |
| 116 if (!maybe_value->ToObject(&value)) return maybe_value; | 129 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 117 ASSERT(!value->IsTheHole()); | 130 ASSERT(!value->IsTheHole()); |
| 118 if (!HasKey(to, value)) { | 131 if (!HasKey(to, value)) { |
| 119 extra++; | 132 extra++; |
| 120 } | 133 } |
| 121 } | 134 } |
| 122 } | 135 } |
| 123 | 136 |
| 124 if (extra == 0) return to; | 137 if (extra == 0) return to; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 135 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 148 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 136 for (int i = 0; i < len0; i++) { | 149 for (int i = 0; i < len0; i++) { |
| 137 Object* e = to->get(i); | 150 Object* e = to->get(i); |
| 138 ASSERT(e->IsString() || e->IsNumber()); | 151 ASSERT(e->IsString() || e->IsNumber()); |
| 139 result->set(i, e, mode); | 152 result->set(i, e, mode); |
| 140 } | 153 } |
| 141 } | 154 } |
| 142 // Fill in the extra values. | 155 // Fill in the extra values. |
| 143 int index = 0; | 156 int index = 0; |
| 144 for (uint32_t y = 0; y < len1; y++) { | 157 for (uint32_t y = 0; y < len1; y++) { |
| 145 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, y)) { | 158 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, |
| 159 y, |
| 160 holder, |
| 161 receiver)) { |
| 146 uint32_t key = | 162 uint32_t key = |
| 147 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); | 163 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); |
| 148 MaybeObject* maybe_value = | 164 MaybeObject* maybe_value = |
| 149 ElementsAccessorSubclass::GetElement(backing_store, key); | 165 ElementsAccessorSubclass::Get(backing_store, key, holder, receiver); |
| 150 Object* value; | 166 Object* value; |
| 151 if (!maybe_value->ToObject(&value)) return maybe_value; | 167 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 152 if (!value->IsTheHole() && !HasKey(to, value)) { | 168 if (!value->IsTheHole() && !HasKey(to, value)) { |
| 153 result->set(len0 + index, value); | 169 result->set(len0 + index, value); |
| 154 index++; | 170 index++; |
| 155 } | 171 } |
| 156 } | 172 } |
| 157 } | 173 } |
| 158 ASSERT(extra == index); | 174 ASSERT(extra == index); |
| 159 return result; | 175 return result; |
| 160 } | 176 } |
| 161 | 177 |
| 162 protected: | 178 protected: |
| 163 static uint32_t GetCapacity(BackingStoreClass* backing_store) { | 179 static uint32_t GetCapacity(BackingStoreClass* backing_store) { |
| 164 return backing_store->length(); | 180 return backing_store->length(); |
| 165 } | 181 } |
| 166 | 182 |
| 167 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { | 183 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { |
| 168 return ElementsAccessorSubclass::GetCapacity( | 184 return ElementsAccessorSubclass::GetCapacity( |
| 169 BackingStoreClass::cast(backing_store)); | 185 BackingStoreClass::cast(backing_store)); |
| 170 } | 186 } |
| 171 | 187 |
| 172 static MaybeObject* GetElement( | |
| 173 BackingStoreClass* backing_store, | |
| 174 uint32_t key) { | |
| 175 return backing_store->get(key); | |
| 176 } | |
| 177 | |
| 178 virtual MaybeObject* GetElement(FixedArrayBase* backing_store, | |
| 179 uint32_t key) { | |
| 180 return ElementsAccessorSubclass::GetElement( | |
| 181 BackingStoreClass::cast(backing_store), key); | |
| 182 } | |
| 183 | |
| 184 static bool HasElementAtIndex(BackingStoreClass* backing_store, | 188 static bool HasElementAtIndex(BackingStoreClass* backing_store, |
| 185 uint32_t index) { | 189 uint32_t index, |
| 190 JSObject* holder, |
| 191 Object* receiver) { |
| 186 uint32_t key = | 192 uint32_t key = |
| 187 ElementsAccessorSubclass::GetKeyForIndex(backing_store, index); | 193 ElementsAccessorSubclass::GetKeyForIndex(backing_store, index); |
| 188 MaybeObject* element = ElementsAccessorSubclass::GetElement(backing_store, | 194 MaybeObject* element = ElementsAccessorSubclass::Get(backing_store, |
| 189 key); | 195 key, |
| 196 holder, |
| 197 receiver); |
| 190 return !element->IsTheHole(); | 198 return !element->IsTheHole(); |
| 191 } | 199 } |
| 192 | 200 |
| 193 virtual bool HasElementAtIndex(FixedArrayBase* backing_store, | 201 virtual bool HasElementAtIndex(FixedArrayBase* backing_store, |
| 194 uint32_t index) { | 202 uint32_t index, |
| 203 JSObject* holder, |
| 204 Object* receiver) { |
| 195 return ElementsAccessorSubclass::HasElementAtIndex( | 205 return ElementsAccessorSubclass::HasElementAtIndex( |
| 196 BackingStoreClass::cast(backing_store), index); | 206 BackingStoreClass::cast(backing_store), index, holder, receiver); |
| 197 } | 207 } |
| 198 | 208 |
| 199 static uint32_t GetKeyForIndex(BackingStoreClass* backing_store, | 209 static uint32_t GetKeyForIndex(BackingStoreClass* backing_store, |
| 200 uint32_t index) { | 210 uint32_t index) { |
| 201 return index; | 211 return index; |
| 202 } | 212 } |
| 203 | 213 |
| 204 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, | 214 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, |
| 205 uint32_t index) { | 215 uint32_t index) { |
| 206 return ElementsAccessorSubclass::GetKeyForIndex( | 216 return ElementsAccessorSubclass::GetKeyForIndex( |
| 207 BackingStoreClass::cast(backing_store), index); | 217 BackingStoreClass::cast(backing_store), index); |
| 208 } | 218 } |
| 209 | 219 |
| 210 private: | 220 private: |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 int length = obj->IsJSArray() | 291 int length = obj->IsJSArray() |
| 282 ? Smi::cast(JSArray::cast(obj)->length())->value() | 292 ? Smi::cast(JSArray::cast(obj)->length())->value() |
| 283 : FixedDoubleArray::cast(obj->elements())->length(); | 293 : FixedDoubleArray::cast(obj->elements())->length(); |
| 284 if (key < static_cast<uint32_t>(length)) { | 294 if (key < static_cast<uint32_t>(length)) { |
| 285 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); | 295 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); |
| 286 } | 296 } |
| 287 return obj->GetHeap()->true_value(); | 297 return obj->GetHeap()->true_value(); |
| 288 } | 298 } |
| 289 | 299 |
| 290 static bool HasElementAtIndex(FixedDoubleArray* backing_store, | 300 static bool HasElementAtIndex(FixedDoubleArray* backing_store, |
| 291 uint32_t index) { | 301 uint32_t index, |
| 302 JSObject* holder, |
| 303 Object* receiver) { |
| 292 return !backing_store->is_the_hole(index); | 304 return !backing_store->is_the_hole(index); |
| 293 } | 305 } |
| 294 }; | 306 }; |
| 295 | 307 |
| 296 | 308 |
| 297 // Super class for all external element arrays. | 309 // Super class for all external element arrays. |
| 298 template<typename ExternalElementsAccessorSubclass, | 310 template<typename ExternalElementsAccessorSubclass, |
| 299 typename ExternalArray> | 311 typename ExternalArray> |
| 300 class ExternalElementsAccessor | 312 class ExternalElementsAccessor |
| 301 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, | 313 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, |
| 302 ExternalArray> { | 314 ExternalArray> { |
| 303 protected: | 315 protected: |
| 304 virtual MaybeObject* GetWithReceiver(JSObject* obj, | 316 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, |
| 305 Object* receiver, | 317 ExternalArray>; |
| 306 uint32_t key) { | 318 |
| 307 ExternalArray* backing_store = ExternalArray::cast(obj->elements()); | 319 static MaybeObject* Get(ExternalArray* backing_store, |
| 320 uint32_t key, |
| 321 JSObject* obj, |
| 322 Object* receiver) { |
| 308 if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) { | 323 if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) { |
| 309 return backing_store->get(key); | 324 return backing_store->get(key); |
| 310 } else { | 325 } else { |
| 311 return obj->GetHeap()->undefined_value(); | 326 return backing_store->GetHeap()->undefined_value(); |
| 312 } | 327 } |
| 313 } | 328 } |
| 314 | 329 |
| 315 virtual MaybeObject* Delete(JSObject* obj, | 330 virtual MaybeObject* Delete(JSObject* obj, |
| 316 uint32_t key, | 331 uint32_t key, |
| 317 JSReceiver::DeleteMode mode) { | 332 JSReceiver::DeleteMode mode) { |
| 318 // External arrays always ignore deletes. | 333 // External arrays always ignore deletes. |
| 319 return obj->GetHeap()->true_value(); | 334 return obj->GetHeap()->true_value(); |
| 320 } | 335 } |
| 321 }; | 336 }; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 class PixelElementsAccessor | 387 class PixelElementsAccessor |
| 373 : public ExternalElementsAccessor<PixelElementsAccessor, | 388 : public ExternalElementsAccessor<PixelElementsAccessor, |
| 374 ExternalPixelArray> { | 389 ExternalPixelArray> { |
| 375 }; | 390 }; |
| 376 | 391 |
| 377 | 392 |
| 378 class DictionaryElementsAccessor | 393 class DictionaryElementsAccessor |
| 379 : public ElementsAccessorBase<DictionaryElementsAccessor, | 394 : public ElementsAccessorBase<DictionaryElementsAccessor, |
| 380 NumberDictionary> { | 395 NumberDictionary> { |
| 381 public: | 396 public: |
| 382 static MaybeObject* GetNumberDictionaryElement( | |
| 383 JSObject* obj, | |
| 384 Object* receiver, | |
| 385 NumberDictionary* backing_store, | |
| 386 uint32_t key) { | |
| 387 int entry = backing_store->FindEntry(key); | |
| 388 if (entry != NumberDictionary::kNotFound) { | |
| 389 Object* element = backing_store->ValueAt(entry); | |
| 390 PropertyDetails details = backing_store->DetailsAt(entry); | |
| 391 if (details.type() == CALLBACKS) { | |
| 392 return obj->GetElementWithCallback(receiver, | |
| 393 element, | |
| 394 key, | |
| 395 obj); | |
| 396 } else { | |
| 397 return element; | |
| 398 } | |
| 399 } | |
| 400 return obj->GetHeap()->the_hole_value(); | |
| 401 } | |
| 402 | |
| 403 static MaybeObject* DeleteCommon(JSObject* obj, | 397 static MaybeObject* DeleteCommon(JSObject* obj, |
| 404 uint32_t key, | 398 uint32_t key, |
| 405 JSReceiver::DeleteMode mode) { | 399 JSReceiver::DeleteMode mode) { |
| 406 Isolate* isolate = obj->GetIsolate(); | 400 Isolate* isolate = obj->GetIsolate(); |
| 407 Heap* heap = isolate->heap(); | 401 Heap* heap = isolate->heap(); |
| 408 FixedArray* backing_store = FixedArray::cast(obj->elements()); | 402 FixedArray* backing_store = FixedArray::cast(obj->elements()); |
| 409 bool is_arguments = | 403 bool is_arguments = |
| 410 (obj->GetElementsKind() == JSObject::NON_STRICT_ARGUMENTS_ELEMENTS); | 404 (obj->GetElementsKind() == JSObject::NON_STRICT_ARGUMENTS_ELEMENTS); |
| 411 if (is_arguments) { | 405 if (is_arguments) { |
| 412 backing_store = FixedArray::cast(backing_store->get(1)); | 406 backing_store = FixedArray::cast(backing_store->get(1)); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 protected: | 441 protected: |
| 448 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 442 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
| 449 NumberDictionary>; | 443 NumberDictionary>; |
| 450 | 444 |
| 451 virtual MaybeObject* Delete(JSObject* obj, | 445 virtual MaybeObject* Delete(JSObject* obj, |
| 452 uint32_t key, | 446 uint32_t key, |
| 453 JSReceiver::DeleteMode mode) { | 447 JSReceiver::DeleteMode mode) { |
| 454 return DeleteCommon(obj, key, mode); | 448 return DeleteCommon(obj, key, mode); |
| 455 } | 449 } |
| 456 | 450 |
| 457 virtual MaybeObject* GetWithReceiver(JSObject* obj, | 451 static MaybeObject* Get(NumberDictionary* backing_store, |
| 458 Object* receiver, | 452 uint32_t key, |
| 459 uint32_t key) { | 453 JSObject* obj, |
| 460 return GetNumberDictionaryElement(obj, | 454 Object* receiver) { |
| 461 receiver, | 455 int entry = backing_store->FindEntry(key); |
| 462 obj->element_dictionary(), | 456 if (entry != NumberDictionary::kNotFound) { |
| 463 key); | 457 Object* element = backing_store->ValueAt(entry); |
| 458 PropertyDetails details = backing_store->DetailsAt(entry); |
| 459 if (details.type() == CALLBACKS) { |
| 460 return obj->GetElementWithCallback(receiver, |
| 461 element, |
| 462 key, |
| 463 obj); |
| 464 } else { |
| 465 return element; |
| 466 } |
| 467 } |
| 468 return obj->GetHeap()->the_hole_value(); |
| 464 } | 469 } |
| 465 | 470 |
| 466 static uint32_t GetKeyForIndex(NumberDictionary* dict, | 471 static uint32_t GetKeyForIndex(NumberDictionary* dict, |
| 467 uint32_t index) { | 472 uint32_t index) { |
| 468 Object* key = dict->KeyAt(index); | 473 Object* key = dict->KeyAt(index); |
| 469 return Smi::cast(key)->value(); | 474 return Smi::cast(key)->value(); |
| 470 } | 475 } |
| 471 | |
| 472 static MaybeObject* GetElement(NumberDictionary* dict, | |
| 473 int key) { | |
| 474 int entry = dict->FindEntry(key); | |
| 475 if (entry != NumberDictionary::kNotFound) { | |
| 476 return dict->ValueAt(entry); | |
| 477 } else { | |
| 478 return dict->GetHeap()->the_hole_value(); | |
| 479 } | |
| 480 } | |
| 481 }; | 476 }; |
| 482 | 477 |
| 483 | 478 |
| 484 class NonStrictArgumentsElementsAccessor | 479 class NonStrictArgumentsElementsAccessor |
| 485 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, | 480 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, |
| 486 FixedArray> { | 481 FixedArray> { |
| 487 protected: | 482 protected: |
| 488 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, | 483 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, |
| 489 FixedArray>; | 484 FixedArray>; |
| 490 | 485 |
| 491 virtual MaybeObject* GetWithReceiver(JSObject* obj, | 486 static MaybeObject* Get(FixedArray* parameter_map, |
| 492 Object* receiver, | 487 uint32_t key, |
| 493 uint32_t key) { | 488 JSObject* obj, |
| 494 FixedArray* parameter_map = FixedArray::cast(obj->elements()); | 489 Object* receiver) { |
| 495 Object* probe = GetParameterMapArg(parameter_map, key); | 490 Object* probe = GetParameterMapArg(parameter_map, key); |
| 496 if (!probe->IsTheHole()) { | 491 if (!probe->IsTheHole()) { |
| 497 Context* context = Context::cast(parameter_map->get(0)); | 492 Context* context = Context::cast(parameter_map->get(0)); |
| 498 int context_index = Smi::cast(probe)->value(); | 493 int context_index = Smi::cast(probe)->value(); |
| 499 ASSERT(!context->get(context_index)->IsTheHole()); | 494 ASSERT(!context->get(context_index)->IsTheHole()); |
| 500 return context->get(context_index); | 495 return context->get(context_index); |
| 501 } else { | 496 } else { |
| 502 // Object is not mapped, defer to the arguments. | 497 // Object is not mapped, defer to the arguments. |
| 503 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 498 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 504 if (arguments->IsDictionary()) { | 499 return ElementsAccessor::ForArray(arguments)->Get(arguments, |
| 505 return DictionaryElementsAccessor::GetNumberDictionaryElement( | 500 key, |
| 506 obj, | 501 obj, |
| 507 receiver, | 502 receiver); |
| 508 NumberDictionary::cast(arguments), | |
| 509 key); | |
| 510 } else if (key < static_cast<uint32_t>(arguments->length())) { | |
| 511 return arguments->get(key); | |
| 512 } | |
| 513 } | 503 } |
| 514 return obj->GetHeap()->the_hole_value(); | |
| 515 } | 504 } |
| 516 | 505 |
| 517 virtual MaybeObject* Delete(JSObject* obj, | 506 virtual MaybeObject* Delete(JSObject* obj, |
| 518 uint32_t key | 507 uint32_t key |
| 519 , | 508 , |
| 520 JSReceiver::DeleteMode mode) { | 509 JSReceiver::DeleteMode mode) { |
| 521 FixedArray* parameter_map = FixedArray::cast(obj->elements()); | 510 FixedArray* parameter_map = FixedArray::cast(obj->elements()); |
| 522 Object* probe = GetParameterMapArg(parameter_map, key); | 511 Object* probe = GetParameterMapArg(parameter_map, key); |
| 523 if (!probe->IsTheHole()) { | 512 if (!probe->IsTheHole()) { |
| 524 // TODO(kmillikin): We could check if this was the last aliased | 513 // TODO(kmillikin): We could check if this was the last aliased |
| (...skipping 16 matching lines...) Expand all Loading... |
| 541 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 530 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
| 542 ForArray(arguments)->GetCapacity(arguments)); | 531 ForArray(arguments)->GetCapacity(arguments)); |
| 543 } | 532 } |
| 544 | 533 |
| 545 static uint32_t GetKeyForIndex(FixedArray* dict, | 534 static uint32_t GetKeyForIndex(FixedArray* dict, |
| 546 uint32_t index) { | 535 uint32_t index) { |
| 547 return index; | 536 return index; |
| 548 } | 537 } |
| 549 | 538 |
| 550 static bool HasElementAtIndex(FixedArray* parameter_map, | 539 static bool HasElementAtIndex(FixedArray* parameter_map, |
| 551 uint32_t index) { | 540 uint32_t index, |
| 541 JSObject* holder, |
| 542 Object* receiver) { |
| 552 Object* probe = GetParameterMapArg(parameter_map, index); | 543 Object* probe = GetParameterMapArg(parameter_map, index); |
| 553 if (!probe->IsTheHole()) { | 544 if (!probe->IsTheHole()) { |
| 554 return true; | 545 return true; |
| 555 } else { | 546 } else { |
| 556 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 547 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 557 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); | 548 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
| 558 return !accessor->GetElement(arguments, index)->IsTheHole(); | 549 return !accessor->Get(arguments, index, holder, receiver)->IsTheHole(); |
| 559 } | |
| 560 } | |
| 561 | |
| 562 static MaybeObject* GetElement(FixedArray* parameter_map, | |
| 563 uint32_t key) { | |
| 564 Object* probe = GetParameterMapArg(parameter_map, key); | |
| 565 if (!probe->IsTheHole()) { | |
| 566 Context* context = Context::cast(parameter_map->get(0)); | |
| 567 int context_index = Smi::cast(probe)->value(); | |
| 568 ASSERT(!context->get(context_index)->IsTheHole()); | |
| 569 return context->get(context_index); | |
| 570 } else { | |
| 571 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | |
| 572 return ForArray(arguments)->GetElement(arguments, key); | |
| 573 } | 550 } |
| 574 } | 551 } |
| 575 | 552 |
| 576 private: | 553 private: |
| 577 | |
| 578 static Object* GetParameterMapArg(FixedArray* parameter_map, | 554 static Object* GetParameterMapArg(FixedArray* parameter_map, |
| 579 uint32_t key) { | 555 uint32_t key) { |
| 580 uint32_t length = parameter_map->length(); | 556 uint32_t length = parameter_map->length(); |
| 581 return key < (length - 2 ) | 557 return key < (length - 2 ) |
| 582 ? parameter_map->get(key + 2) | 558 ? parameter_map->get(key + 2) |
| 583 : parameter_map->GetHeap()->the_hole_value(); | 559 : parameter_map->GetHeap()->the_hole_value(); |
| 584 } | 560 } |
| 585 }; | 561 }; |
| 586 | 562 |
| 587 | 563 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 &element_accessors.float_elements_handler, | 626 &element_accessors.float_elements_handler, |
| 651 &element_accessors.double_elements_handler, | 627 &element_accessors.double_elements_handler, |
| 652 &element_accessors.pixel_elements_handler | 628 &element_accessors.pixel_elements_handler |
| 653 }; | 629 }; |
| 654 | 630 |
| 655 elements_accessors_ = accessor_array; | 631 elements_accessors_ = accessor_array; |
| 656 } | 632 } |
| 657 | 633 |
| 658 | 634 |
| 659 } } // namespace v8::internal | 635 } } // namespace v8::internal |
| OLD | NEW |