Revision: 4734
Author: [email protected]
Date: Wed May 26 09:11:30 2010
Log: Fix: make string indexing work with Infinity.
NumberToUint32 that I was trying to use maps -0 to +0 (as desired) but
also maps +/-Infinity to +0, which made +/-Infinity a valid string
index. I fixed it by introducing a new runtime function with the right
semantics.
TEST=LayoutTests/fast/js/char-at.html,mjsunit/string-charat.js
Review URL: http://codereview.chromium.org/2223003
http://code.google.com/p/v8/source/detail?r=4734
Modified:
/branches/bleeding_edge/src/arm/codegen-arm.cc
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
/branches/bleeding_edge/src/x64/codegen-x64.cc
/branches/bleeding_edge/test/mjsunit/string-charat.js
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc Wed May 26 07:23:19 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc Wed May 26 09:11:30 2010
@@ -9284,11 +9284,7 @@
__ Push(object_, index_, result_);
__ push(index_); // Consumed by runtime conversion function.
if (index_flags_ == STRING_INDEX_IS_NUMBER) {
- // Strictly speaking, NumberToInteger should be called here, but
- // our string lengths don't exceed 32 bits and using ToUint32 maps
- // -0 to 0, which is what is required by the spec when accessing
- // strings.
- __ CallRuntime(Runtime::kNumberToJSUint32, 1);
+ __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
} else {
ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
// NumberToSmi discards numbers that are not exact integers.
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed May 26 07:23:19
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed May 26 09:11:30
2010
@@ -12655,11 +12655,7 @@
__ push(result_);
__ push(index_); // Consumed by runtime conversion function.
if (index_flags_ == STRING_INDEX_IS_NUMBER) {
- // Strictly speaking, NumberToInteger should be called here, but
- // our string lengths don't exceed 32 bits and using ToUint32 maps
- // -0 to 0, which is what is required by the spec when accessing
- // strings.
- __ CallRuntime(Runtime::kNumberToJSUint32, 1);
+ __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
} else {
ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
// NumberToSmi discards numbers that are not exact integers.
=======================================
--- /branches/bleeding_edge/src/runtime.cc Wed May 26 02:24:44 2010
+++ /branches/bleeding_edge/src/runtime.cc Wed May 26 09:11:30 2010
@@ -5285,6 +5285,25 @@
}
return Heap::NumberFromDouble(DoubleToInteger(number));
}
+
+
+static Object* Runtime_NumberToIntegerMapMinusZero(Arguments args) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 1);
+
+ CONVERT_DOUBLE_CHECKED(number, args[0]);
+
+ // We do not include 0 so that we don't have to treat +0 / -0 cases.
+ if (number > 0 && number <= Smi::kMaxValue) {
+ return Smi::FromInt(static_cast<int>(number));
+ }
+
+ double double_value = DoubleToInteger(number);
+ // Map both -0 and +0 to +0.
+ if (double_value == 0) double_value = 0;
+
+ return Heap::NumberFromDouble(double_value);
+}
static Object* Runtime_NumberToJSUint32(Arguments args) {
=======================================
--- /branches/bleeding_edge/src/runtime.h Thu Apr 29 08:14:39 2010
+++ /branches/bleeding_edge/src/runtime.h Wed May 26 09:11:30 2010
@@ -102,6 +102,7 @@
F(NumberToString, 1, 1) \
F(NumberToStringSkipCache, 1, 1) \
F(NumberToInteger, 1, 1) \
+ F(NumberToIntegerMapMinusZero, 1, 1) \
F(NumberToJSUint32, 1, 1) \
F(NumberToJSInt32, 1, 1) \
F(NumberToSmi, 1, 1) \
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc Wed May 26 07:23:19 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc Wed May 26 09:11:30 2010
@@ -10935,11 +10935,7 @@
__ push(result_);
__ push(index_); // Consumed by runtime conversion function.
if (index_flags_ == STRING_INDEX_IS_NUMBER) {
- // Strictly speaking, NumberToInteger should be called here, but
- // our string lengths don't exceed 32 bits and using ToUint32 maps
- // -0 to 0, which is what is required by the spec when accessing
- // strings.
- __ CallRuntime(Runtime::kNumberToJSUint32, 1);
+ __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
} else {
ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
// NumberToSmi discards numbers that are not exact integers.
=======================================
--- /branches/bleeding_edge/test/mjsunit/string-charat.js Wed May 26
07:23:19 2010
+++ /branches/bleeding_edge/test/mjsunit/string-charat.js Wed May 26
09:11:30 2010
@@ -41,6 +41,8 @@
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));
@@ -67,6 +69,8 @@
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)));
}
basicTest();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev