Chromium Code Reviews| 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 |