| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdlib.h> | 5 #include <stdlib.h> |
| 6 #include <limits> | 6 #include <limits> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 5735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5746 isolate, content, | 5746 isolate, content, |
| 5747 JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS)); | 5747 JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS)); |
| 5748 | 5748 |
| 5749 // Test again, since cache may have been built by preceding call. | 5749 // Test again, since cache may have been built by preceding call. |
| 5750 if (object->IsSimpleEnum()) return object->map(); | 5750 if (object->IsSimpleEnum()) return object->map(); |
| 5751 | 5751 |
| 5752 return *content; | 5752 return *content; |
| 5753 } | 5753 } |
| 5754 | 5754 |
| 5755 | 5755 |
| 5756 // Find the length of the prototype chain that is to be handled as one. If a |
| 5757 // prototype object is hidden it is to be viewed as part of the the object it |
| 5758 // is prototype for. |
| 5759 static int OwnPrototypeChainLength(JSObject* obj) { |
| 5760 int count = 1; |
| 5761 for (PrototypeIterator iter(obj->GetIsolate(), obj); |
| 5762 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { |
| 5763 count++; |
| 5764 } |
| 5765 return count; |
| 5766 } |
| 5767 |
| 5768 |
| 5756 // Return the names of the own named properties. | 5769 // Return the names of the own named properties. |
| 5757 // args[0]: object | 5770 // args[0]: object |
| 5758 // args[1]: PropertyAttributes as int | 5771 // args[1]: PropertyAttributes as int |
| 5759 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { | 5772 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { |
| 5760 HandleScope scope(isolate); | 5773 HandleScope scope(isolate); |
| 5761 DCHECK(args.length() == 2); | 5774 DCHECK(args.length() == 2); |
| 5762 if (!args[0]->IsJSObject()) { | 5775 if (!args[0]->IsJSObject()) { |
| 5763 return isolate->heap()->undefined_value(); | 5776 return isolate->heap()->undefined_value(); |
| 5764 } | 5777 } |
| 5765 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 5778 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
| 5766 CONVERT_SMI_ARG_CHECKED(filter_value, 1); | 5779 CONVERT_SMI_ARG_CHECKED(filter_value, 1); |
| 5767 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); | 5780 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); |
| 5768 | 5781 |
| 5782 // Skip the global proxy as it has no properties and always delegates to the |
| 5783 // real global object. |
| 5784 if (obj->IsJSGlobalProxy()) { |
| 5785 // Only collect names if access is permitted. |
| 5786 if (obj->IsAccessCheckNeeded() && |
| 5787 !isolate->MayNamedAccess( |
| 5788 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
| 5789 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); |
| 5790 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 5791 return *isolate->factory()->NewJSArray(0); |
| 5792 } |
| 5793 PrototypeIterator iter(isolate, obj); |
| 5794 obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 5795 } |
| 5796 |
| 5797 // Find the number of objects making up this. |
| 5798 int length = OwnPrototypeChainLength(*obj); |
| 5799 |
| 5769 // Find the number of own properties for each of the objects. | 5800 // Find the number of own properties for each of the objects. |
| 5801 ScopedVector<int> own_property_count(length); |
| 5770 int total_property_count = 0; | 5802 int total_property_count = 0; |
| 5771 { | 5803 { |
| 5772 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); | 5804 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
| 5773 for (; !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); | 5805 for (int i = 0; i < length; i++) { |
| 5774 iter.Advance()) { | |
| 5775 DCHECK(!iter.IsAtEnd()); | 5806 DCHECK(!iter.IsAtEnd()); |
| 5776 Handle<JSObject> jsproto = | 5807 Handle<JSObject> jsproto = |
| 5777 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 5808 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 5778 // Only collect names if access is permitted. | 5809 // Only collect names if access is permitted. |
| 5779 if (jsproto->IsAccessCheckNeeded() && | 5810 if (jsproto->IsAccessCheckNeeded() && |
| 5780 !isolate->MayNamedAccess(jsproto, | 5811 !isolate->MayNamedAccess(jsproto, |
| 5781 isolate->factory()->undefined_value(), | 5812 isolate->factory()->undefined_value(), |
| 5782 v8::ACCESS_KEYS)) { | 5813 v8::ACCESS_KEYS)) { |
| 5783 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); | 5814 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); |
| 5784 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5815 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 5785 return *isolate->factory()->NewJSArray(0); | 5816 return *isolate->factory()->NewJSArray(0); |
| 5786 } | 5817 } |
| 5787 int n; | 5818 int n; |
| 5788 n = jsproto->NumberOfOwnProperties(filter); | 5819 n = jsproto->NumberOfOwnProperties(filter); |
| 5820 own_property_count[i] = n; |
| 5789 total_property_count += n; | 5821 total_property_count += n; |
| 5822 iter.Advance(); |
| 5790 } | 5823 } |
| 5791 } | 5824 } |
| 5792 | 5825 |
| 5793 // Allocate an array with storage for all the property names. | 5826 // Allocate an array with storage for all the property names. |
| 5794 Handle<FixedArray> names = | 5827 Handle<FixedArray> names = |
| 5795 isolate->factory()->NewFixedArray(total_property_count); | 5828 isolate->factory()->NewFixedArray(total_property_count); |
| 5796 | 5829 |
| 5797 // Get the property names. | 5830 // Get the property names. |
| 5798 int next_copy_index = 0; | 5831 int next_copy_index = 0; |
| 5799 int hidden_strings = 0; | 5832 int hidden_strings = 0; |
| 5800 { | 5833 { |
| 5801 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); | 5834 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
| 5802 for (; !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); | 5835 for (int i = 0; i < length; i++) { |
| 5803 iter.Advance()) { | 5836 DCHECK(!iter.IsAtEnd()); |
| 5804 Handle<JSObject> jsproto = | 5837 Handle<JSObject> jsproto = |
| 5805 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 5838 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 5806 int own_property_count = | 5839 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); |
| 5807 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); | 5840 if (i > 0) { |
| 5808 if (!jsproto.is_identical_to(obj)) { | |
| 5809 // Names from hidden prototypes may already have been added | 5841 // Names from hidden prototypes may already have been added |
| 5810 // for inherited function template instances. Count the duplicates | 5842 // for inherited function template instances. Count the duplicates |
| 5811 // and stub them out; the final copy pass at the end ignores holes. | 5843 // and stub them out; the final copy pass at the end ignores holes. |
| 5812 for (int j = next_copy_index; j < next_copy_index + own_property_count; | 5844 for (int j = next_copy_index; |
| 5813 j++) { | 5845 j < next_copy_index + own_property_count[i]; j++) { |
| 5814 Object* name_from_hidden_proto = names->get(j); | 5846 Object* name_from_hidden_proto = names->get(j); |
| 5815 for (int k = 0; k < next_copy_index; k++) { | 5847 for (int k = 0; k < next_copy_index; k++) { |
| 5816 if (names->get(k) != isolate->heap()->hidden_string()) { | 5848 if (names->get(k) != isolate->heap()->hidden_string()) { |
| 5817 Object* name = names->get(k); | 5849 Object* name = names->get(k); |
| 5818 if (name_from_hidden_proto == name) { | 5850 if (name_from_hidden_proto == name) { |
| 5819 names->set(j, isolate->heap()->hidden_string()); | 5851 names->set(j, isolate->heap()->hidden_string()); |
| 5820 hidden_strings++; | 5852 hidden_strings++; |
| 5821 break; | 5853 break; |
| 5822 } | 5854 } |
| 5823 } | 5855 } |
| 5824 } | 5856 } |
| 5825 } | 5857 } |
| 5826 } | 5858 } |
| 5827 next_copy_index += own_property_count; | 5859 next_copy_index += own_property_count[i]; |
| 5828 | 5860 |
| 5829 // Hidden properties only show up if the filter does not skip strings. | 5861 // Hidden properties only show up if the filter does not skip strings. |
| 5830 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { | 5862 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { |
| 5831 hidden_strings++; | 5863 hidden_strings++; |
| 5832 } | 5864 } |
| 5865 iter.Advance(); |
| 5833 } | 5866 } |
| 5834 } | 5867 } |
| 5835 | 5868 |
| 5836 // Filter out name of hidden properties object and | 5869 // Filter out name of hidden properties object and |
| 5837 // hidden prototype duplicates. | 5870 // hidden prototype duplicates. |
| 5838 if (hidden_strings > 0) { | 5871 if (hidden_strings > 0) { |
| 5839 Handle<FixedArray> old_names = names; | 5872 Handle<FixedArray> old_names = names; |
| 5840 names = isolate->factory()->NewFixedArray( | 5873 names = isolate->factory()->NewFixedArray( |
| 5841 names->length() - hidden_strings); | 5874 names->length() - hidden_strings); |
| 5842 int dest_pos = 0; | 5875 int dest_pos = 0; |
| (...skipping 9813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15656 } | 15689 } |
| 15657 return NULL; | 15690 return NULL; |
| 15658 } | 15691 } |
| 15659 | 15692 |
| 15660 | 15693 |
| 15661 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15694 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
| 15662 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15695 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
| 15663 } | 15696 } |
| 15664 | 15697 |
| 15665 } } // namespace v8::internal | 15698 } } // namespace v8::internal |
| OLD | NEW |