Revision: 5554
Author: [email protected]
Date: Wed Sep 29 09:04:15 2010
Log: Backport r5553 "Do not invoke indexed interceptor getters for negative
indices" to 2.1.
Review URL: http://codereview.chromium.org/3587002
http://code.google.com/p/v8/source/detail?r=5554
Modified:
/branches/2.1/src/arm/ic-arm.cc
/branches/2.1/src/globals.h
/branches/2.1/src/ia32/ic-ia32.cc
/branches/2.1/src/stub-cache.cc
/branches/2.1/src/version.cc
/branches/2.1/src/x64/ic-x64.cc
/branches/2.1/test/cctest/test-api.cc
=======================================
--- /branches/2.1/src/arm/ic-arm.cc Fri Mar 26 02:27:16 2010
+++ /branches/2.1/src/arm/ic-arm.cc Wed Sep 29 09:04:15 2010
@@ -1004,8 +1004,9 @@
// Check that the receiver isn't a smi.
__ BranchOnSmi(r1, &slow);
- // Check that the key is a smi.
- __ BranchOnNotSmi(r0, &slow);
+ // Check that the key is an array index, that is Uint32.
+ __ tst(r0, Operand(kSmiTagMask | kSmiSignMask));
+ __ b(ne, &slow);
// Get the map of the receiver.
__ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
=======================================
--- /branches/2.1/src/globals.h Wed Mar 24 01:21:20 2010
+++ /branches/2.1/src/globals.h Wed Sep 29 09:04:15 2010
@@ -146,6 +146,9 @@
const intptr_t kIntptrSignBit = 0x80000000;
#endif
+// Mask for the sign bit in a smi.
+const intptr_t kSmiSignMask = kIntptrSignBit;
+
const int kObjectAlignmentBits = kPointerSizeLog2;
const intptr_t kObjectAlignment = 1 << kObjectAlignmentBits;
const intptr_t kObjectAlignmentMask = kObjectAlignment - 1;
=======================================
--- /branches/2.1/src/ia32/ic-ia32.cc Fri Mar 26 02:27:16 2010
+++ /branches/2.1/src/ia32/ic-ia32.cc Wed Sep 29 09:04:15 2010
@@ -694,8 +694,8 @@
__ test(edx, Immediate(kSmiTagMask));
__ j(zero, &slow, not_taken);
- // Check that the key is a smi.
- __ test(eax, Immediate(kSmiTagMask));
+ // Check that the key is an array index, that is Uint32.
+ __ test(eax, Immediate(kSmiTagMask | kSmiSignMask));
__ j(not_zero, &slow, not_taken);
// Get the map of the receiver.
=======================================
--- /branches/2.1/src/stub-cache.cc Fri Mar 26 02:27:16 2010
+++ /branches/2.1/src/stub-cache.cc Wed Sep 29 09:04:15 2010
@@ -925,6 +925,7 @@
Object* KeyedLoadPropertyWithInterceptor(Arguments args) {
JSObject* receiver = JSObject::cast(args[0]);
+ ASSERT(Smi::cast(args[1])->value() >= 0);
uint32_t index = Smi::cast(args[1])->value();
return receiver->GetElementWithInterceptor(receiver, index);
}
=======================================
--- /branches/2.1/src/version.cc Wed Aug 18 00:35:42 2010
+++ /branches/2.1/src/version.cc Wed Sep 29 09:04:15 2010
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 2
#define MINOR_VERSION 1
#define BUILD_NUMBER 10
-#define PATCH_LEVEL 16
+#define PATCH_LEVEL 17
#define CANDIDATE_VERSION false
// Define SONAME to have the SCons build the put a specific SONAME into the
=======================================
--- /branches/2.1/src/x64/ic-x64.cc Fri Mar 26 02:27:16 2010
+++ /branches/2.1/src/x64/ic-x64.cc Wed Sep 29 09:04:15 2010
@@ -683,8 +683,8 @@
// Check that the receiver isn't a smi.
__ JumpIfSmi(rcx, &slow);
- // Check that the key is a smi.
- __ JumpIfNotSmi(rax, &slow);
+ // Check that the key is an array index, that is Uint32.
+ __ JumpIfNotPositiveSmi(rax, &slow);
// Get the map of the receiver.
__ movq(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
=======================================
--- /branches/2.1/test/cctest/test-api.cc Fri Mar 26 02:27:16 2010
+++ /branches/2.1/test/cctest/test-api.cc Wed Sep 29 09:04:15 2010
@@ -2755,7 +2755,7 @@
static v8::Handle<Value> IdentityIndexedPropertyGetter(
uint32_t index,
const AccessorInfo& info) {
- return v8::Integer::New(index);
+ return v8::Integer::NewFromUnsigned(index);
}
@@ -2857,6 +2857,45 @@
"}";
ExpectString(code, "PASSED");
}
+
+
+THREADED_TEST(IndexedInterceptorWithNegativeIndices) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+ LocalContext context;
+ Local<v8::Object> obj = templ->NewInstance();
+ context->Global()->Set(v8_str("obj"), obj);
+
+ const char* code =
+ "try {"
+ " for (var i = 0; i < 100; i++) {"
+ " var expected = i;"
+ " var key = i;"
+ " if (i == 25) {"
+ " key = -1;"
+ " expected = undefined;"
+ " }"
+ " if (i == 50) {"
+ " /* probe minimal Smi number on 32-bit platforms */"
+ " key = -(1 << 30);"
+ " expected = undefined;"
+ " }"
+ " if (i == 75) {"
+ " /* probe minimal Smi number on 64-bit platforms */"
+ " key = 1 << 31;"
+ " expected = undefined;"
+ " }"
+ " var v = obj[key];"
+ " if (v != expected) throw 'Wrong value ' + v + ' at iteration '
+ i;"
+ " }"
+ " 'PASSED'"
+ "} catch(e) {"
+ " e"
+ "}";
+ ExpectString(code, "PASSED");
+}
THREADED_TEST(IndexedInterceptorWithNotSmiLookup) {
@@ -2872,11 +2911,12 @@
"try {"
" for (var i = 0; i < 100; i++) {"
" var expected = i;"
+ " var key = i;"
" if (i == 50) {"
- " i = 'foobar';"
+ " key = 'foobar';"
" expected = undefined;"
" }"
- " var v = obj[i];"
+ " var v = obj[key];"
" if (v != expected) throw 'Wrong value ' + v + ' at iteration '
+ i;"
" }"
" 'PASSED'"
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev