| 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 "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 2301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2312 } | 2312 } |
| 2313 } | 2313 } |
| 2314 return Api::Success(isolate); | 2314 return Api::Success(isolate); |
| 2315 } | 2315 } |
| 2316 } | 2316 } |
| 2317 return Api::NewError("Object does not implement the 'List' interface"); | 2317 return Api::NewError("Object does not implement the 'List' interface"); |
| 2318 } | 2318 } |
| 2319 } | 2319 } |
| 2320 | 2320 |
| 2321 | 2321 |
| 2322 // --- Byte Arrays --- | 2322 // --- Typed Data --- |
| 2323 | 2323 |
| 2324 | 2324 |
| 2325 DART_EXPORT bool Dart_IsByteArray(Dart_Handle object) { | 2325 // Helper method to get the type of a TypedData object. |
| 2326 return RawObject::IsByteArrayClassId(Api::ClassId(object)); | 2326 static Dart_TypedData_Type GetType(intptr_t class_id) { |
| 2327 Dart_TypedData_Type type; |
| 2328 switch (class_id) { |
| 2329 case kByteArrayCid : |
| 2330 type = kByteData; |
| 2331 break; |
| 2332 case kInt8ArrayCid : |
| 2333 case kExternalInt8ArrayCid : |
| 2334 type = kInt8; |
| 2335 break; |
| 2336 case kUint8ArrayCid : |
| 2337 case kExternalUint8ArrayCid : |
| 2338 type = kUint8; |
| 2339 break; |
| 2340 case kUint8ClampedArrayCid : |
| 2341 case kExternalUint8ClampedArrayCid : |
| 2342 type = kUint8Clamped; |
| 2343 break; |
| 2344 case kInt16ArrayCid : |
| 2345 case kExternalInt16ArrayCid : |
| 2346 type = kInt16; |
| 2347 break; |
| 2348 case kUint16ArrayCid : |
| 2349 case kExternalUint16ArrayCid : |
| 2350 type = kUint16; |
| 2351 break; |
| 2352 case kInt32ArrayCid : |
| 2353 case kExternalInt32ArrayCid : |
| 2354 type = kInt32; |
| 2355 break; |
| 2356 case kUint32ArrayCid : |
| 2357 case kExternalUint32ArrayCid : |
| 2358 type = kUint32; |
| 2359 break; |
| 2360 case kInt64ArrayCid : |
| 2361 case kExternalInt64ArrayCid : |
| 2362 type = kInt64; |
| 2363 break; |
| 2364 case kUint64ArrayCid : |
| 2365 case kExternalUint64ArrayCid : |
| 2366 type = kUint64; |
| 2367 break; |
| 2368 case kFloat32ArrayCid : |
| 2369 case kExternalFloat32ArrayCid : |
| 2370 type = kFloat32; |
| 2371 break; |
| 2372 case kFloat64ArrayCid : |
| 2373 case kExternalFloat64ArrayCid : |
| 2374 type = kFloat64; |
| 2375 break; |
| 2376 default: |
| 2377 type = kInvalid; |
| 2378 break; |
| 2379 } |
| 2380 return type; |
| 2327 } | 2381 } |
| 2328 | 2382 |
| 2329 | 2383 |
| 2330 DART_EXPORT bool Dart_IsByteArrayExternal(Dart_Handle object) { | 2384 DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfTypedData(Dart_Handle object) { |
| 2331 return RawObject::IsExternalByteArrayClassId(Api::ClassId(object)); | 2385 intptr_t class_id = Api::ClassId(object); |
| 2386 return GetType(class_id); |
| 2332 } | 2387 } |
| 2333 | 2388 |
| 2334 | 2389 |
| 2335 DART_EXPORT Dart_Handle Dart_NewByteArray(intptr_t length) { | 2390 DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfExternalTypedData( |
| 2336 Isolate* isolate = Isolate::Current(); | 2391 Dart_Handle object) { |
| 2337 DARTSCOPE(isolate); | 2392 intptr_t class_id = Api::ClassId(object); |
| 2338 CHECK_LENGTH(length, Uint8Array::kMaxElements); | 2393 if (!RawObject::IsExternalByteArrayClassId(class_id)) { |
| 2339 CHECK_CALLBACK_STATE(isolate); | 2394 return kInvalid; |
| 2340 return Api::NewHandle(isolate, Uint8Array::New(length)); | 2395 } |
| 2396 return GetType(class_id); |
| 2341 } | 2397 } |
| 2342 | 2398 |
| 2343 | 2399 |
| 2344 DART_EXPORT Dart_Handle Dart_NewExternalByteArray( | 2400 template<typename type> |
| 2345 uint8_t* data, | 2401 static Dart_Handle NewTypedData(Isolate* isolate, intptr_t length) { |
| 2402 CHECK_LENGTH(length, type::kMaxElements); |
| 2403 return Api::NewHandle(isolate, type::New(length)); |
| 2404 } |
| 2405 |
| 2406 |
| 2407 template<typename type, typename datatype> |
| 2408 static Dart_Handle NewExternalTypedData( |
| 2409 void* data, |
| 2346 intptr_t length, | 2410 intptr_t length, |
| 2347 void* peer, | 2411 void* peer, |
| 2348 Dart_WeakPersistentHandleFinalizer callback) { | 2412 Dart_WeakPersistentHandleFinalizer callback) { |
| 2349 Isolate* isolate = Isolate::Current(); | 2413 CHECK_LENGTH(length, type::kMaxElements); |
| 2350 DARTSCOPE(isolate); | 2414 const type& obj = |
| 2351 if (data == NULL && length != 0) { | 2415 type::Handle(type::New(reinterpret_cast<datatype*>(data), length)); |
| 2352 RETURN_NULL_ERROR(data); | |
| 2353 } | |
| 2354 CHECK_LENGTH(length, ExternalUint8Array::kMaxElements); | |
| 2355 CHECK_CALLBACK_STATE(isolate); | |
| 2356 const ExternalUint8Array& obj = ExternalUint8Array::Handle( | |
| 2357 ExternalUint8Array::New(data, length)); | |
| 2358 return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback)); | 2416 return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback)); |
| 2359 } | 2417 } |
| 2360 | 2418 |
| 2361 | 2419 |
| 2362 DART_EXPORT Dart_Handle Dart_NewExternalClampedByteArray( | 2420 DART_EXPORT Dart_Handle Dart_NewTypedData(Dart_TypedData_Type type, |
| 2363 uint8_t* data, | 2421 intptr_t length) { |
| 2422 Isolate* isolate = Isolate::Current(); |
| 2423 DARTSCOPE(isolate); |
| 2424 CHECK_CALLBACK_STATE(isolate); |
| 2425 switch (type) { |
| 2426 case kByteData : |
| 2427 // TODO(asiva): Add a new ByteArray::New() method. |
| 2428 break; |
| 2429 case kInt8 : |
| 2430 return NewTypedData<Int8Array>(isolate, length); |
| 2431 case kUint8 : |
| 2432 return NewTypedData<Uint8Array>(isolate, length); |
| 2433 case kUint8Clamped : |
| 2434 return NewTypedData<Uint8ClampedArray>(isolate, length); |
| 2435 case kInt16 : |
| 2436 return NewTypedData<Int16Array>(isolate, length); |
| 2437 case kUint16 : |
| 2438 return NewTypedData<Uint16Array>(isolate, length); |
| 2439 case kInt32 : |
| 2440 return NewTypedData<Int32Array>(isolate, length); |
| 2441 case kUint32 : |
| 2442 return NewTypedData<Uint32Array>(isolate, length); |
| 2443 case kInt64 : |
| 2444 return NewTypedData<Int64Array>(isolate, length); |
| 2445 case kUint64 : |
| 2446 return NewTypedData<Uint64Array>(isolate, length); |
| 2447 case kFloat32 : |
| 2448 return NewTypedData<Float32Array>(isolate, length); |
| 2449 case kFloat64 : |
| 2450 return NewTypedData<Float64Array>(isolate, length); |
| 2451 default: |
| 2452 return Api::NewError("%s expects argument 'type' to be of 'TypedData'", |
| 2453 CURRENT_FUNC); |
| 2454 } |
| 2455 UNREACHABLE(); |
| 2456 return Api::Null(isolate); |
| 2457 } |
| 2458 |
| 2459 |
| 2460 DART_EXPORT Dart_Handle Dart_NewExternalTypedData( |
| 2461 Dart_TypedData_Type type, |
| 2462 void* data, |
| 2364 intptr_t length, | 2463 intptr_t length, |
| 2365 void* peer, | 2464 void* peer, |
| 2366 Dart_WeakPersistentHandleFinalizer callback) { | 2465 Dart_WeakPersistentHandleFinalizer callback) { |
| 2367 Isolate* isolate = Isolate::Current(); | 2466 Isolate* isolate = Isolate::Current(); |
| 2368 DARTSCOPE(isolate); | 2467 DARTSCOPE(isolate); |
| 2369 if (data == NULL && length != 0) { | 2468 if (data == NULL && length != 0) { |
| 2370 RETURN_NULL_ERROR(data); | 2469 RETURN_NULL_ERROR(data); |
| 2371 } | 2470 } |
| 2372 CHECK_LENGTH(length, ExternalUint8ClampedArray::kMaxElements); | |
| 2373 CHECK_CALLBACK_STATE(isolate); | 2471 CHECK_CALLBACK_STATE(isolate); |
| 2374 const ExternalUint8ClampedArray& obj = ExternalUint8ClampedArray::Handle( | 2472 switch (type) { |
| 2375 ExternalUint8ClampedArray::New(data, length)); | 2473 case kByteData : |
| 2376 return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback)); | 2474 // TODO(asiva): Allocate external ByteData object. |
| 2475 break; |
| 2476 case kInt8 : |
| 2477 return NewExternalTypedData<ExternalInt8Array, int8_t>(data, |
| 2478 length, |
| 2479 peer, |
| 2480 callback); |
| 2481 case kUint8 : |
| 2482 return NewExternalTypedData<ExternalUint8Array, uint8_t>(data, |
| 2483 length, |
| 2484 peer, |
| 2485 callback); |
| 2486 case kUint8Clamped : |
| 2487 return NewExternalTypedData<ExternalUint8ClampedArray, uint8_t>(data, |
| 2488 length, |
| 2489 peer, |
| 2490 callback); |
| 2491 case kInt16 : |
| 2492 return NewExternalTypedData<ExternalInt16Array, int16_t>(data, |
| 2493 length, |
| 2494 peer, |
| 2495 callback); |
| 2496 case kUint16 : |
| 2497 return NewExternalTypedData<ExternalUint16Array, uint16_t>(data, |
| 2498 length, |
| 2499 peer, |
| 2500 callback); |
| 2501 case kInt32 : |
| 2502 return NewExternalTypedData<ExternalInt32Array, int32_t>(data, |
| 2503 length, |
| 2504 peer, |
| 2505 callback); |
| 2506 case kUint32 : |
| 2507 return NewExternalTypedData<ExternalUint32Array, uint32_t>(data, |
| 2508 length, |
| 2509 peer, |
| 2510 callback); |
| 2511 case kInt64 : |
| 2512 return NewExternalTypedData<ExternalInt64Array, int64_t>(data, |
| 2513 length, |
| 2514 peer, |
| 2515 callback); |
| 2516 case kUint64 : |
| 2517 return NewExternalTypedData<ExternalUint64Array, uint64_t>(data, |
| 2518 length, |
| 2519 peer, |
| 2520 callback); |
| 2521 case kFloat32 : |
| 2522 return NewExternalTypedData<ExternalFloat32Array, float>(data, |
| 2523 length, |
| 2524 peer, |
| 2525 callback); |
| 2526 case kFloat64 : |
| 2527 return NewExternalTypedData<ExternalFloat64Array, double>(data, |
| 2528 length, |
| 2529 peer, |
| 2530 callback); |
| 2531 default: |
| 2532 return Api::NewError("%s expects argument 'type' to be of" |
| 2533 " 'external TypedData'", CURRENT_FUNC); |
| 2534 } |
| 2535 UNREACHABLE(); |
| 2536 return Api::Null(isolate); |
| 2377 } | 2537 } |
| 2378 | 2538 |
| 2379 | 2539 |
| 2380 DART_EXPORT Dart_Handle Dart_ExternalByteArrayGetData(Dart_Handle object, | 2540 DART_EXPORT Dart_Handle Dart_ExternalTypedDataGetPeer(Dart_Handle object, |
| 2381 void** data) { | |
| 2382 Isolate* isolate = Isolate::Current(); | |
| 2383 DARTSCOPE(isolate); | |
| 2384 const ExternalUint8Array& array = | |
| 2385 Api::UnwrapExternalUint8ArrayHandle(isolate, object); | |
| 2386 if (array.IsNull()) { | |
| 2387 RETURN_TYPE_ERROR(isolate, object, ExternalUint8Array); | |
| 2388 } | |
| 2389 if (data == NULL) { | |
| 2390 RETURN_NULL_ERROR(data); | |
| 2391 } | |
| 2392 *data = array.GetData(); | |
| 2393 return Api::Success(isolate); | |
| 2394 } | |
| 2395 | |
| 2396 | |
| 2397 DART_EXPORT Dart_Handle Dart_ExternalByteArrayGetPeer(Dart_Handle object, | |
| 2398 void** peer) { | 2541 void** peer) { |
| 2399 Isolate* isolate = Isolate::Current(); | 2542 Isolate* isolate = Isolate::Current(); |
| 2400 DARTSCOPE(isolate); | 2543 DARTSCOPE(isolate); |
| 2401 const ExternalUint8Array& array = | 2544 const ByteArray& array = |
| 2402 Api::UnwrapExternalUint8ArrayHandle(isolate, object); | 2545 Api::UnwrapByteArrayHandle(isolate, object); |
| 2403 if (array.IsNull()) { | 2546 if (array.IsNull()) { |
| 2404 RETURN_TYPE_ERROR(isolate, object, ExternalUint8Array); | 2547 RETURN_TYPE_ERROR(isolate, object, ByteArray); |
| 2405 } | 2548 } |
| 2406 if (peer == NULL) { | 2549 if (peer == NULL) { |
| 2407 RETURN_NULL_ERROR(peer); | 2550 RETURN_NULL_ERROR(peer); |
| 2408 } | 2551 } |
| 2409 *peer = array.GetPeer(); | 2552 *peer = array.GetPeer(); |
| 2410 return Api::Success(isolate); | 2553 return Api::Success(isolate); |
| 2411 } | 2554 } |
| 2412 | 2555 |
| 2413 | 2556 |
| 2414 DART_EXPORT Dart_Handle Dart_ScalarListAcquireData(Dart_Handle array, | 2557 DART_EXPORT Dart_Handle Dart_TypedDataAcquireData(Dart_Handle object, |
| 2415 Dart_Scalar_Type* type, | 2558 Dart_TypedData_Type* type, |
| 2416 void** data, | 2559 void** data, |
| 2417 intptr_t* len) { | 2560 intptr_t* len) { |
| 2418 Isolate* isolate = Isolate::Current(); | 2561 Isolate* isolate = Isolate::Current(); |
| 2419 DARTSCOPE(isolate); | 2562 DARTSCOPE(isolate); |
| 2420 intptr_t class_id = Api::ClassId(array); | 2563 intptr_t class_id = Api::ClassId(object); |
| 2421 if (!RawObject::IsByteArrayClassId(class_id)) { | 2564 if (!RawObject::IsByteArrayClassId(class_id)) { |
| 2422 RETURN_TYPE_ERROR(isolate, array, 'scalar list'); | 2565 RETURN_TYPE_ERROR(isolate, object, 'TypedData'); |
| 2423 } | 2566 } |
| 2424 if (type == NULL) { | 2567 if (type == NULL) { |
| 2425 RETURN_NULL_ERROR(type); | 2568 RETURN_NULL_ERROR(type); |
| 2426 } | 2569 } |
| 2427 if (data == NULL) { | 2570 if (data == NULL) { |
| 2428 RETURN_NULL_ERROR(data); | 2571 RETURN_NULL_ERROR(data); |
| 2429 } | 2572 } |
| 2430 if (len == NULL) { | 2573 if (len == NULL) { |
| 2431 RETURN_NULL_ERROR(len); | 2574 RETURN_NULL_ERROR(len); |
| 2432 } | 2575 } |
| 2433 // Get the type of typed array. | 2576 // Get the type of typed data object. |
| 2434 switch (class_id) { | 2577 *type = GetType(class_id); |
| 2435 case kByteArrayCid : | 2578 const ByteArray& obj = Api::UnwrapByteArrayHandle(isolate, object); |
| 2436 *type = kByteArray; | |
| 2437 break; | |
| 2438 case kInt8ArrayCid : | |
| 2439 case kExternalInt8ArrayCid : | |
| 2440 *type = kInt8; | |
| 2441 break; | |
| 2442 case kUint8ArrayCid : | |
| 2443 case kExternalUint8ArrayCid : | |
| 2444 *type = kUint8; | |
| 2445 break; | |
| 2446 case kUint8ClampedArrayCid : | |
| 2447 case kExternalUint8ClampedArrayCid : | |
| 2448 *type = kUint8Clamped; | |
| 2449 break; | |
| 2450 case kInt16ArrayCid : | |
| 2451 case kExternalInt16ArrayCid : | |
| 2452 *type = kInt16; | |
| 2453 break; | |
| 2454 case kUint16ArrayCid : | |
| 2455 case kExternalUint16ArrayCid : | |
| 2456 *type = kUint16; | |
| 2457 break; | |
| 2458 case kInt32ArrayCid : | |
| 2459 case kExternalInt32ArrayCid : | |
| 2460 *type = kInt32; | |
| 2461 break; | |
| 2462 case kUint32ArrayCid : | |
| 2463 case kExternalUint32ArrayCid : | |
| 2464 *type = kUint32; | |
| 2465 break; | |
| 2466 case kInt64ArrayCid : | |
| 2467 case kExternalInt64ArrayCid : | |
| 2468 *type = kInt64; | |
| 2469 break; | |
| 2470 case kUint64ArrayCid : | |
| 2471 case kExternalUint64ArrayCid : | |
| 2472 *type = kUint64; | |
| 2473 break; | |
| 2474 case kFloat32ArrayCid : | |
| 2475 case kExternalFloat32ArrayCid : | |
| 2476 *type = kFloat32; | |
| 2477 break; | |
| 2478 case kFloat64ArrayCid : | |
| 2479 case kExternalFloat64ArrayCid : | |
| 2480 *type = kFloat64; | |
| 2481 break; | |
| 2482 } | |
| 2483 const ByteArray& obj = Api::UnwrapByteArrayHandle(isolate, array); | |
| 2484 ASSERT(!obj.IsNull()); | 2579 ASSERT(!obj.IsNull()); |
| 2485 *len = obj.Length(); | 2580 *len = obj.Length(); |
| 2486 // If it is an external typed array object just return the data field. | 2581 // If it is an external typed data object just return the data field. |
| 2487 if (RawObject::IsExternalByteArrayClassId(class_id)) { | 2582 if (RawObject::IsExternalByteArrayClassId(class_id)) { |
| 2488 *data = reinterpret_cast<void*>(obj.ByteAddr(0)); | 2583 *data = reinterpret_cast<void*>(obj.ByteAddr(0)); |
| 2489 } else { | 2584 } else { |
| 2490 // Regular typed array object, set up some GC and API callback guards. | 2585 // Regular typed data object, set up some GC and API callback guards. |
| 2491 isolate->IncrementNoGCScopeDepth(); | 2586 isolate->IncrementNoGCScopeDepth(); |
| 2492 START_NO_CALLBACK_SCOPE(isolate); | 2587 START_NO_CALLBACK_SCOPE(isolate); |
| 2493 *data = reinterpret_cast<void*>(obj.ByteAddr(0)); | 2588 *data = reinterpret_cast<void*>(obj.ByteAddr(0)); |
| 2494 } | 2589 } |
| 2495 return Api::Success(isolate); | 2590 return Api::Success(isolate); |
| 2496 } | 2591 } |
| 2497 | 2592 |
| 2498 | 2593 |
| 2499 DART_EXPORT Dart_Handle Dart_ScalarListReleaseData(Dart_Handle array) { | 2594 DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object) { |
| 2500 Isolate* isolate = Isolate::Current(); | 2595 Isolate* isolate = Isolate::Current(); |
| 2501 DARTSCOPE(isolate); | 2596 DARTSCOPE(isolate); |
| 2502 intptr_t class_id = Api::ClassId(array); | 2597 intptr_t class_id = Api::ClassId(object); |
| 2503 if (!RawObject::IsByteArrayClassId(class_id)) { | 2598 if (!RawObject::IsByteArrayClassId(class_id)) { |
| 2504 RETURN_TYPE_ERROR(isolate, array, 'scalar list'); | 2599 RETURN_TYPE_ERROR(isolate, object, 'TypedData'); |
| 2505 } | 2600 } |
| 2506 if (!RawObject::IsExternalByteArrayClassId(class_id)) { | 2601 if (!RawObject::IsExternalByteArrayClassId(class_id)) { |
| 2507 isolate->DecrementNoGCScopeDepth(); | 2602 isolate->DecrementNoGCScopeDepth(); |
| 2508 END_NO_CALLBACK_SCOPE(isolate); | 2603 END_NO_CALLBACK_SCOPE(isolate); |
| 2509 } | 2604 } |
| 2510 return Api::Success(isolate); | 2605 return Api::Success(isolate); |
| 2511 } | 2606 } |
| 2512 | 2607 |
| 2513 | 2608 |
| 2514 // --- Closures --- | 2609 // --- Closures --- |
| (...skipping 2074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4589 } | 4684 } |
| 4590 { | 4685 { |
| 4591 NoGCScope no_gc; | 4686 NoGCScope no_gc; |
| 4592 RawObject* raw_obj = obj.raw(); | 4687 RawObject* raw_obj = obj.raw(); |
| 4593 isolate->heap()->SetPeer(raw_obj, peer); | 4688 isolate->heap()->SetPeer(raw_obj, peer); |
| 4594 } | 4689 } |
| 4595 return Api::Success(isolate); | 4690 return Api::Success(isolate); |
| 4596 } | 4691 } |
| 4597 | 4692 |
| 4598 } // namespace dart | 4693 } // namespace dart |
| OLD | NEW |