OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 1881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1892 | 1892 |
1893 | 1893 |
1894 DART_EXPORT Dart_Handle Dart_ListLength(Dart_Handle list, intptr_t* len) { | 1894 DART_EXPORT Dart_Handle Dart_ListLength(Dart_Handle list, intptr_t* len) { |
1895 Isolate* isolate = Isolate::Current(); | 1895 Isolate* isolate = Isolate::Current(); |
1896 DARTSCOPE(isolate); | 1896 DARTSCOPE(isolate); |
1897 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); | 1897 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); |
1898 if (obj.IsError()) { | 1898 if (obj.IsError()) { |
1899 // Pass through errors. | 1899 // Pass through errors. |
1900 return list; | 1900 return list; |
1901 } | 1901 } |
1902 if (obj.IsByteArray()) { | 1902 if (obj.IsTypedData()) { |
1903 GET_LIST_LENGTH(isolate, ByteArray, obj, len); | 1903 GET_LIST_LENGTH(isolate, TypedData, obj, len); |
1904 } | 1904 } |
1905 if (obj.IsArray()) { | 1905 if (obj.IsArray()) { |
1906 GET_LIST_LENGTH(isolate, Array, obj, len); | 1906 GET_LIST_LENGTH(isolate, Array, obj, len); |
1907 } | 1907 } |
1908 if (obj.IsGrowableObjectArray()) { | 1908 if (obj.IsGrowableObjectArray()) { |
1909 GET_LIST_LENGTH(isolate, GrowableObjectArray, obj, len); | 1909 GET_LIST_LENGTH(isolate, GrowableObjectArray, obj, len); |
1910 } | 1910 } |
1911 if (obj.IsExternalTypedData()) { | |
1912 GET_LIST_LENGTH(isolate, ExternalTypedData, obj, len); | |
1913 } | |
1911 CHECK_CALLBACK_STATE(isolate); | 1914 CHECK_CALLBACK_STATE(isolate); |
1912 | 1915 |
1913 // Now check and handle a dart object that implements the List interface. | 1916 // Now check and handle a dart object that implements the List interface. |
1914 const Instance& instance = | 1917 const Instance& instance = |
1915 Instance::Handle(isolate, GetListInstance(isolate, obj)); | 1918 Instance::Handle(isolate, GetListInstance(isolate, obj)); |
1916 if (instance.IsNull()) { | 1919 if (instance.IsNull()) { |
1917 return Api::NewError("Object does not implement the List interface"); | 1920 return Api::NewError("Object does not implement the List interface"); |
1918 } | 1921 } |
1919 const String& name = String::Handle(Field::GetterName(Symbols::Length())); | 1922 const String& name = String::Handle(Field::GetterName(Symbols::Length())); |
1920 const Function& function = | 1923 const Function& function = |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2163 return Api::NewError("Invalid length passed in to access array elements"); \ | 2166 return Api::NewError("Invalid length passed in to access array elements"); \ |
2164 | 2167 |
2165 | 2168 |
2166 DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, | 2169 DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, |
2167 intptr_t offset, | 2170 intptr_t offset, |
2168 uint8_t* native_array, | 2171 uint8_t* native_array, |
2169 intptr_t length) { | 2172 intptr_t length) { |
2170 Isolate* isolate = Isolate::Current(); | 2173 Isolate* isolate = Isolate::Current(); |
2171 DARTSCOPE(isolate); | 2174 DARTSCOPE(isolate); |
2172 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); | 2175 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); |
2173 if (obj.IsUint8Array() || obj.IsExternalUint8Array() || | 2176 if (obj.IsTypedData()) { |
2174 obj.IsUint8ClampedArray() || obj.IsExternalUint8ClampedArray() || | 2177 const TypedData& array = TypedData::Cast(obj); |
2175 obj.IsInt8Array() || obj.IsExternalInt8Array()) { | 2178 if (array.ElementSizeInBytes() == 1) { |
Ivan Posva
2013/03/29 00:42:22
So it is not possible to get the byte sized chunks
siva
2013/03/29 18:02:33
This code of getting truncated values out of a Lis
| |
2176 const ByteArray& byte_array = ByteArray::Cast(obj); | 2179 if (Utils::RangeCheck(offset, length, array.Length())) { |
2177 if (Utils::RangeCheck(offset, length, byte_array.Length())) { | 2180 NoGCScope no_gc; |
2178 ByteArray::Copy(native_array, byte_array, offset, length); | 2181 memmove(native_array, |
2179 return Api::Success(isolate); | 2182 reinterpret_cast<uint8_t*>(array.DataAddr(offset)), |
2183 length); | |
2184 return Api::Success(isolate); | |
2185 } | |
2186 return Api::NewError("Invalid length passed in to access list elements"); | |
2180 } | 2187 } |
2181 return Api::NewError("Invalid length passed in to access list elements"); | 2188 } |
Ivan Posva
2013/03/29 00:42:22
Why did you go away from the if-else if-else if-el
siva
2013/03/29 18:02:33
I had to do it above because of the fall through i
| |
2182 } else if (obj.IsArray()) { | 2189 if (obj.IsArray()) { |
2183 GET_LIST_ELEMENT_AS_BYTES(isolate, | 2190 GET_LIST_ELEMENT_AS_BYTES(isolate, |
2184 Array, | 2191 Array, |
2185 obj, | 2192 obj, |
2186 native_array, | 2193 native_array, |
2187 offset, | 2194 offset, |
2188 length); | 2195 length); |
2189 } else if (obj.IsGrowableObjectArray()) { | 2196 } |
2197 if (obj.IsGrowableObjectArray()) { | |
2190 GET_LIST_ELEMENT_AS_BYTES(isolate, | 2198 GET_LIST_ELEMENT_AS_BYTES(isolate, |
2191 GrowableObjectArray, | 2199 GrowableObjectArray, |
2192 obj, | 2200 obj, |
2193 native_array, | 2201 native_array, |
2194 offset, | 2202 offset, |
2195 length); | 2203 length); |
2196 } else if (obj.IsError()) { | 2204 } |
2205 if (obj.IsError()) { | |
2197 return list; | 2206 return list; |
2198 } else { | 2207 } |
2199 CHECK_CALLBACK_STATE(isolate); | 2208 CHECK_CALLBACK_STATE(isolate); |
2200 | 2209 |
2201 // Check and handle a dart object that implements the List interface. | 2210 // Check and handle a dart object that implements the List interface. |
2202 const Instance& instance = | 2211 const Instance& instance = |
2203 Instance::Handle(isolate, GetListInstance(isolate, obj)); | 2212 Instance::Handle(isolate, GetListInstance(isolate, obj)); |
2204 if (!instance.IsNull()) { | 2213 if (!instance.IsNull()) { |
2205 const Function& function = Function::Handle( | 2214 const Function& function = Function::Handle( |
2206 isolate, | 2215 isolate, |
2207 Resolver::ResolveDynamic(instance, Symbols::IndexToken(), 2, 0)); | 2216 Resolver::ResolveDynamic(instance, Symbols::IndexToken(), 2, 0)); |
2208 if (!function.IsNull()) { | 2217 if (!function.IsNull()) { |
2209 Object& result = Object::Handle(isolate); | 2218 Object& result = Object::Handle(isolate); |
2210 Integer& intobj = Integer::Handle(isolate); | 2219 Integer& intobj = Integer::Handle(isolate); |
2211 const int kNumArgs = 2; | 2220 const int kNumArgs = 2; |
2212 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); | 2221 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
2213 args.SetAt(0, instance); // Set up the receiver as the first argument. | 2222 args.SetAt(0, instance); // Set up the receiver as the first argument. |
2214 for (int i = 0; i < length; i++) { | 2223 for (int i = 0; i < length; i++) { |
2215 intobj = Integer::New(offset + i); | 2224 intobj = Integer::New(offset + i); |
2216 args.SetAt(1, intobj); | 2225 args.SetAt(1, intobj); |
2217 result = DartEntry::InvokeFunction(function, args); | 2226 result = DartEntry::InvokeFunction(function, args); |
2218 if (result.IsError()) { | 2227 if (result.IsError()) { |
2219 return Api::NewHandle(isolate, result.raw()); | 2228 return Api::NewHandle(isolate, result.raw()); |
2220 } | |
2221 if (!result.IsInteger()) { | |
2222 return Api::NewError("%s expects the argument 'list' to be " | |
2223 "a List of int", CURRENT_FUNC); | |
2224 } | |
2225 const Integer& integer_result = Integer::Cast(result); | |
2226 ASSERT(integer_result.AsInt64Value() <= 0xff); | |
2227 // TODO(hpayer): value should always be smaller then 0xff. Add error | |
2228 // handling. | |
2229 native_array[i] = | |
2230 static_cast<uint8_t>(integer_result.AsInt64Value() & 0xff); | |
2231 } | 2229 } |
2232 return Api::Success(isolate); | 2230 if (!result.IsInteger()) { |
2231 return Api::NewError("%s expects the argument 'list' to be " | |
2232 "a List of int", CURRENT_FUNC); | |
2233 } | |
2234 const Integer& integer_result = Integer::Cast(result); | |
2235 ASSERT(integer_result.AsInt64Value() <= 0xff); | |
2236 // TODO(hpayer): value should always be smaller then 0xff. Add error | |
2237 // handling. | |
2238 native_array[i] = | |
2239 static_cast<uint8_t>(integer_result.AsInt64Value() & 0xff); | |
2233 } | 2240 } |
2241 return Api::Success(isolate); | |
2234 } | 2242 } |
2235 return Api::NewError("Object does not implement the 'List' interface"); | |
2236 } | 2243 } |
2244 return Api::NewError("Object does not implement the 'List' interface"); | |
2237 } | 2245 } |
2238 | 2246 |
2239 | 2247 |
2240 #define SET_LIST_ELEMENT_AS_BYTES(isolate, type, obj, native_array, offset, \ | 2248 #define SET_LIST_ELEMENT_AS_BYTES(isolate, type, obj, native_array, offset, \ |
2241 length) \ | 2249 length) \ |
2242 const type& array = type::Cast(obj); \ | 2250 const type& array = type::Cast(obj); \ |
2243 Integer& integer = Integer::Handle(isolate); \ | 2251 Integer& integer = Integer::Handle(isolate); \ |
2244 if (Utils::RangeCheck(offset, length, array.Length())) { \ | 2252 if (Utils::RangeCheck(offset, length, array.Length())) { \ |
2245 for (int i = 0; i < length; i++) { \ | 2253 for (int i = 0; i < length; i++) { \ |
2246 integer = Integer::New(native_array[i]); \ | 2254 integer = Integer::New(native_array[i]); \ |
2247 array.SetAt(offset + i, integer); \ | 2255 array.SetAt(offset + i, integer); \ |
2248 } \ | 2256 } \ |
2249 return Api::Success(isolate); \ | 2257 return Api::Success(isolate); \ |
2250 } \ | 2258 } \ |
2251 return Api::NewError("Invalid length passed in to set array elements"); \ | 2259 return Api::NewError("Invalid length passed in to set array elements"); \ |
2252 | 2260 |
2253 | 2261 |
2254 DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list, | 2262 DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list, |
2255 intptr_t offset, | 2263 intptr_t offset, |
2256 uint8_t* native_array, | 2264 uint8_t* native_array, |
2257 intptr_t length) { | 2265 intptr_t length) { |
2258 Isolate* isolate = Isolate::Current(); | 2266 Isolate* isolate = Isolate::Current(); |
2259 DARTSCOPE(isolate); | 2267 DARTSCOPE(isolate); |
2260 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); | 2268 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); |
2261 if (obj.IsUint8Array() || obj.IsExternalUint8Array() || | 2269 if (obj.IsTypedData()) { |
2262 obj.IsUint8ClampedArray() || obj.IsExternalUint8ClampedArray()) { | 2270 const TypedData& array = TypedData::Cast(obj); |
2263 const ByteArray& byte_array = ByteArray::Cast(obj); | 2271 if (array.ElementSizeInBytes() == 1) { |
Ivan Posva
2013/03/29 00:42:22
ditto
siva
2013/03/29 18:02:33
I had to do it above because of the fall through i
| |
2264 if (Utils::RangeCheck(offset, length, byte_array.Length())) { | 2272 if (Utils::RangeCheck(offset, length, array.Length())) { |
2265 ByteArray::Copy(byte_array, offset, native_array, length); | 2273 NoGCScope no_gc; |
2266 return Api::Success(isolate); | 2274 memmove(reinterpret_cast<uint8_t*>(array.DataAddr(offset)), |
2275 native_array, | |
2276 length); | |
2277 return Api::Success(isolate); | |
2278 } | |
2279 return Api::NewError("Invalid length passed in to access list elements"); | |
2267 } | 2280 } |
2268 return Api::NewError("Invalid length passed in to set list elements"); | 2281 } |
2269 } else if (obj.IsArray() && !obj.IsImmutableArray()) { | 2282 if (obj.IsArray() && !obj.IsImmutableArray()) { |
2270 // If the list is immutable we call into Dart for the indexed setter to | 2283 // If the list is immutable we call into Dart for the indexed setter to |
2271 // get the unsupported operation exception as the result. | 2284 // get the unsupported operation exception as the result. |
2272 SET_LIST_ELEMENT_AS_BYTES(isolate, | 2285 SET_LIST_ELEMENT_AS_BYTES(isolate, |
2273 Array, | 2286 Array, |
2274 obj, | 2287 obj, |
2275 native_array, | 2288 native_array, |
2276 offset, | 2289 offset, |
2277 length); | 2290 length); |
2278 } else if (obj.IsGrowableObjectArray()) { | 2291 } |
2292 if (obj.IsGrowableObjectArray()) { | |
2279 SET_LIST_ELEMENT_AS_BYTES(isolate, | 2293 SET_LIST_ELEMENT_AS_BYTES(isolate, |
2280 GrowableObjectArray, | 2294 GrowableObjectArray, |
2281 obj, | 2295 obj, |
2282 native_array, | 2296 native_array, |
2283 offset, | 2297 offset, |
2284 length); | 2298 length); |
2285 } else if (obj.IsError()) { | 2299 } |
2300 if (obj.IsError()) { | |
2286 return list; | 2301 return list; |
2287 } else { | 2302 } |
2288 CHECK_CALLBACK_STATE(isolate); | 2303 CHECK_CALLBACK_STATE(isolate); |
2289 | 2304 |
2290 // Check and handle a dart object that implements the List interface. | 2305 // Check and handle a dart object that implements the List interface. |
2291 const Instance& instance = | 2306 const Instance& instance = |
2292 Instance::Handle(isolate, GetListInstance(isolate, obj)); | 2307 Instance::Handle(isolate, GetListInstance(isolate, obj)); |
2293 if (!instance.IsNull()) { | 2308 if (!instance.IsNull()) { |
2294 const Function& function = Function::Handle( | 2309 const Function& function = Function::Handle( |
2295 isolate, | 2310 isolate, |
2296 Resolver::ResolveDynamic(instance, | 2311 Resolver::ResolveDynamic(instance, |
2297 Symbols::AssignIndexToken(), | 2312 Symbols::AssignIndexToken(), |
2298 3, | 2313 3, |
2299 0)); | 2314 0)); |
2300 if (!function.IsNull()) { | 2315 if (!function.IsNull()) { |
2301 Integer& indexobj = Integer::Handle(isolate); | 2316 Integer& indexobj = Integer::Handle(isolate); |
2302 Integer& valueobj = Integer::Handle(isolate); | 2317 Integer& valueobj = Integer::Handle(isolate); |
2303 const int kNumArgs = 3; | 2318 const int kNumArgs = 3; |
2304 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); | 2319 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
2305 args.SetAt(0, instance); // Set up the receiver as the first argument. | 2320 args.SetAt(0, instance); // Set up the receiver as the first argument. |
2306 for (int i = 0; i < length; i++) { | 2321 for (int i = 0; i < length; i++) { |
2307 indexobj = Integer::New(offset + i); | 2322 indexobj = Integer::New(offset + i); |
2308 valueobj = Integer::New(native_array[i]); | 2323 valueobj = Integer::New(native_array[i]); |
2309 args.SetAt(1, indexobj); | 2324 args.SetAt(1, indexobj); |
2310 args.SetAt(2, valueobj); | 2325 args.SetAt(2, valueobj); |
2311 const Object& result = Object::Handle( | 2326 const Object& result = Object::Handle( |
2312 isolate, DartEntry::InvokeFunction(function, args)); | 2327 isolate, DartEntry::InvokeFunction(function, args)); |
2313 if (result.IsError()) { | 2328 if (result.IsError()) { |
2314 return Api::NewHandle(isolate, result.raw()); | 2329 return Api::NewHandle(isolate, result.raw()); |
2315 } | |
2316 } | 2330 } |
2317 return Api::Success(isolate); | |
2318 } | 2331 } |
2332 return Api::Success(isolate); | |
2319 } | 2333 } |
2320 return Api::NewError("Object does not implement the 'List' interface"); | |
2321 } | 2334 } |
2335 return Api::NewError("Object does not implement the 'List' interface"); | |
2322 } | 2336 } |
2323 | 2337 |
2324 | 2338 |
2325 // --- Typed Data --- | 2339 // --- Typed Data --- |
2326 | 2340 |
2327 | 2341 |
2328 // Helper method to get the type of a TypedData object. | 2342 // Helper method to get the type of a TypedData object. |
2329 static Dart_TypedData_Type GetType(intptr_t class_id) { | 2343 static Dart_TypedData_Type GetType(intptr_t class_id) { |
2330 Dart_TypedData_Type type; | 2344 Dart_TypedData_Type type; |
2331 switch (class_id) { | 2345 switch (class_id) { |
(...skipping 2469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4801 } | 4815 } |
4802 { | 4816 { |
4803 NoGCScope no_gc; | 4817 NoGCScope no_gc; |
4804 RawObject* raw_obj = obj.raw(); | 4818 RawObject* raw_obj = obj.raw(); |
4805 isolate->heap()->SetPeer(raw_obj, peer); | 4819 isolate->heap()->SetPeer(raw_obj, peer); |
4806 } | 4820 } |
4807 return Api::Success(isolate); | 4821 return Api::Success(isolate); |
4808 } | 4822 } |
4809 | 4823 |
4810 } // namespace dart | 4824 } // namespace dart |
OLD | NEW |