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

Side by Side Diff: vm/dart_api_impl.cc

Issue 8417003: Enhance the array access API to deal with any objct that implements the list interface. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: '' Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | vm/dart_api_impl_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "include/dart_api.h" 5 #include "include/dart_api.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart.h" 10 #include "vm/dart.h"
(...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 } 842 }
843 strncpy(res, string_value, string_length + 1); 843 strncpy(res, string_value, string_length + 1);
844 ASSERT(res[string_length] == '\0'); 844 ASSERT(res[string_length] == '\0');
845 *result = res; 845 *result = res;
846 return Api::Success(); 846 return Api::Success();
847 } 847 }
848 return Api::Error("Object is not a String"); 848 return Api::Error("Object is not a String");
849 } 849 }
850 850
851 851
852 static RawInstance* GetListInstance(Isolate* isolate, const Object& obj) {
853 if (obj.IsInstance()) {
854 Instance& instance = Instance::Handle();
855 instance ^= obj.raw();
856 const Type& type = Type::Handle(isolate->object_store()->list_interface());
857 return instance.Is(type) ? instance.raw() : Instance::null();
858 }
859 return Instance::null();
860 }
861
862
852 DART_EXPORT bool Dart_IsArray(Dart_Handle object) { 863 DART_EXPORT bool Dart_IsArray(Dart_Handle object) {
853 Zone zone; // Setup a VM zone as we are creating some handles. 864 Zone zone; // Setup a VM zone as we are creating some handles.
854 HandleScope scope; // Setup a VM handle scope. 865 HandleScope scope; // Setup a VM handle scope.
855 const Object& obj = Object::Handle(Api::UnwrapHandle(object)); 866 const Object& obj = Object::Handle(Api::UnwrapHandle(object));
856 return obj.IsArray(); 867 // TODO(5526318): Make access to GrowableObjectArray more efficient.
868 return (obj.IsArray() || (GetListInstance(Isolate::Current(), obj) !=
869 Instance::null()));
857 } 870 }
858 871
859 872
860 DART_EXPORT Dart_Handle Dart_NewArray(intptr_t length) { 873 DART_EXPORT Dart_Handle Dart_NewArray(intptr_t length) {
861 Zone zone; // Setup a VM zone as we are creating some handles. 874 Zone zone; // Setup a VM zone as we are creating some handles.
862 HandleScope scope; // Setup a VM handle scope. 875 HandleScope scope; // Setup a VM handle scope.
863 const Array& obj = Array::Handle(Array::New(length)); 876 const Array& obj = Array::Handle(Array::New(length));
864 return Api::NewLocalHandle(obj); 877 return Api::NewLocalHandle(obj);
865 } 878 }
866 879
867 880
868 DART_EXPORT Dart_Handle Dart_GetLength(Dart_Handle array, intptr_t* len) { 881 DART_EXPORT Dart_Handle Dart_GetLength(Dart_Handle array, intptr_t* len) {
869 Zone zone; // Setup a VM zone as we are creating some handles. 882 Zone zone; // Setup a VM zone as we are creating some handles.
870 HandleScope scope; // Setup a VM handle scope. 883 HandleScope scope; // Setup a VM handle scope.
871 const Object& obj = Object::Handle(Api::UnwrapHandle(array)); 884 const Object& obj = Object::Handle(Api::UnwrapHandle(array));
872 if (obj.IsArray()) { 885 if (obj.IsArray()) {
873 Array& array_obj = Array::Handle(); 886 Array& array_obj = Array::Handle();
874 array_obj ^= obj.raw(); 887 array_obj ^= obj.raw();
875 *len = array_obj.Length(); 888 *len = array_obj.Length();
876 return Api::Success(); 889 return Api::Success();
877 } 890 }
878 return Api::Error("Object is not an Array"); 891 // TODO(5526318): Make access to GrowableObjectArray more efficient.
892 // Now check and handle a dart object that implements the List interface.
893 Isolate* isolate = Isolate::Current();
894 const Instance& instance = Instance::Handle(GetListInstance(isolate, obj));
895 if (!instance.IsNull()) {
896 String& name = String::Handle(String::New("length"));
897 name = Field::GetterName(name);
898 const Function& function = Function::Handle(
899 Resolver::ResolveDynamic(instance, name, 1, 0));
900 if (!function.IsNull()) {
901 GrowableArray<const Object*> args(0);
902 LongJump* base = isolate->long_jump_base();
903 LongJump jump;
904 isolate->set_long_jump_base(&jump);
905 Dart_Handle result;
906 if (setjmp(*jump.Set()) == 0) {
907 const Array& kNoArgumentNames = Array::Handle();
908 const Instance& retval = Instance::Handle(
909 DartEntry::InvokeDynamic(instance,
910 function,
911 args,
912 kNoArgumentNames));
913 result = Api::Success();
914 if (retval.IsSmi() || retval.IsMint()) {
915 Integer& integer = Integer::Handle();
916 integer ^= retval.raw();
917 *len = integer.AsInt64Value();
918 } else if (retval.IsBigint()) {
919 Bigint& bigint = Bigint::Handle();
920 bigint ^= retval.raw();
921 if (BigintOperations::FitsIntoInt64(bigint)) {
922 *len = BigintOperations::ToInt64(bigint);
923 } else {
924 result = Api::Error("Length of List object is greater than the "
925 "maximum value that 'len' parameter can hold");
926 }
927 } else {
928 result = Api::Error("Length of List object is not an integer");
929 }
930 } else {
931 SetupErrorResult(&result);
932 }
933 isolate->set_long_jump_base(base);
934 return result;
935 }
936 }
937 return Api::Error("Object does not implement the list inteface");
938 }
939
940
941 static RawObject* GetArrayAt(Isolate* isolate,
942 const Instance& instance,
943 const Integer& index,
944 const Function& function,
945 Dart_Handle* result) {
946 ASSERT(isolate != NULL);
947 ASSERT(result != NULL);
948 LongJump* base = isolate->long_jump_base();
949 LongJump jump;
950 isolate->set_long_jump_base(&jump);
951 if (setjmp(*jump.Set()) == 0) {
952 Instance& retval = Instance::Handle();
953 GrowableArray<const Object*> args(0);
954 args.Add(&index);
955 const Array& kNoArgumentNames = Array::Handle();
956 retval = DartEntry::InvokeDynamic(instance,
957 function,
958 args,
959 kNoArgumentNames);
960 if (retval.IsUnhandledException()) {
961 *result = Api::Error("Unexpected exception in '[]'");
962 } else {
963 *result = Api::Success();
964 }
965 isolate->set_long_jump_base(base);
966 return retval.raw();
967 }
968 SetupErrorResult(result);
969 isolate->set_long_jump_base(base);
970 return Object::null();
879 } 971 }
880 972
881 973
882 DART_EXPORT Dart_Handle Dart_ArrayGet(Dart_Handle array, 974 DART_EXPORT Dart_Handle Dart_ArrayGet(Dart_Handle array,
883 intptr_t offset, 975 intptr_t offset,
884 uint8_t* native_array, 976 uint8_t* native_array,
885 intptr_t length) { 977 intptr_t length) {
886 Zone zone; // Setup a VM zone as we are creating some handles. 978 Zone zone; // Setup a VM zone as we are creating some handles.
887 HandleScope scope; // Setup a VM handle scope. 979 HandleScope scope; // Setup a VM handle scope.
888 const Object& obj = Object::Handle(Api::UnwrapHandle(array)); 980 const Object& obj = Object::Handle(Api::UnwrapHandle(array));
889 if (obj.IsArray()) { 981 if (obj.IsArray()) {
890 Array& array_obj = Array::Handle(); 982 Array& array_obj = Array::Handle();
891 array_obj ^= obj.raw(); 983 array_obj ^= obj.raw();
892 if ((offset + length) <= array_obj.Length()) { 984 if ((offset + length) <= array_obj.Length()) {
893 Object& element = Object::Handle(); 985 Object& element = Object::Handle();
894 Integer& integer = Integer::Handle(); 986 Integer& integer = Integer::Handle();
895 for (int i = 0; i < length; i++) { 987 for (int i = 0; i < length; i++) {
896 element = array_obj.At(offset + i); 988 element = array_obj.At(offset + i);
897 integer ^= element.raw(); 989 integer ^= element.raw();
898 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); 990 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff);
899 ASSERT(integer.AsInt64Value() <= 0xff); 991 ASSERT(integer.AsInt64Value() <= 0xff);
900 // TODO(hpayer): value should always be smaller then 0xff. Add error 992 // TODO(hpayer): value should always be smaller then 0xff. Add error
901 // handling. 993 // handling.
902 } 994 }
903 return Api::Success(); 995 return Api::Success();
904 } 996 }
905 return Api::Error("Invalid length passed in to access array elements"); 997 return Api::Error("Invalid length passed in to access array elements");
906 } 998 }
907 return Api::Error("Object is not an Array"); 999 // TODO(5526318): Make access to GrowableObjectArray more efficient.
1000 // Now check and handle a dart object that implements the List interface.
1001 Isolate* isolate = Isolate::Current();
1002 const Instance& instance = Instance::Handle(GetListInstance(isolate, obj));
1003 if (!instance.IsNull()) {
1004 String& name = String::Handle(String::New("[]"));
1005 const Function& function = Function::Handle(
1006 Resolver::ResolveDynamic(instance, name, 2, 0));
1007 if (!function.IsNull()) {
1008 Object& element = Object::Handle();
1009 Integer& intobj = Integer::Handle();
1010 Dart_Handle result;
1011 for (int i = 0; i < length; i++) {
1012 intobj = Integer::New(offset + i);
1013 element = GetArrayAt(isolate, instance, intobj, function, &result);
1014 if (!Dart_IsValid(result)) {
1015 return result; // Error condition.
1016 }
1017 intobj ^= element.raw();
1018 ASSERT(intobj.AsInt64Value() <= 0xff);
1019 // TODO(hpayer): value should always be smaller then 0xff. Add error
1020 // handling.
1021 native_array[i] = static_cast<uint8_t>(intobj.AsInt64Value() & 0xff);
1022 }
1023 return Api::Success();
1024 }
1025 }
1026 return Api::Error("Object does not implement the 'List' interface");
908 } 1027 }
909 1028
910 1029
911 DART_EXPORT Dart_Handle Dart_ArrayGetAt(Dart_Handle array, intptr_t index) { 1030 DART_EXPORT Dart_Handle Dart_ArrayGetAt(Dart_Handle array, intptr_t index) {
912 Zone zone; // Setup a VM zone as we are creating some handles. 1031 Zone zone; // Setup a VM zone as we are creating some handles.
913 HandleScope scope; // Setup a VM handle scope. 1032 HandleScope scope; // Setup a VM handle scope.
914 const Object& obj = Object::Handle(Api::UnwrapHandle(array)); 1033 const Object& obj = Object::Handle(Api::UnwrapHandle(array));
915 if (obj.IsArray()) { 1034 if (obj.IsArray()) {
916 Array& array_obj = Array::Handle(); 1035 Array& array_obj = Array::Handle();
917 array_obj ^= obj.raw(); 1036 array_obj ^= obj.raw();
918 if ((index >= 0) && (index < array_obj.Length())) { 1037 if ((index >= 0) && (index < array_obj.Length())) {
919 const Object& element = Object::Handle(array_obj.At(index)); 1038 const Object& element = Object::Handle(array_obj.At(index));
920 return Api::NewLocalHandle(element); 1039 return Api::NewLocalHandle(element);
921 } 1040 }
922 return Api::Error("Invalid index passed in to access array element"); 1041 return Api::Error("Invalid index passed in to access array element");
923 } 1042 }
924 return Api::Error("Object is not an Array"); 1043 // TODO(5526318): Make access to GrowableObjectArray more efficient.
1044 // Now check and handle a dart object that implements the List interface.
1045 Isolate* isolate = Isolate::Current();
1046 const Instance& instance = Instance::Handle(GetListInstance(isolate, obj));
1047 if (!instance.IsNull()) {
1048 String& name = String::Handle(String::New("[]"));
1049 const Function& function = Function::Handle(
1050 Resolver::ResolveDynamic(instance, name, 2, 0));
1051 if (!function.IsNull()) {
1052 Object& element = Object::Handle();
1053 Integer& indexobj = Integer::Handle();
1054 Dart_Handle result;
1055 indexobj = Integer::New(index);
1056 element = GetArrayAt(isolate, instance, indexobj, function, &result);
1057 if (!Dart_IsValid(result)) {
1058 return result; // Error condition.
1059 }
1060 return Api::NewLocalHandle(element);
1061 }
1062 }
1063 return Api::Error("Object does not implement the 'List' interface");
1064 }
1065
1066
1067 static void SetArrayAt(Isolate* isolate,
1068 const Instance& instance,
1069 const Integer& index,
1070 const Object& value,
1071 const Function& function,
1072 Dart_Handle* result) {
1073 ASSERT(isolate != NULL);
1074 ASSERT(result != NULL);
1075 LongJump* base = isolate->long_jump_base();
1076 LongJump jump;
1077 isolate->set_long_jump_base(&jump);
1078 if (setjmp(*jump.Set()) == 0) {
1079 GrowableArray<const Object*> args(1);
1080 args.Add(&index);
1081 args.Add(&value);
1082 Instance& retval = Instance::Handle();
1083 const Array& kNoArgumentNames = Array::Handle();
1084 retval = DartEntry::InvokeDynamic(instance,
1085 function,
1086 args,
1087 kNoArgumentNames);
1088 if (retval.IsUnhandledException()) {
1089 *result = Api::Error("Unexpected exception in '[]='");
1090 } else {
1091 *result = Api::Success();
1092 }
1093 } else {
1094 SetupErrorResult(result);
1095 }
1096 isolate->set_long_jump_base(base);
925 } 1097 }
926 1098
927 1099
928 DART_EXPORT Dart_Handle Dart_ArraySet(Dart_Handle array, 1100 DART_EXPORT Dart_Handle Dart_ArraySet(Dart_Handle array,
929 intptr_t offset, 1101 intptr_t offset,
930 uint8_t* native_array, 1102 uint8_t* native_array,
931 intptr_t length) { 1103 intptr_t length) {
932 Zone zone; 1104 Zone zone;
933 HandleScope scope; 1105 HandleScope scope;
934 const Object& obj = Object::Handle(Api::UnwrapHandle(array)); 1106 const Object& obj = Object::Handle(Api::UnwrapHandle(array));
935 if (obj.IsArray()) { 1107 if (obj.IsArray()) {
936 Array& array_obj = Array::Handle(); 1108 Array& array_obj = Array::Handle();
937 array_obj ^= obj.raw(); 1109 array_obj ^= obj.raw();
938 Integer& integer = Integer::Handle(); 1110 Integer& integer = Integer::Handle();
939 if ((offset + length) <= array_obj.Length()) { 1111 if ((offset + length) <= array_obj.Length()) {
940 for (int i = 0; i < length; i++) { 1112 for (int i = 0; i < length; i++) {
941 integer ^= Integer::New(native_array[i]); 1113 integer ^= Integer::New(native_array[i]);
942 array_obj.SetAt(offset + i, integer); 1114 array_obj.SetAt(offset + i, integer);
943 } 1115 }
944 return Api::Success(); 1116 return Api::Success();
945 } 1117 }
946 return Api::Error("Invalid length passed in to set array elements"); 1118 return Api::Error("Invalid length passed in to set array elements");
947 } 1119 }
948 return Api::Error("Object is not an Array"); 1120 // TODO(5526318): Make access to GrowableObjectArray more efficient.
1121 // Now check and handle a dart object that implements the List interface.
1122 Isolate* isolate = Isolate::Current();
1123 const Instance& instance = Instance::Handle(GetListInstance(isolate, obj));
1124 if (!instance.IsNull()) {
1125 String& name = String::Handle(String::New("[]="));
1126 const Function& function = Function::Handle(
1127 Resolver::ResolveDynamic(instance, name, 3, 0));
1128 if (!function.IsNull()) {
1129 Integer& indexobj = Integer::Handle();
1130 Integer& valueobj = Integer::Handle();
1131 Dart_Handle result;
1132 for (int i = 0; i < length; i++) {
1133 indexobj = Integer::New(offset + i);
1134 valueobj ^= Integer::New(native_array[i]);
1135 SetArrayAt(isolate, instance, indexobj, valueobj, function, &result);
1136 if (!Dart_IsValid(result)) {
1137 return result; // Error condition.
1138 }
1139 }
1140 return Api::Success();
1141 }
1142 }
1143 return Api::Error("Object does not implement the 'List' interface");
949 } 1144 }
950 1145
1146
951 DART_EXPORT Dart_Handle Dart_ArraySetAt(Dart_Handle array, 1147 DART_EXPORT Dart_Handle Dart_ArraySetAt(Dart_Handle array,
952 intptr_t index, 1148 intptr_t index,
953 Dart_Handle value) { 1149 Dart_Handle value) {
954 Zone zone; // Setup a VM zone as we are creating some handles. 1150 Zone zone; // Setup a VM zone as we are creating some handles.
955 HandleScope scope; // Setup a VM handle scope. 1151 HandleScope scope; // Setup a VM handle scope.
956 const Object& obj = Object::Handle(Api::UnwrapHandle(array)); 1152 const Object& obj = Object::Handle(Api::UnwrapHandle(array));
957 if (obj.IsArray()) { 1153 if (obj.IsArray()) {
958 Array& array_obj = Array::Handle(); 1154 Array& array_obj = Array::Handle();
959 array_obj ^= obj.raw(); 1155 array_obj ^= obj.raw();
960 const Object& value_obj = Object::Handle(Api::UnwrapHandle(value)); 1156 const Object& value_obj = Object::Handle(Api::UnwrapHandle(value));
961 if ((index >= 0) && (index < array_obj.Length())) { 1157 if ((index >= 0) && (index < array_obj.Length())) {
962 array_obj.SetAt(index, value_obj); 1158 array_obj.SetAt(index, value_obj);
963 return Api::Success(); 1159 return Api::Success();
964 } 1160 }
965 return Api::Error("Invalid index passed in to set array element"); 1161 return Api::Error("Invalid index passed in to set array element");
966 } 1162 }
967 return Api::Error("Object is not an Array"); 1163 // TODO(5526318): Make access to GrowableObjectArray more efficient.
1164 // Now check and handle a dart object that implements the List interface.
1165 Isolate* isolate = Isolate::Current();
1166 const Instance& instance = Instance::Handle(GetListInstance(isolate, obj));
1167 if (!instance.IsNull()) {
1168 String& name = String::Handle(String::New("[]="));
1169 const Function& function = Function::Handle(
1170 Resolver::ResolveDynamic(instance, name, 3, 0));
1171 if (!function.IsNull()) {
1172 Dart_Handle result;
1173 const Integer& index_obj = Integer::Handle(Integer::New(index));
1174 const Object& value_obj = Object::Handle(Api::UnwrapHandle(value));
1175 SetArrayAt(isolate, instance, index_obj, value_obj, function, &result);
1176 return result;
1177 }
1178 }
1179 return Api::Error("Object does not implement the 'List' interface");
968 } 1180 }
969 1181
970 1182
971 // NOTE: Need to pass 'result' as a parameter here in order to avoid 1183 // NOTE: Need to pass 'result' as a parameter here in order to avoid
972 // warning: variable 'result' might be clobbered by 'longjmp' or 'vfork' 1184 // warning: variable 'result' might be clobbered by 'longjmp' or 'vfork'
973 // which shows up because of the use of setjmp. 1185 // which shows up because of the use of setjmp.
974 static void InvokeStatic(const Function& function, 1186 static void InvokeStatic(const Function& function,
975 GrowableArray<const Object*>& args, 1187 GrowableArray<const Object*>& args,
976 Dart_Handle* result) { 1188 Dart_Handle* result) {
977 Isolate* isolate = Isolate::Current(); 1189 Isolate* isolate = Isolate::Current();
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 ASSERT(isolate != NULL); 1985 ASSERT(isolate != NULL);
1774 ApiState* state = isolate->api_state(); 1986 ApiState* state = isolate->api_state();
1775 ASSERT(state != NULL); 1987 ASSERT(state != NULL);
1776 ApiLocalScope* scope = state->top_scope(); 1988 ApiLocalScope* scope = state->top_scope();
1777 ASSERT(scope != NULL); 1989 ASSERT(scope != NULL);
1778 return scope->zone().Reallocate(ptr, old_size, new_size); 1990 return scope->zone().Reallocate(ptr, old_size, new_size);
1779 } 1991 }
1780 1992
1781 1993
1782 } // namespace dart 1994 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698