| Index: src/lookup.cc
|
| diff --git a/src/lookup.cc b/src/lookup.cc
|
| index 39d80df83c704bce79e0a8f9cd5fb912fe667bf0..e5eecce234116e1098c8bd23e5c2fdc6fc1bb9d0 100644
|
| --- a/src/lookup.cc
|
| +++ b/src/lookup.cc
|
| @@ -29,7 +29,13 @@ void LookupIterator::Next() {
|
| // Continue lookup if lookup on current holder failed.
|
| do {
|
| JSReceiver* maybe_holder = NextHolder(map);
|
| - if (maybe_holder == NULL) break;
|
| + if (maybe_holder == nullptr) {
|
| + if (interceptor_state_ == InterceptorState::kSkipNonMasking) {
|
| + RestartLookupForNonMaskingInterceptors();
|
| + return;
|
| + }
|
| + break;
|
| + }
|
| holder = maybe_holder;
|
| map = holder->map();
|
| state_ = LookupInHolder(map, holder);
|
| @@ -42,10 +48,21 @@ void LookupIterator::Next() {
|
| }
|
|
|
|
|
| -Handle<JSReceiver> LookupIterator::GetRoot() const {
|
| - if (receiver_->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver_);
|
| - Handle<Object> root =
|
| - handle(receiver_->GetRootMap(isolate_)->prototype(), isolate_);
|
| +void LookupIterator::RestartLookupForNonMaskingInterceptors() {
|
| + interceptor_state_ = InterceptorState::kProcessNonMasking;
|
| + state_ = NOT_FOUND;
|
| + property_details_ = PropertyDetails::Empty();
|
| + number_ = DescriptorArray::kNotFound;
|
| + holder_ = initial_holder_;
|
| + holder_map_ = handle(holder_->map(), isolate_);
|
| + Next();
|
| +}
|
| +
|
| +
|
| +Handle<JSReceiver> LookupIterator::GetRoot(Handle<Object> receiver,
|
| + Isolate* isolate) {
|
| + if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
|
| + auto root = handle(receiver->GetRootMap(isolate)->prototype(), isolate);
|
| CHECK(!root->IsNull());
|
| return Handle<JSReceiver>::cast(root);
|
| }
|
| @@ -80,6 +97,7 @@ bool LookupIterator::HasAccess() const {
|
|
|
| void LookupIterator::ReloadPropertyInformation() {
|
| state_ = BEFORE_PROPERTY;
|
| + interceptor_state_ = InterceptorState::kUninitialized;
|
| state_ = LookupInHolder(*holder_map_, *holder_);
|
| DCHECK(IsFound() || holder_map_->is_dictionary_map());
|
| }
|
| @@ -354,4 +372,22 @@ void LookupIterator::InternalizeName() {
|
| if (name_->IsUniqueName()) return;
|
| name_ = factory()->InternalizeString(Handle<String>::cast(name_));
|
| }
|
| +
|
| +
|
| +bool LookupIterator::SkipInterceptor(JSObject* holder) {
|
| + auto info = holder->GetNamedInterceptor();
|
| + // TODO(dcarney): check for symbol/can_intercept_symbols here as well.
|
| + if (info->non_masking()) {
|
| + switch (interceptor_state_) {
|
| + case InterceptorState::kUninitialized:
|
| + interceptor_state_ = InterceptorState::kSkipNonMasking;
|
| + // Fall through.
|
| + case InterceptorState::kSkipNonMasking:
|
| + return true;
|
| + case InterceptorState::kProcessNonMasking:
|
| + return false;
|
| + }
|
| + }
|
| + return interceptor_state_ == InterceptorState::kProcessNonMasking;
|
| +}
|
| } } // namespace v8::internal
|
|
|