Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(660)

Unified Diff: runtime/vm/dart_api_message.cc

Issue 9325022: Decode the Dart message into a Dart_CMessage structure before calling the native port callback (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments from asiva@ Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/dart_api_message.h ('k') | runtime/vm/dart_api_state.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/dart_api_message.cc
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cef65c67e1b7dcba785bc5d613ed87adaa6799f4
--- /dev/null
+++ b/runtime/vm/dart_api_message.cc
@@ -0,0 +1,259 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/dart_api_message.h"
+#include "vm/object.h"
+#include "vm/object_store.h"
+
+namespace dart {
+
+// TODO(sgjesse): When the external message format is done these
+// duplicate constants from snapshot.cc should be removed.
+enum {
+ kInstanceId = ObjectStore::kMaxId,
+ kMaxPredefinedObjectIds,
+};
+static const int kNumInitialReferences = 4;
+
+ApiMessageReader::ApiMessageReader(const uint8_t* buffer,
+ intptr_t length,
+ ReAlloc alloc)
+ : BaseReader(buffer, length),
+ alloc_(alloc),
+ backward_references_(kNumInitialReferences) {
+ Init();
+}
+
+
+void ApiMessageReader::Init() {
+ // Initialize marker objects used to handle Lists.
+ // TODO(sjesse): Remove this when message serialization format is
+ // updated.
+ memset(&type_arguments_marker, 0, sizeof(type_arguments_marker));
+ memset(&dynamic_type_marker, 0, sizeof(dynamic_type_marker));
+ type_arguments_marker.type =
+ static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kTypeArguments);
+ dynamic_type_marker.type =
+ static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kDynamicType);
+}
+
+
+Dart_CObject* ApiMessageReader::ReadMessage() {
+ // Read the object out of the message.
+ return ReadObject();
+}
+
+
+intptr_t ApiMessageReader::LookupInternalClass(intptr_t class_header) {
+ SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header);
+ ASSERT(header_type == kObjectId);
+ intptr_t header_value = SerializedHeaderData::decode(class_header);
+ return header_value;
+}
+
+
+Dart_CObject* ApiMessageReader::AllocateDartCObject(Dart_CObject::Type type) {
+ Dart_CObject* value =
+ reinterpret_cast<Dart_CObject*>(alloc_(NULL, 0, sizeof(Dart_CObject)));
+ value->type = type;
+ return value;
+}
+
+
+Dart_CObject* ApiMessageReader::AllocateDartCObjectNull() {
+ return AllocateDartCObject(Dart_CObject::kNull);
+}
+
+
+Dart_CObject* ApiMessageReader::AllocateDartCObjectBool(bool val) {
+ Dart_CObject* value = AllocateDartCObject(Dart_CObject::kBool);
+ value->value.as_bool = val;
+ return value;
+}
+
+
+Dart_CObject* ApiMessageReader::AllocateDartCObjectInt32(int32_t val) {
+ Dart_CObject* value = AllocateDartCObject(Dart_CObject::kInt32);
+ value->value.as_int32 = val;
+ return value;
+}
+
+
+Dart_CObject* ApiMessageReader::AllocateDartCObjectDouble(double val) {
+ Dart_CObject* value = AllocateDartCObject(Dart_CObject::kDouble);
+ value->value.as_double = val;
+ return value;
+}
+
+
+Dart_CObject* ApiMessageReader::AllocateDartCObjectString(intptr_t length) {
+ // Allocate a Dart_CObject structure followed by an array of chars
+ // for the string content. The pointer to the string content is set
+ // up to this area.
+ Dart_CObject* value =
+ reinterpret_cast<Dart_CObject*>(
+ alloc_(NULL, 0, sizeof(Dart_CObject) + length + 1));
+ value->value.as_string = reinterpret_cast<char*>(value) + sizeof(*value);
+ value->type = Dart_CObject::kString;
+ return value;
+}
+
+
+Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) {
+ // Allocate a Dart_CObject structure followed by an array of
+ // pointers to Dart_CObject structures. The pointer to the array
+ // content is set up to this area.
+ Dart_CObject* value =
+ reinterpret_cast<Dart_CObject*>(
+ alloc_(NULL, 0, sizeof(Dart_CObject) + length * sizeof(value)));
+ value->type = Dart_CObject::kArray;
+ value->value.as_array.length = length;
+ if (length > 0) {
+ value->value.as_array.values = reinterpret_cast<Dart_CObject**>(value + 1);
+ } else {
+ value->value.as_array.values = NULL;
+ }
+ return value;
+}
+
+
+Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) {
+ // Read the class header information and lookup the class.
+ intptr_t class_header = ReadIntptrValue();
+ intptr_t tags = ReadIntptrValue();
+ USE(tags);
+ intptr_t class_id;
+
+ // Reading of regular dart instances is not supported.
+ if (SerializedHeaderData::decode(class_header) == kInstanceId) {
+ return NULL;
+ }
+
+ ASSERT((class_header & kSmiTagMask) != 0);
+ class_id = LookupInternalClass(class_header);
+ switch (class_id) {
+ case Object::kClassClass: {
+ return NULL;
+ }
+ case Object::kTypeArgumentsClass: {
+ // TODO(sjesse): Remove this when message serialization format is
+ // updated (currently length is leaked).
+ AddBackwardReference(object_id, NULL);
+ Dart_CObject* length = ReadObject();
+ ASSERT(length->type == Dart_CObject::kInt32);
+ for (int i = 0; i < length->value.as_int32; i++) {
+ Dart_CObject* type = ReadObject();
+ if (type != &dynamic_type_marker) return NULL;
+ }
+ return &type_arguments_marker;
+ break;
+ }
+ case ObjectStore::kArrayClass: {
+ intptr_t len = ReadSmiValue();
+ Dart_CObject* value = AllocateDartCObjectArray(len);
+ AddBackwardReference(object_id, value);
+ // Skip type arguments.
+ // TODO(sjesse): Remove this when message serialization format is
+ // updated (currently type_arguments is leaked).
+ Dart_CObject* type_arguments = ReadObject();
+ if (type_arguments != &type_arguments_marker &&
+ type_arguments->type != Dart_CObject::kNull) {
+ return NULL;
+ }
+ for (int i = 0; i < len; i++) {
+ value->value.as_array.values[i] = ReadObject();
+ }
+ return value;
+ break;
+ }
+ case ObjectStore::kDoubleClass: {
+ // Read the double value for the object.
+ Dart_CObject* object = AllocateDartCObjectDouble(Read<double>());
+ AddBackwardReference(object_id, object);
+ return object;
+ break;
+ }
+ case ObjectStore::kOneByteStringClass: {
+ intptr_t len = ReadSmiValue();
+ intptr_t hash = ReadSmiValue();
+ USE(hash);
+ Dart_CObject* object = AllocateDartCObjectString(len);
+ AddBackwardReference(object_id, object);
+ char* p = object->value.as_string;
+ for (intptr_t i = 0; i < len; i++) {
+ *p = Read<uint8_t>();
+ p++;
+ }
+ *p = '\0';
+ return object;
+ break;
+ }
+ case ObjectStore::kTwoByteStringClass:
+ // Two byte strings not supported.
+ return NULL;
+ break;
+ case ObjectStore::kFourByteStringClass:
+ // Four byte strings not supported.
+ return NULL;
+ break;
+ default:
+ // Everything else not supported.
+ return NULL;
+ }
+}
+
+
+Dart_CObject* ApiMessageReader::ReadIndexedObject(intptr_t object_id) {
+ if (object_id == Object::kNullObject) {
+ return AllocateDartCObjectNull();
+ } else if (object_id == ObjectStore::kTrueValue) {
+ return AllocateDartCObjectBool(true);
+ } else if (object_id == ObjectStore::kFalseValue) {
+ return AllocateDartCObjectBool(false);
+ } else if (object_id == ObjectStore::kDynamicType ||
+ object_id == ObjectStore::kDoubleInterface ||
+ object_id == ObjectStore::kIntInterface ||
+ object_id == ObjectStore::kBoolInterface ||
+ object_id == ObjectStore::kStringInterface) {
+ // Always return dynamic type (this is only a marker).
+ return &dynamic_type_marker;
+ } else {
+ intptr_t index = object_id - kMaxPredefinedObjectIds;
+ ASSERT(index < backward_references_.length());
+ ASSERT(backward_references_[index] != NULL);
+ return backward_references_[index];
+ }
+ return NULL;
+}
+
+
+Dart_CObject* ApiMessageReader::ReadObjectImpl(intptr_t header) {
+ SerializedHeaderType header_type = SerializedHeaderTag::decode(header);
+ intptr_t header_value = SerializedHeaderData::decode(header);
+
+ if (header_type == kObjectId) {
+ return ReadIndexedObject(header_value);
+ }
+ ASSERT(header_type == kInlined);
+ return ReadInlinedObject(header_value);
+}
+
+
+Dart_CObject* ApiMessageReader::ReadObject() {
+ int64_t value = Read<int64_t>();
+ if ((value & kSmiTagMask) == 0) {
+ Dart_CObject* dart_value = AllocateDartCObjectInt32(value >> kSmiTagShift);
+ return dart_value;
+ }
+ ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
+ return ReadObjectImpl(value);
+}
+
+
+void ApiMessageReader::AddBackwardReference(intptr_t id, Dart_CObject* obj) {
+ ASSERT((id - kMaxPredefinedObjectIds) == backward_references_.length());
+ backward_references_.Add(obj);
+}
+
+} // namespace dart
« no previous file with comments | « runtime/vm/dart_api_message.h ('k') | runtime/vm/dart_api_state.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698