| Index: runtime/vm/dart_api_impl.cc
|
| ===================================================================
|
| --- runtime/vm/dart_api_impl.cc (revision 20386)
|
| +++ runtime/vm/dart_api_impl.cc (working copy)
|
| @@ -2074,8 +2074,7 @@
|
| Isolate* isolate = Isolate::Current();
|
| // Lookup the class ArgumentError in dart:core.
|
| const String& lib_url = String::Handle(String::New("dart:core"));
|
| - const String& class_name =
|
| - String::Handle(String::New("ArgumentError"));
|
| + const String& class_name = String::Handle(String::New("ArgumentError"));
|
| const Library& lib =
|
| Library::Handle(isolate, Library::LookupLibrary(lib_url));
|
| if (lib.IsNull()) {
|
| @@ -2093,9 +2092,10 @@
|
| lib_url.ToCString()));
|
| return ApiError::New(message);
|
| }
|
| + Object& result = Object::Handle(isolate);
|
| String& dot_name = String::Handle(String::New("."));
|
| - Object& result = Object::Handle(isolate);
|
| - result = ResolveConstructor(CURRENT_FUNC, cls, class_name, dot_name, 1);
|
| + String& constr_name = String::Handle(String::Concat(class_name, dot_name));
|
| + result = ResolveConstructor(CURRENT_FUNC, cls, class_name, constr_name, 1);
|
| if (result.IsError()) return result.raw();
|
| ASSERT(result.IsFunction());
|
| Function& constructor = Function::Handle(isolate);
|
| @@ -2329,9 +2329,6 @@
|
| static Dart_TypedData_Type GetType(intptr_t class_id) {
|
| Dart_TypedData_Type type;
|
| switch (class_id) {
|
| - case kByteArrayCid :
|
| - type = kByteData;
|
| - break;
|
| case kTypedDataInt8ArrayCid :
|
| case kExternalTypedDataInt8ArrayCid :
|
| type = kInt8;
|
| @@ -2386,23 +2383,80 @@
|
|
|
| DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfTypedData(Dart_Handle object) {
|
| intptr_t class_id = Api::ClassId(object);
|
| - if (!RawObject::IsTypedDataClassId(class_id)) {
|
| - return kInvalid;
|
| + if (RawObject::IsTypedDataClassId(class_id)) {
|
| + return GetType(class_id);
|
| }
|
| - return GetType(class_id);
|
| + Isolate* isolate = Isolate::Current();
|
| + const Library& lib =
|
| + Library::Handle(isolate->object_store()->typeddata_library());
|
| + const Class& cls =
|
| + Class::Handle(isolate,
|
| + lib.LookupClassAllowPrivate(Symbols::_ByteDataView()));
|
| + if (isolate->class_table()->At(class_id) == cls.raw()) {
|
| + return kByteData;
|
| + }
|
| + return kInvalid;
|
| }
|
|
|
|
|
| DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfExternalTypedData(
|
| Dart_Handle object) {
|
| intptr_t class_id = Api::ClassId(object);
|
| - if (!RawObject::IsExternalTypedDataClassId(class_id)) {
|
| - return kInvalid;
|
| + if (RawObject::IsExternalTypedDataClassId(class_id)) {
|
| + return GetType(class_id);
|
| }
|
| - return GetType(class_id);
|
| + Isolate* isolate = Isolate::Current();
|
| + const Library& lib =
|
| + Library::Handle(isolate->object_store()->typeddata_library());
|
| + const Class& cls =
|
| + Class::Handle(isolate,
|
| + lib.LookupClassAllowPrivate(Symbols::_ByteDataView()));
|
| + if (isolate->class_table()->At(class_id) == cls.raw()) {
|
| + return kByteData;
|
| + }
|
| + return kInvalid;
|
| }
|
|
|
|
|
| +static RawObject* GetByteDataConstructor(Isolate* isolate,
|
| + const String& constructor_name,
|
| + intptr_t num_args) {
|
| + const Library& lib =
|
| + Library::Handle(isolate->object_store()->typeddata_library());
|
| + ASSERT(!lib.IsNull());
|
| + const Class& cls =
|
| + Class::Handle(isolate, lib.LookupClassAllowPrivate(Symbols::ByteData()));
|
| + ASSERT(!cls.IsNull());
|
| + return ResolveConstructor(CURRENT_FUNC,
|
| + cls,
|
| + Symbols::ByteData(),
|
| + constructor_name,
|
| + num_args);
|
| +}
|
| +
|
| +
|
| +static Dart_Handle NewByteData(Isolate* isolate, intptr_t length) {
|
| + CHECK_LENGTH(length, TypedData::MaxElements(kTypedDataInt8ArrayCid));
|
| + Object& result = Object::Handle(isolate);
|
| + result = GetByteDataConstructor(isolate, Symbols::ByteDataDot(), 1);
|
| + ASSERT(!result.IsNull());
|
| + ASSERT(result.IsFunction());
|
| + const Function& factory = Function::Cast(result);
|
| + ASSERT(!factory.IsConstructor());
|
| +
|
| + // Create the argument list.
|
| + const Array& args = Array::Handle(isolate, Array::New(2));
|
| + // Factories get type arguments.
|
| + args.SetAt(0, TypeArguments::Handle(isolate));
|
| + args.SetAt(1, Smi::Handle(isolate, Smi::New(length)));
|
| +
|
| + // Invoke the constructor and return the new object.
|
| + result = DartEntry::InvokeFunction(factory, args);
|
| + ASSERT(result.IsInstance() || result.IsNull() || result.IsError());
|
| + return Api::NewHandle(isolate, result.raw());
|
| +}
|
| +
|
| +
|
| static Dart_Handle NewTypedData(Isolate* isolate,
|
| intptr_t cid,
|
| intptr_t length) {
|
| @@ -2426,6 +2480,47 @@
|
| }
|
|
|
|
|
| +static Dart_Handle NewExternalByteData(Isolate* isolate,
|
| + void* data,
|
| + intptr_t length,
|
| + void* peer,
|
| + Dart_WeakPersistentHandleFinalizer cb) {
|
| + Dart_Handle ext_data = NewExternalTypedData(kExternalTypedDataUint8ArrayCid,
|
| + data,
|
| + length,
|
| + peer,
|
| + cb);
|
| + if (::Dart_IsError(ext_data)) {
|
| + return ext_data;
|
| + }
|
| + Object& result = Object::Handle(isolate);
|
| + result = GetByteDataConstructor(isolate, Symbols::ByteDataDotview(), 3);
|
| + ASSERT(!result.IsNull());
|
| + ASSERT(result.IsFunction());
|
| + const Function& factory = Function::Cast(result);
|
| + ASSERT(!factory.IsConstructor());
|
| +
|
| + // Create the argument list.
|
| + const intptr_t num_args = 3;
|
| + const Array& args = Array::Handle(isolate, Array::New(num_args + 1));
|
| + // Factories get type arguments.
|
| + args.SetAt(0, TypeArguments::Handle(isolate));
|
| + const ExternalTypedData& array =
|
| + Api::UnwrapExternalTypedDataHandle(isolate, ext_data);
|
| + args.SetAt(1, array);
|
| + Smi& smi = Smi::Handle(isolate);
|
| + smi = Smi::New(0);
|
| + args.SetAt(2, smi);
|
| + smi = Smi::New(length);
|
| + args.SetAt(3, smi);
|
| +
|
| + // Invoke the constructor and return the new object.
|
| + result = DartEntry::InvokeFunction(factory, args);
|
| + ASSERT(result.IsNull() || result.IsInstance() || result.IsError());
|
| + return Api::NewHandle(isolate, result.raw());
|
| +}
|
| +
|
| +
|
| DART_EXPORT Dart_Handle Dart_NewTypedData(Dart_TypedData_Type type,
|
| intptr_t length) {
|
| Isolate* isolate = Isolate::Current();
|
| @@ -2433,8 +2528,7 @@
|
| CHECK_CALLBACK_STATE(isolate);
|
| switch (type) {
|
| case kByteData :
|
| - // TODO(asiva): Add a new ByteArray::New() method.
|
| - break;
|
| + return NewByteData(isolate, length);
|
| case kInt8 :
|
| return NewTypedData(isolate, kTypedDataInt8ArrayCid, length);
|
| case kUint8 :
|
| @@ -2480,8 +2574,7 @@
|
| CHECK_CALLBACK_STATE(isolate);
|
| switch (type) {
|
| case kByteData :
|
| - // TODO(asiva): Allocate external ByteData object.
|
| - break;
|
| + return NewExternalByteData(isolate, data, length, peer, callback);
|
| case kInt8 :
|
| return NewExternalTypedData(kExternalTypedDataInt8ArrayCid,
|
| data,
|
| @@ -3462,10 +3555,9 @@
|
| static RawObject* ResolveConstructor(const char* current_func,
|
| const Class& cls,
|
| const String& class_name,
|
| - const String& dotted_name,
|
| + const String& constr_name,
|
| int num_args) {
|
| // The constructor must be present in the interface.
|
| - String& constr_name = String::Handle(String::Concat(class_name, dotted_name));
|
| const Function& constructor =
|
| Function::Handle(cls.LookupFunctionAllowPrivate(constr_name));
|
| if (constructor.IsNull() ||
|
| @@ -3550,8 +3642,13 @@
|
| }
|
|
|
| // Resolve the constructor.
|
| - result = ResolveConstructor(
|
| - "Dart_New", cls, base_constructor_name, dot_name, number_of_arguments);
|
| + String& constr_name =
|
| + String::Handle(String::Concat(base_constructor_name, dot_name));
|
| + result = ResolveConstructor("Dart_New",
|
| + cls,
|
| + base_constructor_name,
|
| + constr_name,
|
| + number_of_arguments);
|
| if (result.IsError()) {
|
| return Api::NewHandle(isolate, result.raw());
|
| }
|
|
|