Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "vm/dart_api_message.h" | 5 #include "vm/dart_api_message.h" |
| 6 #include "vm/object.h" | 6 #include "vm/object.h" |
| 7 #include "vm/snapshot_ids.h" | 7 #include "vm/snapshot_ids.h" |
| 8 #include "vm/symbols.h" | 8 #include "vm/symbols.h" |
| 9 #include "vm/unicode.h" | 9 #include "vm/unicode.h" |
| 10 | 10 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 Dart_CObject* value = | 118 Dart_CObject* value = |
| 119 reinterpret_cast<Dart_CObject*>( | 119 reinterpret_cast<Dart_CObject*>( |
| 120 alloc_(NULL, 0, sizeof(Dart_CObject) + length + 1)); | 120 alloc_(NULL, 0, sizeof(Dart_CObject) + length + 1)); |
| 121 ASSERT(value != NULL); | 121 ASSERT(value != NULL); |
| 122 value->value.as_string = reinterpret_cast<char*>(value) + sizeof(*value); | 122 value->value.as_string = reinterpret_cast<char*>(value) + sizeof(*value); |
| 123 value->type = Dart_CObject::kString; | 123 value->type = Dart_CObject::kString; |
| 124 return value; | 124 return value; |
| 125 } | 125 } |
| 126 | 126 |
| 127 | 127 |
| 128 Dart_CObject* ApiMessageReader::AllocateDartCObjectUint8Array(intptr_t length) { | 128 static int SizeInBytes(Dart_CObject::TypedDataType type) { |
| 129 switch (type) { | |
| 130 case Dart_CObject::kInt8Array: | |
| 131 case Dart_CObject::kUint8Array: | |
| 132 return 1; | |
| 133 case Dart_CObject::kInt16Array: | |
| 134 case Dart_CObject::kUint16Array: | |
| 135 return 2; | |
| 136 default: | |
| 137 break; | |
| 138 } | |
| 139 UNREACHABLE(); | |
| 140 return -1; | |
| 141 } | |
| 142 | |
| 143 | |
| 144 Dart_CObject* ApiMessageReader::AllocateDartCObjectTypedData( | |
| 145 Dart_CObject::TypedDataType type, intptr_t length) { | |
| 129 // Allocate a Dart_CObject structure followed by an array of bytes | 146 // Allocate a Dart_CObject structure followed by an array of bytes |
| 130 // for the byte array content. The pointer to the byte array content | 147 // for the byte array content. The pointer to the byte array content |
| 131 // is set up to this area. | 148 // is set up to this area. |
| 149 intptr_t length_in_bytes = SizeInBytes(type) * length; | |
|
siva
2013/04/15 23:28:45
The code for SizeInBytes is duplicated here and in
| |
| 132 Dart_CObject* value = | 150 Dart_CObject* value = |
| 133 reinterpret_cast<Dart_CObject*>( | 151 reinterpret_cast<Dart_CObject*>( |
| 134 alloc_(NULL, 0, sizeof(Dart_CObject) + length)); | 152 alloc_(NULL, 0, sizeof(Dart_CObject) + length_in_bytes)); |
| 135 ASSERT(value != NULL); | 153 ASSERT(value != NULL); |
| 136 value->type = Dart_CObject::kUint8Array; | 154 value->type = Dart_CObject::kTypedData; |
| 137 value->value.as_array.length = length; | 155 value->value.as_typed_data.type = type; |
| 156 value->value.as_typed_data.length = length_in_bytes; | |
| 138 if (length > 0) { | 157 if (length > 0) { |
| 139 value->value.as_byte_array.values = | 158 value->value.as_typed_data.values = |
| 140 reinterpret_cast<uint8_t*>(value) + sizeof(*value); | 159 reinterpret_cast<uint8_t*>(value) + sizeof(*value); |
| 141 } else { | 160 } else { |
| 142 value->value.as_byte_array.values = NULL; | 161 value->value.as_typed_data.values = NULL; |
| 143 } | 162 } |
| 144 return value; | 163 return value; |
| 145 } | 164 } |
| 146 | 165 |
| 147 | 166 |
| 148 Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) { | 167 Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) { |
| 149 // Allocate a Dart_CObject structure followed by an array of | 168 // Allocate a Dart_CObject structure followed by an array of |
| 150 // pointers to Dart_CObject structures. The pointer to the array | 169 // pointers to Dart_CObject structures. The pointer to the array |
| 151 // content is set up to this area. | 170 // content is set up to this area. |
| 152 Dart_CObject* value = | 171 Dart_CObject* value = |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 Dart_CObject* reference, | 203 Dart_CObject* reference, |
| 185 DeserializeState state) { | 204 DeserializeState state) { |
| 186 BackRefNode* value = | 205 BackRefNode* value = |
| 187 reinterpret_cast<BackRefNode*>(alloc_(NULL, 0, sizeof(BackRefNode))); | 206 reinterpret_cast<BackRefNode*>(alloc_(NULL, 0, sizeof(BackRefNode))); |
| 188 value->set_reference(reference); | 207 value->set_reference(reference); |
| 189 value->set_state(state); | 208 value->set_state(state); |
| 190 return value; | 209 return value; |
| 191 } | 210 } |
| 192 | 211 |
| 193 | 212 |
| 213 static Dart_CObject::TypedDataType GetTypedDataTypeFromView( | |
| 214 Dart_CObject_Internal* object) { | |
| 215 struct { | |
| 216 const char* name; | |
| 217 Dart_CObject::TypedDataType type; | |
| 218 } view_class_names[] = { | |
| 219 { "_Int8ArrayView", Dart_CObject::kInt8Array }, | |
| 220 { "_Uint8ArrayView", Dart_CObject::kUint8Array }, | |
| 221 { "_Int16ArrayView", Dart_CObject::kInt16Array }, | |
| 222 { "_Uint16ArrayView", Dart_CObject::kUint16Array }, | |
| 223 { NULL, Dart_CObject::kNumberOfTypedDataTypes }, | |
| 224 }; | |
| 225 | |
| 226 char* library_url = | |
| 227 object->cls->internal.as_class.library_url->value.as_string; | |
| 228 char* class_name = | |
| 229 object->cls->internal.as_class.class_name->value.as_string; | |
| 230 if (strcmp("dart:typeddata", library_url) != 0) { | |
| 231 return Dart_CObject::kNumberOfTypedDataTypes; | |
| 232 } | |
| 233 int i = 0; | |
| 234 while (view_class_names[i].name != NULL) { | |
| 235 if (strncmp(view_class_names[i].name, | |
| 236 class_name, | |
| 237 strlen(view_class_names[i].name)) == 0) { | |
| 238 return view_class_names[i].type; | |
| 239 } | |
| 240 i++; | |
| 241 } | |
| 242 return Dart_CObject::kNumberOfTypedDataTypes; | |
| 243 } | |
| 244 | |
| 245 | |
| 246 static int GetTypedDataTypeElementSize(Dart_CObject::TypedDataType type) { | |
| 247 switch (type) { | |
| 248 case Dart_CObject::kInt8Array: | |
| 249 case Dart_CObject::kUint8Array: | |
| 250 return 1; | |
| 251 case Dart_CObject::kInt16Array: | |
| 252 case Dart_CObject::kUint16Array: | |
| 253 return 2; | |
| 254 default: | |
| 255 break; | |
| 256 } | |
| 257 UNREACHABLE(); | |
| 258 return -1; | |
| 259 } | |
|
siva
2013/04/15 23:28:45
Ditto comment about GetTypedDataTypeElementSize, m
| |
| 260 | |
| 261 | |
| 194 Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) { | 262 Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) { |
| 195 // Read the class header information and lookup the class. | 263 // Read the class header information and lookup the class. |
| 196 intptr_t class_header = ReadIntptrValue(); | 264 intptr_t class_header = ReadIntptrValue(); |
| 197 intptr_t tags = ReadIntptrValue(); | 265 intptr_t tags = ReadIntptrValue(); |
| 198 USE(tags); | 266 USE(tags); |
| 199 intptr_t class_id; | 267 intptr_t class_id; |
| 200 | 268 |
| 201 // There is limited support for reading regular dart instances. Only | 269 // There is limited support for reading regular dart instances. Only |
| 202 // typed data views are currently handled. | 270 // typed data views are currently handled. |
| 203 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) { | 271 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) { |
| 204 Dart_CObject_Internal* object = | 272 Dart_CObject_Internal* object = |
| 205 reinterpret_cast<Dart_CObject_Internal*>(GetBackRef(object_id)); | 273 reinterpret_cast<Dart_CObject_Internal*>(GetBackRef(object_id)); |
| 206 if (object == NULL) { | 274 if (object == NULL) { |
| 207 object = | 275 object = |
| 208 AllocateDartCObjectInternal(Dart_CObject_Internal::kUninitialized); | 276 AllocateDartCObjectInternal(Dart_CObject_Internal::kUninitialized); |
| 209 AddBackRef(object_id, object, kIsDeserialized); | 277 AddBackRef(object_id, object, kIsDeserialized); |
| 210 // Read class of object. | 278 // Read class of object. |
| 211 object->cls = reinterpret_cast<Dart_CObject_Internal*>(ReadObjectImpl()); | 279 object->cls = reinterpret_cast<Dart_CObject_Internal*>(ReadObjectImpl()); |
| 212 ASSERT(object->cls->type == | 280 ASSERT(object->cls->type == |
| 213 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kClass)); | 281 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kClass)); |
| 214 } | 282 } |
| 215 ASSERT(object->type == | 283 ASSERT(object->type == |
| 216 static_cast<Dart_CObject::Type>( | 284 static_cast<Dart_CObject::Type>( |
| 217 Dart_CObject_Internal::kUninitialized)); | 285 Dart_CObject_Internal::kUninitialized)); |
| 218 | 286 |
| 219 // Handle typed data views. | 287 // Handle typed data views. |
| 220 char* library_url = | 288 Dart_CObject::TypedDataType type = GetTypedDataTypeFromView(object); |
| 221 object->cls->internal.as_class.library_url->value.as_string; | 289 if (type != Dart_CObject::kNumberOfTypedDataTypes) { |
| 222 char* class_name = | |
| 223 object->cls->internal.as_class.class_name->value.as_string; | |
| 224 if (strcmp("dart:typeddata", library_url) == 0 && | |
| 225 strncmp("_Uint8ArrayView", class_name, 15) == 0) { | |
| 226 object->type = | 290 object->type = |
| 227 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kView); | 291 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kView); |
| 228 // Skip type arguments. | 292 ReadObjectImpl(); // Skip type arguments. |
| 229 ReadObjectImpl(); | |
| 230 object->internal.as_view.buffer = ReadObjectImpl(); | 293 object->internal.as_view.buffer = ReadObjectImpl(); |
| 231 object->internal.as_view.offset_in_bytes = ReadSmiValue(); | 294 object->internal.as_view.offset_in_bytes = ReadSmiValue(); |
| 232 object->internal.as_view.length = ReadSmiValue(); | 295 object->internal.as_view.length = ReadSmiValue(); |
| 296 ReadObjectImpl(); // Skip last field. | |
| 233 | 297 |
| 234 // The buffer is fully read now as typed data objects are | 298 // The buffer is fully read now as typed data objects are |
| 235 // serialized in-line. | 299 // serialized in-line. |
| 236 Dart_CObject* buffer = object->internal.as_view.buffer; | 300 Dart_CObject* buffer = object->internal.as_view.buffer; |
| 237 ASSERT(buffer->type == Dart_CObject::kUint8Array); | 301 ASSERT(buffer->type == Dart_CObject::kTypedData); |
| 238 | 302 |
| 239 // Now turn the view into a byte array. | 303 // Now turn the view into a byte array. |
| 240 object->type = Dart_CObject::kUint8Array; | 304 object->type = Dart_CObject::kTypedData; |
| 241 object->value.as_byte_array.length = object->internal.as_view.length; | 305 object->value.as_typed_data.type = type; |
| 242 object->value.as_byte_array.values = | 306 object->value.as_typed_data.length = |
| 243 buffer->value.as_byte_array.values + | 307 object->internal.as_view.length * |
| 308 GetTypedDataTypeElementSize(type); | |
| 309 object->value.as_typed_data.values = | |
| 310 buffer->value.as_typed_data.values + | |
| 244 object->internal.as_view.offset_in_bytes; | 311 object->internal.as_view.offset_in_bytes; |
| 245 } else { | 312 } else { |
| 246 // TODO(sgjesse): Handle other instances. Currently this will | 313 // TODO(sgjesse): Handle other instances. Currently this will |
| 247 // skew the reading as the fields of the instance is not read. | 314 // skew the reading as the fields of the instance is not read. |
| 248 } | 315 } |
| 249 return object; | 316 return object; |
| 250 } | 317 } |
| 251 | 318 |
| 252 ASSERT((class_header & kSmiTagMask) != 0); | 319 ASSERT((class_header & kSmiTagMask) != 0); |
| 253 class_id = LookupInternalClass(class_header); | 320 class_id = LookupInternalClass(class_header); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 502 char* p = object->value.as_string; | 569 char* p = object->value.as_string; |
| 503 i = 0; | 570 i = 0; |
| 504 while (i < len) { | 571 while (i < len) { |
| 505 p += Utf8::Encode(Utf16::Next(utf16, &i, len), p); | 572 p += Utf8::Encode(Utf16::Next(utf16, &i, len), p); |
| 506 } | 573 } |
| 507 *p = '\0'; | 574 *p = '\0'; |
| 508 ASSERT(p == (object->value.as_string + utf8_len)); | 575 ASSERT(p == (object->value.as_string + utf8_len)); |
| 509 ::free(utf16); | 576 ::free(utf16); |
| 510 return object; | 577 return object; |
| 511 } | 578 } |
| 579 | |
| 580 #define READ_TYPED_DATA(type, ctype) \ | |
| 581 { \ | |
| 582 intptr_t len = ReadSmiValue(); \ | |
| 583 Dart_CObject* object = \ | |
| 584 AllocateDartCObjectTypedData(Dart_CObject::k##type##Array, len); \ | |
| 585 AddBackRef(object_id, object, kIsDeserialized); \ | |
| 586 if (len > 0) { \ | |
| 587 ctype* p = \ | |
| 588 reinterpret_cast<ctype*>(object->value.as_typed_data.values); \ | |
| 589 for (intptr_t i = 0; i < len; i++) { \ | |
| 590 p[i] = Read<ctype>(); \ | |
| 591 } \ | |
| 592 } \ | |
| 593 return object; \ | |
| 594 } \ | |
| 595 | |
| 596 case kTypedDataInt8ArrayCid: | |
| 597 case kExternalTypedDataInt8ArrayCid: | |
| 598 READ_TYPED_DATA(Int8, int8_t); | |
| 599 | |
| 512 case kTypedDataUint8ArrayCid: | 600 case kTypedDataUint8ArrayCid: |
| 513 case kExternalTypedDataUint8ArrayCid: { | 601 case kExternalTypedDataUint8ArrayCid: |
| 514 intptr_t len = ReadSmiValue(); | 602 READ_TYPED_DATA(Uint8, uint8_t); |
| 515 Dart_CObject* object = AllocateDartCObjectUint8Array(len); | 603 |
| 516 AddBackRef(object_id, object, kIsDeserialized); | 604 case kTypedDataInt16ArrayCid: |
| 517 if (len > 0) { | 605 case kExternalTypedDataInt16ArrayCid: |
| 518 uint8_t* p = object->value.as_byte_array.values; | 606 READ_TYPED_DATA(Int16, int16_t); |
| 519 for (intptr_t i = 0; i < len; i++) { | 607 |
| 520 p[i] = Read<uint8_t>(); | 608 case kTypedDataUint16ArrayCid: |
| 521 } | 609 case kExternalTypedDataUint16ArrayCid: |
| 522 } | 610 READ_TYPED_DATA(Uint16, uint16_t); |
| 523 return object; | 611 |
| 524 } | |
| 525 case kGrowableObjectArrayCid: { | 612 case kGrowableObjectArrayCid: { |
| 526 // A GrowableObjectArray is serialized as its length followed by | 613 // A GrowableObjectArray is serialized as its length followed by |
| 527 // its backing store. The backing store is an array with a | 614 // its backing store. The backing store is an array with a |
| 528 // length which might be longer than the length of the | 615 // length which might be longer than the length of the |
| 529 // GrowableObjectArray. | 616 // GrowableObjectArray. |
| 530 intptr_t len = ReadSmiValue(); | 617 intptr_t len = ReadSmiValue(); |
| 531 | 618 |
| 532 Dart_CObject* value = GetBackRef(object_id); | 619 Dart_CObject* value = GetBackRef(object_id); |
| 533 ASSERT(value == NULL); | 620 ASSERT(value == NULL); |
| 534 // Allocate an empty array for the GrowableObjectArray which | 621 // Allocate an empty array for the GrowableObjectArray which |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 917 reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t))); | 1004 reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t))); |
| 918 bool success = Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len); | 1005 bool success = Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len); |
| 919 ASSERT(success); | 1006 ASSERT(success); |
| 920 for (intptr_t i = 0; i < len; i++) { | 1007 for (intptr_t i = 0; i < len; i++) { |
| 921 Write<uint16_t>(utf16_str[i]); | 1008 Write<uint16_t>(utf16_str[i]); |
| 922 } | 1009 } |
| 923 ::free(utf16_str); | 1010 ::free(utf16_str); |
| 924 } | 1011 } |
| 925 break; | 1012 break; |
| 926 } | 1013 } |
| 927 case Dart_CObject::kUint8Array: { | 1014 case Dart_CObject::kTypedData: { |
| 928 // Write out the serialization header value for this object. | 1015 // Write out the serialization header value for this object. |
| 929 WriteInlinedHeader(object); | 1016 WriteInlinedHeader(object); |
| 930 // Write out the class and tags information. | 1017 // Write out the class and tags information. |
| 931 WriteIndexedObject(kTypedDataUint8ArrayCid); | 1018 intptr_t class_id; |
| 932 WriteIntptrValue(RawObject::ClassIdTag::update( | 1019 switch (object->value.as_typed_data.type) { |
| 933 kTypedDataUint8ArrayCid, 0)); | 1020 case Dart_CObject::kInt8Array: |
| 934 uint8_t* bytes = object->value.as_byte_array.values; | 1021 class_id = kTypedDataInt8ArrayCid; |
| 935 intptr_t len = object->value.as_byte_array.length; | 1022 break; |
| 1023 case Dart_CObject::kUint8Array: | |
| 1024 class_id = kTypedDataUint8ArrayCid; | |
| 1025 break; | |
| 1026 default: | |
| 1027 UNIMPLEMENTED(); | |
| 1028 } | |
| 1029 | |
| 1030 WriteIndexedObject(class_id); | |
| 1031 WriteIntptrValue(RawObject::ClassIdTag::update(class_id, 0)); | |
| 1032 uint8_t* bytes = object->value.as_typed_data.values; | |
| 1033 intptr_t len = object->value.as_typed_data.length; | |
| 936 WriteSmi(len); | 1034 WriteSmi(len); |
| 937 for (intptr_t i = 0; i < len; i++) { | 1035 for (intptr_t i = 0; i < len; i++) { |
| 938 Write<uint8_t>(bytes[i]); | 1036 Write<uint8_t>(bytes[i]); |
| 939 } | 1037 } |
| 940 break; | 1038 break; |
| 941 } | 1039 } |
| 942 case Dart_CObject::kExternalUint8Array: { | 1040 case Dart_CObject::kExternalTypedData: { |
| 943 // TODO(ager): we are writing C pointers into the message in | 1041 // TODO(ager): we are writing C pointers into the message in |
| 944 // order to post external arrays through ports. We need to make | 1042 // order to post external arrays through ports. We need to make |
| 945 // sure that messages containing pointers can never be posted | 1043 // sure that messages containing pointers can never be posted |
| 946 // to other processes. | 1044 // to other processes. |
| 947 | 1045 |
| 948 // Write out serialization header value for this object. | 1046 // Write out serialization header value for this object. |
| 949 WriteInlinedHeader(object); | 1047 WriteInlinedHeader(object); |
| 950 // Write out the class and tag information. | 1048 // Write out the class and tag information. |
| 951 WriteIndexedObject(kExternalTypedDataUint8ArrayCid); | 1049 WriteIndexedObject(kExternalTypedDataUint8ArrayCid); |
| 952 WriteIntptrValue(RawObject::ClassIdTag::update( | 1050 WriteIntptrValue(RawObject::ClassIdTag::update( |
| 953 kExternalTypedDataUint8ArrayCid, 0)); | 1051 kExternalTypedDataUint8ArrayCid, 0)); |
| 954 int length = object->value.as_external_byte_array.length; | 1052 int length = object->value.as_external_typed_data.length; |
| 955 uint8_t* data = object->value.as_external_byte_array.data; | 1053 uint8_t* data = object->value.as_external_typed_data.data; |
| 956 void* peer = object->value.as_external_byte_array.peer; | 1054 void* peer = object->value.as_external_typed_data.peer; |
| 957 Dart_WeakPersistentHandleFinalizer callback = | 1055 Dart_WeakPersistentHandleFinalizer callback = |
| 958 object->value.as_external_byte_array.callback; | 1056 object->value.as_external_typed_data.callback; |
| 959 WriteSmi(length); | 1057 WriteSmi(length); |
| 960 WriteIntptrValue(reinterpret_cast<intptr_t>(data)); | 1058 WriteIntptrValue(reinterpret_cast<intptr_t>(data)); |
| 961 WriteIntptrValue(reinterpret_cast<intptr_t>(peer)); | 1059 WriteIntptrValue(reinterpret_cast<intptr_t>(peer)); |
| 962 WriteIntptrValue(reinterpret_cast<intptr_t>(callback)); | 1060 WriteIntptrValue(reinterpret_cast<intptr_t>(callback)); |
| 963 break; | 1061 break; |
| 964 } | 1062 } |
| 965 default: | 1063 default: |
| 966 UNREACHABLE(); | 1064 UNREACHABLE(); |
| 967 } | 1065 } |
| 968 | 1066 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 984 if (!success) { | 1082 if (!success) { |
| 985 UnmarkAllCObjects(object); | 1083 UnmarkAllCObjects(object); |
| 986 return false; | 1084 return false; |
| 987 } | 1085 } |
| 988 } | 1086 } |
| 989 UnmarkAllCObjects(object); | 1087 UnmarkAllCObjects(object); |
| 990 return true; | 1088 return true; |
| 991 } | 1089 } |
| 992 | 1090 |
| 993 } // namespace dart | 1091 } // namespace dart |
| OLD | NEW |