| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |