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