| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #ifndef RUNTIME_BIN_DARTUTILS_H_ |
| #define RUNTIME_BIN_DARTUTILS_H_ |
| |
| #include "bin/isolate_data.h" |
| #include "include/dart_api.h" |
| #include "include/dart_native_api.h" |
| #include "platform/assert.h" |
| #include "platform/globals.h" |
| |
| namespace dart { |
| namespace bin { |
| |
| // Forward declarations. |
| class File; |
| class OSError; |
| |
| /* Handles error handles returned from Dart API functions. If a value |
| * is an error, uses Dart_PropagateError to throw it to the enclosing |
| * Dart activation. Otherwise, returns the original handle. |
| * |
| * This function can be used to wrap most API functions, but API |
| * functions can also be nested without this error check, since all |
| * API functions return any error handles passed in as arguments, unchanged. |
| */ |
| static inline Dart_Handle ThrowIfError(Dart_Handle handle) { |
| if (Dart_IsError(handle)) { |
| Dart_PropagateError(handle); |
| } |
| return handle; |
| } |
| |
| class CommandLineOptions { |
| public: |
| explicit CommandLineOptions(int max_count) |
| : count_(0), max_count_(max_count), arguments_(NULL) { |
| static const int kWordSize = sizeof(intptr_t); |
| arguments_ = reinterpret_cast<const char**>(malloc(max_count * kWordSize)); |
| if (arguments_ == NULL) { |
| max_count_ = 0; |
| } |
| } |
| ~CommandLineOptions() { |
| free(arguments_); |
| count_ = 0; |
| max_count_ = 0; |
| arguments_ = NULL; |
| } |
| |
| int count() const { return count_; } |
| const char** arguments() const { return arguments_; } |
| |
| const char* GetArgument(int index) const { |
| return (index >= 0 && index < count_) ? arguments_[index] : NULL; |
| } |
| void AddArgument(const char* argument) { |
| if (count_ < max_count_) { |
| arguments_[count_] = argument; |
| count_ += 1; |
| } else { |
| abort(); // We should never get into this situation. |
| } |
| } |
| |
| void operator delete(void* pointer) { abort(); } |
| |
| private: |
| void* operator new(size_t size); |
| |
| int count_; |
| int max_count_; |
| const char** arguments_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CommandLineOptions); |
| }; |
| |
| class DartUtils { |
| public: |
| // Returns the integer value of a Dart object. If the object is not |
| // an integer value an API error is propagated. |
| static int64_t GetIntegerValue(Dart_Handle value_obj); |
| // Returns the integer value of a Dart object. If the object is not |
| // an integer value or outside the requested range an API error is |
| // propagated. |
| static int64_t GetInt64ValueCheckRange(Dart_Handle value_obj, |
| int64_t lower, |
| int64_t upper); |
| // Returns the intptr_t value of a Dart object. If the object is not |
| // an integer value or the value is outside the intptr_t range an |
| // API error is propagated. |
| static intptr_t GetIntptrValue(Dart_Handle value_obj); |
| // Checks that the value object is an integer object that fits in a |
| // signed 64-bit integer. If it is, the value is returned in the |
| // value out parameter and true is returned. Otherwise, false is |
| // returned. |
| static bool GetInt64Value(Dart_Handle value_obj, int64_t* value); |
| // Returns the string value of a Dart object. If the object is not |
| // a string value an API error is propagated. |
| static const char* GetStringValue(Dart_Handle str_obj); |
| // Returns the boolean value of a Dart object. If the object is not |
| // a boolean value an API error is propagated. |
| static bool GetBooleanValue(Dart_Handle bool_obj); |
| |
| static Dart_Handle SetIntegerField(Dart_Handle handle, |
| const char* name, |
| int64_t val); |
| static Dart_Handle SetStringField(Dart_Handle handle, |
| const char* name, |
| const char* val); |
| static bool IsDartSchemeURL(const char* url_name); |
| static bool IsDartExtensionSchemeURL(const char* url_name); |
| static bool IsDartIOLibURL(const char* url_name); |
| static bool IsDartBuiltinLibURL(const char* url_name); |
| static bool IsHttpSchemeURL(const char* url_name); |
| static const char* RemoveScheme(const char* url); |
| static char* DirName(const char* url); |
| static void* MapExecutable(const char* name, intptr_t* file_len); |
| static void* OpenFile(const char* name, bool write); |
| static void ReadFile(const uint8_t** data, intptr_t* file_len, void* stream); |
| static void WriteFile(const void* buffer, intptr_t num_bytes, void* stream); |
| static void CloseFile(void* stream); |
| static bool EntropySource(uint8_t* buffer, intptr_t length); |
| static Dart_Handle ReadStringFromFile(const char* filename); |
| static Dart_Handle MakeUint8Array(const uint8_t* buffer, intptr_t length); |
| static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, |
| Dart_Handle library, |
| Dart_Handle url); |
| static Dart_Handle LoadScript(const char* script_uri); |
| static Dart_Handle PrepareForScriptLoading(bool is_service_isolate, |
| bool trace_loading); |
| static Dart_Handle SetupServiceLoadPort(); |
| static Dart_Handle SetupPackageRoot(const char* package_root, |
| const char* packages_file); |
| static Dart_Handle SetupIOLibrary(const char* script_uri); |
| |
| static bool PostNull(Dart_Port port_id); |
| static bool PostInt32(Dart_Port port_id, int32_t value); |
| static bool PostInt64(Dart_Port port_id, int64_t value); |
| |
| static Dart_Handle GetDartType(const char* library_url, |
| const char* class_name); |
| // Create a new Dart OSError object with the current OS error. |
| static Dart_Handle NewDartOSError(); |
| // Create a new Dart OSError object with the provided OS error. |
| static Dart_Handle NewDartOSError(OSError* os_error); |
| static Dart_Handle NewDartExceptionWithOSError(const char* library_url, |
| const char* exception_name, |
| const char* message, |
| Dart_Handle os_error); |
| static Dart_Handle NewDartExceptionWithMessage(const char* library_url, |
| const char* exception_name, |
| const char* message); |
| static Dart_Handle NewDartArgumentError(const char* message); |
| static Dart_Handle NewDartUnsupportedError(const char* message); |
| static Dart_Handle NewDartIOException(const char* exception_name, |
| const char* message, |
| Dart_Handle os_error); |
| |
| // Create a new Dart String object from a C String. |
| static Dart_Handle NewString(const char* str) { |
| ASSERT(str != NULL); |
| return Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(str), |
| strlen(str)); |
| } |
| |
| // Allocate length bytes for a C string with Dart_ScopeAllocate. |
| static char* ScopedCString(intptr_t length) { |
| char* result = NULL; |
| result = |
| reinterpret_cast<char*>(Dart_ScopeAllocate(length * sizeof(*result))); |
| return result; |
| } |
| |
| // Copy str into a buffer allocated with Dart_ScopeAllocate. |
| static char* ScopedCopyCString(const char* str) { |
| size_t str_len = strlen(str); |
| char* result = ScopedCString(str_len + 1); |
| memmove(result, str, str_len); |
| result[str_len] = '\0'; |
| return result; |
| } |
| |
| // Create a new Dart InternalError object with the provided message. |
| static Dart_Handle NewError(const char* format, ...); |
| static Dart_Handle NewInternalError(const char* message); |
| |
| static Dart_Handle BuiltinLib() { |
| IsolateData* isolate_data = |
| reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
| return isolate_data->builtin_lib(); |
| } |
| |
| static bool SetOriginalWorkingDirectory(); |
| static Dart_Handle GetCanonicalizableWorkingDirectory(); |
| |
| static const char* MapLibraryUrl(const char* url_string); |
| |
| static Dart_Handle ResolveUriInWorkingDirectory(Dart_Handle script_uri); |
| static Dart_Handle ResolveScript(Dart_Handle url); |
| |
| enum MagicNumber { |
| kSnapshotMagicNumber, |
| kKernelMagicNumber, |
| kUnknownMagicNumber |
| }; |
| |
| // static const uint8_t* GetMagicNumber(MagicNumber number); |
| |
| // Sniffs the specified text_buffer to see if it contains the magic number |
| // representing a script snapshot. If the text_buffer is a script snapshot |
| // the return value is an updated pointer to the text_buffer pointing past |
| // the magic number value. The 'buffer_len' parameter is also appropriately |
| // adjusted. |
| static MagicNumber SniffForMagicNumber(const uint8_t** text_buffer, |
| intptr_t* buffer_len); |
| |
| // Write a magic number to indicate a script snapshot file. |
| static void WriteMagicNumber(File* file); |
| |
| // Global state that stores the original working directory.. |
| static const char* original_working_directory; |
| |
| // Global state that captures the URL mappings specified on the command line. |
| static CommandLineOptions* url_mapping; |
| |
| static const char* const kDartScheme; |
| static const char* const kDartExtensionScheme; |
| static const char* const kAsyncLibURL; |
| static const char* const kBuiltinLibURL; |
| static const char* const kCoreLibURL; |
| static const char* const kInternalLibURL; |
| static const char* const kIsolateLibURL; |
| static const char* const kIOLibURL; |
| static const char* const kIOLibPatchURL; |
| static const char* const kUriLibURL; |
| static const char* const kHttpScheme; |
| static const char* const kVMServiceLibURL; |
| |
| static Dart_Handle LibraryFilePath(Dart_Handle library_uri); |
| |
| private: |
| static Dart_Handle SetWorkingDirectory(); |
| static Dart_Handle PrepareBuiltinLibrary(Dart_Handle builtin_lib, |
| Dart_Handle internal_lib, |
| bool is_service_isolate, |
| bool trace_loading); |
| static Dart_Handle PrepareCoreLibrary(Dart_Handle core_lib, |
| Dart_Handle builtin_lib, |
| bool is_service_isolate); |
| static Dart_Handle PrepareAsyncLibrary(Dart_Handle async_lib, |
| Dart_Handle isolate_lib); |
| static Dart_Handle PrepareIOLibrary(Dart_Handle io_lib); |
| static Dart_Handle PrepareIsolateLibrary(Dart_Handle isolate_lib); |
| |
| DISALLOW_ALLOCATION(); |
| DISALLOW_IMPLICIT_CONSTRUCTORS(DartUtils); |
| }; |
| |
| class CObject { |
| public: |
| // These match the constants in sdk/lib/io/common.dart. |
| static const int kSuccess = 0; |
| static const int kArgumentError = 1; |
| static const int kOSError = 2; |
| static const int kFileClosedError = 3; |
| |
| explicit CObject(Dart_CObject* cobject) : cobject_(cobject) {} |
| Dart_CObject_Type type() { return cobject_->type; } |
| Dart_TypedData_Type byte_array_type() { |
| ASSERT(type() == Dart_CObject_kTypedData || |
| type() == Dart_CObject_kExternalTypedData); |
| return cobject_->value.as_typed_data.type; |
| } |
| |
| bool IsNull() { return type() == Dart_CObject_kNull; } |
| bool IsBool() { return type() == Dart_CObject_kBool; } |
| bool IsInt32() { return type() == Dart_CObject_kInt32; } |
| bool IsInt64() { return type() == Dart_CObject_kInt64; } |
| bool IsInt32OrInt64() { return IsInt32() || IsInt64(); } |
| bool IsIntptr() { return IsInt32OrInt64(); } |
| bool IsBigint() { return type() == Dart_CObject_kBigint; } |
| bool IsDouble() { return type() == Dart_CObject_kDouble; } |
| bool IsString() { return type() == Dart_CObject_kString; } |
| bool IsArray() { return type() == Dart_CObject_kArray; } |
| bool IsTypedData() { return type() == Dart_CObject_kTypedData; } |
| bool IsUint8Array() { |
| return type() == Dart_CObject_kTypedData && |
| byte_array_type() == Dart_TypedData_kUint8; |
| } |
| bool IsSendPort() { return type() == Dart_CObject_kSendPort; } |
| |
| bool IsTrue() { |
| return type() == Dart_CObject_kBool && cobject_->value.as_bool; |
| } |
| |
| bool IsFalse() { |
| return type() == Dart_CObject_kBool && !cobject_->value.as_bool; |
| } |
| |
| void* operator new(size_t size) { return Dart_ScopeAllocate(size); } |
| |
| static CObject* Null(); |
| static CObject* True(); |
| static CObject* False(); |
| static CObject* Bool(bool value); |
| static Dart_CObject* NewInt32(int32_t value); |
| static Dart_CObject* NewInt64(int64_t value); |
| static Dart_CObject* NewIntptr(intptr_t value); |
| static Dart_CObject* NewBigint(const char* hex_value); |
| static char* BigintToHexValue(Dart_CObject* bigint); |
| static Dart_CObject* NewDouble(double value); |
| static Dart_CObject* NewString(intptr_t length); |
| static Dart_CObject* NewString(const char* str); |
| static Dart_CObject* NewArray(intptr_t length); |
| static Dart_CObject* NewUint8Array(intptr_t length); |
| static Dart_CObject* NewUint32Array(intptr_t length); |
| static Dart_CObject* NewExternalUint8Array( |
| intptr_t length, |
| uint8_t* data, |
| void* peer, |
| Dart_WeakPersistentHandleFinalizer callback); |
| |
| static Dart_CObject* NewIOBuffer(int64_t length); |
| static void FreeIOBufferData(Dart_CObject* object); |
| |
| Dart_CObject* AsApiCObject() { return cobject_; } |
| |
| // Create a new CObject array with an illegal arguments error. |
| static CObject* IllegalArgumentError(); |
| // Create a new CObject array with a file closed error. |
| static CObject* FileClosedError(); |
| // Create a new CObject array with the current OS error. |
| static CObject* NewOSError(); |
| // Create a new CObject array with the specified OS error. |
| static CObject* NewOSError(OSError* os_error); |
| |
| protected: |
| CObject() : cobject_(NULL) {} |
| Dart_CObject* cobject_; |
| |
| private: |
| static Dart_CObject* New(Dart_CObject_Type type, int additional_bytes = 0); |
| |
| static Dart_CObject api_null_; |
| static Dart_CObject api_true_; |
| static Dart_CObject api_false_; |
| static CObject null_; |
| static CObject true_; |
| static CObject false_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObject); |
| }; |
| |
| #define DECLARE_COBJECT_CONSTRUCTORS(t) \ |
| explicit CObject##t(Dart_CObject* cobject) : CObject(cobject) { \ |
| ASSERT(type() == Dart_CObject_k##t); \ |
| cobject_ = cobject; \ |
| } \ |
| explicit CObject##t(CObject* cobject) : CObject() { \ |
| ASSERT(cobject != NULL); \ |
| ASSERT(cobject->type() == Dart_CObject_k##t); \ |
| cobject_ = cobject->AsApiCObject(); \ |
| } |
| |
| #define DECLARE_COBJECT_TYPED_DATA_CONSTRUCTORS(t) \ |
| explicit CObject##t##Array(Dart_CObject* cobject) : CObject(cobject) { \ |
| ASSERT(type() == Dart_CObject_kTypedData); \ |
| ASSERT(byte_array_type() == Dart_TypedData_k##t); \ |
| cobject_ = cobject; \ |
| } \ |
| explicit CObject##t##Array(CObject* cobject) : CObject() { \ |
| ASSERT(cobject != NULL); \ |
| ASSERT(cobject->type() == Dart_CObject_kTypedData); \ |
| ASSERT(cobject->byte_array_type() == Dart_TypedData_k##t); \ |
| cobject_ = cobject->AsApiCObject(); \ |
| } |
| |
| #define DECLARE_COBJECT_EXTERNAL_TYPED_DATA_CONSTRUCTORS(t) \ |
| explicit CObjectExternal##t##Array(Dart_CObject* cobject) \ |
| : CObject(cobject) { \ |
| ASSERT(type() == Dart_CObject_kExternalTypedData); \ |
| ASSERT(byte_array_type() == Dart_TypedData_k##t); \ |
| cobject_ = cobject; \ |
| } \ |
| explicit CObjectExternal##t##Array(CObject* cobject) : CObject() { \ |
| ASSERT(cobject != NULL); \ |
| ASSERT(cobject->type() == Dart_CObject_kExternalTypedData); \ |
| ASSERT(cobject->byte_array_type() == Dart_TypedData_k##t); \ |
| cobject_ = cobject->AsApiCObject(); \ |
| } |
| |
| class CObjectBool : public CObject { |
| public: |
| DECLARE_COBJECT_CONSTRUCTORS(Bool) |
| |
| bool Value() const { return cobject_->value.as_bool; } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectBool); |
| }; |
| |
| class CObjectInt32 : public CObject { |
| public: |
| DECLARE_COBJECT_CONSTRUCTORS(Int32) |
| |
| int32_t Value() const { return cobject_->value.as_int32; } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectInt32); |
| }; |
| |
| class CObjectInt64 : public CObject { |
| public: |
| DECLARE_COBJECT_CONSTRUCTORS(Int64) |
| |
| int64_t Value() const { return cobject_->value.as_int64; } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectInt64); |
| }; |
| |
| class CObjectIntptr : public CObject { |
| public: |
| explicit CObjectIntptr(Dart_CObject* cobject) : CObject(cobject) { |
| ASSERT(type() == Dart_CObject_kInt32 || type() == Dart_CObject_kInt64); |
| cobject_ = cobject; |
| } |
| explicit CObjectIntptr(CObject* cobject) : CObject() { |
| ASSERT(cobject != NULL); |
| ASSERT(cobject->type() == Dart_CObject_kInt64 || |
| cobject->type() == Dart_CObject_kInt32); |
| cobject_ = cobject->AsApiCObject(); |
| } |
| |
| intptr_t Value() { |
| intptr_t result; |
| if (type() == Dart_CObject_kInt32) { |
| result = cobject_->value.as_int32; |
| } else { |
| ASSERT(sizeof(result) == 8); |
| result = static_cast<intptr_t>(cobject_->value.as_int64); |
| } |
| return result; |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectIntptr); |
| }; |
| |
| class CObjectBigint : public CObject { |
| public: |
| // DECLARE_COBJECT_CONSTRUCTORS(Bigint) would miss hex_value_ initialization. |
| explicit CObjectBigint(Dart_CObject* cobject) : CObject(cobject) { |
| ASSERT(type() == Dart_CObject_kBigint); |
| cobject_ = cobject; |
| hex_value_ = NULL; |
| } |
| explicit CObjectBigint(CObject* cobject) : CObject() { |
| ASSERT(cobject != NULL); |
| ASSERT(cobject->type() == Dart_CObject_kBigint); |
| cobject_ = cobject->AsApiCObject(); |
| hex_value_ = NULL; |
| } |
| |
| char* Value() { |
| if (hex_value_ == NULL) { |
| hex_value_ = BigintToHexValue(cobject_); |
| } |
| ASSERT(hex_value_ != NULL); |
| return hex_value_; |
| } |
| |
| ~CObjectBigint() { free(hex_value_); } |
| |
| private: |
| char* hex_value_; |
| DISALLOW_COPY_AND_ASSIGN(CObjectBigint); |
| }; |
| |
| class CObjectDouble : public CObject { |
| public: |
| DECLARE_COBJECT_CONSTRUCTORS(Double) |
| |
| double Value() const { return cobject_->value.as_double; } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectDouble); |
| }; |
| |
| class CObjectString : public CObject { |
| public: |
| DECLARE_COBJECT_CONSTRUCTORS(String) |
| |
| intptr_t Length() const { return strlen(cobject_->value.as_string); } |
| char* CString() const { return cobject_->value.as_string; } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectString); |
| }; |
| |
| class CObjectArray : public CObject { |
| public: |
| DECLARE_COBJECT_CONSTRUCTORS(Array) |
| |
| intptr_t Length() const { return cobject_->value.as_array.length; } |
| CObject* operator[](intptr_t index) const { |
| return new CObject(cobject_->value.as_array.values[index]); |
| } |
| void SetAt(intptr_t index, CObject* value) { |
| cobject_->value.as_array.values[index] = value->AsApiCObject(); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectArray); |
| }; |
| |
| class CObjectSendPort : public CObject { |
| public: |
| DECLARE_COBJECT_CONSTRUCTORS(SendPort) |
| |
| Dart_Port Value() const { return cobject_->value.as_send_port.id; } |
| Dart_Port OriginId() const { return cobject_->value.as_send_port.origin_id; } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectSendPort); |
| }; |
| |
| class CObjectTypedData : public CObject { |
| public: |
| explicit CObjectTypedData(Dart_CObject* cobject) : CObject(cobject) { |
| ASSERT(type() == Dart_CObject_kTypedData); |
| cobject_ = cobject; |
| } |
| explicit CObjectTypedData(CObject* cobject) : CObject() { |
| ASSERT(cobject != NULL); |
| ASSERT(cobject->type() == Dart_CObject_kTypedData); |
| cobject_ = cobject->AsApiCObject(); |
| } |
| |
| Dart_TypedData_Type Type() const { |
| return cobject_->value.as_typed_data.type; |
| } |
| intptr_t Length() const { return cobject_->value.as_typed_data.length; } |
| uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectTypedData); |
| }; |
| |
| class CObjectUint8Array : public CObject { |
| public: |
| DECLARE_COBJECT_TYPED_DATA_CONSTRUCTORS(Uint8) |
| |
| intptr_t Length() const { return cobject_->value.as_typed_data.length; } |
| uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectUint8Array); |
| }; |
| |
| class CObjectExternalUint8Array : public CObject { |
| public: |
| DECLARE_COBJECT_EXTERNAL_TYPED_DATA_CONSTRUCTORS(Uint8) |
| |
| intptr_t Length() const { |
| return cobject_->value.as_external_typed_data.length; |
| } |
| void SetLength(intptr_t length) { |
| cobject_->value.as_external_typed_data.length = length; |
| } |
| uint8_t* Data() const { return cobject_->value.as_external_typed_data.data; } |
| void* Peer() const { return cobject_->value.as_external_typed_data.peer; } |
| Dart_WeakPersistentHandleFinalizer Callback() const { |
| return cobject_->value.as_external_typed_data.callback; |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CObjectExternalUint8Array); |
| }; |
| |
| class ScopedBlockingCall { |
| public: |
| ScopedBlockingCall() { Dart_ThreadDisableProfiling(); } |
| |
| ~ScopedBlockingCall() { Dart_ThreadEnableProfiling(); } |
| |
| private: |
| DISALLOW_ALLOCATION(); |
| DISALLOW_COPY_AND_ASSIGN(ScopedBlockingCall); |
| }; |
| |
| // Where the argument to the constructor is the handle for an object |
| // implementing List<int>, this class creates a scope in which the memory |
| // backing the list can be accessed. |
| // |
| // Do not make Dart_ API calls while in a ScopedMemBuffer. |
| // Do not call Dart_PropagateError while in a ScopedMemBuffer. |
| class ScopedMemBuffer { |
| public: |
| explicit ScopedMemBuffer(Dart_Handle object) { |
| if (!Dart_IsTypedData(object) && !Dart_IsList(object)) { |
| Dart_ThrowException( |
| DartUtils::NewDartArgumentError("Argument is not a List<int>")); |
| } |
| |
| uint8_t* bytes = NULL; |
| intptr_t bytes_len = 0; |
| bool is_typed_data = false; |
| if (Dart_IsTypedData(object)) { |
| is_typed_data = true; |
| Dart_TypedData_Type typ; |
| ThrowIfError(Dart_TypedDataAcquireData( |
| object, &typ, reinterpret_cast<void**>(&bytes), &bytes_len)); |
| } else { |
| ASSERT(Dart_IsList(object)); |
| ThrowIfError(Dart_ListLength(object, &bytes_len)); |
| bytes = Dart_ScopeAllocate(bytes_len); |
| ASSERT(bytes != NULL); |
| ThrowIfError(Dart_ListGetAsBytes(object, 0, bytes, bytes_len)); |
| } |
| |
| object_ = object; |
| bytes_ = bytes; |
| bytes_len_ = bytes_len; |
| is_typed_data_ = is_typed_data; |
| } |
| |
| ~ScopedMemBuffer() { |
| if (is_typed_data_) { |
| ThrowIfError(Dart_TypedDataReleaseData(object_)); |
| } |
| } |
| |
| uint8_t* get() const { return bytes_; } |
| intptr_t length() const { return bytes_len_; } |
| |
| private: |
| Dart_Handle object_; |
| uint8_t* bytes_; |
| intptr_t bytes_len_; |
| bool is_typed_data_; |
| |
| DISALLOW_ALLOCATION(); |
| DISALLOW_COPY_AND_ASSIGN(ScopedMemBuffer); |
| }; |
| |
| } // namespace bin |
| } // namespace dart |
| |
| #endif // RUNTIME_BIN_DARTUTILS_H_ |