Chromium Code Reviews| 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 static MaybeObject* Get(BackingStoreClass* backing_store, | 84 static MaybeObject* Get(BackingStoreClass* backing_store, |
| 85 uint32_t key, | 85 uint32_t key, |
| 86 JSObject* obj, | 86 JSObject* obj, |
| 87 Object* receiver) { | 87 Object* receiver) { |
| 88 if (key < ElementsAccessorSubclass::GetCapacity(backing_store)) { | 88 if (key < ElementsAccessorSubclass::GetCapacity(backing_store)) { |
| 89 return backing_store->get(key); | 89 return backing_store->get(key); |
| 90 } | 90 } |
| 91 return backing_store->GetHeap()->the_hole_value(); | 91 return backing_store->GetHeap()->the_hole_value(); |
| 92 } | 92 } |
| 93 | 93 |
| 94 virtual MaybeObject* Set(JSObject* obj, | |
| 95 uint32_t key, | |
| 96 Object* value, | |
| 97 PropertyAttributes attributes) = 0; | |
|
danno
2011/10/24 21:09:02
Use CRTP here. The virtual Set method should call
| |
| 98 | |
| 99 virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, | |
|
danno
2011/10/24 21:09:02
Can you get away with a single Set wrapper in the
| |
| 100 uint32_t index, | |
| 101 Object* value, | |
| 102 PropertyAttributes attributes) = 0; | |
| 103 | |
| 94 virtual MaybeObject* Delete(JSObject* obj, | 104 virtual MaybeObject* Delete(JSObject* obj, |
| 95 uint32_t key, | 105 uint32_t key, |
| 96 JSReceiver::DeleteMode mode) = 0; | 106 JSReceiver::DeleteMode mode) = 0; |
| 97 | 107 |
| 98 virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from, | 108 virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from, |
| 99 FixedArray* to, | 109 FixedArray* to, |
| 100 JSObject* holder, | 110 JSObject* holder, |
| 101 Object* receiver) { | 111 Object* receiver) { |
| 102 int len0 = to->length(); | 112 int len0 = to->length(); |
| 103 #ifdef DEBUG | 113 #ifdef DEBUG |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 if (4 * num_used <= backing_store->length()) { | 275 if (4 * num_used <= backing_store->length()) { |
| 266 MaybeObject* result = obj->NormalizeElements(); | 276 MaybeObject* result = obj->NormalizeElements(); |
| 267 if (result->IsFailure()) return result; | 277 if (result->IsFailure()) return result; |
| 268 } | 278 } |
| 269 } | 279 } |
| 270 } | 280 } |
| 271 return heap->true_value(); | 281 return heap->true_value(); |
| 272 } | 282 } |
| 273 | 283 |
| 274 protected: | 284 protected: |
| 285 virtual MaybeObject* Set(JSObject* obj, | |
| 286 uint32_t key, | |
| 287 Object* value, | |
| 288 PropertyAttributes attributes) { | |
| 289 // Normalize the elements to enable attributes on the element and make | |
| 290 // sure that we never go back to fast case. | |
| 291 if (attributes != NONE && attributes != ABSENT) { | |
| 292 MaybeObject* maybe_dictionary = obj->NormalizeElements(); | |
| 293 NumberDictionary* dictionary; | |
| 294 if (!maybe_dictionary->To(&dictionary)) { | |
| 295 return maybe_dictionary; | |
| 296 } | |
| 297 dictionary->set_requires_slow_elements(); | |
| 298 return ForKind(DICTIONARY_ELEMENTS)->Set(obj, key, value, attributes); | |
| 299 } | |
| 300 | |
| 301 // TODO(mstarzinger): Not yet implemented. | |
| 302 UNREACHABLE(); | |
| 303 return NULL; | |
| 304 } | |
| 305 | |
| 306 virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, | |
| 307 uint32_t index, | |
| 308 Object* value, | |
| 309 PropertyAttributes attributes) { | |
| 310 // TODO(mstarzinger): Not yet implemented. | |
| 311 UNREACHABLE(); | |
| 312 return NULL; | |
| 313 } | |
| 314 | |
| 275 virtual MaybeObject* Delete(JSObject* obj, | 315 virtual MaybeObject* Delete(JSObject* obj, |
| 276 uint32_t key, | 316 uint32_t key, |
| 277 JSReceiver::DeleteMode mode) { | 317 JSReceiver::DeleteMode mode) { |
| 278 return DeleteCommon(obj, key); | 318 return DeleteCommon(obj, key); |
| 279 } | 319 } |
| 280 }; | 320 }; |
| 281 | 321 |
| 282 | 322 |
| 283 class FastDoubleElementsAccessor | 323 class FastDoubleElementsAccessor |
| 284 : public ElementsAccessorBase<FastDoubleElementsAccessor, | 324 : public ElementsAccessorBase<FastDoubleElementsAccessor, |
| 285 FixedDoubleArray> { | 325 FixedDoubleArray> { |
| 286 protected: | 326 protected: |
| 287 friend class ElementsAccessorBase<FastDoubleElementsAccessor, | 327 friend class ElementsAccessorBase<FastDoubleElementsAccessor, |
| 288 FixedDoubleArray>; | 328 FixedDoubleArray>; |
| 289 | 329 |
| 330 virtual MaybeObject* Set(JSObject* obj, | |
| 331 uint32_t key, | |
| 332 Object* value, | |
| 333 PropertyAttributes attributes) { | |
| 334 // Normalize the elements to enable attributes on the element and make | |
| 335 // sure that we never go back to fast case. | |
| 336 if (attributes != NONE && attributes != ABSENT) { | |
| 337 MaybeObject* maybe_dictionary = obj->NormalizeElements(); | |
| 338 NumberDictionary* dictionary; | |
| 339 if (!maybe_dictionary->To(&dictionary)) { | |
| 340 return maybe_dictionary; | |
| 341 } | |
| 342 dictionary->set_requires_slow_elements(); | |
| 343 return ForKind(DICTIONARY_ELEMENTS)->Set(obj, key, value, attributes); | |
| 344 } | |
| 345 | |
| 346 // TODO(mstarzinger): Not yet implemented. | |
| 347 UNREACHABLE(); | |
| 348 return NULL; | |
| 349 } | |
| 350 | |
| 351 virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, | |
| 352 uint32_t index, | |
| 353 Object* value, | |
| 354 PropertyAttributes attributes) { | |
| 355 // TODO(mstarzinger): Not yet implemented. | |
| 356 UNREACHABLE(); | |
| 357 return NULL; | |
| 358 } | |
| 359 | |
| 290 virtual MaybeObject* Delete(JSObject* obj, | 360 virtual MaybeObject* Delete(JSObject* obj, |
| 291 uint32_t key, | 361 uint32_t key, |
| 292 JSReceiver::DeleteMode mode) { | 362 JSReceiver::DeleteMode mode) { |
| 293 int length = obj->IsJSArray() | 363 int length = obj->IsJSArray() |
| 294 ? Smi::cast(JSArray::cast(obj)->length())->value() | 364 ? Smi::cast(JSArray::cast(obj)->length())->value() |
| 295 : FixedDoubleArray::cast(obj->elements())->length(); | 365 : FixedDoubleArray::cast(obj->elements())->length(); |
| 296 if (key < static_cast<uint32_t>(length)) { | 366 if (key < static_cast<uint32_t>(length)) { |
| 297 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); | 367 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); |
| 298 } | 368 } |
| 299 return obj->GetHeap()->true_value(); | 369 return obj->GetHeap()->true_value(); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 322 uint32_t key, | 392 uint32_t key, |
| 323 JSObject* obj, | 393 JSObject* obj, |
| 324 Object* receiver) { | 394 Object* receiver) { |
| 325 if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) { | 395 if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) { |
| 326 return backing_store->get(key); | 396 return backing_store->get(key); |
| 327 } else { | 397 } else { |
| 328 return backing_store->GetHeap()->undefined_value(); | 398 return backing_store->GetHeap()->undefined_value(); |
| 329 } | 399 } |
| 330 } | 400 } |
| 331 | 401 |
| 402 virtual MaybeObject* Set(JSObject* obj, | |
| 403 uint32_t key, | |
| 404 Object* value, | |
| 405 PropertyAttributes attributes) { | |
| 406 // There is no way to set attributes for external elements. | |
| 407 ASSERT(attributes == NONE || attributes == ABSENT); | |
| 408 | |
| 409 // TODO(mstarzinger): Not yet implemented. | |
| 410 UNREACHABLE(); | |
| 411 return NULL; | |
| 412 } | |
| 413 | |
| 414 virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, | |
| 415 uint32_t index, | |
| 416 Object* value, | |
| 417 PropertyAttributes attributes) { | |
| 418 // TODO(mstarzinger): Not yet implemented. | |
| 419 UNREACHABLE(); | |
| 420 return NULL; | |
| 421 } | |
| 422 | |
| 332 virtual MaybeObject* Delete(JSObject* obj, | 423 virtual MaybeObject* Delete(JSObject* obj, |
| 333 uint32_t key, | 424 uint32_t key, |
| 334 JSReceiver::DeleteMode mode) { | 425 JSReceiver::DeleteMode mode) { |
| 335 // External arrays always ignore deletes. | 426 // External arrays always ignore deletes. |
| 336 return obj->GetHeap()->true_value(); | 427 return obj->GetHeap()->true_value(); |
| 337 } | 428 } |
| 338 }; | 429 }; |
| 339 | 430 |
| 340 | 431 |
| 341 class ExternalByteElementsAccessor | 432 class ExternalByteElementsAccessor |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 return isolate->Throw(*error); | 528 return isolate->Throw(*error); |
| 438 } | 529 } |
| 439 } | 530 } |
| 440 return heap->true_value(); | 531 return heap->true_value(); |
| 441 } | 532 } |
| 442 | 533 |
| 443 protected: | 534 protected: |
| 444 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 535 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
| 445 NumberDictionary>; | 536 NumberDictionary>; |
| 446 | 537 |
| 538 virtual MaybeObject* Set(JSObject* obj, | |
| 539 uint32_t key, | |
| 540 Object* value, | |
| 541 PropertyAttributes attributes) { | |
| 542 NumberDictionary* dictionary = NumberDictionary::cast(obj->elements()); | |
| 543 MaybeObject* maybe_elements = | |
| 544 SetInternal(dictionary, key, value, attributes); | |
| 545 FixedArray* new_elements; | |
| 546 if (!maybe_elements->To(&new_elements)) { | |
| 547 return maybe_elements; | |
| 548 } | |
| 549 if (new_elements != dictionary) { | |
| 550 obj->set_elements(new_elements); | |
| 551 } | |
| 552 return value; | |
| 553 } | |
| 554 | |
| 555 virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, | |
| 556 uint32_t key, | |
| 557 Object* value, | |
| 558 PropertyAttributes attributes) { | |
| 559 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); | |
| 560 PropertyDetails details = PropertyDetails(attributes, NORMAL); | |
| 561 return dictionary->Set(key, value, details); | |
| 562 } | |
| 563 | |
| 447 virtual MaybeObject* Delete(JSObject* obj, | 564 virtual MaybeObject* Delete(JSObject* obj, |
| 448 uint32_t key, | 565 uint32_t key, |
| 449 JSReceiver::DeleteMode mode) { | 566 JSReceiver::DeleteMode mode) { |
| 450 return DeleteCommon(obj, key, mode); | 567 return DeleteCommon(obj, key, mode); |
| 451 } | 568 } |
| 452 | 569 |
| 453 static MaybeObject* Get(NumberDictionary* backing_store, | 570 static MaybeObject* Get(NumberDictionary* backing_store, |
| 454 uint32_t key, | 571 uint32_t key, |
| 455 JSObject* obj, | 572 JSObject* obj, |
| 456 Object* receiver) { | 573 Object* receiver) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 } else { | 615 } else { |
| 499 // Object is not mapped, defer to the arguments. | 616 // Object is not mapped, defer to the arguments. |
| 500 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 617 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 501 return ElementsAccessor::ForArray(arguments)->Get(arguments, | 618 return ElementsAccessor::ForArray(arguments)->Get(arguments, |
| 502 key, | 619 key, |
| 503 obj, | 620 obj, |
| 504 receiver); | 621 receiver); |
| 505 } | 622 } |
| 506 } | 623 } |
| 507 | 624 |
| 625 virtual MaybeObject* Set(JSObject* obj, | |
| 626 uint32_t key, | |
| 627 Object* value, | |
| 628 PropertyAttributes attributes) { | |
| 629 // Normalize the elements to enable attributes on the element and make | |
| 630 // sure that we never go back to fast case. | |
| 631 if (attributes != NONE && attributes != ABSENT) { | |
| 632 MaybeObject* maybe_dictionary = obj->NormalizeElements(); | |
| 633 NumberDictionary* dictionary; | |
| 634 if (!maybe_dictionary->To(&dictionary)) { | |
| 635 return maybe_dictionary; | |
| 636 } | |
| 637 dictionary->set_requires_slow_elements(); | |
| 638 | |
| 639 // Object is not mapped, defer to the arguments. | |
| 640 FixedArray* parameter_map = FixedArray::cast(obj->elements()); | |
| 641 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
| 642 MaybeObject* maybe_elements = ElementsAccessor::ForArray(arguments)-> | |
| 643 SetInternal(arguments, key, value, attributes); | |
| 644 FixedArray* new_elements; | |
| 645 if (!maybe_elements->To(&new_elements)) { | |
| 646 return maybe_elements; | |
| 647 } | |
| 648 if (new_elements != arguments) { | |
| 649 parameter_map->set(1, new_elements); | |
| 650 } | |
| 651 | |
| 652 return value; | |
| 653 } | |
| 654 | |
| 655 // TODO(mstarzinger): Not yet implemented. | |
| 656 UNREACHABLE(); | |
| 657 return NULL; | |
| 658 } | |
| 659 | |
| 660 virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, | |
| 661 uint32_t index, | |
| 662 Object* value, | |
| 663 PropertyAttributes attributes) { | |
| 664 // The non-strict arguments object itself cannot be a backing store. | |
| 665 UNREACHABLE(); | |
| 666 return NULL; | |
| 667 } | |
| 668 | |
| 508 virtual MaybeObject* Delete(JSObject* obj, | 669 virtual MaybeObject* Delete(JSObject* obj, |
| 509 uint32_t key | 670 uint32_t key, |
| 510 , | |
| 511 JSReceiver::DeleteMode mode) { | 671 JSReceiver::DeleteMode mode) { |
| 512 FixedArray* parameter_map = FixedArray::cast(obj->elements()); | 672 FixedArray* parameter_map = FixedArray::cast(obj->elements()); |
| 513 Object* probe = GetParameterMapArg(parameter_map, key); | 673 Object* probe = GetParameterMapArg(parameter_map, key); |
| 514 if (!probe->IsTheHole()) { | 674 if (!probe->IsTheHole()) { |
| 515 // TODO(kmillikin): We could check if this was the last aliased | 675 // TODO(kmillikin): We could check if this was the last aliased |
| 516 // parameter, and revert to normal elements in that case. That | 676 // parameter, and revert to normal elements in that case. That |
| 517 // would enable GC of the context. | 677 // would enable GC of the context. |
| 518 parameter_map->set_the_hole(key + 2); | 678 parameter_map->set_the_hole(key + 2); |
| 519 } else { | 679 } else { |
| 520 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 680 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 634 }; | 794 }; |
| 635 | 795 |
| 636 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == | 796 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == |
| 637 kElementsKindCount); | 797 kElementsKindCount); |
| 638 | 798 |
| 639 elements_accessors_ = accessor_array; | 799 elements_accessors_ = accessor_array; |
| 640 } | 800 } |
| 641 | 801 |
| 642 | 802 |
| 643 } } // namespace v8::internal | 803 } } // namespace v8::internal |
| OLD | NEW |