19dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// Copyright 2010 the V8 project authors. All rights reserved.
29dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// Redistribution and use in source and binary forms, with or without
39dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// modification, are permitted provided that the following conditions are
49dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// met:
59dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//
69dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//     * Redistributions of source code must retain the above copyright
79dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//       notice, this list of conditions and the following disclaimer.
89dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//     * Redistributions in binary form must reproduce the above
99dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//       copyright notice, this list of conditions and the following
109dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//       disclaimer in the documentation and/or other materials provided
119dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//       with the distribution.
129dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//     * Neither the name of Google Inc. nor the names of its
139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//       contributors may be used to endorse or promote products derived
149dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//       from this software without specific prior written permission.
159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen//
169dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
209dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
219dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
269dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
283e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu// Flags: --expose-externalize-string --expose-gc
299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvar size = 1024;
319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenfunction test() {
339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  var str = "";
349dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
359dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Build an ascii cons string.
369dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  for (var i = 0; i < size; i++) {
379dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen      str += String.fromCharCode(i & 0x7f);
389dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
399dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertTrue(isAsciiString(str));
409dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
419dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  var twoByteExternalWithAsciiData =
429dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen      "AA" + (function() { return "A"; })();
439dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  externalizeString(twoByteExternalWithAsciiData, true /* force two-byte */);
449dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertFalse(isAsciiString(twoByteExternalWithAsciiData));
459dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  var realTwoByteExternalString =
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "\u1234\u1234\u1234\u1234" + (function() { return "\u1234"; })();
489dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  externalizeString(realTwoByteExternalString);
499dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertFalse(isAsciiString(realTwoByteExternalString));
509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
519dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertTrue(isAsciiString(["a", twoByteExternalWithAsciiData].join("")));
529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
539dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Appending a two-byte string that contains only ascii chars should
549dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // still produce an ascii cons.
559dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  var str1 = str + twoByteExternalWithAsciiData;
569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertTrue(isAsciiString(str1));
579dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Force flattening of the string.
599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  var old_length = str1.length - twoByteExternalWithAsciiData.length;
609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  for (var i = 0; i < old_length; i++) {
619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    assertEquals(String.fromCharCode(i & 0x7f), str1[i]);
629dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
639dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  for (var i = old_length; i < str1.length; i++) {
649dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    assertEquals("A", str1[i]);
659dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
679dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Flattened string should still be ascii.
689dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertTrue(isAsciiString(str1));
699dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Lower-casing an ascii string should produce ascii.
719dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertTrue(isAsciiString(str1.toLowerCase()));
729dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
739dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertFalse(isAsciiString(["a", realTwoByteExternalString].join("")));
749dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
759dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Appending a real two-byte string should produce a two-byte cons.
769dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  var str2 = str + realTwoByteExternalString;
779dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertFalse(isAsciiString(str2));
789dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
799dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Force flattening of the string.
809dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  old_length = str2.length - realTwoByteExternalString.length;
819dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  for (var i = 0; i < old_length; i++) {
829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    assertEquals(String.fromCharCode(i & 0x7f), str2[i]);
839dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
849dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  for (var i = old_length; i < str.length; i++) {
859dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    assertEquals("\u1234", str2[i]);
869dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
879dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
889dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Flattened string should still be two-byte.
899dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  assertFalse(isAsciiString(str2));
909dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
919dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// Run the test many times to ensure IC-s don't break things.
939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenfor (var i = 0; i < 10; i++) {
949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  test();
959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
963e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
973e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu// Clean up string to make Valgrind happy.
983e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhugc();
993e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhugc();
100