| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 12 matching lines...) Expand all Loading... |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "objects.h" | 30 #include "objects.h" |
| 31 #include "elements.h" | 31 #include "elements.h" |
| 32 #include "utils.h" | 32 #include "utils.h" |
| 33 | 33 #include "v8conversions.h" |
| 34 | 34 |
| 35 // Each concrete ElementsAccessor can handle exactly one ElementsKind, | 35 // Each concrete ElementsAccessor can handle exactly one ElementsKind, |
| 36 // several abstract ElementsAccessor classes are used to allow sharing | 36 // several abstract ElementsAccessor classes are used to allow sharing |
| 37 // common code. | 37 // common code. |
| 38 // | 38 // |
| 39 // Inheritance hierarchy: | 39 // Inheritance hierarchy: |
| 40 // - ElementsAccessorBase (abstract) | 40 // - ElementsAccessorBase (abstract) |
| 41 // - FastElementsAccessor (abstract) | 41 // - FastElementsAccessor (abstract) |
| 42 // - FastSmiOrObjectElementsAccessor | 42 // - FastSmiOrObjectElementsAccessor |
| 43 // - FastPackedSmiElementsAccessor | 43 // - FastPackedSmiElementsAccessor |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 int entry = from->FindEntry(i + from_start); | 476 int entry = from->FindEntry(i + from_start); |
| 477 if (entry != SeededNumberDictionary::kNotFound) { | 477 if (entry != SeededNumberDictionary::kNotFound) { |
| 478 to->set(i + to_start, from->ValueAt(entry)->Number()); | 478 to->set(i + to_start, from->ValueAt(entry)->Number()); |
| 479 } else { | 479 } else { |
| 480 to->set_the_hole(i + to_start); | 480 to->set_the_hole(i + to_start); |
| 481 } | 481 } |
| 482 } | 482 } |
| 483 } | 483 } |
| 484 | 484 |
| 485 | 485 |
| 486 static void TraceTopFrame() { |
| 487 StackFrameIterator it; |
| 488 if (it.done()) { |
| 489 PrintF("unknown location (no JavaScript frames present)"); |
| 490 return; |
| 491 } |
| 492 StackFrame* raw_frame = it.frame(); |
| 493 if (raw_frame->is_internal()) { |
| 494 Isolate* isolate = Isolate::Current(); |
| 495 Code* apply_builtin = isolate->builtins()->builtin( |
| 496 Builtins::kFunctionApply); |
| 497 if (raw_frame->unchecked_code() == apply_builtin) { |
| 498 PrintF("apply from "); |
| 499 it.Advance(); |
| 500 raw_frame = it.frame(); |
| 501 } |
| 502 } |
| 503 JavaScriptFrame::PrintTop(stdout, false, true); |
| 504 } |
| 505 |
| 506 |
| 507 void CheckArrayAbuse(JSObject* obj, const char* op, uint32_t key) { |
| 508 Object* raw_length = NULL; |
| 509 const char* elements_type = "array"; |
| 510 if (obj->IsJSArray()) { |
| 511 JSArray* array = JSArray::cast(obj); |
| 512 raw_length = array->length(); |
| 513 } else { |
| 514 raw_length = Smi::FromInt(obj->elements()->length()); |
| 515 elements_type = "object"; |
| 516 } |
| 517 |
| 518 if (raw_length->IsNumber()) { |
| 519 double n = raw_length->Number(); |
| 520 if (FastI2D(FastD2UI(n)) == n) { |
| 521 int32_t int32_length = DoubleToInt32(n); |
| 522 if (key >= static_cast<uint32_t>(int32_length)) { |
| 523 PrintF("[OOB %s %s (%s length = %d, element accessed = %d) in ", |
| 524 elements_type, op, elements_type, |
| 525 static_cast<int>(int32_length), |
| 526 static_cast<int>(key)); |
| 527 TraceTopFrame(); |
| 528 PrintF("]\n"); |
| 529 } |
| 530 } else { |
| 531 PrintF("[%s elements length not integer value in ", elements_type); |
| 532 TraceTopFrame(); |
| 533 PrintF("]\n"); |
| 534 } |
| 535 } else { |
| 536 PrintF("[%s elements length not a number in ", elements_type); |
| 537 TraceTopFrame(); |
| 538 PrintF("]\n"); |
| 539 } |
| 540 } |
| 541 |
| 542 |
| 486 // Base class for element handler implementations. Contains the | 543 // Base class for element handler implementations. Contains the |
| 487 // the common logic for objects with different ElementsKinds. | 544 // the common logic for objects with different ElementsKinds. |
| 488 // Subclasses must specialize method for which the element | 545 // Subclasses must specialize method for which the element |
| 489 // implementation differs from the base class implementation. | 546 // implementation differs from the base class implementation. |
| 490 // | 547 // |
| 491 // This class is intended to be used in the following way: | 548 // This class is intended to be used in the following way: |
| 492 // | 549 // |
| 493 // class SomeElementsAccessor : | 550 // class SomeElementsAccessor : |
| 494 // public ElementsAccessorBase<SomeElementsAccessor, | 551 // public ElementsAccessorBase<SomeElementsAccessor, |
| 495 // BackingStoreClass> { | 552 // BackingStoreClass> { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 receiver, holder, key, backing_store); | 620 receiver, holder, key, backing_store); |
| 564 } | 621 } |
| 565 | 622 |
| 566 MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver, | 623 MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver, |
| 567 JSObject* holder, | 624 JSObject* holder, |
| 568 uint32_t key, | 625 uint32_t key, |
| 569 FixedArrayBase* backing_store) { | 626 FixedArrayBase* backing_store) { |
| 570 if (backing_store == NULL) { | 627 if (backing_store == NULL) { |
| 571 backing_store = holder->elements(); | 628 backing_store = holder->elements(); |
| 572 } | 629 } |
| 630 |
| 631 if (FLAG_trace_array_abuse) { |
| 632 CheckArrayAbuse(holder, "element read", key); |
| 633 } |
| 634 |
| 573 return ElementsAccessorSubclass::GetImpl( | 635 return ElementsAccessorSubclass::GetImpl( |
| 574 receiver, holder, key, backing_store); | 636 receiver, holder, key, backing_store); |
| 575 } | 637 } |
| 576 | 638 |
| 577 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, | 639 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
| 578 JSObject* obj, | 640 JSObject* obj, |
| 579 uint32_t key, | 641 uint32_t key, |
| 580 FixedArrayBase* backing_store) { | 642 FixedArrayBase* backing_store) { |
| 581 return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) | 643 return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) |
| 582 ? BackingStore::cast(backing_store)->get(key) | 644 ? BackingStore::cast(backing_store)->get(key) |
| (...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1896 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; | 1958 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; |
| 1897 new_backing_store->set(0, length); | 1959 new_backing_store->set(0, length); |
| 1898 { MaybeObject* result = array->SetContent(new_backing_store); | 1960 { MaybeObject* result = array->SetContent(new_backing_store); |
| 1899 if (result->IsFailure()) return result; | 1961 if (result->IsFailure()) return result; |
| 1900 } | 1962 } |
| 1901 return array; | 1963 return array; |
| 1902 } | 1964 } |
| 1903 | 1965 |
| 1904 | 1966 |
| 1905 } } // namespace v8::internal | 1967 } } // namespace v8::internal |
| OLD | NEW |