Index: runtime/vm/dart_api_message.cc |
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc |
index 5315301baef99a21bf587b324ed0342745bd06ad..2efc4cf845cb92069282503026e1c8b02d12410f 100644 |
--- a/runtime/vm/dart_api_message.cc |
+++ b/runtime/vm/dart_api_message.cc |
@@ -125,21 +125,40 @@ Dart_CObject* ApiMessageReader::AllocateDartCObjectString(intptr_t length) { |
} |
-Dart_CObject* ApiMessageReader::AllocateDartCObjectUint8Array(intptr_t length) { |
+static int SizeInBytes(Dart_CObject::TypedDataType type) { |
+ switch (type) { |
+ case Dart_CObject::kInt8Array: |
+ case Dart_CObject::kUint8Array: |
+ return 1; |
+ case Dart_CObject::kInt16Array: |
+ case Dart_CObject::kUint16Array: |
+ return 2; |
+ default: |
+ break; |
+ } |
+ UNREACHABLE(); |
+ return -1; |
+} |
+ |
+ |
+Dart_CObject* ApiMessageReader::AllocateDartCObjectTypedData( |
+ Dart_CObject::TypedDataType type, intptr_t length) { |
// Allocate a Dart_CObject structure followed by an array of bytes |
// for the byte array content. The pointer to the byte array content |
// is set up to this area. |
+ intptr_t length_in_bytes = SizeInBytes(type) * length; |
siva
2013/04/15 23:28:45
The code for SizeInBytes is duplicated here and in
|
Dart_CObject* value = |
reinterpret_cast<Dart_CObject*>( |
- alloc_(NULL, 0, sizeof(Dart_CObject) + length)); |
+ alloc_(NULL, 0, sizeof(Dart_CObject) + length_in_bytes)); |
ASSERT(value != NULL); |
- value->type = Dart_CObject::kUint8Array; |
- value->value.as_array.length = length; |
+ value->type = Dart_CObject::kTypedData; |
+ value->value.as_typed_data.type = type; |
+ value->value.as_typed_data.length = length_in_bytes; |
if (length > 0) { |
- value->value.as_byte_array.values = |
+ value->value.as_typed_data.values = |
reinterpret_cast<uint8_t*>(value) + sizeof(*value); |
} else { |
- value->value.as_byte_array.values = NULL; |
+ value->value.as_typed_data.values = NULL; |
} |
return value; |
} |
@@ -191,6 +210,55 @@ ApiMessageReader::BackRefNode* ApiMessageReader::AllocateBackRefNode( |
} |
+static Dart_CObject::TypedDataType GetTypedDataTypeFromView( |
+ Dart_CObject_Internal* object) { |
+ struct { |
+ const char* name; |
+ Dart_CObject::TypedDataType type; |
+ } view_class_names[] = { |
+ { "_Int8ArrayView", Dart_CObject::kInt8Array }, |
+ { "_Uint8ArrayView", Dart_CObject::kUint8Array }, |
+ { "_Int16ArrayView", Dart_CObject::kInt16Array }, |
+ { "_Uint16ArrayView", Dart_CObject::kUint16Array }, |
+ { NULL, Dart_CObject::kNumberOfTypedDataTypes }, |
+ }; |
+ |
+ char* library_url = |
+ object->cls->internal.as_class.library_url->value.as_string; |
+ char* class_name = |
+ object->cls->internal.as_class.class_name->value.as_string; |
+ if (strcmp("dart:typeddata", library_url) != 0) { |
+ return Dart_CObject::kNumberOfTypedDataTypes; |
+ } |
+ int i = 0; |
+ while (view_class_names[i].name != NULL) { |
+ if (strncmp(view_class_names[i].name, |
+ class_name, |
+ strlen(view_class_names[i].name)) == 0) { |
+ return view_class_names[i].type; |
+ } |
+ i++; |
+ } |
+ return Dart_CObject::kNumberOfTypedDataTypes; |
+} |
+ |
+ |
+static int GetTypedDataTypeElementSize(Dart_CObject::TypedDataType type) { |
+ switch (type) { |
+ case Dart_CObject::kInt8Array: |
+ case Dart_CObject::kUint8Array: |
+ return 1; |
+ case Dart_CObject::kInt16Array: |
+ case Dart_CObject::kUint16Array: |
+ return 2; |
+ default: |
+ break; |
+ } |
+ UNREACHABLE(); |
+ return -1; |
+} |
siva
2013/04/15 23:28:45
Ditto comment about GetTypedDataTypeElementSize, m
|
+ |
+ |
Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) { |
// Read the class header information and lookup the class. |
intptr_t class_header = ReadIntptrValue(); |
@@ -217,30 +285,29 @@ Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) { |
Dart_CObject_Internal::kUninitialized)); |
// Handle typed data views. |
- char* library_url = |
- object->cls->internal.as_class.library_url->value.as_string; |
- char* class_name = |
- object->cls->internal.as_class.class_name->value.as_string; |
- if (strcmp("dart:typeddata", library_url) == 0 && |
- strncmp("_Uint8ArrayView", class_name, 15) == 0) { |
+ Dart_CObject::TypedDataType type = GetTypedDataTypeFromView(object); |
+ if (type != Dart_CObject::kNumberOfTypedDataTypes) { |
object->type = |
static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kView); |
- // Skip type arguments. |
- ReadObjectImpl(); |
+ ReadObjectImpl(); // Skip type arguments. |
object->internal.as_view.buffer = ReadObjectImpl(); |
object->internal.as_view.offset_in_bytes = ReadSmiValue(); |
object->internal.as_view.length = ReadSmiValue(); |
+ ReadObjectImpl(); // Skip last field. |
// The buffer is fully read now as typed data objects are |
// serialized in-line. |
Dart_CObject* buffer = object->internal.as_view.buffer; |
- ASSERT(buffer->type == Dart_CObject::kUint8Array); |
+ ASSERT(buffer->type == Dart_CObject::kTypedData); |
// Now turn the view into a byte array. |
- object->type = Dart_CObject::kUint8Array; |
- object->value.as_byte_array.length = object->internal.as_view.length; |
- object->value.as_byte_array.values = |
- buffer->value.as_byte_array.values + |
+ object->type = Dart_CObject::kTypedData; |
+ object->value.as_typed_data.type = type; |
+ object->value.as_typed_data.length = |
+ object->internal.as_view.length * |
+ GetTypedDataTypeElementSize(type); |
+ object->value.as_typed_data.values = |
+ buffer->value.as_typed_data.values + |
object->internal.as_view.offset_in_bytes; |
} else { |
// TODO(sgjesse): Handle other instances. Currently this will |
@@ -509,19 +576,39 @@ Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id, |
::free(utf16); |
return object; |
} |
+ |
+#define READ_TYPED_DATA(type, ctype) \ |
+ { \ |
+ intptr_t len = ReadSmiValue(); \ |
+ Dart_CObject* object = \ |
+ AllocateDartCObjectTypedData(Dart_CObject::k##type##Array, len); \ |
+ AddBackRef(object_id, object, kIsDeserialized); \ |
+ if (len > 0) { \ |
+ ctype* p = \ |
+ reinterpret_cast<ctype*>(object->value.as_typed_data.values); \ |
+ for (intptr_t i = 0; i < len; i++) { \ |
+ p[i] = Read<ctype>(); \ |
+ } \ |
+ } \ |
+ return object; \ |
+ } \ |
+ |
+ case kTypedDataInt8ArrayCid: |
+ case kExternalTypedDataInt8ArrayCid: |
+ READ_TYPED_DATA(Int8, int8_t); |
+ |
case kTypedDataUint8ArrayCid: |
- case kExternalTypedDataUint8ArrayCid: { |
- intptr_t len = ReadSmiValue(); |
- Dart_CObject* object = AllocateDartCObjectUint8Array(len); |
- AddBackRef(object_id, object, kIsDeserialized); |
- if (len > 0) { |
- uint8_t* p = object->value.as_byte_array.values; |
- for (intptr_t i = 0; i < len; i++) { |
- p[i] = Read<uint8_t>(); |
- } |
- } |
- return object; |
- } |
+ case kExternalTypedDataUint8ArrayCid: |
+ READ_TYPED_DATA(Uint8, uint8_t); |
+ |
+ case kTypedDataInt16ArrayCid: |
+ case kExternalTypedDataInt16ArrayCid: |
+ READ_TYPED_DATA(Int16, int16_t); |
+ |
+ case kTypedDataUint16ArrayCid: |
+ case kExternalTypedDataUint16ArrayCid: |
+ READ_TYPED_DATA(Uint16, uint16_t); |
+ |
case kGrowableObjectArrayCid: { |
// A GrowableObjectArray is serialized as its length followed by |
// its backing store. The backing store is an array with a |
@@ -924,22 +1011,33 @@ bool ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object, |
} |
break; |
} |
- case Dart_CObject::kUint8Array: { |
+ case Dart_CObject::kTypedData: { |
// Write out the serialization header value for this object. |
WriteInlinedHeader(object); |
// Write out the class and tags information. |
- WriteIndexedObject(kTypedDataUint8ArrayCid); |
- WriteIntptrValue(RawObject::ClassIdTag::update( |
- kTypedDataUint8ArrayCid, 0)); |
- uint8_t* bytes = object->value.as_byte_array.values; |
- intptr_t len = object->value.as_byte_array.length; |
+ intptr_t class_id; |
+ switch (object->value.as_typed_data.type) { |
+ case Dart_CObject::kInt8Array: |
+ class_id = kTypedDataInt8ArrayCid; |
+ break; |
+ case Dart_CObject::kUint8Array: |
+ class_id = kTypedDataUint8ArrayCid; |
+ break; |
+ default: |
+ UNIMPLEMENTED(); |
+ } |
+ |
+ WriteIndexedObject(class_id); |
+ WriteIntptrValue(RawObject::ClassIdTag::update(class_id, 0)); |
+ uint8_t* bytes = object->value.as_typed_data.values; |
+ intptr_t len = object->value.as_typed_data.length; |
WriteSmi(len); |
for (intptr_t i = 0; i < len; i++) { |
Write<uint8_t>(bytes[i]); |
} |
break; |
} |
- case Dart_CObject::kExternalUint8Array: { |
+ case Dart_CObject::kExternalTypedData: { |
// TODO(ager): we are writing C pointers into the message in |
// order to post external arrays through ports. We need to make |
// sure that messages containing pointers can never be posted |
@@ -951,11 +1049,11 @@ bool ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object, |
WriteIndexedObject(kExternalTypedDataUint8ArrayCid); |
WriteIntptrValue(RawObject::ClassIdTag::update( |
kExternalTypedDataUint8ArrayCid, 0)); |
- int length = object->value.as_external_byte_array.length; |
- uint8_t* data = object->value.as_external_byte_array.data; |
- void* peer = object->value.as_external_byte_array.peer; |
+ int length = object->value.as_external_typed_data.length; |
+ uint8_t* data = object->value.as_external_typed_data.data; |
+ void* peer = object->value.as_external_typed_data.peer; |
Dart_WeakPersistentHandleFinalizer callback = |
- object->value.as_external_byte_array.callback; |
+ object->value.as_external_typed_data.callback; |
WriteSmi(length); |
WriteIntptrValue(reinterpret_cast<intptr_t>(data)); |
WriteIntptrValue(reinterpret_cast<intptr_t>(peer)); |