}
-static Object* CharCodeAt(String* subject, Object* index) {
- uint32_t i = 0;
- if (!index->ToArrayIndex(&i)) return Heap::nan_value();
- // Flatten the string. If someone wants to get a char at an index
- // in a cons string, it is likely that more indices will be
- // accessed.
- Object* flat = subject->TryFlatten();
- if (flat->IsFailure()) return flat;
- subject = String::cast(flat);
- if (i >= static_cast<uint32_t>(subject->length())) {
- return Heap::nan_value();
- }
- return Smi::FromInt(subject->Get(i));
-}
-
-
static Object* CharFromCode(Object* char_code) {
uint32_t code;
if (char_code->ToArrayIndex(&code)) {
CONVERT_CHECKED(String, subject, args[0]);
Object* index = args[1];
- return CharCodeAt(subject, index);
-}
+ RUNTIME_ASSERT(index->IsNumber());
+ uint32_t i = 0;
+ if (index->IsSmi()) {
+ int value = Smi::cast(index)->value();
+ if (value < 0) return Heap::nan_value();
+ i = value;
+ } else {
+ ASSERT(index->IsHeapNumber());
+ double value = HeapNumber::cast(index)->value();
+ i = static_cast<uint32_t>(value);
+ }
-static Object* Runtime_StringCharAt(Arguments args) {
- NoHandleAllocation ha;
- ASSERT(args.length() == 2);
+ // Flatten the string. If someone wants to get a char at an index
+ // in a cons string, it is likely that more indices will be
+ // accessed.
+ Object* flat = subject->TryFlatten();
+ if (flat->IsFailure()) return flat;
+ subject = String::cast(flat);
- CONVERT_CHECKED(String, subject, args[0]);
- Object* index = args[1];
- Object* code = CharCodeAt(subject, index);
- if (code == Heap::nan_value()) {
- return Heap::undefined_value();
+ if (i >= static_cast<uint32_t>(subject->length())) {
+ return Heap::nan_value();
}
- return CharFromCode(code);
+
+ return Smi::FromInt(subject->Get(i));
}
}
+
+
+
static Object* Runtime_NumberToIntegerMapMinusZero(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
var s = "test";
+function getTwoByteString() { return "\u1234t"; }
+function getCons() { return "testtesttesttest" + getTwoByteString() }
+
var slowIndex1 = { valueOf: function() { return 1; } };
var slowIndex2 = { toString: function() { return "2"; } };
var slowIndexOutOfRange = { valueOf: function() { return -1; } };
-function basicTest() {
- assertEquals("t", s.charAt());
- assertEquals("t", s.charAt("string"));
- assertEquals("t", s.charAt(null));
- assertEquals("t", s.charAt(void 0));
- assertEquals("t", s.charAt(false));
- assertEquals("e", s.charAt(true));
- assertEquals("", s.charAt(-1));
- assertEquals("", s.charAt(4));
- assertEquals("", s.charAt(slowIndexOutOfRange));
- assertEquals("", s.charAt(1/0));
- assertEquals("", s.charAt(-1/0));
- assertEquals("t", s.charAt(0));
- assertEquals("t", s.charAt(-0.0));
- assertEquals("t", s.charAt(0.4));
- assertEquals("e", s.charAt(slowIndex1));
- assertEquals("s", s.charAt(slowIndex2));
- assertEquals("t", s.charAt(3));
- assertEquals("t", s.charAt(3.4));
- assertEquals("t", s.charAt(NaN));
-
- assertEquals(116, s.charCodeAt());
- assertEquals(116, s.charCodeAt("string"));
- assertEquals(116, s.charCodeAt(null));
- assertEquals(116, s.charCodeAt(void 0));
- assertEquals(116, s.charCodeAt(false));
- assertEquals(101, s.charCodeAt(true));
- assertEquals(116, s.charCodeAt(0));
- assertEquals(116, s.charCodeAt(-0.0));
- assertEquals(116, s.charCodeAt(0.4));
- assertEquals(101, s.charCodeAt(slowIndex1));
- assertEquals(115, s.charCodeAt(slowIndex2));
- assertEquals(116, s.charCodeAt(3));
- assertEquals(116, s.charCodeAt(3.4));
- assertEquals(116, s.charCodeAt(NaN));
- assertTrue(isNaN(s.charCodeAt(-1)));
- assertTrue(isNaN(s.charCodeAt(4)));
- assertTrue(isNaN(s.charCodeAt(slowIndexOutOfRange)));
- assertTrue(isNaN(s.charCodeAt(1/0)));
- assertTrue(isNaN(s.charCodeAt(-1/0)));
+function basicTest(s, len) {
+ assertEquals("t", s().charAt());
+ assertEquals("t", s().charAt("string"));
+ assertEquals("t", s().charAt(null));
+ assertEquals("t", s().charAt(void 0));
+ assertEquals("t", s().charAt(false));
+ assertEquals("e", s().charAt(true));
+ assertEquals("", s().charAt(-1));
+ assertEquals("", s().charAt(len));
+ assertEquals("", s().charAt(slowIndexOutOfRange));
+ assertEquals("", s().charAt(1/0));
+ assertEquals("", s().charAt(-1/0));
+ assertEquals("t", s().charAt(0));
+ assertEquals("t", s().charAt(-0.0));
+ assertEquals("t", s().charAt(0.4));
+ assertEquals("e", s().charAt(slowIndex1));
+ assertEquals("s", s().charAt(slowIndex2));
+ assertEquals("t", s().charAt(3));
+ assertEquals("t", s().charAt(3.4));
+ assertEquals("t", s().charAt(NaN));
+
+ assertEquals(116, s().charCodeAt());
+ assertEquals(116, s().charCodeAt("string"));
+ assertEquals(116, s().charCodeAt(null));
+ assertEquals(116, s().charCodeAt(void 0));
+ assertEquals(116, s().charCodeAt(false));
+ assertEquals(101, s().charCodeAt(true));
+ assertEquals(116, s().charCodeAt(0));
+ assertEquals(116, s().charCodeAt(-0.0));
+ assertEquals(116, s().charCodeAt(0.4));
+ assertEquals(101, s().charCodeAt(slowIndex1));
+ assertEquals(115, s().charCodeAt(slowIndex2));
+ assertEquals(116, s().charCodeAt(3));
+ assertEquals(116, s().charCodeAt(3.4));
+ assertEquals(116, s().charCodeAt(NaN));
+ assertTrue(isNaN(s().charCodeAt(-1)));
+ assertTrue(isNaN(s().charCodeAt(len)));
+ assertTrue(isNaN(s().charCodeAt(slowIndexOutOfRange)));
+ assertTrue(isNaN(s().charCodeAt(1/0)));
+ assertTrue(isNaN(s().charCodeAt(-1/0)));
}
-basicTest();
+basicTest(function() { return s; }, s.length);
+basicTest(getCons, getCons().length);
// Make sure enough of the one-char string cache is filled.
var alpha = ['@'];
// Test custom string IC-s.
for (var i = 0; i < 20; i++) {
- basicTest();
+ basicTest(function() { return s; }, s.length);
+ basicTest(getCons, getCons().length);
stealTest();
}