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 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 case CONSTANT_TRANSITION: | 596 case CONSTANT_TRANSITION: |
597 case NULL_DESCRIPTOR: | 597 case NULL_DESCRIPTOR: |
598 break; | 598 break; |
599 } | 599 } |
600 UNREACHABLE(); | 600 UNREACHABLE(); |
601 return NULL; | 601 return NULL; |
602 } | 602 } |
603 | 603 |
604 | 604 |
605 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 605 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
606 Object* holder = NULL; | 606 Heap* heap = IsSmi() |
607 if (IsSmi()) { | 607 ? Isolate::Current()->heap() |
608 Context* global_context = Isolate::Current()->context()->global_context(); | 608 : HeapObject::cast(this)->GetHeap(); |
609 holder = global_context->number_function()->instance_prototype(); | 609 Object* holder = this; |
610 } else { | |
611 HeapObject* heap_object = HeapObject::cast(this); | |
612 | 610 |
613 if (heap_object->IsJSObject()) { | 611 // Iterate up the prototype chain until an element is found or the null |
614 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); | 612 // prototype is encountered. |
| 613 for (holder = this; |
| 614 holder != heap->null_value(); |
| 615 holder = holder->GetPrototype()) { |
| 616 if (holder->IsSmi()) { |
| 617 Context* global_context = Isolate::Current()->context()->global_context(); |
| 618 holder = global_context->number_function()->instance_prototype(); |
| 619 } else { |
| 620 HeapObject* heap_object = HeapObject::cast(holder); |
| 621 if (!heap_object->IsJSObject()) { |
| 622 Isolate* isolate = heap->isolate(); |
| 623 Context* global_context = isolate->context()->global_context(); |
| 624 if (heap_object->IsString()) { |
| 625 holder = global_context->string_function()->instance_prototype(); |
| 626 } else if (heap_object->IsHeapNumber()) { |
| 627 holder = global_context->number_function()->instance_prototype(); |
| 628 } else if (heap_object->IsBoolean()) { |
| 629 holder = global_context->boolean_function()->instance_prototype(); |
| 630 } else if (heap_object->IsJSProxy()) { |
| 631 return heap->undefined_value(); // For now... |
| 632 } else { |
| 633 // Undefined and null have no indexed properties. |
| 634 ASSERT(heap_object->IsUndefined() || heap_object->IsNull()); |
| 635 return heap->undefined_value(); |
| 636 } |
| 637 } |
615 } | 638 } |
616 Heap* heap = heap_object->GetHeap(); | |
617 Isolate* isolate = heap->isolate(); | |
618 | 639 |
619 Context* global_context = isolate->context()->global_context(); | 640 // Inline the case for JSObjects. Doing so significantly improves the |
620 if (heap_object->IsString()) { | 641 // performance of fetching elements where checking the prototype chain is |
621 holder = global_context->string_function()->instance_prototype(); | 642 // necessary. |
622 } else if (heap_object->IsHeapNumber()) { | 643 JSObject* js_object = JSObject::cast(holder); |
623 holder = global_context->number_function()->instance_prototype(); | 644 |
624 } else if (heap_object->IsBoolean()) { | 645 // Check access rights if needed. |
625 holder = global_context->boolean_function()->instance_prototype(); | 646 if (js_object->IsAccessCheckNeeded()) { |
626 } else if (heap_object->IsJSProxy()) { | 647 Isolate* isolate = heap->isolate(); |
627 return heap->undefined_value(); // For now... | 648 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) { |
628 } else { | 649 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET); |
629 // Undefined and null have no indexed properties. | 650 return heap->undefined_value(); |
630 ASSERT(heap_object->IsUndefined() || heap_object->IsNull()); | 651 } |
631 return heap->undefined_value(); | 652 } |
| 653 |
| 654 if (js_object->HasIndexedInterceptor()) { |
| 655 return js_object->GetElementWithInterceptor(receiver, index); |
| 656 } |
| 657 |
| 658 if (js_object->elements() != heap->empty_fixed_array()) { |
| 659 MaybeObject* result = js_object->GetElementsAccessor()->GetWithReceiver( |
| 660 js_object, |
| 661 receiver, |
| 662 index); |
| 663 if (result != heap->the_hole_value()) return result; |
632 } | 664 } |
633 } | 665 } |
634 | 666 |
635 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); | 667 return heap->undefined_value(); |
636 } | 668 } |
637 | 669 |
638 | 670 |
639 Object* Object::GetPrototype() { | 671 Object* Object::GetPrototype() { |
640 if (IsSmi()) { | 672 if (IsSmi()) { |
641 Heap* heap = Isolate::Current()->heap(); | 673 Heap* heap = Isolate::Current()->heap(); |
642 Context* context = heap->isolate()->context()->global_context(); | 674 Context* context = heap->isolate()->context()->global_context(); |
643 return context->number_function()->instance_prototype(); | 675 return context->number_function()->instance_prototype(); |
644 } | 676 } |
645 | 677 |
(...skipping 8336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8982 if (raw_result != heap->the_hole_value()) return raw_result; | 9014 if (raw_result != heap->the_hole_value()) return raw_result; |
8983 | 9015 |
8984 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 9016 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
8985 | 9017 |
8986 Object* pt = holder_handle->GetPrototype(); | 9018 Object* pt = holder_handle->GetPrototype(); |
8987 if (pt == heap->null_value()) return heap->undefined_value(); | 9019 if (pt == heap->null_value()) return heap->undefined_value(); |
8988 return pt->GetElementWithReceiver(*this_handle, index); | 9020 return pt->GetElementWithReceiver(*this_handle, index); |
8989 } | 9021 } |
8990 | 9022 |
8991 | 9023 |
8992 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, | |
8993 uint32_t index) { | |
8994 // Check access rights if needed. | |
8995 if (IsAccessCheckNeeded()) { | |
8996 Heap* heap = GetHeap(); | |
8997 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) { | |
8998 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); | |
8999 return heap->undefined_value(); | |
9000 } | |
9001 } | |
9002 | |
9003 if (HasIndexedInterceptor()) { | |
9004 return GetElementWithInterceptor(receiver, index); | |
9005 } | |
9006 | |
9007 Heap* heap = GetHeap(); | |
9008 if (elements() != heap->empty_fixed_array()) { | |
9009 MaybeObject* result = GetElementsAccessor()->GetWithReceiver(this, | |
9010 receiver, | |
9011 index); | |
9012 if (result != heap->the_hole_value()) return result; | |
9013 } | |
9014 | |
9015 Object* pt = GetPrototype(); | |
9016 if (pt == heap->null_value()) return heap->undefined_value(); | |
9017 return pt->GetElementWithReceiver(receiver, index); | |
9018 } | |
9019 | |
9020 | |
9021 bool JSObject::HasDenseElements() { | 9024 bool JSObject::HasDenseElements() { |
9022 int capacity = 0; | 9025 int capacity = 0; |
9023 int used = 0; | 9026 int used = 0; |
9024 GetElementsCapacityAndUsage(&capacity, &used); | 9027 GetElementsCapacityAndUsage(&capacity, &used); |
9025 return (capacity == 0) || (used > (capacity / 2)); | 9028 return (capacity == 0) || (used > (capacity / 2)); |
9026 } | 9029 } |
9027 | 9030 |
9028 | 9031 |
9029 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { | 9032 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { |
9030 *capacity = 0; | 9033 *capacity = 0; |
(...skipping 2855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11886 if (break_point_objects()->IsUndefined()) return 0; | 11889 if (break_point_objects()->IsUndefined()) return 0; |
11887 // Single break point. | 11890 // Single break point. |
11888 if (!break_point_objects()->IsFixedArray()) return 1; | 11891 if (!break_point_objects()->IsFixedArray()) return 1; |
11889 // Multiple break points. | 11892 // Multiple break points. |
11890 return FixedArray::cast(break_point_objects())->length(); | 11893 return FixedArray::cast(break_point_objects())->length(); |
11891 } | 11894 } |
11892 #endif | 11895 #endif |
11893 | 11896 |
11894 | 11897 |
11895 } } // namespace v8::internal | 11898 } } // namespace v8::internal |
OLD | NEW |