| Index: runtime/platform/text_buffer.cc | 
| diff --git a/runtime/platform/text_buffer.cc b/runtime/platform/text_buffer.cc | 
| index 1536dac13b3adb2f7a329e1eb3b30a4abe86b2cb..9cbb5773da14daaf8dd5e8ddcfb2703070bce410 100644 | 
| --- a/runtime/platform/text_buffer.cc | 
| +++ b/runtime/platform/text_buffer.cc | 
| @@ -8,6 +8,7 @@ | 
| #include "platform/globals.h" | 
| #include "platform/utils.h" | 
| #include "vm/os.h" | 
| +#include "vm/unicode.h" | 
|  | 
| namespace dart { | 
|  | 
| @@ -78,60 +79,52 @@ intptr_t TextBuffer::Printf(const char* format, ...) { | 
| return len; | 
| } | 
|  | 
| - | 
| -// Write a UTF-16 code unit so it can be read by a JSON parser in a string | 
| -// literal. Use escape sequences for characters other than printable ASCII. | 
| +// Write a UTF-32 code unit so it can be read by a JSON parser in a string | 
| +// literal. Use official encoding from JSON specification. http://json.org/ | 
| void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) { | 
| switch (codeunit) { | 
| case '"': | 
| -      Printf("%s", "\\\""); | 
| +      AddRaw(reinterpret_cast<uint8_t const*>("\\\""), 2); | 
| break; | 
| case '\\': | 
| -      Printf("%s", "\\\\"); | 
| +      AddRaw(reinterpret_cast<uint8_t const*>("\\\\"), 2); | 
| break; | 
| case '/': | 
| -      Printf("%s", "\\/"); | 
| +      AddRaw(reinterpret_cast<uint8_t const*>("\\/"), 2); | 
| break; | 
| case '\b': | 
| -      Printf("%s", "\\b"); | 
| +      AddRaw(reinterpret_cast<uint8_t const*>("\\b"), 2); | 
| break; | 
| case '\f': | 
| -      Printf("%s", "\\f"); | 
| +      AddRaw(reinterpret_cast<uint8_t const*>("\\f"), 2); | 
| break; | 
| case '\n': | 
| -      Printf("%s", "\\n"); | 
| +      AddRaw(reinterpret_cast<uint8_t const*>("\\n"), 2); | 
| break; | 
| case '\r': | 
| -      Printf("%s", "\\r"); | 
| +      AddRaw(reinterpret_cast<uint8_t const*>("\\r"), 2); | 
| break; | 
| case '\t': | 
| -      Printf("%s", "\\t"); | 
| +      AddRaw(reinterpret_cast<uint8_t const*>("\\t"), 2); | 
| break; | 
| default: | 
| if (codeunit < 0x20) { | 
| -        // Encode character as \u00HH. | 
| -        uint32_t digit2 = (codeunit >> 4) & 0xf; | 
| -        uint32_t digit3 = (codeunit & 0xf); | 
| -        Printf("\\u00%c%c", | 
| -               digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, | 
| -               digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); | 
| -      } else if (codeunit > 127) { | 
| -        // Encode character as \uHHHH. | 
| -        uint32_t digit0 = (codeunit >> 12) & 0xf; | 
| -        uint32_t digit1 = (codeunit >> 8) & 0xf; | 
| -        uint32_t digit2 = (codeunit >> 4) & 0xf; | 
| -        uint32_t digit3 = (codeunit & 0xf); | 
| -        Printf("\\u%c%c%c%c", | 
| -               digit0 > 9 ? 'A' + (digit0 - 10) : '0' + digit0, | 
| -               digit1 > 9 ? 'A' + (digit1 - 10) : '0' + digit1, | 
| -               digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, | 
| -               digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); | 
| +        EscapeAndAddUTF16CodeUnit(codeunit); | 
| } else { | 
| -        AddChar(codeunit); | 
| +        char encoded[6]; | 
| +        intptr_t length = Utf8::Length(codeunit); | 
| +        Utf8::Encode(codeunit, encoded); | 
| +        AddRaw(reinterpret_cast<uint8_t const*>(encoded), length); | 
| } | 
| } | 
| } | 
|  | 
| +// Write an incomplete UTF-16 code unit so it can be read by a JSON parser in a | 
| +// string literal. | 
| +void TextBuffer::EscapeAndAddUTF16CodeUnit(uint16_t codeunit) { | 
| +  Printf("\\u%04X", codeunit); | 
| +} | 
| + | 
|  | 
| void TextBuffer::AddString(const char* s) { | 
| Printf("%s", s); | 
|  |