| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/lookup.h" | 5 #include "src/lookup.h" |
| 6 | 6 |
| 7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
| 8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
| 9 #include "src/elements.h" | 9 #include "src/elements.h" |
| 10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 interceptor_state_ = interceptor_state; | 85 interceptor_state_ = interceptor_state; |
| 86 property_details_ = PropertyDetails::Empty(); | 86 property_details_ = PropertyDetails::Empty(); |
| 87 holder_ = initial_holder_; | 87 holder_ = initial_holder_; |
| 88 holder_map_ = handle(holder_->map(), isolate_); | 88 holder_map_ = handle(holder_->map(), isolate_); |
| 89 number_ = DescriptorArray::kNotFound; | 89 number_ = DescriptorArray::kNotFound; |
| 90 Next(); | 90 Next(); |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 // static | 94 // static |
| 95 Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate, | 95 Handle<JSReceiver> LookupIterator::GetRootForNonJSReceiver( |
| 96 Handle<Object> receiver, | 96 Isolate* isolate, Handle<Object> receiver, uint32_t index) { |
| 97 uint32_t index) { | |
| 98 if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver); | |
| 99 // Strings are the only objects with properties (only elements) directly on | 97 // Strings are the only objects with properties (only elements) directly on |
| 100 // the wrapper. Hence we can skip generating the wrapper for all other cases. | 98 // the wrapper. Hence we can skip generating the wrapper for all other cases. |
| 101 if (index != kMaxUInt32 && receiver->IsString() && | 99 if (index != kMaxUInt32 && receiver->IsString() && |
| 102 index < static_cast<uint32_t>(String::cast(*receiver)->length())) { | 100 index < static_cast<uint32_t>(String::cast(*receiver)->length())) { |
| 103 // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the native | 101 // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the native |
| 104 // context, ensuring that we don't leak it into JS? | 102 // context, ensuring that we don't leak it into JS? |
| 105 Handle<JSFunction> constructor = isolate->string_function(); | 103 Handle<JSFunction> constructor = isolate->string_function(); |
| 106 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor); | 104 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor); |
| 107 Handle<JSValue>::cast(result)->set_value(*receiver); | 105 Handle<JSValue>::cast(result)->set_value(*receiver); |
| 108 return result; | 106 return result; |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 } else if (property_details_.type() == v8::internal::DATA) { | 521 } else if (property_details_.type() == v8::internal::DATA) { |
| 524 holder->WriteToField(descriptor_number(), *value); | 522 holder->WriteToField(descriptor_number(), *value); |
| 525 } else { | 523 } else { |
| 526 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); | 524 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); |
| 527 } | 525 } |
| 528 } | 526 } |
| 529 | 527 |
| 530 | 528 |
| 531 bool LookupIterator::IsIntegerIndexedExotic(JSReceiver* holder) { | 529 bool LookupIterator::IsIntegerIndexedExotic(JSReceiver* holder) { |
| 532 DCHECK(exotic_index_state_ != ExoticIndexState::kNotExotic); | 530 DCHECK(exotic_index_state_ != ExoticIndexState::kNotExotic); |
| 533 // Currently typed arrays are the only such objects. | |
| 534 if (!holder->IsJSTypedArray()) return false; | |
| 535 if (exotic_index_state_ == ExoticIndexState::kExotic) return true; | 531 if (exotic_index_state_ == ExoticIndexState::kExotic) return true; |
| 536 if (!InternalHolderIsReceiverOrHiddenPrototype()) { | 532 if (!InternalHolderIsReceiverOrHiddenPrototype()) { |
| 537 exotic_index_state_ = ExoticIndexState::kNotExotic; | 533 exotic_index_state_ = ExoticIndexState::kNotExotic; |
| 538 return false; | 534 return false; |
| 539 } | 535 } |
| 540 DCHECK(exotic_index_state_ == ExoticIndexState::kUninitialized); | 536 DCHECK(exotic_index_state_ == ExoticIndexState::kUninitialized); |
| 541 bool result = false; | 537 bool result = false; |
| 542 // Compute and cache result. | 538 // Compute and cache result. |
| 543 if (IsElement()) { | 539 if (IsElement()) { |
| 544 result = index_ >= JSTypedArray::cast(holder)->length_value(); | 540 result = index_ >= JSTypedArray::cast(holder)->length_value(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 559 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); | 555 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); |
| 560 } | 556 } |
| 561 | 557 |
| 562 | 558 |
| 563 bool LookupIterator::HasInterceptor(Map* map) const { | 559 bool LookupIterator::HasInterceptor(Map* map) const { |
| 564 if (IsElement()) return map->has_indexed_interceptor(); | 560 if (IsElement()) return map->has_indexed_interceptor(); |
| 565 return map->has_named_interceptor(); | 561 return map->has_named_interceptor(); |
| 566 } | 562 } |
| 567 | 563 |
| 568 | 564 |
| 569 Handle<InterceptorInfo> LookupIterator::GetInterceptor() const { | |
| 570 DCHECK_EQ(INTERCEPTOR, state_); | |
| 571 return handle(GetInterceptor(JSObject::cast(*holder_)), isolate_); | |
| 572 } | |
| 573 | |
| 574 | |
| 575 InterceptorInfo* LookupIterator::GetInterceptor(JSObject* holder) const { | |
| 576 if (IsElement()) return holder->GetIndexedInterceptor(); | |
| 577 return holder->GetNamedInterceptor(); | |
| 578 } | |
| 579 | |
| 580 | |
| 581 bool LookupIterator::SkipInterceptor(JSObject* holder) { | 565 bool LookupIterator::SkipInterceptor(JSObject* holder) { |
| 582 auto info = GetInterceptor(holder); | 566 auto info = GetInterceptor(holder); |
| 583 // TODO(dcarney): check for symbol/can_intercept_symbols here as well. | 567 // TODO(dcarney): check for symbol/can_intercept_symbols here as well. |
| 584 if (info->non_masking()) { | 568 if (info->non_masking()) { |
| 585 switch (interceptor_state_) { | 569 switch (interceptor_state_) { |
| 586 case InterceptorState::kUninitialized: | 570 case InterceptorState::kUninitialized: |
| 587 interceptor_state_ = InterceptorState::kSkipNonMasking; | 571 interceptor_state_ = InterceptorState::kSkipNonMasking; |
| 588 // Fall through. | 572 // Fall through. |
| 589 case InterceptorState::kSkipNonMasking: | 573 case InterceptorState::kSkipNonMasking: |
| 590 return true; | 574 return true; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 switch (state_) { | 610 switch (state_) { |
| 627 case NOT_FOUND: | 611 case NOT_FOUND: |
| 628 if (map->IsJSProxyMap()) return JSPROXY; | 612 if (map->IsJSProxyMap()) return JSPROXY; |
| 629 if (map->is_access_check_needed() && | 613 if (map->is_access_check_needed() && |
| 630 (IsElement() || !isolate_->IsInternallyUsedPropertyName(name_))) { | 614 (IsElement() || !isolate_->IsInternallyUsedPropertyName(name_))) { |
| 631 return ACCESS_CHECK; | 615 return ACCESS_CHECK; |
| 632 } | 616 } |
| 633 // Fall through. | 617 // Fall through. |
| 634 case ACCESS_CHECK: | 618 case ACCESS_CHECK: |
| 635 if (exotic_index_state_ != ExoticIndexState::kNotExotic && | 619 if (exotic_index_state_ != ExoticIndexState::kNotExotic && |
| 636 IsIntegerIndexedExotic(holder)) { | 620 holder->IsJSTypedArray() && IsIntegerIndexedExotic(holder)) { |
| 637 return INTEGER_INDEXED_EXOTIC; | 621 return INTEGER_INDEXED_EXOTIC; |
| 638 } | 622 } |
| 639 if (check_interceptor() && HasInterceptor(map) && | 623 if (check_interceptor() && HasInterceptor(map) && |
| 640 !SkipInterceptor(JSObject::cast(holder))) { | 624 !SkipInterceptor(JSObject::cast(holder))) { |
| 641 return INTERCEPTOR; | 625 return INTERCEPTOR; |
| 642 } | 626 } |
| 643 // Fall through. | 627 // Fall through. |
| 644 case INTERCEPTOR: | 628 case INTERCEPTOR: |
| 645 if (IsElement()) { | 629 if (IsElement()) { |
| 646 // TODO(verwaest): Optimize. | 630 // TODO(verwaest): Optimize. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 // Fall through. | 699 // Fall through. |
| 716 default: | 700 default: |
| 717 return NOT_FOUND; | 701 return NOT_FOUND; |
| 718 } | 702 } |
| 719 UNREACHABLE(); | 703 UNREACHABLE(); |
| 720 return state_; | 704 return state_; |
| 721 } | 705 } |
| 722 | 706 |
| 723 } // namespace internal | 707 } // namespace internal |
| 724 } // namespace v8 | 708 } // namespace v8 |
| OLD | NEW |