OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "platform/assert.h" | 5 #include "platform/assert.h" |
6 | 6 |
7 #include "include/dart_native_api.h" | 7 #include "include/dart_native_api.h" |
8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
9 #include "vm/debugger.h" | 9 #include "vm/debugger.h" |
10 #include "vm/json_stream.h" | 10 #include "vm/json_stream.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 count_(-1) { | 58 count_(-1) { |
59 ObjectIdRing* ring = NULL; | 59 ObjectIdRing* ring = NULL; |
60 Isolate* isolate = Isolate::Current(); | 60 Isolate* isolate = Isolate::Current(); |
61 if (isolate != NULL) { | 61 if (isolate != NULL) { |
62 ring = isolate->object_id_ring(); | 62 ring = isolate->object_id_ring(); |
63 } | 63 } |
64 default_id_zone_.Init(ring, ObjectIdRing::kAllocateId); | 64 default_id_zone_.Init(ring, ObjectIdRing::kAllocateId); |
65 } | 65 } |
66 | 66 |
67 | 67 |
68 JSONStream::~JSONStream() { | 68 JSONStream::~JSONStream() {} |
69 } | |
70 | 69 |
71 | 70 |
72 void JSONStream::Setup(Zone* zone, | 71 void JSONStream::Setup(Zone* zone, |
73 Dart_Port reply_port, | 72 Dart_Port reply_port, |
74 const Instance& seq, | 73 const Instance& seq, |
75 const String& method, | 74 const String& method, |
76 const Array& param_keys, | 75 const Array& param_keys, |
77 const Array& param_values, | 76 const Array& param_values, |
78 bool parameters_are_dart_objects) { | 77 bool parameters_are_dart_objects) { |
79 set_reply_port(reply_port); | 78 set_reply_port(reply_port); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 jsobj.AddProperty("method", js->method()); | 160 jsobj.AddProperty("method", js->method()); |
162 { | 161 { |
163 JSONObject params(&jsobj, "params"); | 162 JSONObject params(&jsobj, "params"); |
164 for (intptr_t i = 0; i < js->num_params(); i++) { | 163 for (intptr_t i = 0; i < js->num_params(); i++) { |
165 params.AddProperty(js->GetParamKey(i), js->GetParamValue(i)); | 164 params.AddProperty(js->GetParamKey(i), js->GetParamValue(i)); |
166 } | 165 } |
167 } | 166 } |
168 } | 167 } |
169 | 168 |
170 | 169 |
171 void JSONStream::PrintError(intptr_t code, | 170 void JSONStream::PrintError(intptr_t code, const char* details_format, ...) { |
172 const char* details_format, ...) { | |
173 SetupError(); | 171 SetupError(); |
174 JSONObject jsobj(this); | 172 JSONObject jsobj(this); |
175 jsobj.AddProperty("code", code); | 173 jsobj.AddProperty("code", code); |
176 jsobj.AddProperty("message", GetJSONRpcErrorMessage(code)); | 174 jsobj.AddProperty("message", GetJSONRpcErrorMessage(code)); |
177 { | 175 { |
178 JSONObject data(&jsobj, "data"); | 176 JSONObject data(&jsobj, "data"); |
179 PrintRequest(&data, this); | 177 PrintRequest(&data, this); |
180 if (details_format != NULL) { | 178 if (details_format != NULL) { |
181 va_list args; | 179 va_list args; |
182 va_start(args, details_format); | 180 va_start(args, details_format); |
183 intptr_t len = OS::VSNPrint(NULL, 0, details_format, args); | 181 intptr_t len = OS::VSNPrint(NULL, 0, details_format, args); |
184 va_end(args); | 182 va_end(args); |
185 | 183 |
186 char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1); | 184 char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1); |
187 va_list args2; | 185 va_list args2; |
188 va_start(args2, details_format); | 186 va_start(args2, details_format); |
189 OS::VSNPrint(buffer, (len + 1), details_format, args2); | 187 OS::VSNPrint(buffer, (len + 1), details_format, args2); |
190 va_end(args2); | 188 va_end(args2); |
191 | 189 |
192 data.AddProperty("details", buffer); | 190 data.AddProperty("details", buffer); |
193 } | 191 } |
194 } | 192 } |
195 } | 193 } |
196 | 194 |
197 | 195 |
198 void JSONStream::PostNullReply(Dart_Port port) { | 196 void JSONStream::PostNullReply(Dart_Port port) { |
199 PortMap::PostMessage(new Message( | 197 PortMap::PostMessage( |
200 port, Object::null(), Message::kNormalPriority)); | 198 new Message(port, Object::null(), Message::kNormalPriority)); |
201 } | 199 } |
202 | 200 |
203 | 201 |
204 static void Finalizer(void* isolate_callback_data, | 202 static void Finalizer(void* isolate_callback_data, |
205 Dart_WeakPersistentHandle handle, | 203 Dart_WeakPersistentHandle handle, |
206 void* buffer) { | 204 void* buffer) { |
207 free(buffer); | 205 free(buffer); |
208 } | 206 } |
209 | 207 |
210 | 208 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 if (!result) { | 253 if (!result) { |
256 free(cstr); | 254 free(cstr); |
257 } | 255 } |
258 | 256 |
259 if (FLAG_trace_service) { | 257 if (FLAG_trace_service) { |
260 Isolate* isolate = Isolate::Current(); | 258 Isolate* isolate = Isolate::Current(); |
261 ASSERT(isolate != NULL); | 259 ASSERT(isolate != NULL); |
262 const char* isolate_name = isolate->name(); | 260 const char* isolate_name = isolate->name(); |
263 int64_t total_time = OS::GetCurrentTimeMicros() - setup_time_micros_; | 261 int64_t total_time = OS::GetCurrentTimeMicros() - setup_time_micros_; |
264 if (result) { | 262 if (result) { |
265 OS::Print("[+%" Pd64 "ms] Isolate %s processed service request %s " | 263 OS::Print("[+%" Pd64 |
| 264 "ms] Isolate %s processed service request %s " |
266 "(%" Pd64 "us)\n", | 265 "(%" Pd64 "us)\n", |
267 Dart::timestamp(), isolate_name, method_, total_time); | 266 Dart::timestamp(), isolate_name, method_, total_time); |
268 } else { | 267 } else { |
269 OS::Print("[+%" Pd64 "ms] Isolate %s processed service request %s " | 268 OS::Print("[+%" Pd64 |
| 269 "ms] Isolate %s processed service request %s " |
270 "(%" Pd64 "us) FAILED\n", | 270 "(%" Pd64 "us) FAILED\n", |
271 Dart::timestamp(), isolate_name, method_, total_time); | 271 Dart::timestamp(), isolate_name, method_, total_time); |
272 } | 272 } |
273 } | 273 } |
274 } | 274 } |
275 | 275 |
276 | 276 |
277 const char* JSONStream::LookupParam(const char* key) const { | 277 const char* JSONStream::LookupParam(const char* key) const { |
278 for (int i = 0; i < num_params(); i++) { | 278 for (int i = 0; i < num_params(); i++) { |
279 if (!strcmp(key, param_keys_[i])) { | 279 if (!strcmp(key, param_keys_[i])) { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 } | 410 } |
411 | 411 |
412 | 412 |
413 void JSONStream::PrintValue(double d) { | 413 void JSONStream::PrintValue(double d) { |
414 PrintCommaIfNeeded(); | 414 PrintCommaIfNeeded(); |
415 buffer_.Printf("%f", d); | 415 buffer_.Printf("%f", d); |
416 } | 416 } |
417 | 417 |
418 | 418 |
419 static const char base64_digits[65] = | 419 static const char base64_digits[65] = |
420 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 420 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
421 static const char base64_pad = '='; | 421 static const char base64_pad = '='; |
422 | 422 |
423 | 423 |
424 void JSONStream::PrintValueBase64(const uint8_t* bytes, intptr_t length) { | 424 void JSONStream::PrintValueBase64(const uint8_t* bytes, intptr_t length) { |
425 PrintCommaIfNeeded(); | 425 PrintCommaIfNeeded(); |
426 buffer_.AddChar('"'); | 426 buffer_.AddChar('"'); |
427 | 427 |
428 intptr_t odd_bits = length % 3; | 428 intptr_t odd_bits = length % 3; |
429 intptr_t even_bits = length - odd_bits; | 429 intptr_t even_bits = length - odd_bits; |
430 for (intptr_t i = 0; i < even_bits; i += 3) { | 430 for (intptr_t i = 0; i < even_bits; i += 3) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 } | 477 } |
478 | 478 |
479 | 479 |
480 void JSONStream::PrintfValue(const char* format, ...) { | 480 void JSONStream::PrintfValue(const char* format, ...) { |
481 PrintCommaIfNeeded(); | 481 PrintCommaIfNeeded(); |
482 | 482 |
483 va_list args; | 483 va_list args; |
484 va_start(args, format); | 484 va_start(args, format); |
485 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 485 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
486 va_end(args); | 486 va_end(args); |
487 char* p = reinterpret_cast<char*>(malloc(len+1)); | 487 char* p = reinterpret_cast<char*>(malloc(len + 1)); |
488 va_start(args, format); | 488 va_start(args, format); |
489 intptr_t len2 = OS::VSNPrint(p, len+1, format, args); | 489 intptr_t len2 = OS::VSNPrint(p, len + 1, format, args); |
490 va_end(args); | 490 va_end(args); |
491 ASSERT(len == len2); | 491 ASSERT(len == len2); |
492 buffer_.AddChar('"'); | 492 buffer_.AddChar('"'); |
493 AddEscapedUTF8String(p); | 493 AddEscapedUTF8String(p); |
494 buffer_.AddChar('"'); | 494 buffer_.AddChar('"'); |
495 free(p); | 495 free(p); |
496 } | 496 } |
497 | 497 |
498 | 498 |
499 void JSONStream::PrintValue(const Object& o, bool ref) { | 499 void JSONStream::PrintValue(const Object& o, bool ref) { |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 PrintValue(timeline_event_block); | 674 PrintValue(timeline_event_block); |
675 } | 675 } |
676 | 676 |
677 | 677 |
678 void JSONStream::PrintfProperty(const char* name, const char* format, ...) { | 678 void JSONStream::PrintfProperty(const char* name, const char* format, ...) { |
679 PrintPropertyName(name); | 679 PrintPropertyName(name); |
680 va_list args; | 680 va_list args; |
681 va_start(args, format); | 681 va_start(args, format); |
682 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 682 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
683 va_end(args); | 683 va_end(args); |
684 char* p = reinterpret_cast<char*>(malloc(len+1)); | 684 char* p = reinterpret_cast<char*>(malloc(len + 1)); |
685 va_start(args, format); | 685 va_start(args, format); |
686 intptr_t len2 = OS::VSNPrint(p, len+1, format, args); | 686 intptr_t len2 = OS::VSNPrint(p, len + 1, format, args); |
687 va_end(args); | 687 va_end(args); |
688 ASSERT(len == len2); | 688 ASSERT(len == len2); |
689 buffer_.AddChar('"'); | 689 buffer_.AddChar('"'); |
690 AddEscapedUTF8String(p); | 690 AddEscapedUTF8String(p); |
691 buffer_.AddChar('"'); | 691 buffer_.AddChar('"'); |
692 free(p); | 692 free(p); |
693 } | 693 } |
694 | 694 |
695 | 695 |
696 void JSONStream::Steal(char** buffer, intptr_t* buffer_length) { | 696 void JSONStream::Steal(char** buffer, intptr_t* buffer_length) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 } | 779 } |
780 } | 780 } |
781 | 781 |
782 | 782 |
783 bool JSONStream::NeedComma() { | 783 bool JSONStream::NeedComma() { |
784 const char* buffer = buffer_.buf(); | 784 const char* buffer = buffer_.buf(); |
785 intptr_t length = buffer_.length(); | 785 intptr_t length = buffer_.length(); |
786 if (length == 0) { | 786 if (length == 0) { |
787 return false; | 787 return false; |
788 } | 788 } |
789 char ch = buffer[length-1]; | 789 char ch = buffer[length - 1]; |
790 return (ch != '[') && (ch != '{') && (ch != ':') && (ch != ','); | 790 return (ch != '[') && (ch != '{') && (ch != ':') && (ch != ','); |
791 } | 791 } |
792 | 792 |
793 | 793 |
794 void JSONStream::EnsureIntegerIsRepresentableInJavaScript(int64_t i) { | 794 void JSONStream::EnsureIntegerIsRepresentableInJavaScript(int64_t i) { |
795 #ifdef DEBUG | 795 #ifdef DEBUG |
796 if (!Utils::IsJavascriptInt(i)) { | 796 if (!Utils::IsJavascriptInt(i)) { |
797 OS::Print("JSONStream::EnsureIntegerIsRepresentableInJavaScript failed on " | 797 OS::Print( |
798 "%" Pd64 "\n", i); | 798 "JSONStream::EnsureIntegerIsRepresentableInJavaScript failed on " |
| 799 "%" Pd64 "\n", |
| 800 i); |
799 UNREACHABLE(); | 801 UNREACHABLE(); |
800 } | 802 } |
801 #endif | 803 #endif |
802 } | 804 } |
803 | 805 |
804 | 806 |
805 void JSONStream::AddEscapedUTF8String(const char* s) { | 807 void JSONStream::AddEscapedUTF8String(const char* s) { |
806 if (s == NULL) { | 808 if (s == NULL) { |
807 return; | 809 return; |
808 } | 810 } |
809 intptr_t len = strlen(s); | 811 intptr_t len = strlen(s); |
810 AddEscapedUTF8String(s, len); | 812 AddEscapedUTF8String(s, len); |
811 } | 813 } |
812 | 814 |
813 | 815 |
814 void JSONStream::AddEscapedUTF8String(const char* s, intptr_t len) { | 816 void JSONStream::AddEscapedUTF8String(const char* s, intptr_t len) { |
815 if (s == NULL) { | 817 if (s == NULL) { |
816 return; | 818 return; |
817 } | 819 } |
818 const uint8_t* s8 = reinterpret_cast<const uint8_t*>(s); | 820 const uint8_t* s8 = reinterpret_cast<const uint8_t*>(s); |
819 intptr_t i = 0; | 821 intptr_t i = 0; |
820 for (; i < len; ) { | 822 for (; i < len;) { |
821 // Extract next UTF8 character. | 823 // Extract next UTF8 character. |
822 int32_t ch = 0; | 824 int32_t ch = 0; |
823 int32_t ch_len = Utf8::Decode(&s8[i], len - i, &ch); | 825 int32_t ch_len = Utf8::Decode(&s8[i], len - i, &ch); |
824 ASSERT(ch_len != 0); | 826 ASSERT(ch_len != 0); |
825 buffer_.EscapeAndAddCodeUnit(ch); | 827 buffer_.EscapeAndAddCodeUnit(ch); |
826 // Move i forward. | 828 // Move i forward. |
827 i += ch_len; | 829 i += ch_len; |
828 } | 830 } |
829 ASSERT(i == len); | 831 ASSERT(i == len); |
830 } | 832 } |
(...skipping 12 matching lines...) Expand all Loading... |
843 } | 845 } |
844 intptr_t limit = offset + count; | 846 intptr_t limit = offset + count; |
845 for (intptr_t i = offset; i < limit; i++) { | 847 for (intptr_t i = offset; i < limit; i++) { |
846 uint16_t code_unit = s.CharAt(i); | 848 uint16_t code_unit = s.CharAt(i); |
847 if (Utf16::IsTrailSurrogate(code_unit)) { | 849 if (Utf16::IsTrailSurrogate(code_unit)) { |
848 buffer_.EscapeAndAddUTF16CodeUnit(code_unit); | 850 buffer_.EscapeAndAddUTF16CodeUnit(code_unit); |
849 } else if (Utf16::IsLeadSurrogate(code_unit)) { | 851 } else if (Utf16::IsLeadSurrogate(code_unit)) { |
850 if (i + 1 == limit) { | 852 if (i + 1 == limit) { |
851 buffer_.EscapeAndAddUTF16CodeUnit(code_unit); | 853 buffer_.EscapeAndAddUTF16CodeUnit(code_unit); |
852 } else { | 854 } else { |
853 uint16_t next_code_unit = s.CharAt(i+1); | 855 uint16_t next_code_unit = s.CharAt(i + 1); |
854 if (Utf16::IsTrailSurrogate(next_code_unit)) { | 856 if (Utf16::IsTrailSurrogate(next_code_unit)) { |
855 uint32_t decoded = Utf16::Decode(code_unit, next_code_unit); | 857 uint32_t decoded = Utf16::Decode(code_unit, next_code_unit); |
856 buffer_.EscapeAndAddCodeUnit(decoded); | 858 buffer_.EscapeAndAddCodeUnit(decoded); |
857 i++; | 859 i++; |
858 } else { | 860 } else { |
859 buffer_.EscapeAndAddUTF16CodeUnit(code_unit); | 861 buffer_.EscapeAndAddUTF16CodeUnit(code_unit); |
860 } | 862 } |
861 } | 863 } |
862 } else { | 864 } else { |
863 buffer_.EscapeAndAddCodeUnit(code_unit); | 865 buffer_.EscapeAndAddCodeUnit(code_unit); |
(...skipping 11 matching lines...) Expand all Loading... |
875 | 877 |
876 void JSONObject::AddFixedServiceId(const char* format, ...) const { | 878 void JSONObject::AddFixedServiceId(const char* format, ...) const { |
877 // Mark that this id is fixed. | 879 // Mark that this id is fixed. |
878 AddProperty("fixedId", true); | 880 AddProperty("fixedId", true); |
879 // Add the id property. | 881 // Add the id property. |
880 stream_->PrintPropertyName("id"); | 882 stream_->PrintPropertyName("id"); |
881 va_list args; | 883 va_list args; |
882 va_start(args, format); | 884 va_start(args, format); |
883 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 885 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
884 va_end(args); | 886 va_end(args); |
885 char* p = reinterpret_cast<char*>(malloc(len+1)); | 887 char* p = reinterpret_cast<char*>(malloc(len + 1)); |
886 va_start(args, format); | 888 va_start(args, format); |
887 intptr_t len2 = OS::VSNPrint(p, len+1, format, args); | 889 intptr_t len2 = OS::VSNPrint(p, len + 1, format, args); |
888 va_end(args); | 890 va_end(args); |
889 ASSERT(len == len2); | 891 ASSERT(len == len2); |
890 stream_->buffer_.AddChar('"'); | 892 stream_->buffer_.AddChar('"'); |
891 stream_->AddEscapedUTF8String(p); | 893 stream_->AddEscapedUTF8String(p); |
892 stream_->buffer_.AddChar('"'); | 894 stream_->buffer_.AddChar('"'); |
893 free(p); | 895 free(p); |
894 } | 896 } |
895 | 897 |
896 | 898 |
897 void JSONObject::AddLocation(const Script& script, | 899 void JSONObject::AddLocation(const Script& script, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 if (!script.IsNull()) { | 936 if (!script.IsNull()) { |
935 location.AddProperty("script", script); | 937 location.AddProperty("script", script); |
936 } else { | 938 } else { |
937 const String& scriptUri = String::Handle(zone, bpt_loc->url()); | 939 const String& scriptUri = String::Handle(zone, bpt_loc->url()); |
938 location.AddPropertyStr("scriptUri", scriptUri); | 940 location.AddPropertyStr("scriptUri", scriptUri); |
939 } | 941 } |
940 if (bpt_loc->requested_line_number() >= 0) { | 942 if (bpt_loc->requested_line_number() >= 0) { |
941 // This unresolved breakpoint was specified at a particular line. | 943 // This unresolved breakpoint was specified at a particular line. |
942 location.AddProperty("line", bpt_loc->requested_line_number()); | 944 location.AddProperty("line", bpt_loc->requested_line_number()); |
943 if (bpt_loc->requested_column_number() >= 0) { | 945 if (bpt_loc->requested_column_number() >= 0) { |
944 location.AddProperty("column", | 946 location.AddProperty("column", bpt_loc->requested_column_number()); |
945 bpt_loc->requested_column_number()); | |
946 } | 947 } |
947 } else { | 948 } else { |
948 // This unresolved breakpoint was requested at some function entry. | 949 // This unresolved breakpoint was requested at some function entry. |
949 location.AddProperty("tokenPos", token_pos); | 950 location.AddProperty("tokenPos", token_pos); |
950 } | 951 } |
951 } | 952 } |
952 | 953 |
953 | 954 |
954 void JSONObject::AddPropertyF(const char* name, | 955 void JSONObject::AddPropertyF(const char* name, const char* format, ...) const { |
955 const char* format, ...) const { | |
956 stream_->PrintPropertyName(name); | 956 stream_->PrintPropertyName(name); |
957 va_list args; | 957 va_list args; |
958 va_start(args, format); | 958 va_start(args, format); |
959 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 959 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
960 va_end(args); | 960 va_end(args); |
961 char* p = reinterpret_cast<char*>(malloc(len+1)); | 961 char* p = reinterpret_cast<char*>(malloc(len + 1)); |
962 va_start(args, format); | 962 va_start(args, format); |
963 intptr_t len2 = OS::VSNPrint(p, len+1, format, args); | 963 intptr_t len2 = OS::VSNPrint(p, len + 1, format, args); |
964 va_end(args); | 964 va_end(args); |
965 ASSERT(len == len2); | 965 ASSERT(len == len2); |
966 stream_->buffer_.AddChar('"'); | 966 stream_->buffer_.AddChar('"'); |
967 stream_->AddEscapedUTF8String(p); | 967 stream_->AddEscapedUTF8String(p); |
968 stream_->buffer_.AddChar('"'); | 968 stream_->buffer_.AddChar('"'); |
969 free(p); | 969 free(p); |
970 } | 970 } |
971 | 971 |
972 | 972 |
973 void JSONArray::AddValueF(const char* format, ...) const { | 973 void JSONArray::AddValueF(const char* format, ...) const { |
974 stream_->PrintCommaIfNeeded(); | 974 stream_->PrintCommaIfNeeded(); |
975 va_list args; | 975 va_list args; |
976 va_start(args, format); | 976 va_start(args, format); |
977 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 977 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
978 va_end(args); | 978 va_end(args); |
979 char* p = reinterpret_cast<char*>(malloc(len+1)); | 979 char* p = reinterpret_cast<char*>(malloc(len + 1)); |
980 va_start(args, format); | 980 va_start(args, format); |
981 intptr_t len2 = OS::VSNPrint(p, len+1, format, args); | 981 intptr_t len2 = OS::VSNPrint(p, len + 1, format, args); |
982 va_end(args); | 982 va_end(args); |
983 ASSERT(len == len2); | 983 ASSERT(len == len2); |
984 stream_->buffer_.AddChar('"'); | 984 stream_->buffer_.AddChar('"'); |
985 stream_->AddEscapedUTF8String(p); | 985 stream_->AddEscapedUTF8String(p); |
986 stream_->buffer_.AddChar('"'); | 986 stream_->buffer_.AddChar('"'); |
987 free(p); | 987 free(p); |
988 } | 988 } |
989 | 989 |
990 #endif // !PRODUCT | 990 #endif // !PRODUCT |
991 | 991 |
992 } // namespace dart | 992 } // namespace dart |
OLD | NEW |