Commit 35672077 authored by antonm@chromium.org's avatar antonm@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5553 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ef135e53
......@@ -1584,8 +1584,9 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
// 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));
......
......@@ -885,8 +885,8 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
__ 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.
......
......@@ -988,6 +988,7 @@ Object* StoreInterceptorProperty(Arguments args) {
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);
}
......
......@@ -893,8 +893,8 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
// 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));
......
......@@ -3061,7 +3061,7 @@ THREADED_TEST(IndexedInterceptorWithIndexedAccessor) {
static v8::Handle<Value> IdentityIndexedPropertyGetter(
uint32_t index,
const AccessorInfo& info) {
return v8::Integer::New(index);
return v8::Integer::NewFromUnsigned(index);
}
......@@ -3186,6 +3186,45 @@ THREADED_TEST(IndexedInterceptorWithDifferentIndices) {
}
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) {
v8::HandleScope scope;
Local<ObjectTemplate> templ = ObjectTemplate::New();
......@@ -3199,11 +3238,12 @@ THREADED_TEST(IndexedInterceptorWithNotSmiLookup) {
"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'"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment