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

Side by Side Diff: runtime/vm/dart_api_message.cc

Issue 11410032: Add support for non ASCII strings when communicating with native ports (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase + update test expectations Created 8 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/snapshot_ids.h" 7 #include "vm/snapshot_ids.h"
8 #include "vm/symbols.h" 8 #include "vm/symbols.h"
9 #include "vm/unicode.h"
9 10
10 namespace dart { 11 namespace dart {
11 12
12 static const int kNumInitialReferences = 4; 13 static const int kNumInitialReferences = 4;
13 14
14 ApiMessageReader::ApiMessageReader(const uint8_t* buffer, 15 ApiMessageReader::ApiMessageReader(const uint8_t* buffer,
15 intptr_t length, 16 intptr_t length,
16 ReAlloc alloc) 17 ReAlloc alloc)
17 : BaseReader(buffer, length), 18 : BaseReader(buffer, length),
18 alloc_(alloc), 19 alloc_(alloc),
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 USE(hash); 349 USE(hash);
349 Dart_CObject* object = AllocateDartCObjectString(len); 350 Dart_CObject* object = AllocateDartCObjectString(len);
350 AddBackRef(object_id, object, kIsDeserialized); 351 AddBackRef(object_id, object, kIsDeserialized);
351 char* p = object->value.as_string; 352 char* p = object->value.as_string;
352 for (intptr_t i = 0; i < len; i++) { 353 for (intptr_t i = 0; i < len; i++) {
353 p[i] = Read<uint8_t>(); 354 p[i] = Read<uint8_t>();
354 } 355 }
355 p[len] = '\0'; 356 p[len] = '\0';
356 return object; 357 return object;
357 } 358 }
358 case kTwoByteStringCid: 359 case kTwoByteStringCid: {
359 // Two byte strings not supported. 360 intptr_t len = ReadSmiValue();
360 return AllocateDartCObjectUnsupported(); 361 intptr_t hash = ReadSmiValue();
362 USE(hash);
363 uint16_t *utf16 =
364 reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t)));
365 intptr_t utf8_len = 0;
366 for (intptr_t i = 0; i < len; i++) {
367 utf16[i] = Read<uint16_t>();
368 // TODO(sgjesse): Check for surrogate pairs.
369 utf8_len += Utf8::Length(utf16[i]);
370 }
371 Dart_CObject* object = AllocateDartCObjectString(utf8_len);
372 AddBackRef(object_id, object, kIsDeserialized);
373 char* p = object->value.as_string;
374 for (intptr_t i = 0; i < len; i++) {
375 // TODO(sgjesse): Check for surrogate pairs.
376 p += Utf8::Encode(utf16[i], p);
377 }
378 *p = '\0';
379 ASSERT(p == object->value.as_string + utf8_len);
380 ::free(utf16);
381 return object;
382 }
361 case kUint8ArrayCid: { 383 case kUint8ArrayCid: {
362 intptr_t len = ReadSmiValue(); 384 intptr_t len = ReadSmiValue();
363 Dart_CObject* object = AllocateDartCObjectUint8Array(len); 385 Dart_CObject* object = AllocateDartCObjectUint8Array(len);
364 AddBackRef(object_id, object, kIsDeserialized); 386 AddBackRef(object_id, object, kIsDeserialized);
365 if (len > 0) { 387 if (len > 0) {
366 uint8_t* p = object->value.as_byte_array.values; 388 uint8_t* p = object->value.as_byte_array.values;
367 for (intptr_t i = 0; i < len; i++) { 389 for (intptr_t i = 0; i < len; i++) {
368 p[i] = Read<uint8_t>(); 390 p[i] = Read<uint8_t>();
369 } 391 }
370 } 392 }
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 void ApiMessageWriter::WriteInlinedHeader(Dart_CObject* object) { 631 void ApiMessageWriter::WriteInlinedHeader(Dart_CObject* object) {
610 // Write out the serialization header value for this object. 632 // Write out the serialization header value for this object.
611 WriteInlinedObjectHeader(kMaxPredefinedObjectIds + object_id_); 633 WriteInlinedObjectHeader(kMaxPredefinedObjectIds + object_id_);
612 // Mark object with its object id. 634 // Mark object with its object id.
613 MarkCObject(object, object_id_); 635 MarkCObject(object, object_id_);
614 // Advance object id. 636 // Advance object id.
615 object_id_++; 637 object_id_++;
616 } 638 }
617 639
618 640
619 void ApiMessageWriter::WriteCObject(Dart_CObject* object) { 641 bool ApiMessageWriter::WriteCObject(Dart_CObject* object) {
620 if (IsCObjectMarked(object)) { 642 if (IsCObjectMarked(object)) {
621 intptr_t object_id = GetMarkedCObjectMark(object); 643 intptr_t object_id = GetMarkedCObjectMark(object);
622 WriteIndexedObject(kMaxPredefinedObjectIds + object_id); 644 WriteIndexedObject(kMaxPredefinedObjectIds + object_id);
623 return; 645 return true;
624 } 646 }
625 647
626 Dart_CObject::Type type = object->type; 648 Dart_CObject::Type type = object->type;
627 if (type == Dart_CObject::kArray) { 649 if (type == Dart_CObject::kArray) {
628 // Write out the serialization header value for this object. 650 // Write out the serialization header value for this object.
629 WriteInlinedHeader(object); 651 WriteInlinedHeader(object);
630 // Write out the class and tags information. 652 // Write out the class and tags information.
631 WriteIndexedObject(kArrayCid); 653 WriteIndexedObject(kArrayCid);
632 WriteIntptrValue(0); 654 WriteIntptrValue(0);
633 655
634 WriteSmi(object->value.as_array.length); 656 WriteSmi(object->value.as_array.length);
635 // Write out the type arguments. 657 // Write out the type arguments.
636 WriteNullObject(); 658 WriteNullObject();
637 // Write out array elements. 659 // Write out array elements.
638 for (int i = 0; i < object->value.as_array.length; i++) { 660 for (int i = 0; i < object->value.as_array.length; i++) {
639 WriteCObjectRef(object->value.as_array.values[i]); 661 bool success = WriteCObjectRef(object->value.as_array.values[i]);
662 if (!success) return false;
640 } 663 }
641 return; 664 return true;
642 } 665 }
643 WriteCObjectInlined(object, type); 666 return WriteCObjectInlined(object, type);
644 } 667 }
645 668
646 669
647 void ApiMessageWriter::WriteCObjectRef(Dart_CObject* object) { 670 bool ApiMessageWriter::WriteCObjectRef(Dart_CObject* object) {
648 if (IsCObjectMarked(object)) { 671 if (IsCObjectMarked(object)) {
649 intptr_t object_id = GetMarkedCObjectMark(object); 672 intptr_t object_id = GetMarkedCObjectMark(object);
650 WriteIndexedObject(kMaxPredefinedObjectIds + object_id); 673 WriteIndexedObject(kMaxPredefinedObjectIds + object_id);
651 return; 674 return true;
652 } 675 }
653 676
654 Dart_CObject::Type type = object->type; 677 Dart_CObject::Type type = object->type;
655 if (type == Dart_CObject::kArray) { 678 if (type == Dart_CObject::kArray) {
656 // Write out the serialization header value for this object. 679 // Write out the serialization header value for this object.
657 WriteInlinedHeader(object); 680 WriteInlinedHeader(object);
658 // Write out the class information. 681 // Write out the class information.
659 WriteIndexedObject(kArrayCid); 682 WriteIndexedObject(kArrayCid);
660 // Write out the length information. 683 // Write out the length information.
661 WriteSmi(object->value.as_array.length); 684 WriteSmi(object->value.as_array.length);
662 // Add object to forward list so that this object is serialized later. 685 // Add object to forward list so that this object is serialized later.
663 AddToForwardList(object); 686 AddToForwardList(object);
664 return; 687 return true;
665 } 688 }
666 WriteCObjectInlined(object, type); 689 return WriteCObjectInlined(object, type);
667 } 690 }
668 691
669 692
670 void ApiMessageWriter::WriteForwardedCObject(Dart_CObject* object) { 693 bool ApiMessageWriter::WriteForwardedCObject(Dart_CObject* object) {
671 ASSERT(IsCObjectMarked(object)); 694 ASSERT(IsCObjectMarked(object));
672 Dart_CObject::Type type = 695 Dart_CObject::Type type =
673 static_cast<Dart_CObject::Type>(object->type & kDartCObjectTypeMask); 696 static_cast<Dart_CObject::Type>(object->type & kDartCObjectTypeMask);
674 ASSERT(type == Dart_CObject::kArray); 697 ASSERT(type == Dart_CObject::kArray);
675 698
676 // Write out the serialization header value for this object. 699 // Write out the serialization header value for this object.
677 intptr_t object_id = GetMarkedCObjectMark(object); 700 intptr_t object_id = GetMarkedCObjectMark(object);
678 WriteInlinedObjectHeader(kMaxPredefinedObjectIds + object_id); 701 WriteInlinedObjectHeader(kMaxPredefinedObjectIds + object_id);
679 // Write out the class and tags information. 702 // Write out the class and tags information.
680 WriteIndexedObject(kArrayCid); 703 WriteIndexedObject(kArrayCid);
681 WriteIntptrValue(0); 704 WriteIntptrValue(0);
682 705
683 WriteSmi(object->value.as_array.length); 706 WriteSmi(object->value.as_array.length);
684 // Write out the type arguments. 707 // Write out the type arguments.
685 WriteNullObject(); 708 WriteNullObject();
686 // Write out array elements. 709 // Write out array elements.
687 for (int i = 0; i < object->value.as_array.length; i++) { 710 for (int i = 0; i < object->value.as_array.length; i++) {
688 WriteCObjectRef(object->value.as_array.values[i]); 711 bool success = WriteCObjectRef(object->value.as_array.values[i]);
712 if (!success) return false;
689 } 713 }
714 return true;
690 } 715 }
691 716
692 717
693 void ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object, 718 bool ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object,
694 Dart_CObject::Type type) { 719 Dart_CObject::Type type) {
695 switch (type) { 720 switch (type) {
696 case Dart_CObject::kNull: 721 case Dart_CObject::kNull:
697 WriteNullObject(); 722 WriteNullObject();
698 break; 723 break;
699 case Dart_CObject::kBool: 724 case Dart_CObject::kBool:
700 if (object->value.as_bool) { 725 if (object->value.as_bool) {
701 WriteIndexedObject(kTrueValue); 726 WriteIndexedObject(kTrueValue);
702 } else { 727 } else {
703 WriteIndexedObject(kFalseValue); 728 WriteIndexedObject(kFalseValue);
(...skipping 23 matching lines...) Expand all
727 case Dart_CObject::kDouble: 752 case Dart_CObject::kDouble:
728 // Write out the serialization header value for this object. 753 // Write out the serialization header value for this object.
729 WriteInlinedHeader(object); 754 WriteInlinedHeader(object);
730 // Write out the class and tags information. 755 // Write out the class and tags information.
731 WriteIndexedObject(kDoubleCid); 756 WriteIndexedObject(kDoubleCid);
732 WriteIntptrValue(0); 757 WriteIntptrValue(0);
733 // Write double value. 758 // Write double value.
734 Write<double>(object->value.as_double); 759 Write<double>(object->value.as_double);
735 break; 760 break;
736 case Dart_CObject::kString: { 761 case Dart_CObject::kString: {
762 const uint8_t* utf8_str =
763 reinterpret_cast<const uint8_t*>(object->value.as_string);
764 intptr_t utf8_len = strlen(object->value.as_string);
765 if (!Utf8::IsValid(utf8_str, utf8_len)) {
766 return false;
767 }
768
769 Utf8::Type type;
770 intptr_t len = Utf8::CodePointCount(utf8_str, utf8_len, &type);
771
737 // Write out the serialization header value for this object. 772 // Write out the serialization header value for this object.
738 WriteInlinedHeader(object); 773 WriteInlinedHeader(object);
739 // Write out the class and tags information. 774 // Write out the class and tags information.
740 WriteIndexedObject(kOneByteStringCid); 775 WriteIndexedObject(type == Utf8::kAscii ? kOneByteStringCid
776 : kTwoByteStringCid);
741 WriteIntptrValue(0); 777 WriteIntptrValue(0);
742 // Write string length, hash and content 778 // Write string length, hash and content
743 char* str = object->value.as_string;
744 intptr_t len = strlen(str);
745 WriteSmi(len); 779 WriteSmi(len);
746 WriteSmi(0); // TODO(sgjesse): Hash - not written. 780 WriteSmi(0); // TODO(sgjesse): Hash - not written.
747 for (intptr_t i = 0; i < len; i++) { 781 if (type == Utf8::kAscii) {
748 Write<uint8_t>(str[i]); 782 for (intptr_t i = 0; i < len; i++) {
783 Write<uint8_t>(utf8_str[i]);
784 }
785 } else {
786 // TODO(sgjesse): Make sure surrogate pairs are handled.
787 uint16_t* utf16_str =
788 reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t)));
789 Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len);
790 for (intptr_t i = 0; i < len; i++) {
791 Write<uint16_t>(utf16_str[i]);
792 }
793 ::free(utf16_str);
749 } 794 }
750 break; 795 break;
751 } 796 }
752 case Dart_CObject::kUint8Array: { 797 case Dart_CObject::kUint8Array: {
753 // Write out the serialization header value for this object. 798 // Write out the serialization header value for this object.
754 WriteInlinedHeader(object); 799 WriteInlinedHeader(object);
755 // Write out the class and tags information. 800 // Write out the class and tags information.
756 WriteIndexedObject(kUint8ArrayCid); 801 WriteIndexedObject(kUint8ArrayCid);
757 WriteIntptrValue(0); 802 WriteIntptrValue(0);
758 uint8_t* bytes = object->value.as_byte_array.values; 803 uint8_t* bytes = object->value.as_byte_array.values;
(...skipping 22 matching lines...) Expand all
781 object->value.as_external_byte_array.callback; 826 object->value.as_external_byte_array.callback;
782 WriteSmi(length); 827 WriteSmi(length);
783 WriteIntptrValue(reinterpret_cast<intptr_t>(data)); 828 WriteIntptrValue(reinterpret_cast<intptr_t>(data));
784 WriteIntptrValue(reinterpret_cast<intptr_t>(peer)); 829 WriteIntptrValue(reinterpret_cast<intptr_t>(peer));
785 WriteIntptrValue(reinterpret_cast<intptr_t>(callback)); 830 WriteIntptrValue(reinterpret_cast<intptr_t>(callback));
786 break; 831 break;
787 } 832 }
788 default: 833 default:
789 UNREACHABLE(); 834 UNREACHABLE();
790 } 835 }
836
837 return true;
791 } 838 }
792 839
793 840
794 void ApiMessageWriter::WriteCMessage(Dart_CObject* object) { 841 bool ApiMessageWriter::WriteCMessage(Dart_CObject* object) {
795 WriteCObject(object); 842 bool success = WriteCObject(object);
843 if (!success) {
844 UnmarkAllCObjects(object);
845 return false;
846 }
796 // Write out all objects that were added to the forward list and have 847 // Write out all objects that were added to the forward list and have
797 // not been serialized yet. These would typically be fields of arrays. 848 // not been serialized yet. These would typically be fields of arrays.
798 // NOTE: The forward list might grow as we process the list. 849 // NOTE: The forward list might grow as we process the list.
799 for (intptr_t i = 0; i < forward_id_; i++) { 850 for (intptr_t i = 0; i < forward_id_; i++) {
800 WriteForwardedCObject(forward_list_[i]); 851 success = WriteForwardedCObject(forward_list_[i]);
852 if (!success) {
853 UnmarkAllCObjects(object);
854 return false;
855 }
801 } 856 }
802 UnmarkAllCObjects(object); 857 UnmarkAllCObjects(object);
858 return true;
803 } 859 }
804 860
805 } // namespace dart 861 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698