OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 // Handle hidden prototypes. If there's a hidden prototype above this thing | 622 // Handle hidden prototypes. If there's a hidden prototype above this thing |
623 // then we have to check it for properties, because they are supposed to | 623 // then we have to check it for properties, because they are supposed to |
624 // look like they are on this object. | 624 // look like they are on this object. |
625 PrototypeIterator iter(isolate, object); | 625 PrototypeIterator iter(isolate, object); |
626 if (!iter.IsAtEnd() && | 626 if (!iter.IsAtEnd() && |
627 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)) | 627 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)) |
628 ->map() | 628 ->map() |
629 ->is_hidden_prototype()) { | 629 ->is_hidden_prototype()) { |
630 // TODO(verwaest): The recursion is not necessary for keys that are array | 630 // TODO(verwaest): The recursion is not necessary for keys that are array |
631 // indices. Removing this. | 631 // indices. Removing this. |
| 632 // Casting to JSObject is fine because JSProxies are never used as |
| 633 // hidden prototypes. |
632 return HasOwnPropertyImplementation( | 634 return HasOwnPropertyImplementation( |
633 isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), | 635 isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), |
634 key); | 636 key); |
635 } | 637 } |
636 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 638 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
637 return isolate->heap()->false_value(); | 639 return isolate->heap()->false_value(); |
638 } | 640 } |
639 | 641 |
640 | 642 |
641 RUNTIME_FUNCTION(Runtime_HasOwnProperty) { | 643 RUNTIME_FUNCTION(Runtime_HasOwnProperty) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 } | 764 } |
763 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 765 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
764 CONVERT_SMI_ARG_CHECKED(filter_value, 1); | 766 CONVERT_SMI_ARG_CHECKED(filter_value, 1); |
765 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); | 767 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); |
766 | 768 |
767 // Find the number of own properties for each of the objects. | 769 // Find the number of own properties for each of the objects. |
768 int total_property_count = 0; | 770 int total_property_count = 0; |
769 for (PrototypeIterator iter(isolate, object, | 771 for (PrototypeIterator iter(isolate, object, |
770 PrototypeIterator::START_AT_RECEIVER); | 772 PrototypeIterator::START_AT_RECEIVER); |
771 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { | 773 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { |
772 Handle<JSObject> jsproto = | 774 // Casting to JSObject is fine because |object| is guaranteed to be one, |
773 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 775 // and we'll only look at hidden prototypes which are never JSProxies. |
| 776 Handle<JSObject> jsproto = PrototypeIterator::GetCurrent<JSObject>(iter); |
774 total_property_count += jsproto->NumberOfOwnProperties(filter); | 777 total_property_count += jsproto->NumberOfOwnProperties(filter); |
775 } | 778 } |
776 | 779 |
777 // Allocate an array with storage for all the property names. | 780 // Allocate an array with storage for all the property names. |
778 Handle<FixedArray> names = | 781 Handle<FixedArray> names = |
779 isolate->factory()->NewFixedArray(total_property_count); | 782 isolate->factory()->NewFixedArray(total_property_count); |
780 | 783 |
781 // Get the property names. | 784 // Get the property names. |
782 int next_copy_index = 0; | 785 int next_copy_index = 0; |
783 int hidden_strings = 0; | 786 int hidden_strings = 0; |
784 Handle<Object> hidden_string = isolate->factory()->hidden_string(); | 787 Handle<Object> hidden_string = isolate->factory()->hidden_string(); |
785 for (PrototypeIterator iter(isolate, object, | 788 for (PrototypeIterator iter(isolate, object, |
786 PrototypeIterator::START_AT_RECEIVER); | 789 PrototypeIterator::START_AT_RECEIVER); |
787 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { | 790 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { |
788 Handle<JSObject> jsproto = | 791 // Casting to JSObject is fine because |object| is guaranteed to be one, |
789 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 792 // and we'll only look at hidden prototypes which are never JSProxies. |
| 793 Handle<JSObject> jsproto = PrototypeIterator::GetCurrent<JSObject>(iter); |
790 int own = jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); | 794 int own = jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); |
791 // Names from hidden prototypes may already have been added | 795 // Names from hidden prototypes may already have been added |
792 // for inherited function template instances. Count the duplicates | 796 // for inherited function template instances. Count the duplicates |
793 // and stub them out; the final copy pass at the end ignores holes. | 797 // and stub them out; the final copy pass at the end ignores holes. |
794 for (int j = next_copy_index; j < next_copy_index + own; j++) { | 798 for (int j = next_copy_index; j < next_copy_index + own; j++) { |
795 Object* name_from_hidden_proto = names->get(j); | 799 Object* name_from_hidden_proto = names->get(j); |
796 if (isolate->IsInternallyUsedPropertyName(name_from_hidden_proto)) { | 800 if (isolate->IsInternallyUsedPropertyName(name_from_hidden_proto)) { |
797 hidden_strings++; | 801 hidden_strings++; |
798 } else { | 802 } else { |
799 for (int k = 0; k < next_copy_index; k++) { | 803 for (int k = 0; k < next_copy_index; k++) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 | 867 |
864 // TODO(cbruni): implement proper prototype lookup like in GetOwnPropertyNames | 868 // TODO(cbruni): implement proper prototype lookup like in GetOwnPropertyNames |
865 if (object->IsJSGlobalProxy()) { | 869 if (object->IsJSGlobalProxy()) { |
866 // All the elements are stored on the globa_object and not directly on the | 870 // All the elements are stored on the globa_object and not directly on the |
867 // global object proxy. | 871 // global object proxy. |
868 PrototypeIterator iter(isolate, object, | 872 PrototypeIterator iter(isolate, object, |
869 PrototypeIterator::START_AT_PROTOTYPE); | 873 PrototypeIterator::START_AT_PROTOTYPE); |
870 if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { | 874 if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { |
871 return *isolate->factory()->NewJSArray(0); | 875 return *isolate->factory()->NewJSArray(0); |
872 } | 876 } |
| 877 // Casting to JSObject is fine because |object| is guaranteed to be one, |
| 878 // and we'll only look at hidden prototypes which are never JSProxies. |
873 object = PrototypeIterator::GetCurrent<JSObject>(iter); | 879 object = PrototypeIterator::GetCurrent<JSObject>(iter); |
874 } | 880 } |
875 | 881 |
876 int n = object->NumberOfOwnElements(NONE); | 882 int n = object->NumberOfOwnElements(NONE); |
877 Handle<FixedArray> names = isolate->factory()->NewFixedArray(n); | 883 Handle<FixedArray> names = isolate->factory()->NewFixedArray(n); |
878 object->GetOwnElementKeys(*names, NONE); | 884 object->GetOwnElementKeys(*names, NONE); |
879 return *isolate->factory()->NewJSArrayWithElements(names); | 885 return *isolate->factory()->NewJSArrayWithElements(names); |
880 } | 886 } |
881 | 887 |
882 | 888 |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 | 1580 |
1575 RUNTIME_FUNCTION(Runtime_ObjectDefineProperties) { | 1581 RUNTIME_FUNCTION(Runtime_ObjectDefineProperties) { |
1576 HandleScope scope(isolate); | 1582 HandleScope scope(isolate); |
1577 DCHECK(args.length() == 2); | 1583 DCHECK(args.length() == 2); |
1578 CONVERT_ARG_HANDLE_CHECKED(Object, o, 0); | 1584 CONVERT_ARG_HANDLE_CHECKED(Object, o, 0); |
1579 CONVERT_ARG_HANDLE_CHECKED(Object, properties, 1); | 1585 CONVERT_ARG_HANDLE_CHECKED(Object, properties, 1); |
1580 return JSReceiver::DefineProperties(isolate, o, properties); | 1586 return JSReceiver::DefineProperties(isolate, o, properties); |
1581 } | 1587 } |
1582 } // namespace internal | 1588 } // namespace internal |
1583 } // namespace v8 | 1589 } // namespace v8 |
OLD | NEW |