Index: src/ic.cc |
=================================================================== |
--- src/ic.cc (revision 2306) |
+++ src/ic.cc (working copy) |
@@ -265,6 +265,39 @@ |
} |
+static bool HasInterceptorGetter(JSObject* object) { |
+ return !object->GetNamedInterceptor()->getter()->IsUndefined(); |
+} |
+ |
+ |
+static void LookupForRead(Object* object, |
+ String* name, |
+ LookupResult* lookup) { |
+ object->Lookup(name, lookup); |
+ if (lookup->IsNotFound() || lookup->type() != INTERCEPTOR) { |
+ return; |
+ } |
+ |
+ JSObject* holder = lookup->holder(); |
+ if (HasInterceptorGetter(holder)) { |
+ return; |
+ } |
+ |
+ // There is no getter, just skip it and lookup down the proto chain |
+ holder->LocalLookupRealNamedProperty(name, lookup); |
+ if (lookup->IsValid()) { |
+ return; |
+ } |
+ |
+ Object* proto = holder->GetPrototype(); |
+ if (proto == Heap::null_value()) { |
+ return; |
+ } |
+ |
+ LookupForRead(proto, name, lookup); |
+} |
+ |
+ |
Object* CallIC::TryCallAsFunction(Object* object) { |
HandleScope scope; |
Handle<Object> target(object); |
@@ -312,7 +345,7 @@ |
// Lookup the property in the object. |
LookupResult lookup; |
- object->Lookup(*name, &lookup); |
+ LookupForRead(*object, *name, &lookup); |
if (!lookup.IsValid()) { |
// If the object does not have the requested property, check which |
@@ -444,6 +477,7 @@ |
break; |
} |
case INTERCEPTOR: { |
+ ASSERT(HasInterceptorGetter(lookup->holder())); |
code = StubCache::ComputeCallInterceptor(argc, *name, *object, |
lookup->holder()); |
break; |
@@ -530,7 +564,7 @@ |
// Named lookup in the object. |
LookupResult lookup; |
- object->Lookup(*name, &lookup); |
+ LookupForRead(*object, *name, &lookup); |
// If lookup is invalid, check if we need to throw an exception. |
if (!lookup.IsValid()) { |
@@ -653,6 +687,7 @@ |
break; |
} |
case INTERCEPTOR: { |
+ ASSERT(HasInterceptorGetter(lookup->holder())); |
code = StubCache::ComputeLoadInterceptor(*name, *receiver, |
lookup->holder()); |
break; |
@@ -744,7 +779,7 @@ |
// Named lookup. |
LookupResult lookup; |
- object->Lookup(*name, &lookup); |
+ LookupForRead(*object, *name, &lookup); |
// If lookup is invalid, check if we need to throw an exception. |
if (!lookup.IsValid()) { |
@@ -838,6 +873,7 @@ |
break; |
} |
case INTERCEPTOR: { |
+ ASSERT(HasInterceptorGetter(lookup->holder())); |
code = StubCache::ComputeKeyedLoadInterceptor(*name, *receiver, |
lookup->holder()); |
break; |
@@ -884,9 +920,9 @@ |
} |
-static bool LookupForStoreIC(JSObject* object, |
- String* name, |
- LookupResult* lookup) { |
+static bool LookupForWrite(JSObject* object, |
+ String* name, |
+ LookupResult* lookup) { |
object->LocalLookup(name, lookup); |
if (!StoreICableLookup(lookup)) { |
return false; |
@@ -929,7 +965,7 @@ |
// Lookup the property locally in the receiver. |
if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { |
LookupResult lookup; |
- if (LookupForStoreIC(*receiver, *name, &lookup)) { |
+ if (LookupForWrite(*receiver, *name, &lookup)) { |
UpdateCaches(&lookup, state, receiver, name, value); |
} |
} |
@@ -995,6 +1031,7 @@ |
break; |
} |
case INTERCEPTOR: { |
+ ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); |
code = StubCache::ComputeStoreInterceptor(*name, *receiver); |
break; |
} |