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