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 |