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/object_store.h" | 7 #include "vm/object_store.h" |
8 | 8 |
9 namespace dart { | 9 namespace dart { |
10 | 10 |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | 321 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); |
322 return ReadObjectImpl(value); | 322 return ReadObjectImpl(value); |
323 } | 323 } |
324 | 324 |
325 | 325 |
326 void ApiMessageReader::AddBackwardReference(intptr_t id, Dart_CObject* obj) { | 326 void ApiMessageReader::AddBackwardReference(intptr_t id, Dart_CObject* obj) { |
327 ASSERT((id - kMaxPredefinedObjectIds) == backward_references_.length()); | 327 ASSERT((id - kMaxPredefinedObjectIds) == backward_references_.length()); |
328 backward_references_.Add(obj); | 328 backward_references_.Add(obj); |
329 } | 329 } |
330 | 330 |
| 331 void ApiMessageWriter::WriteMessage(intptr_t field_count, intptr_t *data) { |
| 332 // Write out the serialization header value for this object. |
| 333 WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds); |
| 334 |
| 335 // Write out the class and tags information. |
| 336 WriteObjectHeader(ObjectStore::kArrayClass, 0); |
| 337 |
| 338 // Write out the length field. |
| 339 Write<RawObject*>(Smi::New(field_count)); |
| 340 |
| 341 // Write out the type arguments. |
| 342 WriteIndexedObject(Object::kNullObject); |
| 343 |
| 344 // Write out the individual Smis. |
| 345 for (int i = 0; i < field_count; i++) { |
| 346 Write<RawObject*>(Integer::New(data[i])); |
| 347 } |
| 348 |
| 349 FinalizeBuffer(); |
| 350 } |
| 351 |
| 352 |
| 353 void ApiMessageWriter::MarkCObject(Dart_CObject* object, intptr_t object_id) { |
| 354 // Mark the object as serialized by adding the object id to the |
| 355 // upper bits of the type field in the Dart_CObject structure. Add |
| 356 // an offset for making marking of object id 0 possible. |
| 357 ASSERT(!IsCObjectMarked(object)); |
| 358 intptr_t mark_value = object_id + kDartCObjectMarkOffset; |
| 359 object->type = static_cast<Dart_CObject::Type>( |
| 360 ((mark_value) << kDartCObjectTypeBits) | object->type); |
| 361 } |
| 362 |
| 363 |
| 364 void ApiMessageWriter::UnmarkCObject(Dart_CObject* object) { |
| 365 ASSERT(IsCObjectMarked(object)); |
| 366 object->type = static_cast<Dart_CObject::Type>( |
| 367 object->type & kDartCObjectTypeMask); |
| 368 } |
| 369 |
| 370 |
| 371 bool ApiMessageWriter::IsCObjectMarked(Dart_CObject* object) { |
| 372 return (object->type & kDartCObjectMarkMask) != 0; |
| 373 } |
| 374 |
| 375 |
| 376 intptr_t ApiMessageWriter::GetMarkedCObjectMark(Dart_CObject* object) { |
| 377 ASSERT(IsCObjectMarked(object)); |
| 378 intptr_t mark_value = ((object->type & kDartCObjectMarkMask) >> 3); |
| 379 // An offset was added to object id for making marking object id 0 possible. |
| 380 return mark_value - kDartCObjectMarkOffset; |
| 381 } |
| 382 |
| 383 |
| 384 void ApiMessageWriter::UnmarkAllCObjects(Dart_CObject* object) { |
| 385 if (!IsCObjectMarked(object)) return; |
| 386 UnmarkCObject(object); |
| 387 if (object->type == Dart_CObject::kArray) { |
| 388 for (int i = 0; i < object->value.as_array.length; i++) { |
| 389 Dart_CObject* element = object->value.as_array.values[i]; |
| 390 UnmarkAllCObjects(element); |
| 391 } |
| 392 } |
| 393 } |
| 394 |
| 395 |
| 396 void ApiMessageWriter::WriteSmi(int64_t value) { |
| 397 ASSERT(Smi::IsValid64(value)); |
| 398 Write<RawObject*>(Smi::New(value)); |
| 399 } |
| 400 |
| 401 |
| 402 void ApiMessageWriter::WriteMint(Dart_CObject* object, int64_t value) { |
| 403 ASSERT(!Smi::IsValid64(value)); |
| 404 // Write out the serialization header value for mint object. |
| 405 WriteInlinedHeader(object); |
| 406 // Write out the class and tags information. |
| 407 WriteObjectHeader(ObjectStore::kMintClass, 0); |
| 408 // Write the 64-bit value. |
| 409 Write<int64_t>(value); |
| 410 } |
| 411 |
| 412 |
| 413 void ApiMessageWriter::WriteInt32(Dart_CObject* object) { |
| 414 int64_t value = object->value.as_int32; |
| 415 if (Smi::IsValid64(value)) { |
| 416 WriteSmi(value); |
| 417 } else { |
| 418 WriteMint(object, value); |
| 419 } |
| 420 } |
| 421 |
| 422 |
| 423 void ApiMessageWriter::WriteInt64(Dart_CObject* object) { |
| 424 int64_t value = object->value.as_int64; |
| 425 if (Smi::IsValid64(value)) { |
| 426 WriteSmi(value); |
| 427 } else { |
| 428 WriteMint(object, value); |
| 429 } |
| 430 } |
| 431 |
| 432 |
| 433 void ApiMessageWriter::WriteInlinedHeader(Dart_CObject* object) { |
| 434 // Write out the serialization header value for this object. |
| 435 WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds + object_id_); |
| 436 // Mark object with its object id. |
| 437 MarkCObject(object, object_id_); |
| 438 // Advance object id. |
| 439 object_id_++; |
| 440 } |
| 441 |
| 442 |
| 443 void ApiMessageWriter::WriteCObject(Dart_CObject* object) { |
| 444 if (IsCObjectMarked(object)) { |
| 445 intptr_t object_id = GetMarkedCObjectMark(object); |
| 446 WriteIndexedObject(kMaxPredefinedObjectIds + object_id); |
| 447 return; |
| 448 } |
| 449 |
| 450 switch (object->type) { |
| 451 case Dart_CObject::kNull: |
| 452 WriteIndexedObject(Object::kNullObject); |
| 453 break; |
| 454 case Dart_CObject::kBool: |
| 455 if (object->value.as_bool) { |
| 456 WriteIndexedObject(ObjectStore::kTrueValue); |
| 457 } else { |
| 458 WriteIndexedObject(ObjectStore::kFalseValue); |
| 459 } |
| 460 break; |
| 461 case Dart_CObject::kInt32: |
| 462 WriteInt32(object); |
| 463 break; |
| 464 case Dart_CObject::kInt64: |
| 465 WriteInt64(object); |
| 466 break; |
| 467 case Dart_CObject::kBigint: { |
| 468 // Write out the serialization header value for this object. |
| 469 WriteInlinedHeader(object); |
| 470 // Write out the class and tags information. |
| 471 WriteObjectHeader(ObjectStore::kBigintClass, 0); |
| 472 // Write hex string length and content |
| 473 char* hex_string = object->value.as_bigint; |
| 474 intptr_t len = strlen(hex_string); |
| 475 WriteIntptrValue(len); |
| 476 for (intptr_t i = 0; i < len; i++) { |
| 477 Write<uint8_t>(hex_string[i]); |
| 478 } |
| 479 break; |
| 480 } |
| 481 case Dart_CObject::kDouble: |
| 482 // Write out the serialization header value for this object. |
| 483 WriteInlinedHeader(object); |
| 484 // Write out the class and tags information. |
| 485 WriteObjectHeader(ObjectStore::kDoubleClass, 0); |
| 486 // Write double value. |
| 487 Write<double>(object->value.as_double); |
| 488 break; |
| 489 case Dart_CObject::kString: { |
| 490 // Write out the serialization header value for this object. |
| 491 WriteInlinedHeader(object); |
| 492 // Write out the class and tags information. |
| 493 WriteObjectHeader(ObjectStore::kOneByteStringClass, 0); |
| 494 // Write string length, hash and content |
| 495 char* str = object->value.as_string; |
| 496 intptr_t len = strlen(str); |
| 497 WriteSmi(len); |
| 498 WriteSmi(0); // TODO(sgjesse): Hash - not written. |
| 499 for (intptr_t i = 0; i < len; i++) { |
| 500 Write<uint8_t>(str[i]); |
| 501 } |
| 502 break; |
| 503 } |
| 504 case Dart_CObject::kArray: { |
| 505 // Write out the serialization header value for this object. |
| 506 WriteInlinedHeader(object); |
| 507 // Write out the class and tags information. |
| 508 WriteObjectHeader(ObjectStore::kArrayClass, 0); |
| 509 WriteSmi(object->value.as_array.length); |
| 510 // Write out the type arguments. |
| 511 WriteIndexedObject(Object::kNullObject); |
| 512 // Write out array elements. |
| 513 for (int i = 0; i < object->value.as_array.length; i++) { |
| 514 WriteCObject(object->value.as_array.values[i]); |
| 515 } |
| 516 break; |
| 517 } |
| 518 case Dart_CObject::kByteArray: { |
| 519 // Write out the serialization header value for this object. |
| 520 WriteInlinedHeader(object); |
| 521 // Write out the class and tags information. |
| 522 WriteObjectHeader(ObjectStore::kInternalByteArrayClass, 0); |
| 523 uint8_t* bytes = object->value.as_byte_array.values; |
| 524 intptr_t len = object->value.as_byte_array.length; |
| 525 WriteSmi(len); |
| 526 for (intptr_t i = 0; i < len; i++) { |
| 527 Write<uint8_t>(bytes[i]); |
| 528 } |
| 529 break; |
| 530 } |
| 531 default: |
| 532 UNREACHABLE(); |
| 533 } |
| 534 } |
| 535 |
| 536 |
| 537 void ApiMessageWriter::WriteCMessage(Dart_CObject* object) { |
| 538 WriteCObject(object); |
| 539 UnmarkAllCObjects(object); |
| 540 FinalizeBuffer(); |
| 541 } |
| 542 |
331 } // namespace dart | 543 } // namespace dart |
OLD | NEW |