| 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 |