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 |
11 namespace dart { | 11 namespace dart { |
12 | 12 |
13 static const int kNumInitialReferences = 4; | 13 static const int kNumInitialReferences = 4; |
14 | 14 |
15 ApiMessageReader::ApiMessageReader(const uint8_t* buffer, | 15 ApiMessageReader::ApiMessageReader(const uint8_t* buffer, intptr_t length) |
16 intptr_t length, | |
17 ReAlloc alloc) | |
18 : BaseReader(buffer, length), | 16 : BaseReader(buffer, length), |
19 alloc_(alloc), | 17 zone_(NULL), |
20 backward_references_(kNumInitialReferences), | 18 backward_references_(kNumInitialReferences), |
21 vm_isolate_references_(kNumInitialReferences), | 19 vm_isolate_references_(kNumInitialReferences), |
22 vm_symbol_references_(NULL) { | 20 vm_symbol_references_(NULL) { |
| 21 // We need to have an enclosing ApiNativeScope. |
| 22 ASSERT(ApiNativeScope::Current() != NULL); |
| 23 zone_ = ApiNativeScope::Current()->zone(); |
| 24 ASSERT(zone_ != NULL); |
23 Init(); | 25 Init(); |
24 } | 26 } |
25 | 27 |
26 | 28 |
27 void ApiMessageReader::Init() { | 29 void ApiMessageReader::Init() { |
28 // Initialize marker objects used to handle Lists. | 30 // Initialize marker objects used to handle Lists. |
29 // TODO(sjesse): Remove this when message serialization format is | 31 // TODO(sjesse): Remove this when message serialization format is |
30 // updated. | 32 // updated. |
31 memset(&type_arguments_marker, 0, sizeof(type_arguments_marker)); | 33 memset(&type_arguments_marker, 0, sizeof(type_arguments_marker)); |
32 memset(&dynamic_type_marker, 0, sizeof(dynamic_type_marker)); | 34 memset(&dynamic_type_marker, 0, sizeof(dynamic_type_marker)); |
(...skipping 14 matching lines...) Expand all Loading... |
47 if (IsVMIsolateObject(class_header)) { | 49 if (IsVMIsolateObject(class_header)) { |
48 return GetVMIsolateObjectId(class_header); | 50 return GetVMIsolateObjectId(class_header); |
49 } | 51 } |
50 ASSERT(SerializedHeaderTag::decode(class_header) == kObjectId); | 52 ASSERT(SerializedHeaderTag::decode(class_header) == kObjectId); |
51 return SerializedHeaderData::decode(class_header); | 53 return SerializedHeaderData::decode(class_header); |
52 } | 54 } |
53 | 55 |
54 | 56 |
55 Dart_CObject* ApiMessageReader::AllocateDartCObject(Dart_CObject_Type type) { | 57 Dart_CObject* ApiMessageReader::AllocateDartCObject(Dart_CObject_Type type) { |
56 Dart_CObject* value = | 58 Dart_CObject* value = |
57 reinterpret_cast<Dart_CObject*>(alloc_(NULL, 0, sizeof(Dart_CObject))); | 59 reinterpret_cast<Dart_CObject*>(allocator(sizeof(Dart_CObject))); |
58 ASSERT(value != NULL); | 60 ASSERT(value != NULL); |
59 value->type = type; | 61 value->type = type; |
60 return value; | 62 return value; |
61 } | 63 } |
62 | 64 |
63 | 65 |
64 Dart_CObject* ApiMessageReader::AllocateDartCObjectUnsupported() { | 66 Dart_CObject* ApiMessageReader::AllocateDartCObjectUnsupported() { |
65 return AllocateDartCObject(Dart_CObject_kUnsupported); | 67 return AllocateDartCObject(Dart_CObject_kUnsupported); |
66 } | 68 } |
67 | 69 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 return value; | 116 return value; |
115 } | 117 } |
116 | 118 |
117 | 119 |
118 Dart_CObject* ApiMessageReader::AllocateDartCObjectString(intptr_t length) { | 120 Dart_CObject* ApiMessageReader::AllocateDartCObjectString(intptr_t length) { |
119 // Allocate a Dart_CObject structure followed by an array of chars | 121 // Allocate a Dart_CObject structure followed by an array of chars |
120 // for the string content. The pointer to the string content is set | 122 // for the string content. The pointer to the string content is set |
121 // up to this area. | 123 // up to this area. |
122 Dart_CObject* value = | 124 Dart_CObject* value = |
123 reinterpret_cast<Dart_CObject*>( | 125 reinterpret_cast<Dart_CObject*>( |
124 alloc_(NULL, 0, sizeof(Dart_CObject) + length + 1)); | 126 allocator(sizeof(Dart_CObject) + length + 1)); |
125 ASSERT(value != NULL); | 127 ASSERT(value != NULL); |
126 value->value.as_string = reinterpret_cast<char*>(value) + sizeof(*value); | 128 value->value.as_string = reinterpret_cast<char*>(value) + sizeof(*value); |
127 value->type = Dart_CObject_kString; | 129 value->type = Dart_CObject_kString; |
128 return value; | 130 return value; |
129 } | 131 } |
130 | 132 |
131 | 133 |
132 static int GetTypedDataSizeInBytes(Dart_TypedData_Type type) { | 134 static int GetTypedDataSizeInBytes(Dart_TypedData_Type type) { |
133 switch (type) { | 135 switch (type) { |
134 case Dart_TypedData_kInt8: | 136 case Dart_TypedData_kInt8: |
(...skipping 20 matching lines...) Expand all Loading... |
155 | 157 |
156 | 158 |
157 Dart_CObject* ApiMessageReader::AllocateDartCObjectTypedData( | 159 Dart_CObject* ApiMessageReader::AllocateDartCObjectTypedData( |
158 Dart_TypedData_Type type, intptr_t length) { | 160 Dart_TypedData_Type type, intptr_t length) { |
159 // Allocate a Dart_CObject structure followed by an array of bytes | 161 // Allocate a Dart_CObject structure followed by an array of bytes |
160 // for the byte array content. The pointer to the byte array content | 162 // for the byte array content. The pointer to the byte array content |
161 // is set up to this area. | 163 // is set up to this area. |
162 intptr_t length_in_bytes = GetTypedDataSizeInBytes(type) * length; | 164 intptr_t length_in_bytes = GetTypedDataSizeInBytes(type) * length; |
163 Dart_CObject* value = | 165 Dart_CObject* value = |
164 reinterpret_cast<Dart_CObject*>( | 166 reinterpret_cast<Dart_CObject*>( |
165 alloc_(NULL, 0, sizeof(Dart_CObject) + length_in_bytes)); | 167 allocator(sizeof(Dart_CObject) + length_in_bytes)); |
166 ASSERT(value != NULL); | 168 ASSERT(value != NULL); |
167 value->type = Dart_CObject_kTypedData; | 169 value->type = Dart_CObject_kTypedData; |
168 value->value.as_typed_data.type = type; | 170 value->value.as_typed_data.type = type; |
169 value->value.as_typed_data.length = length_in_bytes; | 171 value->value.as_typed_data.length = length_in_bytes; |
170 if (length > 0) { | 172 if (length > 0) { |
171 value->value.as_typed_data.values = | 173 value->value.as_typed_data.values = |
172 reinterpret_cast<uint8_t*>(value) + sizeof(*value); | 174 reinterpret_cast<uint8_t*>(value) + sizeof(*value); |
173 } else { | 175 } else { |
174 value->value.as_typed_data.values = NULL; | 176 value->value.as_typed_data.values = NULL; |
175 } | 177 } |
176 return value; | 178 return value; |
177 } | 179 } |
178 | 180 |
179 | 181 |
180 Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) { | 182 Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) { |
181 // Allocate a Dart_CObject structure followed by an array of | 183 // Allocate a Dart_CObject structure followed by an array of |
182 // pointers to Dart_CObject structures. The pointer to the array | 184 // pointers to Dart_CObject structures. The pointer to the array |
183 // content is set up to this area. | 185 // content is set up to this area. |
184 Dart_CObject* value = | 186 Dart_CObject* value = |
185 reinterpret_cast<Dart_CObject*>( | 187 reinterpret_cast<Dart_CObject*>( |
186 alloc_(NULL, 0, sizeof(Dart_CObject) + length * sizeof(value))); | 188 allocator(sizeof(Dart_CObject) + length * sizeof(value))); |
187 ASSERT(value != NULL); | 189 ASSERT(value != NULL); |
188 value->type = Dart_CObject_kArray; | 190 value->type = Dart_CObject_kArray; |
189 value->value.as_array.length = length; | 191 value->value.as_array.length = length; |
190 if (length > 0) { | 192 if (length > 0) { |
191 value->value.as_array.values = reinterpret_cast<Dart_CObject**>(value + 1); | 193 value->value.as_array.values = reinterpret_cast<Dart_CObject**>(value + 1); |
192 } else { | 194 } else { |
193 value->value.as_array.values = NULL; | 195 value->value.as_array.values = NULL; |
194 } | 196 } |
195 return value; | 197 return value; |
196 } | 198 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 UNREACHABLE(); | 234 UNREACHABLE(); |
233 return NULL; | 235 return NULL; |
234 } | 236 } |
235 } | 237 } |
236 | 238 |
237 | 239 |
238 Dart_CObject_Internal* ApiMessageReader::AllocateDartCObjectInternal( | 240 Dart_CObject_Internal* ApiMessageReader::AllocateDartCObjectInternal( |
239 Dart_CObject_Internal::Type type) { | 241 Dart_CObject_Internal::Type type) { |
240 Dart_CObject_Internal* value = | 242 Dart_CObject_Internal* value = |
241 reinterpret_cast<Dart_CObject_Internal*>( | 243 reinterpret_cast<Dart_CObject_Internal*>( |
242 alloc_(NULL, 0, sizeof(Dart_CObject_Internal))); | 244 allocator(sizeof(Dart_CObject_Internal))); |
243 ASSERT(value != NULL); | 245 ASSERT(value != NULL); |
244 value->type = static_cast<Dart_CObject_Type>(type); | 246 value->type = static_cast<Dart_CObject_Type>(type); |
245 return value; | 247 return value; |
246 } | 248 } |
247 | 249 |
248 | 250 |
249 Dart_CObject_Internal* ApiMessageReader::AllocateDartCObjectClass() { | 251 Dart_CObject_Internal* ApiMessageReader::AllocateDartCObjectClass() { |
250 return AllocateDartCObjectInternal(Dart_CObject_Internal::kClass); | 252 return AllocateDartCObjectInternal(Dart_CObject_Internal::kClass); |
251 } | 253 } |
252 | 254 |
253 | 255 |
254 ApiMessageReader::BackRefNode* ApiMessageReader::AllocateBackRefNode( | 256 ApiMessageReader::BackRefNode* ApiMessageReader::AllocateBackRefNode( |
255 Dart_CObject* reference, | 257 Dart_CObject* reference, |
256 DeserializeState state) { | 258 DeserializeState state) { |
257 BackRefNode* value = | 259 BackRefNode* value = |
258 reinterpret_cast<BackRefNode*>(alloc_(NULL, 0, sizeof(BackRefNode))); | 260 reinterpret_cast<BackRefNode*>(allocator(sizeof(BackRefNode))); |
259 value->set_reference(reference); | 261 value->set_reference(reference); |
260 value->set_state(state); | 262 value->set_state(state); |
261 return value; | 263 return value; |
262 } | 264 } |
263 | 265 |
264 | 266 |
265 static Dart_TypedData_Type GetTypedDataTypeFromView( | 267 static Dart_TypedData_Type GetTypedDataTypeFromView( |
266 Dart_CObject_Internal* object, | 268 Dart_CObject_Internal* object, |
267 char* class_name) { | 269 char* class_name) { |
268 struct { | 270 struct { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 Dart_CObject* object; | 400 Dart_CObject* object; |
399 if (vm_symbol_references_ != NULL && | 401 if (vm_symbol_references_ != NULL && |
400 (object = vm_symbol_references_[symbol_id]) != NULL) { | 402 (object = vm_symbol_references_[symbol_id]) != NULL) { |
401 return object; | 403 return object; |
402 } | 404 } |
403 | 405 |
404 if (vm_symbol_references_ == NULL) { | 406 if (vm_symbol_references_ == NULL) { |
405 intptr_t size = | 407 intptr_t size = |
406 (sizeof(*vm_symbol_references_) * Symbols::kMaxPredefinedId); | 408 (sizeof(*vm_symbol_references_) * Symbols::kMaxPredefinedId); |
407 vm_symbol_references_ = | 409 vm_symbol_references_ = |
408 reinterpret_cast<Dart_CObject**>(alloc_(NULL, 0, size)); | 410 reinterpret_cast<Dart_CObject**>(allocator(size)); |
409 memset(vm_symbol_references_, 0, size); | 411 memset(vm_symbol_references_, 0, size); |
410 } | 412 } |
411 | 413 |
412 object = CreateDartCObjectString(Symbols::GetVMSymbol(object_id)); | 414 object = CreateDartCObjectString(Symbols::GetVMSymbol(object_id)); |
413 ASSERT(vm_symbol_references_[symbol_id] == NULL); | 415 ASSERT(vm_symbol_references_[symbol_id] == NULL); |
414 vm_symbol_references_[symbol_id] = object; | 416 vm_symbol_references_[symbol_id] = object; |
415 return object; | 417 return object; |
416 } | 418 } |
417 | 419 |
418 | 420 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 case kDoubleCid: { | 616 case kDoubleCid: { |
615 // Doubles are handled specially when being sent as part of message | 617 // Doubles are handled specially when being sent as part of message |
616 // snapshots. | 618 // snapshots. |
617 UNREACHABLE(); | 619 UNREACHABLE(); |
618 } | 620 } |
619 case kOneByteStringCid: { | 621 case kOneByteStringCid: { |
620 intptr_t len = ReadSmiValue(); | 622 intptr_t len = ReadSmiValue(); |
621 intptr_t hash = ReadSmiValue(); | 623 intptr_t hash = ReadSmiValue(); |
622 USE(hash); | 624 USE(hash); |
623 uint8_t *latin1 = | 625 uint8_t *latin1 = |
624 reinterpret_cast<uint8_t*>(::malloc(len * sizeof(uint8_t))); | 626 reinterpret_cast<uint8_t*>(allocator(len * sizeof(uint8_t))); |
625 intptr_t utf8_len = 0; | 627 intptr_t utf8_len = 0; |
626 for (intptr_t i = 0; i < len; i++) { | 628 for (intptr_t i = 0; i < len; i++) { |
627 latin1[i] = Read<uint8_t>(); | 629 latin1[i] = Read<uint8_t>(); |
628 utf8_len += Utf8::Length(latin1[i]); | 630 utf8_len += Utf8::Length(latin1[i]); |
629 } | 631 } |
630 Dart_CObject* object = AllocateDartCObjectString(utf8_len); | 632 Dart_CObject* object = AllocateDartCObjectString(utf8_len); |
631 AddBackRef(object_id, object, kIsDeserialized); | 633 AddBackRef(object_id, object, kIsDeserialized); |
632 char* p = object->value.as_string; | 634 char* p = object->value.as_string; |
633 for (intptr_t i = 0; i < len; i++) { | 635 for (intptr_t i = 0; i < len; i++) { |
634 p += Utf8::Encode(latin1[i], p); | 636 p += Utf8::Encode(latin1[i], p); |
635 } | 637 } |
636 *p = '\0'; | 638 *p = '\0'; |
637 ASSERT(p == (object->value.as_string + utf8_len)); | 639 ASSERT(p == (object->value.as_string + utf8_len)); |
638 ::free(latin1); | |
639 return object; | 640 return object; |
640 } | 641 } |
641 case kTwoByteStringCid: { | 642 case kTwoByteStringCid: { |
642 intptr_t len = ReadSmiValue(); | 643 intptr_t len = ReadSmiValue(); |
643 intptr_t hash = ReadSmiValue(); | 644 intptr_t hash = ReadSmiValue(); |
644 USE(hash); | 645 USE(hash); |
645 uint16_t *utf16 = | 646 uint16_t *utf16 = reinterpret_cast<uint16_t*>( |
646 reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t))); | 647 allocator(len * sizeof(uint16_t))); |
647 intptr_t utf8_len = 0; | 648 intptr_t utf8_len = 0; |
648 // Read all the UTF-16 code units. | 649 // Read all the UTF-16 code units. |
649 for (intptr_t i = 0; i < len; i++) { | 650 for (intptr_t i = 0; i < len; i++) { |
650 utf16[i] = Read<uint16_t>(); | 651 utf16[i] = Read<uint16_t>(); |
651 } | 652 } |
652 // Calculate the UTF-8 length and check if the string can be | 653 // Calculate the UTF-8 length and check if the string can be |
653 // UTF-8 encoded. | 654 // UTF-8 encoded. |
654 bool valid = true; | 655 bool valid = true; |
655 intptr_t i = 0; | 656 intptr_t i = 0; |
656 while (i < len && valid) { | 657 while (i < len && valid) { |
657 int32_t ch = Utf16::Next(utf16, &i, len); | 658 int32_t ch = Utf16::Next(utf16, &i, len); |
658 utf8_len += Utf8::Length(ch); | 659 utf8_len += Utf8::Length(ch); |
659 valid = !Utf16::IsSurrogate(ch); | 660 valid = !Utf16::IsSurrogate(ch); |
660 } | 661 } |
661 if (!valid) { | 662 if (!valid) { |
662 return AllocateDartCObjectUnsupported(); | 663 return AllocateDartCObjectUnsupported(); |
663 } | 664 } |
664 Dart_CObject* object = AllocateDartCObjectString(utf8_len); | 665 Dart_CObject* object = AllocateDartCObjectString(utf8_len); |
665 AddBackRef(object_id, object, kIsDeserialized); | 666 AddBackRef(object_id, object, kIsDeserialized); |
666 char* p = object->value.as_string; | 667 char* p = object->value.as_string; |
667 i = 0; | 668 i = 0; |
668 while (i < len) { | 669 while (i < len) { |
669 p += Utf8::Encode(Utf16::Next(utf16, &i, len), p); | 670 p += Utf8::Encode(Utf16::Next(utf16, &i, len), p); |
670 } | 671 } |
671 *p = '\0'; | 672 *p = '\0'; |
672 ASSERT(p == (object->value.as_string + utf8_len)); | 673 ASSERT(p == (object->value.as_string + utf8_len)); |
673 ::free(utf16); | |
674 return object; | 674 return object; |
675 } | 675 } |
676 case kSendPortCid: { | 676 case kSendPortCid: { |
677 int64_t value64 = Read<int64_t>(); | 677 int64_t value64 = Read<int64_t>(); |
678 int64_t originId = Read<uint64_t>(); | 678 int64_t originId = Read<uint64_t>(); |
679 Dart_CObject* object = AllocateDartCObject(Dart_CObject_kSendPort); | 679 Dart_CObject* object = AllocateDartCObject(Dart_CObject_kSendPort); |
680 object->value.as_send_port.id = value64; | 680 object->value.as_send_port.id = value64; |
681 object->value.as_send_port.origin_id = originId; | 681 object->value.as_send_port.origin_id = originId; |
682 AddBackRef(object_id, object, kIsDeserialized); | 682 AddBackRef(object_id, object, kIsDeserialized); |
683 return object; | 683 return object; |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 if (!success) { | 1316 if (!success) { |
1317 UnmarkAllCObjects(object); | 1317 UnmarkAllCObjects(object); |
1318 return false; | 1318 return false; |
1319 } | 1319 } |
1320 } | 1320 } |
1321 UnmarkAllCObjects(object); | 1321 UnmarkAllCObjects(object); |
1322 return true; | 1322 return true; |
1323 } | 1323 } |
1324 | 1324 |
1325 } // namespace dart | 1325 } // namespace dart |
OLD | NEW |