OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 #include "vm/dart_api_message.h" |
| 6 #include "vm/object.h" |
| 7 #include "vm/object_store.h" |
| 8 |
| 9 namespace dart { |
| 10 |
| 11 // TODO(sgjesse): When the external message format is done these |
| 12 // duplicate constants from snapshot.cc should be removed. |
| 13 enum { |
| 14 kInstanceId = ObjectStore::kMaxId, |
| 15 kMaxPredefinedObjectIds, |
| 16 }; |
| 17 static const int kNumInitialReferences = 4; |
| 18 |
| 19 ApiMessageReader::ApiMessageReader(const uint8_t* buffer, |
| 20 intptr_t length, |
| 21 ReAlloc alloc) |
| 22 : BaseReader(buffer, length), |
| 23 alloc_(alloc), |
| 24 backward_references_(kNumInitialReferences) { |
| 25 Init(); |
| 26 } |
| 27 |
| 28 |
| 29 void ApiMessageReader::Init() { |
| 30 // Initialize marker objects used to handle Lists. |
| 31 // TODO(sjesse): Remove this when message serialization format is |
| 32 // updated. |
| 33 memset(&type_arguments_marker, 0, sizeof(type_arguments_marker)); |
| 34 memset(&dynamic_type_marker, 0, sizeof(dynamic_type_marker)); |
| 35 type_arguments_marker.type = |
| 36 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kTypeArguments); |
| 37 dynamic_type_marker.type = |
| 38 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kDynamicType); |
| 39 } |
| 40 |
| 41 |
| 42 Dart_CObject* ApiMessageReader::ReadMessage() { |
| 43 // Read the object out of the message. |
| 44 return ReadObject(); |
| 45 } |
| 46 |
| 47 |
| 48 intptr_t ApiMessageReader::LookupInternalClass(intptr_t class_header) { |
| 49 SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); |
| 50 ASSERT(header_type == kObjectId); |
| 51 intptr_t header_value = SerializedHeaderData::decode(class_header); |
| 52 return header_value; |
| 53 } |
| 54 |
| 55 |
| 56 Dart_CObject* ApiMessageReader::AllocateDartCObject(Dart_CObject::Type type) { |
| 57 Dart_CObject* value = |
| 58 reinterpret_cast<Dart_CObject*>(alloc_(NULL, 0, sizeof(Dart_CObject))); |
| 59 value->type = type; |
| 60 return value; |
| 61 } |
| 62 |
| 63 |
| 64 Dart_CObject* ApiMessageReader::AllocateDartCObjectNull() { |
| 65 return AllocateDartCObject(Dart_CObject::kNull); |
| 66 } |
| 67 |
| 68 |
| 69 Dart_CObject* ApiMessageReader::AllocateDartCObjectBool(bool val) { |
| 70 Dart_CObject* value = AllocateDartCObject(Dart_CObject::kBool); |
| 71 value->value.as_bool = val; |
| 72 return value; |
| 73 } |
| 74 |
| 75 |
| 76 Dart_CObject* ApiMessageReader::AllocateDartCObjectInt32(int32_t val) { |
| 77 Dart_CObject* value = AllocateDartCObject(Dart_CObject::kInt32); |
| 78 value->value.as_int32 = val; |
| 79 return value; |
| 80 } |
| 81 |
| 82 |
| 83 Dart_CObject* ApiMessageReader::AllocateDartCObjectDouble(double val) { |
| 84 Dart_CObject* value = AllocateDartCObject(Dart_CObject::kDouble); |
| 85 value->value.as_double = val; |
| 86 return value; |
| 87 } |
| 88 |
| 89 |
| 90 Dart_CObject* ApiMessageReader::AllocateDartCObjectString(intptr_t length) { |
| 91 // Allocate a Dart_CObject structure followed by an array of chars |
| 92 // for the string content. The pointer to the string content is set |
| 93 // up to this area. |
| 94 Dart_CObject* value = |
| 95 reinterpret_cast<Dart_CObject*>( |
| 96 alloc_(NULL, 0, sizeof(Dart_CObject) + length + 1)); |
| 97 value->value.as_string = reinterpret_cast<char*>(value) + sizeof(*value); |
| 98 value->type = Dart_CObject::kString; |
| 99 return value; |
| 100 } |
| 101 |
| 102 |
| 103 Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) { |
| 104 // Allocate a Dart_CObject structure followed by an array of |
| 105 // pointers to Dart_CObject structures. The pointer to the array |
| 106 // content is set up to this area. |
| 107 Dart_CObject* value = |
| 108 reinterpret_cast<Dart_CObject*>( |
| 109 alloc_(NULL, 0, sizeof(Dart_CObject) + length * sizeof(value))); |
| 110 value->type = Dart_CObject::kArray; |
| 111 value->value.as_array.length = length; |
| 112 if (length > 0) { |
| 113 value->value.as_array.values = reinterpret_cast<Dart_CObject**>(value + 1); |
| 114 } else { |
| 115 value->value.as_array.values = NULL; |
| 116 } |
| 117 return value; |
| 118 } |
| 119 |
| 120 |
| 121 Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) { |
| 122 // Read the class header information and lookup the class. |
| 123 intptr_t class_header = ReadIntptrValue(); |
| 124 intptr_t tags = ReadIntptrValue(); |
| 125 USE(tags); |
| 126 intptr_t class_id; |
| 127 |
| 128 // Reading of regular dart instances is not supported. |
| 129 if (SerializedHeaderData::decode(class_header) == kInstanceId) { |
| 130 return NULL; |
| 131 } |
| 132 |
| 133 ASSERT((class_header & kSmiTagMask) != 0); |
| 134 class_id = LookupInternalClass(class_header); |
| 135 switch (class_id) { |
| 136 case Object::kClassClass: { |
| 137 return NULL; |
| 138 } |
| 139 case Object::kTypeArgumentsClass: { |
| 140 // TODO(sjesse): Remove this when message serialization format is |
| 141 // updated (currently length is leaked). |
| 142 AddBackwardReference(object_id, NULL); |
| 143 Dart_CObject* length = ReadObject(); |
| 144 ASSERT(length->type == Dart_CObject::kInt32); |
| 145 for (int i = 0; i < length->value.as_int32; i++) { |
| 146 Dart_CObject* type = ReadObject(); |
| 147 if (type != &dynamic_type_marker) return NULL; |
| 148 } |
| 149 return &type_arguments_marker; |
| 150 break; |
| 151 } |
| 152 case ObjectStore::kArrayClass: { |
| 153 intptr_t len = ReadSmiValue(); |
| 154 Dart_CObject* value = AllocateDartCObjectArray(len); |
| 155 AddBackwardReference(object_id, value); |
| 156 // Skip type arguments. |
| 157 // TODO(sjesse): Remove this when message serialization format is |
| 158 // updated (currently type_arguments is leaked). |
| 159 Dart_CObject* type_arguments = ReadObject(); |
| 160 if (type_arguments != &type_arguments_marker && |
| 161 type_arguments->type != Dart_CObject::kNull) { |
| 162 return NULL; |
| 163 } |
| 164 for (int i = 0; i < len; i++) { |
| 165 value->value.as_array.values[i] = ReadObject(); |
| 166 } |
| 167 return value; |
| 168 break; |
| 169 } |
| 170 case ObjectStore::kDoubleClass: { |
| 171 // Read the double value for the object. |
| 172 Dart_CObject* object = AllocateDartCObjectDouble(Read<double>()); |
| 173 AddBackwardReference(object_id, object); |
| 174 return object; |
| 175 break; |
| 176 } |
| 177 case ObjectStore::kOneByteStringClass: { |
| 178 intptr_t len = ReadSmiValue(); |
| 179 intptr_t hash = ReadSmiValue(); |
| 180 USE(hash); |
| 181 Dart_CObject* object = AllocateDartCObjectString(len); |
| 182 AddBackwardReference(object_id, object); |
| 183 char* p = object->value.as_string; |
| 184 for (intptr_t i = 0; i < len; i++) { |
| 185 *p = Read<uint8_t>(); |
| 186 p++; |
| 187 } |
| 188 *p = '\0'; |
| 189 return object; |
| 190 break; |
| 191 } |
| 192 case ObjectStore::kTwoByteStringClass: |
| 193 // Two byte strings not supported. |
| 194 return NULL; |
| 195 break; |
| 196 case ObjectStore::kFourByteStringClass: |
| 197 // Four byte strings not supported. |
| 198 return NULL; |
| 199 break; |
| 200 default: |
| 201 // Everything else not supported. |
| 202 return NULL; |
| 203 } |
| 204 } |
| 205 |
| 206 |
| 207 Dart_CObject* ApiMessageReader::ReadIndexedObject(intptr_t object_id) { |
| 208 if (object_id == Object::kNullObject) { |
| 209 return AllocateDartCObjectNull(); |
| 210 } else if (object_id == ObjectStore::kTrueValue) { |
| 211 return AllocateDartCObjectBool(true); |
| 212 } else if (object_id == ObjectStore::kFalseValue) { |
| 213 return AllocateDartCObjectBool(false); |
| 214 } else if (object_id == ObjectStore::kDynamicType || |
| 215 object_id == ObjectStore::kDoubleInterface || |
| 216 object_id == ObjectStore::kIntInterface || |
| 217 object_id == ObjectStore::kBoolInterface || |
| 218 object_id == ObjectStore::kStringInterface) { |
| 219 // Always return dynamic type (this is only a marker). |
| 220 return &dynamic_type_marker; |
| 221 } else { |
| 222 intptr_t index = object_id - kMaxPredefinedObjectIds; |
| 223 ASSERT(index < backward_references_.length()); |
| 224 ASSERT(backward_references_[index] != NULL); |
| 225 return backward_references_[index]; |
| 226 } |
| 227 return NULL; |
| 228 } |
| 229 |
| 230 |
| 231 Dart_CObject* ApiMessageReader::ReadObjectImpl(intptr_t header) { |
| 232 SerializedHeaderType header_type = SerializedHeaderTag::decode(header); |
| 233 intptr_t header_value = SerializedHeaderData::decode(header); |
| 234 |
| 235 if (header_type == kObjectId) { |
| 236 return ReadIndexedObject(header_value); |
| 237 } |
| 238 ASSERT(header_type == kInlined); |
| 239 return ReadInlinedObject(header_value); |
| 240 } |
| 241 |
| 242 |
| 243 Dart_CObject* ApiMessageReader::ReadObject() { |
| 244 int64_t value = Read<int64_t>(); |
| 245 if ((value & kSmiTagMask) == 0) { |
| 246 Dart_CObject* dart_value = AllocateDartCObjectInt32(value >> kSmiTagShift); |
| 247 return dart_value; |
| 248 } |
| 249 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); |
| 250 return ReadObjectImpl(value); |
| 251 } |
| 252 |
| 253 |
| 254 void ApiMessageReader::AddBackwardReference(intptr_t id, Dart_CObject* obj) { |
| 255 ASSERT((id - kMaxPredefinedObjectIds) == backward_references_.length()); |
| 256 backward_references_.Add(obj); |
| 257 } |
| 258 |
| 259 } // namespace dart |
OLD | NEW |