1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2008 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar s = "test";
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction getTwoByteString() { return "\u1234t"; }
317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction getCons() { return "testtesttesttest" + getTwoByteString() }
327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvar slowIndex1 = { valueOf: function() { return 1; } };
347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvar slowIndex2 = { toString: function() { return "2"; } };
357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvar slowIndexOutOfRange = { valueOf: function() { return -1; } };
367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction basicTest(s, len) {
387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt());
397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt("string"));
407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(null));
417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(void 0));
427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(false));
437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("e", s().charAt(true));
447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("", s().charAt(-1));
457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("", s().charAt(len));
467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("", s().charAt(slowIndexOutOfRange));
477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("", s().charAt(1/0));
487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("", s().charAt(-1/0));
497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(0));
507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(-0.0));
517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(-0.1));
527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(0.4));
537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("e", s().charAt(slowIndex1));
547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("s", s().charAt(slowIndex2));
557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(3));
567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(3.4));
577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("t", s().charAt(NaN));
587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt());
607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt("string"));
617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(null));
627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(void 0));
637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(false));
647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(101, s().charCodeAt(true));
657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(0));
667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(-0.0));
677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(-0.1));
687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(0.4));
697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(101, s().charCodeAt(slowIndex1));
707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(115, s().charCodeAt(slowIndex2));
717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(3));
727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(3.4));
737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(116, s().charCodeAt(NaN));
747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(isNaN(s().charCodeAt(-1)));
757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(isNaN(s().charCodeAt(len)));
767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(isNaN(s().charCodeAt(slowIndexOutOfRange)));
777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(isNaN(s().charCodeAt(1/0)));
787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(isNaN(s().charCodeAt(-1/0)));
797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochbasicTest(function() { return s; }, s.length);
817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochbasicTest(getCons, getCons().length);
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Make sure enough of the one-char string cache is filled.
846ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvar alpha = ['@'];
856ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockfor (var i = 1; i < 128; i++) {
866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  var c = String.fromCharCode(i);
876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  alpha[i] = c.charAt(0);
886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
896ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvar alphaStr = alpha.join("");
906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Now test chars.
926ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockfor (var i = 1; i < 128; i++) {
936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  assertEquals(alpha[i], alphaStr.charAt(i));
946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  assertEquals(String.fromCharCode(i), alphaStr.charAt(i));
956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Test stealing String.prototype.{charAt,charCodeAt}.
987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvar o = {
997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  charAt: String.prototype.charAt,
1007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  charCodeAt: String.prototype.charCodeAt,
1017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  toString: function() { return "012"; },
1027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  valueOf: function() { return "should not be called"; }
1037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch};
1047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction stealTest() {
1067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("0", o.charAt(0));
1077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("1", o.charAt(1));
1087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("1", o.charAt(1.4));
1097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("1", o.charAt(slowIndex1));
1107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("2", o.charAt(2));
1117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("2", o.charAt(slowIndex2));
1127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(48, o.charCodeAt(0));
1137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(49, o.charCodeAt(1));
1147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(49, o.charCodeAt(1.4));
1157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(49, o.charCodeAt(slowIndex1));
1167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(50, o.charCodeAt(2));
1177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(50, o.charCodeAt(slowIndex2));
1187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("", o.charAt(-1));
1197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("", o.charAt(-1.4));
1207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("", o.charAt(10));
1217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("", o.charAt(slowIndexOutOfRange));
1227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(isNaN(o.charCodeAt(-1)));
1237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(isNaN(o.charCodeAt(-1.4)));
1247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(isNaN(o.charCodeAt(10)));
1257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(isNaN(o.charCodeAt(slowIndexOutOfRange)));
1267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
1277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochstealTest();
1287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Test custom string IC-s.
1307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfor (var i = 0; i < 20; i++) {
1317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  basicTest(function() { return s; }, s.length);
1327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  basicTest(getCons, getCons().length);
1337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  stealTest();
1347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
1357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvar badToString = function() { return []; };
1377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction testBadToString_charAt() {
1397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var goodToString = o.toString;
1407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var hasCaught = false;
1417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var numCalls = 0;
1427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var result;
1437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  try {
1447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    for (var i = 0; i < 20; i++) {
1457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      if (i == 10) o.toString = o.valueOf = badToString;
1467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      result = o.charAt(1);
1477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      numCalls++;
1487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
1497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } catch (e) {
1507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    hasCaught = true;
1517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } finally {
1527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    o.toString = goodToString;
1537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
1547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(hasCaught);
1557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("1", result);
1567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(10, numCalls);
1577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
1587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochtestBadToString_charAt();
1597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction testBadToString_charCodeAt() {
1617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var goodToString = o.toString;
1627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var hasCaught = false;
1637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var numCalls = 0;
1647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var result;
1657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  try {
1667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    for (var i = 0; i < 20; i++) {
1677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      if (i == 10) o.toString = o.valueOf = badToString;
1687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      result = o.charCodeAt(1);
1697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      numCalls++;
1707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
1717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } catch (e) {
1727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    hasCaught = true;
1737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } finally {
1747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    o.toString = goodToString;
1757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
1767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(hasCaught);
1777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(49, result);
1787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(10, numCalls);
1797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
1807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochtestBadToString_charCodeAt();
1817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvar badIndex = {
1837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  toString: badToString,
1847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  valueOf: badToString
1857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch};
1867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction testBadIndex_charAt() {
1887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var index = 1;
1897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var hasCaught = false;
1907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var numCalls = 0;
1917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var result;
1927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  try {
1937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    for (var i = 0; i < 20; i++) {
1947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      if (i == 10) index = badIndex;
1957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      result = o.charAt(index);
1967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      numCalls++;
1977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
1987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } catch (e) {
1997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    hasCaught = true;
2007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
2017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(hasCaught);
2027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("1", result);
2037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(10, numCalls);
2047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
2057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochtestBadIndex_charAt();
2067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction testBadIndex_charCodeAt() {
2087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var index = 1;
2097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var hasCaught = false;
2107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var numCalls = 0;
2117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var result;
2127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  try {
2137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    for (var i = 0; i < 20; i++) {
2147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      if (i == 10) index = badIndex;
2157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      result = o.charCodeAt(index);
2167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      numCalls++;
2177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
2187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } catch (e) {
2197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    hasCaught = true;
2207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
2217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertTrue(hasCaught);
2227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(49, result);
2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(10, numCalls);
2247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
2257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochtestBadIndex_charCodeAt();
2267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction testPrototypeChange_charAt() {
2287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var result, oldResult;
2297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  for (var i = 0; i < 20; i++) {
2307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    if (i == 10) {
2317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      oldResult = result;
2327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      String.prototype.charAt = function() { return "%"; };
2337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
2347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    result = s.charAt(1);
2357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
2367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("%", result);
2377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals("e", oldResult);
2387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  delete String.prototype.charAt;  // Restore the default.
2397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
2407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochtestPrototypeChange_charAt();
2417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction testPrototypeChange_charCodeAt() {
2437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  var result, oldResult;
2447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  for (var i = 0; i < 20; i++) {
2457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    if (i == 10) {
2467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      oldResult = result;
2477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      String.prototype.charCodeAt = function() { return 42; };
2487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
2497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    result = s.charCodeAt(1);
2507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
2517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(42, result);
2527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  assertEquals(101, oldResult);
2537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  delete String.prototype.charCodeAt;  // Restore the default.
2547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
2557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochtestPrototypeChange_charCodeAt();
256