| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 2222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2233 } | 2233 } |
| 2234 } | 2234 } |
| 2235 return Api::Success(isolate); | 2235 return Api::Success(isolate); |
| 2236 } | 2236 } |
| 2237 } | 2237 } |
| 2238 return Api::NewError("Object does not implement the 'List' interface"); | 2238 return Api::NewError("Object does not implement the 'List' interface"); |
| 2239 } | 2239 } |
| 2240 } | 2240 } |
| 2241 | 2241 |
| 2242 | 2242 |
| 2243 // --- Byte Arrays --- | 2243 // --- Typed Data --- |
| 2244 | 2244 |
| 2245 | 2245 |
| 2246 DART_EXPORT bool Dart_IsByteArray(Dart_Handle object) { | 2246 // Helper method to get the type of a TypedData object. |
| 2247 return RawObject::IsByteArrayClassId(Api::ClassId(object)); | 2247 static Dart_TypedData_Type GetType(intptr_t class_id) { |
| 2248 Dart_TypedData_Type type; |
| 2249 switch (class_id) { |
| 2250 case kByteArrayCid : |
| 2251 type = kByteData; |
| 2252 break; |
| 2253 case kInt8ArrayCid : |
| 2254 case kExternalInt8ArrayCid : |
| 2255 type = kInt8; |
| 2256 break; |
| 2257 case kUint8ArrayCid : |
| 2258 case kExternalUint8ArrayCid : |
| 2259 type = kUint8; |
| 2260 break; |
| 2261 case kUint8ClampedArrayCid : |
| 2262 case kExternalUint8ClampedArrayCid : |
| 2263 type = kUint8Clamped; |
| 2264 break; |
| 2265 case kInt16ArrayCid : |
| 2266 case kExternalInt16ArrayCid : |
| 2267 type = kInt16; |
| 2268 break; |
| 2269 case kUint16ArrayCid : |
| 2270 case kExternalUint16ArrayCid : |
| 2271 type = kUint16; |
| 2272 break; |
| 2273 case kInt32ArrayCid : |
| 2274 case kExternalInt32ArrayCid : |
| 2275 type = kInt32; |
| 2276 break; |
| 2277 case kUint32ArrayCid : |
| 2278 case kExternalUint32ArrayCid : |
| 2279 type = kUint32; |
| 2280 break; |
| 2281 case kInt64ArrayCid : |
| 2282 case kExternalInt64ArrayCid : |
| 2283 type = kInt64; |
| 2284 break; |
| 2285 case kUint64ArrayCid : |
| 2286 case kExternalUint64ArrayCid : |
| 2287 type = kUint64; |
| 2288 break; |
| 2289 case kFloat32ArrayCid : |
| 2290 case kExternalFloat32ArrayCid : |
| 2291 type = kFloat32; |
| 2292 break; |
| 2293 case kFloat64ArrayCid : |
| 2294 case kExternalFloat64ArrayCid : |
| 2295 type = kFloat64; |
| 2296 break; |
| 2297 default: |
| 2298 type = kInvalid; |
| 2299 break; |
| 2300 } |
| 2301 return type; |
| 2248 } | 2302 } |
| 2249 | 2303 |
| 2250 | 2304 |
| 2251 DART_EXPORT bool Dart_IsByteArrayExternal(Dart_Handle object) { | 2305 DART_EXPORT Dart_TypedData_Type Dart_IsTypedData(Dart_Handle object) { |
| 2252 return RawObject::IsExternalByteArrayClassId(Api::ClassId(object)); | 2306 intptr_t class_id = Api::ClassId(object); |
| 2307 return GetType(class_id); |
| 2253 } | 2308 } |
| 2254 | 2309 |
| 2255 | 2310 |
| 2256 DART_EXPORT Dart_Handle Dart_NewByteArray(intptr_t length) { | 2311 DART_EXPORT Dart_TypedData_Type Dart_IsExternalTypedData(Dart_Handle object) { |
| 2257 Isolate* isolate = Isolate::Current(); | 2312 intptr_t class_id = Api::ClassId(object); |
| 2258 DARTSCOPE(isolate); | 2313 if (!RawObject::IsExternalByteArrayClassId(class_id)) { |
| 2259 CHECK_LENGTH(length, Uint8Array::kMaxElements); | 2314 return kInvalid; |
| 2260 CHECK_CALLBACK_STATE(isolate); | 2315 } |
| 2261 return Api::NewHandle(isolate, Uint8Array::New(length)); | 2316 return GetType(class_id); |
| 2262 } | 2317 } |
| 2263 | 2318 |
| 2264 | 2319 |
| 2265 DART_EXPORT Dart_Handle Dart_NewExternalByteArray( | 2320 template<typename type> |
| 2266 uint8_t* data, | 2321 static Dart_Handle NewTypedData(Isolate* isolate, intptr_t length) { |
| 2322 CHECK_LENGTH(length, type::kMaxElements); |
| 2323 return Api::NewHandle(isolate, type::New(length)); |
| 2324 } |
| 2325 |
| 2326 |
| 2327 template<typename type, typename datatype> |
| 2328 static Dart_Handle NewExternalTypedData( |
| 2329 void* data, |
| 2267 intptr_t length, | 2330 intptr_t length, |
| 2268 void* peer, | 2331 void* peer, |
| 2269 Dart_WeakPersistentHandleFinalizer callback) { | 2332 Dart_WeakPersistentHandleFinalizer callback) { |
| 2270 Isolate* isolate = Isolate::Current(); | 2333 CHECK_LENGTH(length, type::kMaxElements); |
| 2271 DARTSCOPE(isolate); | 2334 const type& obj = |
| 2272 if (data == NULL && length != 0) { | 2335 type::Handle(type::New(reinterpret_cast<datatype*>(data), length)); |
| 2273 RETURN_NULL_ERROR(data); | |
| 2274 } | |
| 2275 CHECK_LENGTH(length, ExternalUint8Array::kMaxElements); | |
| 2276 CHECK_CALLBACK_STATE(isolate); | |
| 2277 const ExternalUint8Array& obj = ExternalUint8Array::Handle( | |
| 2278 ExternalUint8Array::New(data, length)); | |
| 2279 return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback)); | 2336 return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback)); |
| 2280 } | 2337 } |
| 2281 | 2338 |
| 2282 | 2339 |
| 2283 DART_EXPORT Dart_Handle Dart_NewExternalClampedByteArray( | 2340 DART_EXPORT Dart_Handle Dart_NewTypedData(Dart_TypedData_Type type, |
| 2284 uint8_t* data, | 2341 intptr_t length) { |
| 2342 Isolate* isolate = Isolate::Current(); |
| 2343 DARTSCOPE(isolate); |
| 2344 CHECK_CALLBACK_STATE(isolate); |
| 2345 switch (type) { |
| 2346 case kByteData : |
| 2347 // TODO(asiva): Add a new ByteArray::New() method. |
| 2348 break; |
| 2349 case kInt8 : |
| 2350 return NewTypedData<Int8Array>(isolate, length); |
| 2351 case kUint8 : |
| 2352 return NewTypedData<Uint8Array>(isolate, length); |
| 2353 case kUint8Clamped : |
| 2354 return NewTypedData<Uint8ClampedArray>(isolate, length); |
| 2355 case kInt16 : |
| 2356 return NewTypedData<Int16Array>(isolate, length); |
| 2357 case kUint16 : |
| 2358 return NewTypedData<Uint16Array>(isolate, length); |
| 2359 case kInt32 : |
| 2360 return NewTypedData<Int32Array>(isolate, length); |
| 2361 case kUint32 : |
| 2362 return NewTypedData<Uint32Array>(isolate, length); |
| 2363 case kInt64 : |
| 2364 return NewTypedData<Int64Array>(isolate, length); |
| 2365 case kUint64 : |
| 2366 return NewTypedData<Uint64Array>(isolate, length); |
| 2367 case kFloat32 : |
| 2368 return NewTypedData<Float32Array>(isolate, length); |
| 2369 case kFloat64 : |
| 2370 return NewTypedData<Float64Array>(isolate, length); |
| 2371 default: |
| 2372 return Api::NewError("%s expects argument 'type' to be of 'TypedData'", |
| 2373 CURRENT_FUNC); |
| 2374 } |
| 2375 UNREACHABLE(); |
| 2376 return Api::Null(isolate); |
| 2377 } |
| 2378 |
| 2379 |
| 2380 DART_EXPORT Dart_Handle Dart_NewExternalTypedData( |
| 2381 void* data, |
| 2382 Dart_TypedData_Type type, |
| 2285 intptr_t length, | 2383 intptr_t length, |
| 2286 void* peer, | 2384 void* peer, |
| 2287 Dart_WeakPersistentHandleFinalizer callback) { | 2385 Dart_WeakPersistentHandleFinalizer callback) { |
| 2288 Isolate* isolate = Isolate::Current(); | 2386 Isolate* isolate = Isolate::Current(); |
| 2289 DARTSCOPE(isolate); | 2387 DARTSCOPE(isolate); |
| 2290 if (data == NULL && length != 0) { | 2388 if (data == NULL && length != 0) { |
| 2291 RETURN_NULL_ERROR(data); | 2389 RETURN_NULL_ERROR(data); |
| 2292 } | 2390 } |
| 2293 CHECK_LENGTH(length, ExternalUint8ClampedArray::kMaxElements); | |
| 2294 CHECK_CALLBACK_STATE(isolate); | 2391 CHECK_CALLBACK_STATE(isolate); |
| 2295 const ExternalUint8ClampedArray& obj = ExternalUint8ClampedArray::Handle( | 2392 switch (type) { |
| 2296 ExternalUint8ClampedArray::New(data, length)); | 2393 case kByteData : |
| 2297 return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback)); | 2394 // TODO(asiva): Allocate external ByteData object. |
| 2395 break; |
| 2396 case kInt8 : |
| 2397 return NewExternalTypedData<ExternalInt8Array, int8_t>(data, |
| 2398 length, |
| 2399 peer, |
| 2400 callback); |
| 2401 case kUint8 : |
| 2402 return NewExternalTypedData<ExternalUint8Array, uint8_t>(data, |
| 2403 length, |
| 2404 peer, |
| 2405 callback); |
| 2406 case kUint8Clamped : |
| 2407 return NewExternalTypedData<ExternalUint8ClampedArray, uint8_t>(data, |
| 2408 length, |
| 2409 peer, |
| 2410 callback); |
| 2411 case kInt16 : |
| 2412 return NewExternalTypedData<ExternalInt16Array, int16_t>(data, |
| 2413 length, |
| 2414 peer, |
| 2415 callback); |
| 2416 case kUint16 : |
| 2417 return NewExternalTypedData<ExternalUint16Array, uint16_t>(data, |
| 2418 length, |
| 2419 peer, |
| 2420 callback); |
| 2421 case kInt32 : |
| 2422 return NewExternalTypedData<ExternalInt32Array, int32_t>(data, |
| 2423 length, |
| 2424 peer, |
| 2425 callback); |
| 2426 case kUint32 : |
| 2427 return NewExternalTypedData<ExternalUint32Array, uint32_t>(data, |
| 2428 length, |
| 2429 peer, |
| 2430 callback); |
| 2431 case kInt64 : |
| 2432 return NewExternalTypedData<ExternalInt64Array, int64_t>(data, |
| 2433 length, |
| 2434 peer, |
| 2435 callback); |
| 2436 case kUint64 : |
| 2437 return NewExternalTypedData<ExternalUint64Array, uint64_t>(data, |
| 2438 length, |
| 2439 peer, |
| 2440 callback); |
| 2441 case kFloat32 : |
| 2442 return NewExternalTypedData<ExternalFloat32Array, float>(data, |
| 2443 length, |
| 2444 peer, |
| 2445 callback); |
| 2446 case kFloat64 : |
| 2447 return NewExternalTypedData<ExternalFloat64Array, double>(data, |
| 2448 length, |
| 2449 peer, |
| 2450 callback); |
| 2451 default: |
| 2452 return Api::NewError("%s expects argument 'type' to be of" |
| 2453 " 'external TypedData'", CURRENT_FUNC); |
| 2454 } |
| 2455 UNREACHABLE(); |
| 2456 return Api::Null(isolate); |
| 2298 } | 2457 } |
| 2299 | 2458 |
| 2300 | 2459 |
| 2301 DART_EXPORT Dart_Handle Dart_ExternalByteArrayGetData(Dart_Handle object, | 2460 DART_EXPORT Dart_Handle Dart_ExternalTypedDataGetPeer(Dart_Handle object, |
| 2302 void** data) { | |
| 2303 Isolate* isolate = Isolate::Current(); | |
| 2304 DARTSCOPE(isolate); | |
| 2305 const ExternalUint8Array& array = | |
| 2306 Api::UnwrapExternalUint8ArrayHandle(isolate, object); | |
| 2307 if (array.IsNull()) { | |
| 2308 RETURN_TYPE_ERROR(isolate, object, ExternalUint8Array); | |
| 2309 } | |
| 2310 if (data == NULL) { | |
| 2311 RETURN_NULL_ERROR(data); | |
| 2312 } | |
| 2313 *data = array.GetData(); | |
| 2314 return Api::Success(isolate); | |
| 2315 } | |
| 2316 | |
| 2317 | |
| 2318 DART_EXPORT Dart_Handle Dart_ExternalByteArrayGetPeer(Dart_Handle object, | |
| 2319 void** peer) { | 2461 void** peer) { |
| 2320 Isolate* isolate = Isolate::Current(); | 2462 Isolate* isolate = Isolate::Current(); |
| 2321 DARTSCOPE(isolate); | 2463 DARTSCOPE(isolate); |
| 2322 const ExternalUint8Array& array = | 2464 const ByteArray& array = |
| 2323 Api::UnwrapExternalUint8ArrayHandle(isolate, object); | 2465 Api::UnwrapByteArrayHandle(isolate, object); |
| 2324 if (array.IsNull()) { | 2466 if (array.IsNull()) { |
| 2325 RETURN_TYPE_ERROR(isolate, object, ExternalUint8Array); | 2467 RETURN_TYPE_ERROR(isolate, object, ByteArray); |
| 2326 } | 2468 } |
| 2327 if (peer == NULL) { | 2469 if (peer == NULL) { |
| 2328 RETURN_NULL_ERROR(peer); | 2470 RETURN_NULL_ERROR(peer); |
| 2329 } | 2471 } |
| 2330 *peer = array.GetPeer(); | 2472 *peer = array.GetPeer(); |
| 2331 return Api::Success(isolate); | 2473 return Api::Success(isolate); |
| 2332 } | 2474 } |
| 2333 | 2475 |
| 2334 | 2476 |
| 2335 DART_EXPORT Dart_Handle Dart_ScalarListAcquireData(Dart_Handle array, | 2477 DART_EXPORT Dart_Handle Dart_TypedDataAcquireData(Dart_Handle object, |
| 2336 Dart_Scalar_Type* type, | 2478 Dart_TypedData_Type* type, |
| 2337 void** data, | 2479 void** data, |
| 2338 intptr_t* len) { | 2480 intptr_t* len) { |
| 2339 Isolate* isolate = Isolate::Current(); | 2481 Isolate* isolate = Isolate::Current(); |
| 2340 DARTSCOPE(isolate); | 2482 DARTSCOPE(isolate); |
| 2341 intptr_t class_id = Api::ClassId(array); | 2483 intptr_t class_id = Api::ClassId(object); |
| 2342 if (!RawObject::IsByteArrayClassId(class_id)) { | 2484 if (!RawObject::IsByteArrayClassId(class_id)) { |
| 2343 RETURN_TYPE_ERROR(isolate, array, 'scalar list'); | 2485 RETURN_TYPE_ERROR(isolate, object, 'TypedData'); |
| 2344 } | 2486 } |
| 2345 if (type == NULL) { | 2487 if (type == NULL) { |
| 2346 RETURN_NULL_ERROR(type); | 2488 RETURN_NULL_ERROR(type); |
| 2347 } | 2489 } |
| 2348 if (data == NULL) { | 2490 if (data == NULL) { |
| 2349 RETURN_NULL_ERROR(data); | 2491 RETURN_NULL_ERROR(data); |
| 2350 } | 2492 } |
| 2351 if (len == NULL) { | 2493 if (len == NULL) { |
| 2352 RETURN_NULL_ERROR(len); | 2494 RETURN_NULL_ERROR(len); |
| 2353 } | 2495 } |
| 2354 // Get the type of typed array. | 2496 // Get the type of typed data object. |
| 2355 switch (class_id) { | 2497 *type = GetType(class_id); |
| 2356 case kByteArrayCid : | 2498 const ByteArray& obj = Api::UnwrapByteArrayHandle(isolate, object); |
| 2357 *type = kByteArray; | |
| 2358 break; | |
| 2359 case kInt8ArrayCid : | |
| 2360 case kExternalInt8ArrayCid : | |
| 2361 *type = kInt8; | |
| 2362 break; | |
| 2363 case kUint8ArrayCid : | |
| 2364 case kExternalUint8ArrayCid : | |
| 2365 *type = kUint8; | |
| 2366 break; | |
| 2367 case kUint8ClampedArrayCid : | |
| 2368 case kExternalUint8ClampedArrayCid : | |
| 2369 *type = kUint8Clamped; | |
| 2370 break; | |
| 2371 case kInt16ArrayCid : | |
| 2372 case kExternalInt16ArrayCid : | |
| 2373 *type = kInt16; | |
| 2374 break; | |
| 2375 case kUint16ArrayCid : | |
| 2376 case kExternalUint16ArrayCid : | |
| 2377 *type = kUint16; | |
| 2378 break; | |
| 2379 case kInt32ArrayCid : | |
| 2380 case kExternalInt32ArrayCid : | |
| 2381 *type = kInt32; | |
| 2382 break; | |
| 2383 case kUint32ArrayCid : | |
| 2384 case kExternalUint32ArrayCid : | |
| 2385 *type = kUint32; | |
| 2386 break; | |
| 2387 case kInt64ArrayCid : | |
| 2388 case kExternalInt64ArrayCid : | |
| 2389 *type = kInt64; | |
| 2390 break; | |
| 2391 case kUint64ArrayCid : | |
| 2392 case kExternalUint64ArrayCid : | |
| 2393 *type = kUint64; | |
| 2394 break; | |
| 2395 case kFloat32ArrayCid : | |
| 2396 case kExternalFloat32ArrayCid : | |
| 2397 *type = kFloat32; | |
| 2398 break; | |
| 2399 case kFloat64ArrayCid : | |
| 2400 case kExternalFloat64ArrayCid : | |
| 2401 *type = kFloat64; | |
| 2402 break; | |
| 2403 } | |
| 2404 const ByteArray& obj = Api::UnwrapByteArrayHandle(isolate, array); | |
| 2405 ASSERT(!obj.IsNull()); | 2499 ASSERT(!obj.IsNull()); |
| 2406 *len = obj.Length(); | 2500 *len = obj.Length(); |
| 2407 // If it is an external typed array object just return the data field. | 2501 // If it is an external typed data object just return the data field. |
| 2408 if (RawObject::IsExternalByteArrayClassId(class_id)) { | 2502 if (RawObject::IsExternalByteArrayClassId(class_id)) { |
| 2409 *data = reinterpret_cast<void*>(obj.ByteAddr(0)); | 2503 *data = reinterpret_cast<void*>(obj.ByteAddr(0)); |
| 2410 } else { | 2504 } else { |
| 2411 // Regular typed array object, set up some GC and API callback guards. | 2505 // Regular typed data object, set up some GC and API callback guards. |
| 2412 isolate->IncrementNoGCScopeDepth(); | 2506 isolate->IncrementNoGCScopeDepth(); |
| 2413 START_NO_CALLBACK_SCOPE(isolate); | 2507 START_NO_CALLBACK_SCOPE(isolate); |
| 2414 *data = reinterpret_cast<void*>(obj.ByteAddr(0)); | 2508 *data = reinterpret_cast<void*>(obj.ByteAddr(0)); |
| 2415 } | 2509 } |
| 2416 return Api::Success(isolate); | 2510 return Api::Success(isolate); |
| 2417 } | 2511 } |
| 2418 | 2512 |
| 2419 | 2513 |
| 2420 DART_EXPORT Dart_Handle Dart_ScalarListReleaseData(Dart_Handle array) { | 2514 DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object) { |
| 2421 Isolate* isolate = Isolate::Current(); | 2515 Isolate* isolate = Isolate::Current(); |
| 2422 DARTSCOPE(isolate); | 2516 DARTSCOPE(isolate); |
| 2423 intptr_t class_id = Api::ClassId(array); | 2517 intptr_t class_id = Api::ClassId(object); |
| 2424 if (!RawObject::IsByteArrayClassId(class_id)) { | 2518 if (!RawObject::IsByteArrayClassId(class_id)) { |
| 2425 RETURN_TYPE_ERROR(isolate, array, 'scalar list'); | 2519 RETURN_TYPE_ERROR(isolate, object, 'TypedData'); |
| 2426 } | 2520 } |
| 2427 if (!RawObject::IsExternalByteArrayClassId(class_id)) { | 2521 if (!RawObject::IsExternalByteArrayClassId(class_id)) { |
| 2428 isolate->DecrementNoGCScopeDepth(); | 2522 isolate->DecrementNoGCScopeDepth(); |
| 2429 END_NO_CALLBACK_SCOPE(isolate); | 2523 END_NO_CALLBACK_SCOPE(isolate); |
| 2430 } | 2524 } |
| 2431 return Api::Success(isolate); | 2525 return Api::Success(isolate); |
| 2432 } | 2526 } |
| 2433 | 2527 |
| 2434 | 2528 |
| 2435 // --- Closures --- | 2529 // --- Closures --- |
| (...skipping 2074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4510 } | 4604 } |
| 4511 { | 4605 { |
| 4512 NoGCScope no_gc; | 4606 NoGCScope no_gc; |
| 4513 RawObject* raw_obj = obj.raw(); | 4607 RawObject* raw_obj = obj.raw(); |
| 4514 isolate->heap()->SetPeer(raw_obj, peer); | 4608 isolate->heap()->SetPeer(raw_obj, peer); |
| 4515 } | 4609 } |
| 4516 return Api::Success(isolate); | 4610 return Api::Success(isolate); |
| 4517 } | 4611 } |
| 4518 | 4612 |
| 4519 } // namespace dart | 4613 } // namespace dart |
| OLD | NEW |