Correctly stringify mixed encoding indirect strings.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 9 Sep 2013 16:15:40 +0000 (16:15 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 9 Sep 2013 16:15:40 +0000 (16:15 +0000)
R=verwaest@chromium.org
BUG=287476

Review URL: https://codereview.chromium.org/23480051

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16598 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/json-stringifier.h
test/cctest/test-strings.cc

index 155ae5f..0d17b35 100644 (file)
@@ -835,14 +835,14 @@ Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) {
 void BasicJsonStringifier::SerializeString(Handle<String> object) {
   object = FlattenGetString(object);
   if (is_ascii_) {
-    if (object->IsOneByteRepresentation()) {
+    if (object->IsOneByteRepresentationUnderneath()) {
       SerializeString_<true, uint8_t>(object);
     } else {
       ChangeEncoding();
       SerializeString(object);
     }
   } else {
-    if (object->IsOneByteRepresentation()) {
+    if (object->IsOneByteRepresentationUnderneath()) {
       SerializeString_<false, uint8_t>(object);
     } else {
       SerializeString_<false, uc16>(object);
index 310d93c..726188d 100644 (file)
@@ -1017,6 +1017,36 @@ TEST(ExternalShortStringAdd) {
 }
 
 
+TEST(JSONStringifySliceMadeExternal) {
+  Isolate* isolate = Isolate::Current();
+  Zone zone(isolate);
+  CcTest::InitializeVM();
+  // Create a sliced string from a one-byte string.  The latter is turned
+  // into a two-byte external string.  Check that JSON.stringify works.
+  v8::HandleScope handle_scope(CcTest::isolate());
+  v8::Handle<v8::String> underlying =
+      CompileRun("var underlying = 'abcdefghijklmnopqrstuvwxyz';"
+                 "underlying")->ToString();
+  v8::Handle<v8::String> slice =
+      CompileRun("var slice = underlying.slice(1);"
+                 "slice")->ToString();
+  CHECK(v8::Utils::OpenHandle(*slice)->IsSlicedString());
+  CHECK(v8::Utils::OpenHandle(*underlying)->IsSeqOneByteString());
+
+  int length = underlying->Length();
+  uc16* two_byte = zone.NewArray<uc16>(length + 1);
+  underlying->Write(two_byte);
+  Resource* resource =
+      new(&zone) Resource(Vector<const uc16>(two_byte, length));
+  CHECK(underlying->MakeExternal(resource));
+  CHECK(v8::Utils::OpenHandle(*slice)->IsSlicedString());
+  CHECK(v8::Utils::OpenHandle(*underlying)->IsExternalTwoByteString());
+
+  CHECK_EQ("\"bcdefghijklmnopqrstuvwxyz\"",
+           *v8::String::Utf8Value(CompileRun("JSON.stringify(slice)")));
+}
+
+
 TEST(CachedHashOverflow) {
   // We incorrectly allowed strings to be tagged as array indices even if their
   // values didn't fit in the hash field.