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 #include "include/dart_mirrors_api.h" | 6 #include "include/dart_mirrors_api.h" |
7 #include "include/dart_native_api.h" | 7 #include "include/dart_native_api.h" |
8 | 8 |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 #include "vm/version.h" | 40 #include "vm/version.h" |
41 | 41 |
42 namespace dart { | 42 namespace dart { |
43 | 43 |
44 DECLARE_FLAG(bool, print_class_table); | 44 DECLARE_FLAG(bool, print_class_table); |
45 DECLARE_FLAG(bool, verify_handles); | 45 DECLARE_FLAG(bool, verify_handles); |
46 DEFINE_FLAG(bool, check_function_fingerprints, false, | 46 DEFINE_FLAG(bool, check_function_fingerprints, false, |
47 "Check function fingerprints"); | 47 "Check function fingerprints"); |
48 DEFINE_FLAG(bool, trace_api, false, | 48 DEFINE_FLAG(bool, trace_api, false, |
49 "Trace invocation of API calls (debug mode only)"); | 49 "Trace invocation of API calls (debug mode only)"); |
| 50 DEFINE_FLAG(bool, verify_acquired_data, false, |
| 51 "Verify correct API acquire/release of typed data."); |
50 | 52 |
51 ThreadLocalKey Api::api_native_key_ = OSThread::kUnsetThreadLocalKey; | 53 ThreadLocalKey Api::api_native_key_ = OSThread::kUnsetThreadLocalKey; |
52 Dart_Handle Api::true_handle_ = NULL; | 54 Dart_Handle Api::true_handle_ = NULL; |
53 Dart_Handle Api::false_handle_ = NULL; | 55 Dart_Handle Api::false_handle_ = NULL; |
54 Dart_Handle Api::null_handle_ = NULL; | 56 Dart_Handle Api::null_handle_ = NULL; |
55 Dart_Handle Api::empty_string_handle_ = NULL; | 57 Dart_Handle Api::empty_string_handle_ = NULL; |
56 | 58 |
57 | 59 |
58 const char* CanonicalFunction(const char* func) { | 60 const char* CanonicalFunction(const char* func) { |
59 if (strncmp(func, "dart::", 6) == 0) { | 61 if (strncmp(func, "dart::", 6) == 0) { |
(...skipping 3367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3427 START_NO_CALLBACK_SCOPE(isolate); | 3429 START_NO_CALLBACK_SCOPE(isolate); |
3428 if (TypedData::IsTypedData(obj)) { | 3430 if (TypedData::IsTypedData(obj)) { |
3429 const TypedData& data_obj = TypedData::Cast(obj); | 3431 const TypedData& data_obj = TypedData::Cast(obj); |
3430 *data = data_obj.DataAddr(offset_in_bytes); | 3432 *data = data_obj.DataAddr(offset_in_bytes); |
3431 } else { | 3433 } else { |
3432 ASSERT(ExternalTypedData::IsExternalTypedData(obj)); | 3434 ASSERT(ExternalTypedData::IsExternalTypedData(obj)); |
3433 const ExternalTypedData& data_obj = ExternalTypedData::Cast(obj); | 3435 const ExternalTypedData& data_obj = ExternalTypedData::Cast(obj); |
3434 *data = data_obj.DataAddr(offset_in_bytes); | 3436 *data = data_obj.DataAddr(offset_in_bytes); |
3435 } | 3437 } |
3436 } | 3438 } |
| 3439 if (FLAG_verify_acquired_data) { |
| 3440 // For now, we just verify that acquire/release are properly matched |
| 3441 // per object. |
| 3442 // TODO(koda): Copy internal data to/from a side buffer which is unmapped |
| 3443 // on release to catch use-after-release bugs. |
| 3444 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
| 3445 WeakTable* table = isolate->api_state()->acquired_table(); |
| 3446 intptr_t current = table->GetValue(obj.raw()); |
| 3447 if (current != 0) { |
| 3448 ASSERT(current == 1); |
| 3449 return Api::NewError("Data was already acquired for this object."); |
| 3450 } |
| 3451 table->SetValue(obj.raw(), 1); |
| 3452 } |
3437 return Api::Success(); | 3453 return Api::Success(); |
3438 } | 3454 } |
3439 | 3455 |
3440 | 3456 |
3441 DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object) { | 3457 DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object) { |
3442 Isolate* isolate = Isolate::Current(); | 3458 Isolate* isolate = Isolate::Current(); |
3443 DARTSCOPE(isolate); | 3459 DARTSCOPE(isolate); |
3444 intptr_t class_id = Api::ClassId(object); | 3460 intptr_t class_id = Api::ClassId(object); |
3445 if (!RawObject::IsExternalTypedDataClassId(class_id) && | 3461 if (!RawObject::IsExternalTypedDataClassId(class_id) && |
3446 !RawObject::IsTypedDataViewClassId(class_id) && | 3462 !RawObject::IsTypedDataViewClassId(class_id) && |
3447 !RawObject::IsTypedDataClassId(class_id)) { | 3463 !RawObject::IsTypedDataClassId(class_id)) { |
3448 RETURN_TYPE_ERROR(isolate, object, 'TypedData'); | 3464 RETURN_TYPE_ERROR(isolate, object, 'TypedData'); |
3449 } | 3465 } |
3450 if (!RawObject::IsExternalTypedDataClassId(class_id)) { | 3466 if (!RawObject::IsExternalTypedDataClassId(class_id)) { |
3451 isolate->DecrementNoGCScopeDepth(); | 3467 isolate->DecrementNoGCScopeDepth(); |
3452 END_NO_CALLBACK_SCOPE(isolate); | 3468 END_NO_CALLBACK_SCOPE(isolate); |
3453 } | 3469 } |
| 3470 if (FLAG_verify_acquired_data) { |
| 3471 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
| 3472 WeakTable* table = isolate->api_state()->acquired_table(); |
| 3473 intptr_t current = table->GetValue(obj.raw()); |
| 3474 if (current != 1) { |
| 3475 ASSERT(current == 0); |
| 3476 return Api::NewError("Data was not acquired for this object."); |
| 3477 } |
| 3478 // Delete entry from table. |
| 3479 table->SetValue(obj.raw(), 0); |
| 3480 } |
3454 return Api::Success(); | 3481 return Api::Success(); |
3455 } | 3482 } |
3456 | 3483 |
3457 | 3484 |
3458 DART_EXPORT Dart_Handle Dart_GetDataFromByteBuffer(Dart_Handle object) { | 3485 DART_EXPORT Dart_Handle Dart_GetDataFromByteBuffer(Dart_Handle object) { |
3459 Isolate* isolate = Isolate::Current(); | 3486 Isolate* isolate = Isolate::Current(); |
3460 CHECK_ISOLATE(isolate); | 3487 CHECK_ISOLATE(isolate); |
3461 intptr_t class_id = Api::ClassId(object); | 3488 intptr_t class_id = Api::ClassId(object); |
3462 if (class_id != kByteBufferCid) { | 3489 if (class_id != kByteBufferCid) { |
3463 RETURN_TYPE_ERROR(isolate, object, 'ByteBuffer'); | 3490 RETURN_TYPE_ERROR(isolate, object, 'ByteBuffer'); |
(...skipping 1961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5425 | 5452 |
5426 | 5453 |
5427 DART_EXPORT void Dart_RegisterRootServiceRequestCallback( | 5454 DART_EXPORT void Dart_RegisterRootServiceRequestCallback( |
5428 const char* name, | 5455 const char* name, |
5429 Dart_ServiceRequestCallback callback, | 5456 Dart_ServiceRequestCallback callback, |
5430 void* user_data) { | 5457 void* user_data) { |
5431 Service::RegisterRootEmbedderCallback(name, callback, user_data); | 5458 Service::RegisterRootEmbedderCallback(name, callback, user_data); |
5432 } | 5459 } |
5433 | 5460 |
5434 } // namespace dart | 5461 } // namespace dart |
OLD | NEW |