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