15ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// Copyright 2010 the V8 project authors. All rights reserved.
25ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// Redistribution and use in source and binary forms, with or without
35ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// modification, are permitted provided that the following conditions are
45ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// met:
55ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//
65ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//     * Redistributions of source code must retain the above copyright
75ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//       notice, this list of conditions and the following disclaimer.
85ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//     * Redistributions in binary form must reproduce the above
95ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//       copyright notice, this list of conditions and the following
105ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//       disclaimer in the documentation and/or other materials provided
115ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//       with the distribution.
125ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//     * Neither the name of Google Inc. nor the names of its
135ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//       contributors may be used to endorse or promote products derived
145ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//       from this software without specific prior written permission.
155ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org//
165ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
28e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// Flags: --expose-externalize-string --expose-gc
295ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
305ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvar size = 1024;
315ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
325ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgfunction test() {
335ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  var str = "";
345ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
355ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Build an ascii cons string.
365ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  for (var i = 0; i < size; i++) {
375ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org      str += String.fromCharCode(i & 0x7f);
385ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  }
392c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertTrue(isOneByteString(str));
405ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
412c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  var twoByteExternalWithOneByteData =
421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      "AA" + (function() { return "A"; })();
432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  externalizeString(twoByteExternalWithOneByteData, true /* force two-byte */);
442c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertFalse(isOneByteString(twoByteExternalWithOneByteData));
455ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
465ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  var realTwoByteExternalString =
470ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      "\u1234\u1234\u1234\u1234" + (function() { return "\u1234"; })();
485ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  externalizeString(realTwoByteExternalString);
492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertFalse(isOneByteString(realTwoByteExternalString));
505ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertTrue(isOneByteString(["a", twoByteExternalWithOneByteData].join("")));
525ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
535ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Appending a two-byte string that contains only ascii chars should
545ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // still produce an ascii cons.
552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  var str1 = str + twoByteExternalWithOneByteData;
562c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertTrue(isOneByteString(str1));
575ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
585ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Force flattening of the string.
592c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  var old_length = str1.length - twoByteExternalWithOneByteData.length;
605ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  for (var i = 0; i < old_length; i++) {
615ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org    assertEquals(String.fromCharCode(i & 0x7f), str1[i]);
625ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  }
635ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  for (var i = old_length; i < str1.length; i++) {
645ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org    assertEquals("A", str1[i]);
655ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  }
665ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
675ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Flattened string should still be ascii.
682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertTrue(isOneByteString(str1));
695ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
705ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Lower-casing an ascii string should produce ascii.
712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertTrue(isOneByteString(str1.toLowerCase()));
725ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertFalse(isOneByteString(["a", realTwoByteExternalString].join("")));
745ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
755ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Appending a real two-byte string should produce a two-byte cons.
765ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  var str2 = str + realTwoByteExternalString;
772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertFalse(isOneByteString(str2));
785ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
795ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Force flattening of the string.
805ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  old_length = str2.length - realTwoByteExternalString.length;
815ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  for (var i = 0; i < old_length; i++) {
825ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org    assertEquals(String.fromCharCode(i & 0x7f), str2[i]);
835ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  }
845ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  for (var i = old_length; i < str.length; i++) {
855ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org    assertEquals("\u1234", str2[i]);
865ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  }
875ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
885ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Flattened string should still be two-byte.
892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  assertFalse(isOneByteString(str2));
905ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
915ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
925ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// Run the test many times to ensure IC-s don't break things.
935ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgfor (var i = 0; i < 10; i++) {
945ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  test();
955ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
96e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
97e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// Clean up string to make Valgrind happy.
98e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orggc();
99e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orggc();
100