Index: test/cctest/test-strings.cc |
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc |
index 310d93c04ea8b9cadda0c1cbad1d3e25658b923f..f9d8fe630509c9944e7c5a4734cc002fce46f6b5 100644 |
--- a/test/cctest/test-strings.cc |
+++ b/test/cctest/test-strings.cc |
@@ -1017,6 +1017,64 @@ TEST(ExternalShortStringAdd) { |
} |
+TEST(JSONStringifySliceMadeExternal) { |
+ Isolate* isolate = Isolate::Current(); |
+ Zone zone(isolate); |
+ CcTest::InitializeVM(); |
+ |
+ // Create a sliced string from a two-byte string. The latter is turned |
+ // into a one-byte external string. Check that JSON.stringify works. |
+ { v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::Handle<v8::String> underlying = |
+ CompileRun("var underlying = '\u2603bcdefghijklmnopqrstuvwxyz';" |
+ "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)->IsSeqTwoByteString()); |
+ |
+ int length = underlying->Length(); |
+ uint8_t* one_byte = zone.NewArray<uint8_t>(length + 1); |
+ underlying->WriteOneByte(one_byte); |
+ AsciiResource* resource = |
+ new(&zone) AsciiResource(Vector<const char>( |
+ reinterpret_cast<char*>(one_byte), length)); |
+ CHECK(underlying->MakeExternal(resource)); |
+ CHECK(v8::Utils::OpenHandle(*slice)->IsSlicedString()); |
+ CHECK(v8::Utils::OpenHandle(*underlying)->IsExternalAsciiString()); |
+ |
+ CHECK_EQ("\"bcdefghijklmnopqrstuvwxyz\"", |
+ *v8::String::Utf8Value(CompileRun("JSON.stringify(slice)"))); |
+ } |
+ |
+ // 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. |