Index: src/ic/ic.cc |
diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
index f755307820770357cbb7904769f32b288cc0433b..43b7651f9e547495ae0f12997e4e317a2caec069 100644 |
--- a/src/ic/ic.cc |
+++ b/src/ic/ic.cc |
@@ -1422,7 +1422,8 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value, |
Handle<JSObject> holder = it->GetHolder<JSObject>(); |
InterceptorInfo* info = holder->GetNamedInterceptor(); |
if (it->HolderIsReceiverOrHiddenPrototype()) { |
- if (!info->setter()->IsUndefined()) return true; |
+ return !info->non_masking() && receiver.is_identical_to(holder) && |
+ !info->setter()->IsUndefined(); |
} else if (!info->getter()->IsUndefined() || |
!info->query()->IsUndefined()) { |
return false; |
@@ -2807,11 +2808,8 @@ RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptorOnly) { |
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
- Handle<Object> result_internal; |
- if (result.is_null()) { |
- return isolate->heap()->no_interceptor_result_sentinel(); |
- } |
- return *result; |
+ if (!result.is_null()) return *result; |
+ return isolate->heap()->no_interceptor_result_sentinel(); |
} |
@@ -2829,15 +2827,32 @@ RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) { |
Handle<JSObject> holder = |
args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex); |
- Handle<Object> result; |
+ InterceptorInfo* interceptor = holder->GetNamedInterceptor(); |
+ PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, |
+ *holder, Object::DONT_THROW); |
+ |
+ v8::GenericNamedPropertyGetterCallback getter = |
+ v8::ToCData<v8::GenericNamedPropertyGetterCallback>( |
+ interceptor->getter()); |
+ Handle<Object> result = arguments.Call(getter, name); |
+ |
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
+ |
+ if (!result.is_null()) return *result; |
+ |
LookupIterator it(receiver, name, holder); |
- // TODO(conradw): Investigate strong mode semantics for this. |
+ // Skip any lookup work until we hit the (possibly non-masking) interceptor. |
+ while (it.state() != LookupIterator::INTERCEPTOR || |
+ !it.GetHolder<JSObject>().is_identical_to(holder)) { |
+ DCHECK(it.state() != LookupIterator::ACCESS_CHECK || it.HasAccess()); |
+ it.Next(); |
+ } |
+ // Skip past the interceptor. |
+ it.Next(); |
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it)); |
if (it.IsFound()) return *result; |
- // Return the undefined result if the reference error should not be thrown. |
- // Note that both keyed and non-keyed loads may end up here. |
LoadICNexus nexus(isolate); |
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
if (!ic.ShouldThrowReferenceError(it.GetReceiver())) { |
@@ -2858,26 +2873,34 @@ RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { |
Handle<JSObject> receiver = args.at<JSObject>(0); |
Handle<Name> name = args.at<Name>(1); |
Handle<Object> value = args.at<Object>(2); |
-#ifdef DEBUG |
- PrototypeIterator iter(isolate, receiver, |
- PrototypeIterator::START_AT_RECEIVER, |
- PrototypeIterator::END_AT_NON_HIDDEN); |
- bool found = false; |
- for (; !iter.IsAtEnd(); iter.Advance()) { |
- Handle<Object> current = PrototypeIterator::GetCurrent(iter); |
- if (current->IsJSObject() && |
- Handle<JSObject>::cast(current)->HasNamedInterceptor()) { |
- found = true; |
- break; |
- } |
+ |
+ DCHECK(receiver->HasNamedInterceptor()); |
+ InterceptorInfo* interceptor = receiver->GetNamedInterceptor(); |
+ DCHECK(!interceptor->non_masking()); |
+ PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, |
+ *receiver, Object::DONT_THROW); |
+ |
+ v8::GenericNamedPropertySetterCallback setter = |
+ v8::ToCData<v8::GenericNamedPropertySetterCallback>( |
+ interceptor->setter()); |
+ Handle<Object> result = arguments.Call(setter, name, value); |
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
+ if (!result.is_null()) return *value; |
+ |
+ LookupIterator it(receiver, name, receiver); |
+ // Skip past any access check on the receiver. |
+ if (it.state() == LookupIterator::ACCESS_CHECK) { |
+ DCHECK(it.HasAccess()); |
+ it.Next(); |
} |
- DCHECK(found); |
-#endif |
- Handle<Object> result; |
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
- isolate, result, |
- JSObject::SetProperty(receiver, name, value, ic.language_mode())); |
- return *result; |
+ // Skip past the interceptor on the receiver. |
+ DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
+ it.Next(); |
+ |
+ MAYBE_RETURN(Object::SetProperty(&it, value, ic.language_mode(), |
+ JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED), |
+ isolate->heap()->exception()); |
+ return *value; |
} |