Index: runtime/vm/dart_api_message.cc |
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc |
index 9f3bcec9b43e7952cfabb9e12af360cfe4dc2d1e..8ea8b416870c019df1b5486a93abe83cae3c7ff7 100644 |
--- a/runtime/vm/dart_api_message.cc |
+++ b/runtime/vm/dart_api_message.cc |
@@ -328,4 +328,216 @@ void ApiMessageReader::AddBackwardReference(intptr_t id, Dart_CObject* obj) { |
backward_references_.Add(obj); |
} |
+void ApiMessageWriter::WriteMessage(intptr_t field_count, intptr_t *data) { |
+ // Write out the serialization header value for this object. |
+ WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds); |
+ |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kArrayClass, 0); |
+ |
+ // Write out the length field. |
+ Write<RawObject*>(Smi::New(field_count)); |
+ |
+ // Write out the type arguments. |
+ WriteIndexedObject(Object::kNullObject); |
+ |
+ // Write out the individual Smis. |
+ for (int i = 0; i < field_count; i++) { |
+ Write<RawObject*>(Integer::New(data[i])); |
+ } |
+ |
+ FinalizeBuffer(); |
+} |
+ |
+ |
+void ApiMessageWriter::MarkCObject(Dart_CObject* object, intptr_t object_id) { |
+ // Mark the object as serialized by adding the object id to the |
+ // upper bits of the type field in the Dart_CObject structure. Add |
+ // an offset for making marking of object id 0 possible. |
+ ASSERT(!IsCObjectMarked(object)); |
+ intptr_t mark_value = object_id + kDartCObjectMarkOffset; |
+ object->type = static_cast<Dart_CObject::Type>( |
+ ((mark_value) << kDartCObjectTypeBits) | object->type); |
+} |
+ |
+ |
+void ApiMessageWriter::UnmarkCObject(Dart_CObject* object) { |
+ ASSERT(IsCObjectMarked(object)); |
+ object->type = static_cast<Dart_CObject::Type>( |
+ object->type & kDartCObjectTypeMask); |
+} |
+ |
+ |
+bool ApiMessageWriter::IsCObjectMarked(Dart_CObject* object) { |
+ return (object->type & kDartCObjectMarkMask) != 0; |
+} |
+ |
+ |
+intptr_t ApiMessageWriter::GetMarkedCObjectMark(Dart_CObject* object) { |
+ ASSERT(IsCObjectMarked(object)); |
+ intptr_t mark_value = ((object->type & kDartCObjectMarkMask) >> 3); |
+ // An offset was added to object id for making marking object id 0 possible. |
+ return mark_value - kDartCObjectMarkOffset; |
+} |
+ |
+ |
+void ApiMessageWriter::UnmarkAllCObjects(Dart_CObject* object) { |
+ if (!IsCObjectMarked(object)) return; |
+ UnmarkCObject(object); |
+ if (object->type == Dart_CObject::kArray) { |
+ for (int i = 0; i < object->value.as_array.length; i++) { |
+ Dart_CObject* element = object->value.as_array.values[i]; |
+ UnmarkAllCObjects(element); |
+ } |
+ } |
+} |
+ |
+ |
+void ApiMessageWriter::WriteSmi(int64_t value) { |
+ ASSERT(Smi::IsValid64(value)); |
+ Write<RawObject*>(Smi::New(value)); |
+} |
+ |
+ |
+void ApiMessageWriter::WriteMint(Dart_CObject* object, int64_t value) { |
+ ASSERT(!Smi::IsValid64(value)); |
+ // Write out the serialization header value for mint object. |
+ WriteInlinedHeader(object); |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kMintClass, 0); |
+ // Write the 64-bit value. |
+ Write<int64_t>(value); |
+} |
+ |
+ |
+void ApiMessageWriter::WriteInt32(Dart_CObject* object) { |
+ int64_t value = object->value.as_int32; |
+ if (Smi::IsValid64(value)) { |
+ WriteSmi(value); |
+ } else { |
+ WriteMint(object, value); |
+ } |
+} |
+ |
+ |
+void ApiMessageWriter::WriteInt64(Dart_CObject* object) { |
+ int64_t value = object->value.as_int64; |
+ if (Smi::IsValid64(value)) { |
+ WriteSmi(value); |
+ } else { |
+ WriteMint(object, value); |
+ } |
+} |
+ |
+ |
+void ApiMessageWriter::WriteInlinedHeader(Dart_CObject* object) { |
+ // Write out the serialization header value for this object. |
+ WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds + object_id_); |
+ // Mark object with its object id. |
+ MarkCObject(object, object_id_); |
+ // Advance object id. |
+ object_id_++; |
+} |
+ |
+ |
+void ApiMessageWriter::WriteCObject(Dart_CObject* object) { |
+ if (IsCObjectMarked(object)) { |
+ intptr_t object_id = GetMarkedCObjectMark(object); |
+ WriteIndexedObject(kMaxPredefinedObjectIds + object_id); |
+ return; |
+ } |
+ |
+ switch (object->type) { |
+ case Dart_CObject::kNull: |
+ WriteIndexedObject(Object::kNullObject); |
+ break; |
+ case Dart_CObject::kBool: |
+ if (object->value.as_bool) { |
+ WriteIndexedObject(ObjectStore::kTrueValue); |
+ } else { |
+ WriteIndexedObject(ObjectStore::kFalseValue); |
+ } |
+ break; |
+ case Dart_CObject::kInt32: |
+ WriteInt32(object); |
+ break; |
+ case Dart_CObject::kInt64: |
+ WriteInt64(object); |
+ break; |
+ case Dart_CObject::kBigint: { |
+ // Write out the serialization header value for this object. |
+ WriteInlinedHeader(object); |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kBigintClass, 0); |
+ // Write hex string length and content |
+ char* hex_string = object->value.as_bigint; |
+ intptr_t len = strlen(hex_string); |
+ WriteIntptrValue(len); |
+ for (intptr_t i = 0; i < len; i++) { |
+ Write<uint8_t>(hex_string[i]); |
+ } |
+ break; |
+ } |
+ case Dart_CObject::kDouble: |
+ // Write out the serialization header value for this object. |
+ WriteInlinedHeader(object); |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kDoubleClass, 0); |
+ // Write double value. |
+ Write<double>(object->value.as_double); |
+ break; |
+ case Dart_CObject::kString: { |
+ // Write out the serialization header value for this object. |
+ WriteInlinedHeader(object); |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kOneByteStringClass, 0); |
+ // Write string length, hash and content |
+ char* str = object->value.as_string; |
+ intptr_t len = strlen(str); |
+ WriteSmi(len); |
+ WriteSmi(0); // TODO(sgjesse): Hash - not written. |
+ for (intptr_t i = 0; i < len; i++) { |
+ Write<uint8_t>(str[i]); |
+ } |
+ break; |
+ } |
+ case Dart_CObject::kArray: { |
+ // Write out the serialization header value for this object. |
+ WriteInlinedHeader(object); |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kArrayClass, 0); |
+ WriteSmi(object->value.as_array.length); |
+ // Write out the type arguments. |
+ WriteIndexedObject(Object::kNullObject); |
+ // Write out array elements. |
+ for (int i = 0; i < object->value.as_array.length; i++) { |
+ WriteCObject(object->value.as_array.values[i]); |
+ } |
+ break; |
+ } |
+ case Dart_CObject::kByteArray: { |
+ // Write out the serialization header value for this object. |
+ WriteInlinedHeader(object); |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kInternalByteArrayClass, 0); |
+ uint8_t* bytes = object->value.as_byte_array.values; |
+ intptr_t len = object->value.as_byte_array.length; |
+ WriteSmi(len); |
+ for (intptr_t i = 0; i < len; i++) { |
+ Write<uint8_t>(bytes[i]); |
+ } |
+ break; |
+ } |
+ default: |
+ UNREACHABLE(); |
+ } |
+} |
+ |
+ |
+void ApiMessageWriter::WriteCMessage(Dart_CObject* object) { |
+ WriteCObject(object); |
+ UnmarkAllCObjects(object); |
+ FinalizeBuffer(); |
+} |
+ |
} // namespace dart |