Revision: 5553
Author: [email protected]
Date: Wed Sep 29 08:08:38 2010
Log: Do not invoke indexed interceptor getters for negative indices.

BUG=https://bugs.webkit.org/show_bug.cgi?id=46689

Review URL: http://codereview.chromium.org/3520006
http://code.google.com/p/v8/source/detail?r=5553

Modified:
 /branches/bleeding_edge/src/arm/ic-arm.cc
 /branches/bleeding_edge/src/ia32/ic-ia32.cc
 /branches/bleeding_edge/src/stub-cache.cc
 /branches/bleeding_edge/src/x64/ic-x64.cc
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/src/arm/ic-arm.cc   Mon Sep 20 06:50:27 2010
+++ /branches/bleeding_edge/src/arm/ic-arm.cc   Wed Sep 29 08:08:38 2010
@@ -1584,8 +1584,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/bleeding_edge/src/ia32/ic-ia32.cc Mon Sep 20 06:50:27 2010
+++ /branches/bleeding_edge/src/ia32/ic-ia32.cc Wed Sep 29 08:08:38 2010
@@ -885,8 +885,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/bleeding_edge/src/stub-cache.cc   Fri Sep 24 04:45:12 2010
+++ /branches/bleeding_edge/src/stub-cache.cc   Wed Sep 29 08:08:38 2010
@@ -988,6 +988,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/bleeding_edge/src/x64/ic-x64.cc   Mon Sep 20 06:50:27 2010
+++ /branches/bleeding_edge/src/x64/ic-x64.cc   Wed Sep 29 08:08:38 2010
@@ -893,8 +893,8 @@
   // Check that the receiver isn't a smi.
   __ JumpIfSmi(rdx, &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(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Fri Sep 24 01:18:33 2010
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Wed Sep 29 08:08:38 2010
@@ -3061,7 +3061,7 @@
 static v8::Handle<Value> IdentityIndexedPropertyGetter(
     uint32_t index,
     const AccessorInfo& info) {
-  return v8::Integer::New(index);
+  return v8::Integer::NewFromUnsigned(index);
 }


@@ -3184,6 +3184,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) {
@@ -3199,11 +3238,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

Reply via email to