| 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 5726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5737 isolate, content, | 5737 isolate, content, |
| 5738 JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS)); | 5738 JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS)); |
| 5739 | 5739 |
| 5740 // Test again, since cache may have been built by preceding call. | 5740 // Test again, since cache may have been built by preceding call. |
| 5741 if (object->IsSimpleEnum()) return object->map(); | 5741 if (object->IsSimpleEnum()) return object->map(); |
| 5742 | 5742 |
| 5743 return *content; | 5743 return *content; |
| 5744 } | 5744 } |
| 5745 | 5745 |
| 5746 | 5746 |
| 5747 // Find the length of the prototype chain that is to be handled as one. If a | |
| 5748 // prototype object is hidden it is to be viewed as part of the the object it | |
| 5749 // is prototype for. | |
| 5750 static int OwnPrototypeChainLength(JSObject* obj) { | |
| 5751 int count = 1; | |
| 5752 for (PrototypeIterator iter(obj->GetIsolate(), obj); | |
| 5753 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { | |
| 5754 count++; | |
| 5755 } | |
| 5756 return count; | |
| 5757 } | |
| 5758 | |
| 5759 | |
| 5760 // Return the names of the own named properties. | 5747 // Return the names of the own named properties. |
| 5761 // args[0]: object | 5748 // args[0]: object |
| 5762 // args[1]: PropertyAttributes as int | 5749 // args[1]: PropertyAttributes as int |
| 5763 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { | 5750 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { |
| 5764 HandleScope scope(isolate); | 5751 HandleScope scope(isolate); |
| 5765 DCHECK(args.length() == 2); | 5752 DCHECK(args.length() == 2); |
| 5766 if (!args[0]->IsJSObject()) { | 5753 if (!args[0]->IsJSObject()) { |
| 5767 return isolate->heap()->undefined_value(); | 5754 return isolate->heap()->undefined_value(); |
| 5768 } | 5755 } |
| 5769 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 5756 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
| 5770 CONVERT_SMI_ARG_CHECKED(filter_value, 1); | 5757 CONVERT_SMI_ARG_CHECKED(filter_value, 1); |
| 5771 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); | 5758 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); |
| 5772 | 5759 |
| 5773 // Skip the global proxy as it has no properties and always delegates to the | |
| 5774 // real global object. | |
| 5775 if (obj->IsJSGlobalProxy()) { | |
| 5776 // Only collect names if access is permitted. | |
| 5777 if (obj->IsAccessCheckNeeded() && | |
| 5778 !isolate->MayNamedAccess( | |
| 5779 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | |
| 5780 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); | |
| 5781 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | |
| 5782 return *isolate->factory()->NewJSArray(0); | |
| 5783 } | |
| 5784 PrototypeIterator iter(isolate, obj); | |
| 5785 obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
| 5786 } | |
| 5787 | |
| 5788 // Find the number of objects making up this. | |
| 5789 int length = OwnPrototypeChainLength(*obj); | |
| 5790 | |
| 5791 // Find the number of own properties for each of the objects. | 5760 // Find the number of own properties for each of the objects. |
| 5792 ScopedVector<int> own_property_count(length); | |
| 5793 int total_property_count = 0; | 5761 int total_property_count = 0; |
| 5794 { | 5762 { |
| 5795 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); | 5763 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
| 5796 for (int i = 0; i < length; i++) { | 5764 for (; !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); |
| 5765 iter.Advance()) { |
| 5797 DCHECK(!iter.IsAtEnd()); | 5766 DCHECK(!iter.IsAtEnd()); |
| 5798 Handle<JSObject> jsproto = | 5767 Handle<JSObject> jsproto = |
| 5799 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 5768 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 5800 // Only collect names if access is permitted. | 5769 // Only collect names if access is permitted. |
| 5801 if (jsproto->IsAccessCheckNeeded() && | 5770 if (jsproto->IsAccessCheckNeeded() && |
| 5802 !isolate->MayNamedAccess(jsproto, | 5771 !isolate->MayNamedAccess(jsproto, |
| 5803 isolate->factory()->undefined_value(), | 5772 isolate->factory()->undefined_value(), |
| 5804 v8::ACCESS_KEYS)) { | 5773 v8::ACCESS_KEYS)) { |
| 5805 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); | 5774 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); |
| 5806 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5775 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 5807 return *isolate->factory()->NewJSArray(0); | 5776 return *isolate->factory()->NewJSArray(0); |
| 5808 } | 5777 } |
| 5809 int n; | 5778 int n; |
| 5810 n = jsproto->NumberOfOwnProperties(filter); | 5779 n = jsproto->NumberOfOwnProperties(filter); |
| 5811 own_property_count[i] = n; | |
| 5812 total_property_count += n; | 5780 total_property_count += n; |
| 5813 iter.Advance(); | |
| 5814 } | 5781 } |
| 5815 } | 5782 } |
| 5816 | 5783 |
| 5817 // Allocate an array with storage for all the property names. | 5784 // Allocate an array with storage for all the property names. |
| 5818 Handle<FixedArray> names = | 5785 Handle<FixedArray> names = |
| 5819 isolate->factory()->NewFixedArray(total_property_count); | 5786 isolate->factory()->NewFixedArray(total_property_count); |
| 5820 | 5787 |
| 5821 // Get the property names. | 5788 // Get the property names. |
| 5822 int next_copy_index = 0; | 5789 int next_copy_index = 0; |
| 5823 int hidden_strings = 0; | 5790 int hidden_strings = 0; |
| 5824 { | 5791 { |
| 5825 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); | 5792 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
| 5826 for (int i = 0; i < length; i++) { | 5793 for (; !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); |
| 5827 DCHECK(!iter.IsAtEnd()); | 5794 iter.Advance()) { |
| 5828 Handle<JSObject> jsproto = | 5795 Handle<JSObject> jsproto = |
| 5829 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 5796 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 5830 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); | 5797 int own_property_count = |
| 5831 if (i > 0) { | 5798 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); |
| 5799 if (!jsproto.is_identical_to(obj)) { |
| 5832 // Names from hidden prototypes may already have been added | 5800 // Names from hidden prototypes may already have been added |
| 5833 // for inherited function template instances. Count the duplicates | 5801 // for inherited function template instances. Count the duplicates |
| 5834 // and stub them out; the final copy pass at the end ignores holes. | 5802 // and stub them out; the final copy pass at the end ignores holes. |
| 5835 for (int j = next_copy_index; | 5803 for (int j = next_copy_index; j < next_copy_index + own_property_count; |
| 5836 j < next_copy_index + own_property_count[i]; j++) { | 5804 j++) { |
| 5837 Object* name_from_hidden_proto = names->get(j); | 5805 Object* name_from_hidden_proto = names->get(j); |
| 5838 for (int k = 0; k < next_copy_index; k++) { | 5806 for (int k = 0; k < next_copy_index; k++) { |
| 5839 if (names->get(k) != isolate->heap()->hidden_string()) { | 5807 if (names->get(k) != isolate->heap()->hidden_string()) { |
| 5840 Object* name = names->get(k); | 5808 Object* name = names->get(k); |
| 5841 if (name_from_hidden_proto == name) { | 5809 if (name_from_hidden_proto == name) { |
| 5842 names->set(j, isolate->heap()->hidden_string()); | 5810 names->set(j, isolate->heap()->hidden_string()); |
| 5843 hidden_strings++; | 5811 hidden_strings++; |
| 5844 break; | 5812 break; |
| 5845 } | 5813 } |
| 5846 } | 5814 } |
| 5847 } | 5815 } |
| 5848 } | 5816 } |
| 5849 } | 5817 } |
| 5850 next_copy_index += own_property_count[i]; | 5818 next_copy_index += own_property_count; |
| 5851 | 5819 |
| 5852 // Hidden properties only show up if the filter does not skip strings. | 5820 // Hidden properties only show up if the filter does not skip strings. |
| 5853 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { | 5821 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { |
| 5854 hidden_strings++; | 5822 hidden_strings++; |
| 5855 } | 5823 } |
| 5856 iter.Advance(); | |
| 5857 } | 5824 } |
| 5858 } | 5825 } |
| 5859 | 5826 |
| 5860 // Filter out name of hidden properties object and | 5827 // Filter out name of hidden properties object and |
| 5861 // hidden prototype duplicates. | 5828 // hidden prototype duplicates. |
| 5862 if (hidden_strings > 0) { | 5829 if (hidden_strings > 0) { |
| 5863 Handle<FixedArray> old_names = names; | 5830 Handle<FixedArray> old_names = names; |
| 5864 names = isolate->factory()->NewFixedArray( | 5831 names = isolate->factory()->NewFixedArray( |
| 5865 names->length() - hidden_strings); | 5832 names->length() - hidden_strings); |
| 5866 int dest_pos = 0; | 5833 int dest_pos = 0; |
| (...skipping 9813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15680 } | 15647 } |
| 15681 return NULL; | 15648 return NULL; |
| 15682 } | 15649 } |
| 15683 | 15650 |
| 15684 | 15651 |
| 15685 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15652 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
| 15686 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15653 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
| 15687 } | 15654 } |
| 15688 | 15655 |
| 15689 } } // namespace v8::internal | 15656 } } // namespace v8::internal |
| OLD | NEW |