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
This commit is contained in:
parent
ef135e5351
commit
3567207741
@ -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'"
|
||||
|
Loading…
Reference in New Issue
Block a user