Diff from the first attempt:

diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index f07018a..34b32be 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -536,11 +536,25 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
   __ EnterInternalFrame();
   __ push(receiver);
   __ push(index);
-  __ CallRuntime(Runtime::kStringCharCodeAt, 1);
+  __ CallRuntime(Runtime::kStringCharCodeAt, 2);
   ASSERT(!code.is(eax));
   __ mov(code, eax);
   __ LeaveInternalFrame();
-  __ jmp(&got_char_code);
+
+  // Check if the runtime call returned NaN char code. If yes, return
+  // undefined. Otherwise, we can continue.
+  if (FLAG_debug_code) {
+    ASSERT(kSmiTag == 0);
+    __ test(code, Immediate(kSmiTagMask));
+    __ j(zero, &got_char_code);
+    __ mov(scratch, FieldOperand(code, HeapObject::kMapOffset));
+    __ cmp(scratch, Factory::heap_number_map());
+    __ Assert(equal, "StringCharCodeAt must return smi or heap number");
+  }
+  __ cmp(code, Factory::nan_value());
+  __ j(not_equal, &got_char_code);
+  __ Set(eax, Immediate(Factory::undefined_value()));
+  __ ret(0);

   __ bind(&miss);
   GenerateMiss(masm);
diff --git a/test/mjsunit/string-index.js b/test/mjsunit/string-index.js
index 3ad71e0..6f11a5b 100644
--- a/test/mjsunit/string-index.js
+++ b/test/mjsunit/string-index.js
@@ -35,6 +35,14 @@ assertEquals("F", foo[0]);
 assertEquals("o", foo[1]);
 assertEquals("o", foo[2]);

+// Test string keyed load IC.
+for (var i = 0; i < 10; i++) {
+  assertEquals("F", foo[0]);
+  assertEquals("o", foo[1]);
+  assertEquals("o", foo[2]);
+  assertEquals("F", (foo[0] + "BarBazQuuxFooBarQuux")[0]);
+}
+
 assertEquals("F", foo["0" + ""], "string index");
 assertEquals("o", foo["1"], "string index");
 assertEquals("o", foo["2"], "string index");
@@ -178,9 +186,9 @@ for (var i = 0; i < 200; ++i) {
   assertEquals(expected, actual);
...skipping...
+  // undefined. Otherwise, we can continue.
+  if (FLAG_debug_code) {
+    ASSERT(kSmiTag == 0);
+    __ test(code, Immediate(kSmiTagMask));
+    __ j(zero, &got_char_code);
+    __ mov(scratch, FieldOperand(code, HeapObject::kMapOffset));
+    __ cmp(scratch, Factory::heap_number_map());
+    __ Assert(equal, "StringCharCodeAt must return smi or heap number");
+  }
+  __ cmp(code, Factory::nan_value());
+  __ j(not_equal, &got_char_code);
+  __ Set(eax, Immediate(Factory::undefined_value()));
+  __ ret(0);

   __ bind(&miss);
   GenerateMiss(masm);
diff --git a/test/mjsunit/string-index.js b/test/mjsunit/string-index.js
index 3ad71e0..6f11a5b 100644
--- a/test/mjsunit/string-index.js
+++ b/test/mjsunit/string-index.js
@@ -35,6 +35,14 @@ assertEquals("F", foo[0]);
 assertEquals("o", foo[1]);
 assertEquals("o", foo[2]);

+// Test string keyed load IC.
+for (var i = 0; i < 10; i++) {
+  assertEquals("F", foo[0]);
+  assertEquals("o", foo[1]);
+  assertEquals("o", foo[2]);
+  assertEquals("F", (foo[0] + "BarBazQuuxFooBarQuux")[0]);
+}
+
 assertEquals("F", foo["0" + ""], "string index");
 assertEquals("o", foo["1"], "string index");
 assertEquals("o", foo["2"], "string index");
@@ -178,9 +186,9 @@ for (var i = 0; i < 200; ++i) {
   assertEquals(expected, actual);
 }

-var keys = [0, '1', 2, 3.0];
-var str = 'abcd', arr = ['a', 'b', 'c', 'd'];
-for (var i = 0; i < 200; ++i) {
+var keys = [0, '1', 2, 3.0, -1, 10];
+var str = 'abcd', arr = ['a', 'b', 'c', 'd', undefined, undefined];
+for (var i = 0; i < 300; ++i) {
   var index = Math.floor(i / 50);
   var key = keys[index];
   var expected = arr[index];


http://codereview.chromium.org/1582041/show

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to