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

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

Issue 558853004: Preserve the contents of Dart strings with unmatched surrogate halfs by avoiding a UTF16 -> UTF8 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: sync and build Created 6 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 8535 matching lines...) Expand 10 before | Expand all | Expand 10 after
8546 JSONObject jsobj(stream); 8546 JSONObject jsobj(stream);
8547 AddTypeProperties(&jsobj, "Script", JSONType(), ref); 8547 AddTypeProperties(&jsobj, "Script", JSONType(), ref);
8548 const String& name = String::Handle(url()); 8548 const String& name = String::Handle(url());
8549 ASSERT(!name.IsNull()); 8549 ASSERT(!name.IsNull());
8550 const String& encoded_url = String::Handle(String::EncodeIRI(name)); 8550 const String& encoded_url = String::Handle(String::EncodeIRI(name));
8551 ASSERT(!encoded_url.IsNull()); 8551 ASSERT(!encoded_url.IsNull());
8552 const Library& lib = Library::Handle(FindLibrary()); 8552 const Library& lib = Library::Handle(FindLibrary());
8553 intptr_t lib_index = (lib.IsNull()) ? -1 : lib.index(); 8553 intptr_t lib_index = (lib.IsNull()) ? -1 : lib.index();
8554 jsobj.AddPropertyF("id", "libraries/%" Pd "/scripts/%s", 8554 jsobj.AddPropertyF("id", "libraries/%" Pd "/scripts/%s",
8555 lib_index, encoded_url.ToCString()); 8555 lib_index, encoded_url.ToCString());
8556 jsobj.AddProperty("name", name.ToCString()); 8556 jsobj.AddPropertyStr("name", name);
8557 jsobj.AddProperty("kind", GetKindAsCString()); 8557 jsobj.AddProperty("kind", GetKindAsCString());
8558 if (ref) { 8558 if (ref) {
8559 return; 8559 return;
8560 } 8560 }
8561 jsobj.AddProperty("owningLibrary", lib); 8561 jsobj.AddProperty("owningLibrary", lib);
8562 const String& source = String::Handle(Source()); 8562 const String& source = String::Handle(Source());
8563 jsobj.AddProperty("source", source.ToCString()); 8563 jsobj.AddPropertyStr("source", source);
8564 8564
8565 // Print the line number table 8565 // Print the line number table
8566 { 8566 {
8567 JSONArray tokenPosTable(&jsobj, "tokenPosTable"); 8567 JSONArray tokenPosTable(&jsobj, "tokenPosTable");
8568 8568
8569 const GrowableObjectArray& lineNumberArray = 8569 const GrowableObjectArray& lineNumberArray =
8570 GrowableObjectArray::Handle(GenerateLineNumberArray()); 8570 GrowableObjectArray::Handle(GenerateLineNumberArray());
8571 Object& value = Object::Handle(); 8571 Object& value = Object::Handle();
8572 intptr_t pos = 0; 8572 intptr_t pos = 0;
8573 8573
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after
9833 9833
9834 9834
9835 void Library::PrintJSONImpl(JSONStream* stream, bool ref) const { 9835 void Library::PrintJSONImpl(JSONStream* stream, bool ref) const {
9836 const char* library_name = String::Handle(name()).ToCString(); 9836 const char* library_name = String::Handle(name()).ToCString();
9837 intptr_t id = index(); 9837 intptr_t id = index();
9838 ASSERT(id >= 0); 9838 ASSERT(id >= 0);
9839 JSONObject jsobj(stream); 9839 JSONObject jsobj(stream);
9840 AddTypeProperties(&jsobj, "Library", JSONType(), ref); 9840 AddTypeProperties(&jsobj, "Library", JSONType(), ref);
9841 jsobj.AddPropertyF("id", "libraries/%" Pd "", id); 9841 jsobj.AddPropertyF("id", "libraries/%" Pd "", id);
9842 jsobj.AddProperty("name", library_name); 9842 jsobj.AddProperty("name", library_name);
9843 const char* library_url = String::Handle(url()).ToCString(); 9843 const String& library_url = String::Handle(url());
9844 jsobj.AddProperty("url", library_url); 9844 jsobj.AddPropertyStr("url", library_url);
9845 if (ref) { 9845 if (ref) {
9846 return; 9846 return;
9847 } 9847 }
9848 { 9848 {
9849 JSONArray jsarr(&jsobj, "classes"); 9849 JSONArray jsarr(&jsobj, "classes");
9850 ClassDictionaryIterator class_iter(*this); 9850 ClassDictionaryIterator class_iter(*this);
9851 Class& klass = Class::Handle(); 9851 Class& klass = Class::Handle();
9852 while (class_iter.HasNext()) { 9852 while (class_iter.HasNext()) {
9853 klass = class_iter.GetNextClass(); 9853 klass = class_iter.GetNextClass();
9854 if (!klass.IsCanonicalSignatureClass() && 9854 if (!klass.IsCanonicalSignatureClass() &&
(...skipping 7898 matching lines...) Expand 10 before | Expand all | Expand 10 after
17753 result = OneByteString::New(length, space); 17753 result = OneByteString::New(length, space);
17754 } else { 17754 } else {
17755 result = TwoByteString::New(length, space); 17755 result = TwoByteString::New(length, space);
17756 } 17756 }
17757 String::Copy(result, 0, str, begin_index, length); 17757 String::Copy(result, 0, str, begin_index, length);
17758 return result.raw(); 17758 return result.raw();
17759 } 17759 }
17760 17760
17761 17761
17762 const char* String::ToCString() const { 17762 const char* String::ToCString() const {
17763 intptr_t length;
17764 return ToCString(&length);
17765 }
17766
17767
17768 const char* String::ToCString(intptr_t* length) const {
17769 if (IsOneByteString()) { 17763 if (IsOneByteString()) {
17770 // Quick conversion if OneByteString contains only ASCII characters. 17764 // Quick conversion if OneByteString contains only ASCII characters.
17771 intptr_t len = Length(); 17765 intptr_t len = Length();
17772 if (len == 0) { 17766 if (len == 0) {
17773 *length = 0;
17774 return ""; 17767 return "";
17775 } 17768 }
17776 Zone* zone = Isolate::Current()->current_zone(); 17769 Zone* zone = Isolate::Current()->current_zone();
17777 uint8_t* result = zone->Alloc<uint8_t>(len + 1); 17770 uint8_t* result = zone->Alloc<uint8_t>(len + 1);
17778 NoGCScope no_gc; 17771 NoGCScope no_gc;
17779 const uint8_t* original_str = OneByteString::CharAddr(*this, 0); 17772 const uint8_t* original_str = OneByteString::CharAddr(*this, 0);
17780 for (intptr_t i = 0; i < len; i++) { 17773 for (intptr_t i = 0; i < len; i++) {
17781 if (original_str[i] <= Utf8::kMaxOneByteChar) { 17774 if (original_str[i] <= Utf8::kMaxOneByteChar) {
17782 result[i] = original_str[i]; 17775 result[i] = original_str[i];
17783 } else { 17776 } else {
17784 len = -1; 17777 len = -1;
17785 break; 17778 break;
17786 } 17779 }
17787 } 17780 }
17788 if (len > 0) { 17781 if (len > 0) {
17789 result[len] = 0; 17782 result[len] = 0;
17790 *length = len;
17791 return reinterpret_cast<const char*>(result); 17783 return reinterpret_cast<const char*>(result);
17792 } 17784 }
17793 } 17785 }
17794 const intptr_t len = Utf8::Length(*this); 17786 const intptr_t len = Utf8::Length(*this);
17795 Zone* zone = Isolate::Current()->current_zone(); 17787 Zone* zone = Isolate::Current()->current_zone();
17796 uint8_t* result = zone->Alloc<uint8_t>(len + 1); 17788 uint8_t* result = zone->Alloc<uint8_t>(len + 1);
17797 ToUTF8(result, len); 17789 ToUTF8(result, len);
17798 result[len] = 0; 17790 result[len] = 0;
17799 *length = len;
17800 return reinterpret_cast<const char*>(result); 17791 return reinterpret_cast<const char*>(result);
17801 } 17792 }
17802 17793
17803 17794
17804 const char* String::ToCStringTruncated(intptr_t max_len,
17805 bool* did_truncate,
17806 intptr_t* length) const {
17807 if (Length() <= max_len) {
17808 *did_truncate = false;
17809 return ToCString(length);
17810 }
17811
17812 intptr_t aligned_limit = max_len;
17813 if (Utf16::IsLeadSurrogate(CharAt(max_len - 1))) {
17814 // Don't let truncation split a surrogate pair.
17815 aligned_limit--;
17816 }
17817 ASSERT(!Utf16::IsLeadSurrogate(CharAt(aligned_limit - 1)));
17818
17819 *did_truncate = true;
17820 const String& truncated =
17821 String::Handle(String::SubString(*this, 0, aligned_limit));
17822 return truncated.ToCString(length);
17823 }
17824
17825
17826 void String::PrintJSONImpl(JSONStream* stream, bool ref) const { 17795 void String::PrintJSONImpl(JSONStream* stream, bool ref) const {
17827 JSONObject jsobj(stream); 17796 JSONObject jsobj(stream);
17828 if (raw() == Symbols::OptimizedOut().raw()) { 17797 if (raw() == Symbols::OptimizedOut().raw()) {
17829 // TODO(turnidge): This is a hack. The user could have this 17798 // TODO(turnidge): This is a hack. The user could have this
17830 // special string in their program. Fixing this involves updating 17799 // special string in their program. Fixing this involves updating
17831 // the debugging api a bit. 17800 // the debugging api a bit.
17832 jsobj.AddProperty("type", "Sentinel"); 17801 jsobj.AddProperty("type", "Sentinel");
17833 jsobj.AddProperty("id", "objects/optimized-out"); 17802 jsobj.AddProperty("id", "objects/optimized-out");
17834 jsobj.AddProperty("valueAsString", "<optimized out>"); 17803 jsobj.AddProperty("valueAsString", "<optimized out>");
17835 return; 17804 return;
17836 } 17805 }
17837 AddTypeProperties(&jsobj, "String", JSONType(), ref); 17806 AddTypeProperties(&jsobj, "String", JSONType(), ref);
17838 PrintSharedInstanceJSON(&jsobj, ref); 17807 PrintSharedInstanceJSON(&jsobj, ref);
17839 ObjectIdRing* ring = Isolate::Current()->object_id_ring(); 17808 ObjectIdRing* ring = Isolate::Current()->object_id_ring();
17840 const intptr_t id = ring->GetIdForObject(raw()); 17809 const intptr_t id = ring->GetIdForObject(raw());
17841 jsobj.AddPropertyF("id", "objects/%" Pd "", id); 17810 jsobj.AddPropertyF("id", "objects/%" Pd "", id);
17842 if (ref) { 17811 if (ref) {
17843 bool did_truncate = false; 17812 bool did_truncate = jsobj.AddPropertyStr("valueAsString", *this, 128);
17844 intptr_t length = 0;
17845 const char* cstr = ToCStringTruncated(128, &did_truncate, &length);
17846 jsobj.AddProperty("valueAsString", cstr, length);
17847 if (did_truncate) { 17813 if (did_truncate) {
17848 jsobj.AddProperty("valueAsStringIsTruncated", did_truncate); 17814 jsobj.AddProperty("valueAsStringIsTruncated", did_truncate);
17849 } 17815 }
17850 } else { 17816 } else {
17851 intptr_t length = 0; 17817 bool did_truncate = jsobj.AddPropertyStr("valueAsString", *this);
17852 const char* cstr = ToCString(&length); 17818 ASSERT(!did_truncate);
17853 jsobj.AddProperty("valueAsString", cstr, length);
17854 } 17819 }
17855 } 17820 }
17856 17821
17857 17822
17858 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { 17823 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const {
17859 ASSERT(array_len >= Utf8::Length(*this)); 17824 ASSERT(array_len >= Utf8::Length(*this));
17860 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); 17825 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len);
17861 } 17826 }
17862 17827
17863 17828
(...skipping 2523 matching lines...) Expand 10 before | Expand all | Expand 10 after
20387 return tag_label.ToCString(); 20352 return tag_label.ToCString();
20388 } 20353 }
20389 20354
20390 20355
20391 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 20356 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
20392 Instance::PrintJSONImpl(stream, ref); 20357 Instance::PrintJSONImpl(stream, ref);
20393 } 20358 }
20394 20359
20395 20360
20396 } // namespace dart 20361 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698