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 |