Rossberg's suggested changes to the LookupIterator.
BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/324383005 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21778 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ea9c67d6c3
commit
7bbe963ae1
@ -14,12 +14,12 @@ namespace internal {
|
||||
void LookupIterator::Next() {
|
||||
has_property_ = false;
|
||||
do {
|
||||
LookupInHolder();
|
||||
state_ = LookupInHolder();
|
||||
} while (!IsFound() && NextHolder());
|
||||
}
|
||||
|
||||
|
||||
Handle<JSReceiver> LookupIterator::GetOrigin() const {
|
||||
Handle<JSReceiver> LookupIterator::GetRoot() const {
|
||||
Handle<Object> receiver = GetReceiver();
|
||||
if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
|
||||
Context* native_context = isolate_->context()->native_context();
|
||||
@ -67,39 +67,38 @@ bool LookupIterator::NextHolder() {
|
||||
}
|
||||
|
||||
|
||||
void LookupIterator::LookupInHolder() {
|
||||
State old_state = state_;
|
||||
state_ = NOT_FOUND;
|
||||
switch (old_state) {
|
||||
LookupIterator::State LookupIterator::LookupInHolder() {
|
||||
switch (state_) {
|
||||
case NOT_FOUND:
|
||||
if (holder_map_->IsJSProxyMap()) {
|
||||
state_ = JSPROXY;
|
||||
return;
|
||||
return JSPROXY;
|
||||
}
|
||||
if (check_access_check() && holder_map_->is_access_check_needed()) {
|
||||
state_ = ACCESS_CHECK;
|
||||
return;
|
||||
return ACCESS_CHECK;
|
||||
}
|
||||
// Fall through.
|
||||
case ACCESS_CHECK:
|
||||
if (check_interceptor() && holder_map_->has_named_interceptor()) {
|
||||
state_ = INTERCEPTOR;
|
||||
return;
|
||||
return INTERCEPTOR;
|
||||
}
|
||||
// Fall through.
|
||||
case INTERCEPTOR:
|
||||
if (holder_map_->is_dictionary_map()) {
|
||||
property_encoding_ = DICTIONARY;
|
||||
} else {
|
||||
DescriptorArray* descriptors = holder_map_->instance_descriptors();
|
||||
number_ = descriptors->SearchWithCache(*name_, *holder_map_);
|
||||
if (number_ == DescriptorArray::kNotFound) return;
|
||||
if (number_ == DescriptorArray::kNotFound) return NOT_FOUND;
|
||||
property_encoding_ = DESCRIPTOR;
|
||||
}
|
||||
state_ = PROPERTY;
|
||||
return PROPERTY;
|
||||
case PROPERTY:
|
||||
return;
|
||||
return NOT_FOUND;
|
||||
case JSPROXY:
|
||||
UNREACHABLE();
|
||||
}
|
||||
UNREACHABLE();
|
||||
return state_;
|
||||
}
|
||||
|
||||
|
||||
@ -140,10 +139,10 @@ bool LookupIterator::HasProperty() {
|
||||
case v8::internal::FIELD:
|
||||
case v8::internal::NORMAL:
|
||||
case v8::internal::CONSTANT:
|
||||
property_type_ = DATA;
|
||||
property_kind_ = DATA;
|
||||
break;
|
||||
case v8::internal::CALLBACKS:
|
||||
property_type_ = ACCESSORS;
|
||||
property_kind_ = ACCESSOR;
|
||||
break;
|
||||
case v8::internal::HANDLER:
|
||||
case v8::internal::NONEXISTENT:
|
||||
@ -180,14 +179,14 @@ Handle<Object> LookupIterator::FetchValue() const {
|
||||
|
||||
Handle<Object> LookupIterator::GetAccessors() const {
|
||||
ASSERT(has_property_);
|
||||
ASSERT_EQ(ACCESSORS, property_type_);
|
||||
ASSERT_EQ(ACCESSOR, property_kind_);
|
||||
return FetchValue();
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> LookupIterator::GetDataValue() const {
|
||||
ASSERT(has_property_);
|
||||
ASSERT_EQ(DATA, property_type_);
|
||||
ASSERT_EQ(DATA, property_kind_);
|
||||
Handle<Object> value = FetchValue();
|
||||
if (value->IsTheHole()) {
|
||||
ASSERT_EQ(DICTIONARY, property_encoding_);
|
||||
|
38
src/lookup.h
38
src/lookup.h
@ -14,7 +14,7 @@ namespace internal {
|
||||
|
||||
class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
public:
|
||||
enum Type {
|
||||
enum Configuration {
|
||||
CHECK_DERIVED = 1 << 0,
|
||||
CHECK_INTERCEPTOR = 1 << 1,
|
||||
CHECK_ACCESS_CHECK = 1 << 2,
|
||||
@ -31,9 +31,9 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
JSPROXY
|
||||
};
|
||||
|
||||
enum PropertyType {
|
||||
enum PropertyKind {
|
||||
DATA,
|
||||
ACCESSORS
|
||||
ACCESSOR
|
||||
};
|
||||
|
||||
enum PropertyEncoding {
|
||||
@ -43,17 +43,17 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
|
||||
LookupIterator(Handle<Object> receiver,
|
||||
Handle<Name> name,
|
||||
Type type = CHECK_ALL)
|
||||
: type_(type),
|
||||
Configuration configuration = CHECK_ALL)
|
||||
: configuration_(configuration),
|
||||
state_(NOT_FOUND),
|
||||
property_type_(DATA),
|
||||
property_kind_(DATA),
|
||||
property_encoding_(DESCRIPTOR),
|
||||
property_details_(NONE, NONEXISTENT, Representation::None()),
|
||||
isolate_(name->GetIsolate()),
|
||||
name_(name),
|
||||
maybe_receiver_(receiver),
|
||||
number_(DescriptorArray::kNotFound) {
|
||||
Handle<JSReceiver> origin = GetOrigin();
|
||||
Handle<JSReceiver> origin = GetRoot();
|
||||
holder_map_ = handle(origin->map());
|
||||
maybe_holder_ = origin;
|
||||
Next();
|
||||
@ -62,10 +62,10 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
LookupIterator(Handle<Object> receiver,
|
||||
Handle<Name> name,
|
||||
Handle<JSReceiver> holder,
|
||||
Type type = CHECK_ALL)
|
||||
: type_(type),
|
||||
Configuration configuration = CHECK_ALL)
|
||||
: configuration_(configuration),
|
||||
state_(NOT_FOUND),
|
||||
property_type_(DATA),
|
||||
property_kind_(DATA),
|
||||
property_encoding_(DESCRIPTOR),
|
||||
property_details_(NONE, NONEXISTENT, Representation::None()),
|
||||
isolate_(name->GetIsolate()),
|
||||
@ -93,7 +93,7 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
ASSERT(IsFound() && state_ != JSPROXY);
|
||||
return Handle<JSObject>::cast(maybe_holder_.ToHandleChecked());
|
||||
}
|
||||
Handle<JSReceiver> GetOrigin() const;
|
||||
Handle<JSReceiver> GetRoot() const;
|
||||
|
||||
/* ACCESS_CHECK */
|
||||
bool HasAccess(v8::AccessType access_type) const;
|
||||
@ -103,9 +103,9 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
// below can be used. It ensures that we are able to provide a definite
|
||||
// answer, and loads extra information about the property.
|
||||
bool HasProperty();
|
||||
PropertyType property_type() const {
|
||||
PropertyKind property_kind() const {
|
||||
ASSERT(has_property_);
|
||||
return property_type_;
|
||||
return property_kind_;
|
||||
}
|
||||
PropertyDetails property_details() const {
|
||||
ASSERT(has_property_);
|
||||
@ -124,7 +124,7 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
Handle<Map> GetReceiverMap() const;
|
||||
|
||||
MUST_USE_RESULT bool NextHolder();
|
||||
void LookupInHolder();
|
||||
State LookupInHolder();
|
||||
Handle<Object> FetchValue() const;
|
||||
|
||||
bool IsBootstrapping() const;
|
||||
@ -137,19 +137,19 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
return !maybe_receiver_.is_null();
|
||||
}
|
||||
bool check_interceptor() const {
|
||||
return !IsBootstrapping() && (type_ & CHECK_INTERCEPTOR) != 0;
|
||||
return !IsBootstrapping() && (configuration_ & CHECK_INTERCEPTOR) != 0;
|
||||
}
|
||||
bool check_derived() const {
|
||||
return (type_ & CHECK_DERIVED) != 0;
|
||||
return (configuration_ & CHECK_DERIVED) != 0;
|
||||
}
|
||||
bool check_access_check() const {
|
||||
return (type_ & CHECK_ACCESS_CHECK) != 0;
|
||||
return (configuration_ & CHECK_ACCESS_CHECK) != 0;
|
||||
}
|
||||
|
||||
Type type_;
|
||||
Configuration configuration_;
|
||||
State state_;
|
||||
bool has_property_;
|
||||
PropertyType property_type_;
|
||||
PropertyKind property_kind_;
|
||||
PropertyEncoding property_encoding_;
|
||||
PropertyDetails property_details_;
|
||||
Isolate* isolate_;
|
||||
|
@ -149,8 +149,8 @@ MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
|
||||
}
|
||||
case LookupIterator::PROPERTY:
|
||||
if (it->HasProperty()) {
|
||||
switch (it->property_type()) {
|
||||
case LookupIterator::ACCESSORS:
|
||||
switch (it->property_kind()) {
|
||||
case LookupIterator::ACCESSOR:
|
||||
return GetPropertyWithAccessor(
|
||||
it->GetReceiver(), it->name(),
|
||||
it->GetHolder(), it->GetAccessors());
|
||||
@ -570,7 +570,7 @@ static bool FindAllCanReadHolder(LookupIterator* it) {
|
||||
for (; it->IsFound(); it->Next()) {
|
||||
if (it->state() == LookupIterator::PROPERTY &&
|
||||
it->HasProperty() &&
|
||||
it->property_type() == LookupIterator::ACCESSORS) {
|
||||
it->property_kind() == LookupIterator::ACCESSOR) {
|
||||
Handle<Object> accessors = it->GetAccessors();
|
||||
if (accessors->IsAccessorInfo()) {
|
||||
if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
|
||||
@ -601,10 +601,10 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
|
||||
LookupResult* result,
|
||||
Handle<Name> name,
|
||||
bool check_prototype) {
|
||||
LookupIterator::Type type = check_prototype
|
||||
LookupIterator::Configuration configuration = check_prototype
|
||||
? LookupIterator::CHECK_DERIVED
|
||||
: LookupIterator::CHECK_OWN_REAL;
|
||||
LookupIterator it(object, name, object, type);
|
||||
LookupIterator it(object, name, object, configuration);
|
||||
if (FindAllCanReadHolder(&it)) return it.property_details().attributes();
|
||||
it.isolate()->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
|
||||
// TODO(yangguo): Issue 3269, check for scheduled exception missing?
|
||||
|
Loading…
Reference in New Issue
Block a user