Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: src/runtime/runtime-object.cc

Issue 1498593006: [proxies] Use JSReceiver::GetKeys() for more purposes (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 isolate, content, JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS, 789 isolate, content, JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS,
790 ENUMERABLE_STRINGS)); 790 ENUMERABLE_STRINGS));
791 791
792 // Test again, since cache may have been built by preceding call. 792 // Test again, since cache may have been built by preceding call.
793 if (object->IsSimpleEnum()) return object->map(); 793 if (object->IsSimpleEnum()) return object->map();
794 794
795 return *content; 795 return *content;
796 } 796 }
797 797
798 798
799 // Return the names of the own named properties. 799 RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) {
800 // args[0]: object
801 // args[1]: PropertyAttributes as int
802 // TODO(cbruni/jkummerow): Use JSReceiver::GetKeys() internally, merge with
803 // Runtime_GetOwnElementNames.
804 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
805 HandleScope scope(isolate); 800 HandleScope scope(isolate);
806 DCHECK(args.length() == 2); 801 DCHECK(args.length() == 2);
807 if (!args[0]->IsJSObject()) { 802 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
808 return isolate->heap()->undefined_value();
809 }
810 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
811 CONVERT_SMI_ARG_CHECKED(filter_value, 1); 803 CONVERT_SMI_ARG_CHECKED(filter_value, 1);
804 PropertyFilter filter = static_cast<PropertyFilter>(filter_value);
812 805
813 // TODO(jkummerow): Temporary compatibility measure. Refactor callers. 806 Handle<FixedArray> keys;
814 // Values of filter_value are defined in macros.py. 807 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
815 PropertyFilter filter = ALL_PROPERTIES; 808 isolate, keys, JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY, filter,
816 if (filter_value & 2) { 809 CONVERT_TO_STRING));
817 filter = static_cast<PropertyFilter>(filter | ONLY_ENUMERABLE);
818 }
819 if (filter_value & 8) {
820 filter = static_cast<PropertyFilter>(filter | SKIP_STRINGS);
821 }
822 if (filter_value & 16) {
823 filter = static_cast<PropertyFilter>(filter | SKIP_SYMBOLS);
824 }
825 DCHECK(filter_value & 32);
826 810
827 // Find the number of own properties for each of the objects. 811 return *isolate->factory()->NewJSArrayWithElements(keys);
828 int total_property_count = 0;
829 for (PrototypeIterator iter(isolate, object,
830 PrototypeIterator::START_AT_RECEIVER);
831 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
832 // Casting to JSObject is fine because |object| is guaranteed to be one,
833 // and we'll only look at hidden prototypes which are never JSProxies.
834 Handle<JSObject> jsproto = PrototypeIterator::GetCurrent<JSObject>(iter);
835 total_property_count += jsproto->NumberOfOwnProperties(filter);
836 }
837
838 // Allocate an array with storage for all the property names.
839 Handle<FixedArray> names =
840 isolate->factory()->NewFixedArray(total_property_count);
841
842 // Get the property names.
843 int next_copy_index = 0;
844 int hidden_strings = 0;
845 Handle<Object> hidden_string = isolate->factory()->hidden_string();
846 for (PrototypeIterator iter(isolate, object,
847 PrototypeIterator::START_AT_RECEIVER);
848 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
849 // Casting to JSObject is fine because |object| is guaranteed to be one,
850 // and we'll only look at hidden prototypes which are never JSProxies.
851 Handle<JSObject> jsproto = PrototypeIterator::GetCurrent<JSObject>(iter);
852 int own = jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
853 // Names from hidden prototypes may already have been added
854 // for inherited function template instances. Count the duplicates
855 // and stub them out; the final copy pass at the end ignores holes.
856 for (int j = next_copy_index; j < next_copy_index + own; j++) {
857 Object* name_from_hidden_proto = names->get(j);
858 if (isolate->IsInternallyUsedPropertyName(name_from_hidden_proto)) {
859 hidden_strings++;
860 } else {
861 for (int k = 0; k < next_copy_index; k++) {
862 Object* name = names->get(k);
863 if (name_from_hidden_proto == name) {
864 names->set(j, *hidden_string);
865 hidden_strings++;
866 break;
867 }
868 }
869 }
870 }
871 next_copy_index += own;
872 }
873
874 CHECK_EQ(total_property_count, next_copy_index);
875
876 if (object->IsAccessCheckNeeded() &&
877 !isolate->MayAccess(handle(isolate->context()), object)) {
878 for (int i = 0; i < total_property_count; i++) {
879 Handle<Name> name(Name::cast(names->get(i)));
880 if (name.is_identical_to(hidden_string)) continue;
881 LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
882 if (!JSObject::AllCanRead(&it)) {
883 names->set(i, *hidden_string);
884 hidden_strings++;
885 }
886 }
887 }
888
889 // Filter out name of hidden properties object and
890 // hidden prototype duplicates.
891 if (hidden_strings > 0) {
892 if (hidden_strings == total_property_count) {
893 names = isolate->factory()->empty_fixed_array();
894 } else {
895 int i;
896 for (i = 0; i < total_property_count; i++) {
897 Object* name = names->get(i);
898 if (name == *hidden_string) break;
899 }
900 int dest_pos = i;
901 for (; i < total_property_count; i++) {
902 Object* name = names->get(i);
903 if (name == *hidden_string) continue;
904 names->set(dest_pos++, name);
905 }
906
907 isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
908 *names, hidden_strings);
909 }
910 }
911
912 return *isolate->factory()->NewJSArrayWithElements(names);
913 } 812 }
914 813
915 814
916 // Return the names of the own indexed properties.
917 // args[0]: object
918 RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
919 HandleScope scope(isolate);
920 DCHECK(args.length() == 1);
921 if (!args[0]->IsJSObject()) {
922 return isolate->heap()->undefined_value();
923 }
924 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
925
926 // TODO(cbruni): implement proper prototype lookup like in GetOwnPropertyNames
927 if (object->IsJSGlobalProxy()) {
928 // All the elements are stored on the globa_object and not directly on the
929 // global object proxy.
930 PrototypeIterator iter(isolate, object,
931 PrototypeIterator::START_AT_PROTOTYPE);
932 if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
933 return *isolate->factory()->NewJSArray(0);
934 }
935 // Casting to JSObject is fine because |object| is guaranteed to be one,
936 // and we'll only look at hidden prototypes which are never JSProxies.
937 object = PrototypeIterator::GetCurrent<JSObject>(iter);
938 }
939
940 int n = object->NumberOfOwnElements(ALL_PROPERTIES);
941 Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
942 object->GetOwnElementKeys(*names, ALL_PROPERTIES);
943 return *isolate->factory()->NewJSArrayWithElements(names);
944 }
945
946
947 // Return information on whether an object has a named or indexed interceptor. 815 // Return information on whether an object has a named or indexed interceptor.
948 // args[0]: object 816 // args[0]: object
949 RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) { 817 RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
950 HandleScope scope(isolate); 818 HandleScope scope(isolate);
951 DCHECK(args.length() == 1); 819 DCHECK(args.length() == 1);
952 if (!args[0]->IsJSObject()) { 820 if (!args[0]->IsJSObject()) {
953 return Smi::FromInt(0); 821 return Smi::FromInt(0);
954 } 822 }
955 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 823 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
956 824
957 int result = 0; 825 int result = 0;
958 if (obj->HasNamedInterceptor()) result |= 2; 826 if (obj->HasNamedInterceptor()) result |= 2;
959 if (obj->HasIndexedInterceptor()) result |= 1; 827 if (obj->HasIndexedInterceptor()) result |= 1;
960 828
961 return Smi::FromInt(result); 829 return Smi::FromInt(result);
962 } 830 }
963 831
964 832
965 // Return property names from named interceptor.
966 // args[0]: object
967 RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
968 HandleScope scope(isolate);
969 DCHECK(args.length() == 1);
970 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
971
972 if (obj->HasNamedInterceptor()) {
973 Handle<JSObject> result;
974 if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
975 return *result;
976 }
977 }
978 return isolate->heap()->undefined_value();
979 }
980
981
982 // Return element names from indexed interceptor.
983 // args[0]: object
984 RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
985 HandleScope scope(isolate);
986 DCHECK(args.length() == 1);
987 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
988
989 if (obj->HasIndexedInterceptor()) {
990 Handle<JSObject> result;
991 if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
992 return *result;
993 }
994 }
995 return isolate->heap()->undefined_value();
996 }
997
998
999 RUNTIME_FUNCTION(Runtime_OwnKeys) {
1000 HandleScope scope(isolate);
1001 DCHECK(args.length() == 1);
1002 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
1003
1004 Handle<FixedArray> contents;
1005 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1006 isolate, contents,
1007 JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY, ENUMERABLE_STRINGS,
1008 CONVERT_TO_STRING));
1009 return *isolate->factory()->NewJSArrayWithElements(contents);
1010 }
1011
1012
1013 RUNTIME_FUNCTION(Runtime_ToFastProperties) { 833 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
1014 HandleScope scope(isolate); 834 HandleScope scope(isolate);
1015 DCHECK(args.length() == 1); 835 DCHECK(args.length() == 1);
1016 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); 836 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
1017 if (object->IsJSObject() && !object->IsJSGlobalObject()) { 837 if (object->IsJSObject() && !object->IsJSGlobalObject()) {
1018 JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0, 838 JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0,
1019 "RuntimeToFastProperties"); 839 "RuntimeToFastProperties");
1020 } 840 }
1021 return *object; 841 return *object;
1022 } 842 }
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 1418
1599 RUNTIME_FUNCTION(Runtime_ObjectDefineProperties) { 1419 RUNTIME_FUNCTION(Runtime_ObjectDefineProperties) {
1600 HandleScope scope(isolate); 1420 HandleScope scope(isolate);
1601 DCHECK(args.length() == 2); 1421 DCHECK(args.length() == 2);
1602 CONVERT_ARG_HANDLE_CHECKED(Object, o, 0); 1422 CONVERT_ARG_HANDLE_CHECKED(Object, o, 0);
1603 CONVERT_ARG_HANDLE_CHECKED(Object, properties, 1); 1423 CONVERT_ARG_HANDLE_CHECKED(Object, properties, 1);
1604 return JSReceiver::DefineProperties(isolate, o, properties); 1424 return JSReceiver::DefineProperties(isolate, o, properties);
1605 } 1425 }
1606 } // namespace internal 1426 } // namespace internal
1607 } // namespace v8 1427 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698