Revision: 23692
Author: [email protected]
Date: Thu Sep 4 12:28:13 2014 UTC
Log: Flatten property_kind into state. Add UNKNOWN as a state for
dict-mode receivers
BUG=
[email protected]
Review URL: https://codereview.chromium.org/540903002
https://code.google.com/p/v8/source/detail?r=23692
Modified:
/branches/bleeding_edge/src/accessors.cc
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ic/arm/handler-compiler-arm.cc
/branches/bleeding_edge/src/ic/arm64/handler-compiler-arm64.cc
/branches/bleeding_edge/src/ic/handler-compiler.cc
/branches/bleeding_edge/src/ic/ia32/handler-compiler-ia32.cc
/branches/bleeding_edge/src/ic/ic.cc
/branches/bleeding_edge/src/ic/mips/handler-compiler-mips.cc
/branches/bleeding_edge/src/ic/mips64/handler-compiler-mips64.cc
/branches/bleeding_edge/src/ic/x64/handler-compiler-x64.cc
/branches/bleeding_edge/src/ic/x87/handler-compiler-x87.cc
/branches/bleeding_edge/src/lookup-inl.h
/branches/bleeding_edge/src/lookup.cc
/branches/bleeding_edge/src/lookup.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/test/cctest/test-api.cc
=======================================
--- /branches/bleeding_edge/src/accessors.cc Mon Sep 1 09:11:44 2014 UTC
+++ /branches/bleeding_edge/src/accessors.cc Thu Sep 4 12:28:13 2014 UTC
@@ -181,7 +181,7 @@
if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;
LookupIterator it(object, Utils::OpenHandle(*name));
- CHECK(it.HasProperty());
+ CHECK_EQ(LookupIterator::ACCESSOR, it.state());
DCHECK(it.HolderIsReceiverOrHiddenPrototype());
Object::SetDataProperty(&it, value);
}
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Wed Sep 3 14:05:55 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Sep 4 12:28:13 2014 UTC
@@ -2488,7 +2488,7 @@
LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
// If the property is already there we skip it
- if (it.IsFound() && it.HasProperty()) continue;
+ if (it.IsFound()) continue;
HandleScope inner(isolate());
DCHECK(!to->HasFastProperties());
// Add to dictionary.
@@ -2516,7 +2516,7 @@
Handle<Name> key(Name::cast(raw_key));
LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
- if (it.IsFound() && it.HasProperty()) continue;
+ if (it.IsFound()) continue;
// Set the property.
Handle<Object> value = Handle<Object>(properties->ValueAt(i),
isolate());
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Thu Sep 4 12:25:57 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Thu Sep 4 12:28:13 2014 UTC
@@ -5297,21 +5297,17 @@
}
switch (it->state()) {
+ case LookupIterator::ACCESSOR:
case LookupIterator::ACCESS_CHECK:
case LookupIterator::INTERCEPTOR:
case LookupIterator::NOT_FOUND:
return kUseGeneric;
- case LookupIterator::PROPERTY:
- if (!it->HasProperty()) return kUseGeneric;
- switch (it->property_kind()) {
- case LookupIterator::DATA:
- if (access_type == STORE && it->IsReadOnly()) return kUseGeneric;
- return kUseCell;
- case LookupIterator::ACCESSOR:
- return kUseGeneric;
- }
+ case LookupIterator::DATA:
+ if (access_type == STORE && it->IsReadOnly()) return kUseGeneric;
+ return kUseCell;
case LookupIterator::JSPROXY:
case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
}
UNREACHABLE();
=======================================
--- /branches/bleeding_edge/src/ic/arm/handler-compiler-arm.cc Wed Sep 3
13:14:55 2014 UTC
+++ /branches/bleeding_edge/src/ic/arm/handler-compiler-arm.cc Thu Sep 4
12:28:13 2014 UTC
@@ -709,8 +709,7 @@
!holder().is_identical_to(it->GetHolder<JSObject>());
bool must_preserve_receiver_reg =
!receiver().is(holder_reg) &&
- (it->property_kind() == LookupIterator::ACCESSOR ||
- must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR ||
must_perform_prototype_check);
// Save necessary data before invoking an interceptor.
// Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/arm64/handler-compiler-arm64.cc Wed Sep
3 13:14:55 2014 UTC
+++ /branches/bleeding_edge/src/ic/arm64/handler-compiler-arm64.cc Thu Sep
4 12:28:13 2014 UTC
@@ -760,8 +760,7 @@
!holder().is_identical_to(it->GetHolder<JSObject>());
bool must_preserve_receiver_reg =
!receiver().is(holder_reg) &&
- (it->property_kind() == LookupIterator::ACCESSOR ||
- must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR ||
must_perform_prototype_check);
// Save necessary data before invoking an interceptor.
// Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/handler-compiler.cc Mon Aug 25 11:20:43
2014 UTC
+++ /branches/bleeding_edge/src/ic/handler-compiler.cc Thu Sep 4 12:28:13
2014 UTC
@@ -225,22 +225,28 @@
// So far the most popular follow ups for interceptor loads are FIELD and
// ExecutableAccessorInfo, so inline only them. Other cases may be added
// later.
- bool inline_followup = it->state() == LookupIterator::PROPERTY;
- if (inline_followup) {
- switch (it->property_kind()) {
- case LookupIterator::DATA:
- inline_followup = it->property_details().type() == FIELD;
- break;
- case LookupIterator::ACCESSOR: {
- Handle<Object> accessors = it->GetAccessors();
- inline_followup = accessors->IsExecutableAccessorInfo();
- if (!inline_followup) break;
- Handle<ExecutableAccessorInfo> info =
- Handle<ExecutableAccessorInfo>::cast(accessors);
- inline_followup = info->getter() != NULL &&
- ExecutableAccessorInfo::IsCompatibleReceiverType(
- isolate(), info, type());
- }
+ bool inline_followup = false;
+ switch (it->state()) {
+ case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
+ UNREACHABLE();
+ case LookupIterator::ACCESS_CHECK:
+ case LookupIterator::INTERCEPTOR:
+ case LookupIterator::JSPROXY:
+ case LookupIterator::NOT_FOUND:
+ break;
+ case LookupIterator::DATA:
+ inline_followup = it->property_details().type() == FIELD;
+ break;
+ case LookupIterator::ACCESSOR: {
+ Handle<Object> accessors = it->GetAccessors();
+ inline_followup = accessors->IsExecutableAccessorInfo();
+ if (!inline_followup) break;
+ Handle<ExecutableAccessorInfo> info =
+ Handle<ExecutableAccessorInfo>::cast(accessors);
+ inline_followup = info->getter() != NULL &&
+ ExecutableAccessorInfo::IsCompatibleReceiverType(
+ isolate(), info, type());
}
}
@@ -264,7 +270,14 @@
set_holder(real_named_property_holder);
Register reg = Frontend(interceptor_reg, it->name());
- switch (it->property_kind()) {
+ switch (it->state()) {
+ case LookupIterator::ACCESS_CHECK:
+ case LookupIterator::INTERCEPTOR:
+ case LookupIterator::JSPROXY:
+ case LookupIterator::NOT_FOUND:
+ case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
+ UNREACHABLE();
case LookupIterator::DATA: {
DCHECK_EQ(FIELD, it->property_details().type());
__ Move(receiver(), reg);
=======================================
--- /branches/bleeding_edge/src/ic/ia32/handler-compiler-ia32.cc Wed Sep 3
13:14:55 2014 UTC
+++ /branches/bleeding_edge/src/ic/ia32/handler-compiler-ia32.cc Thu Sep 4
12:28:13 2014 UTC
@@ -699,8 +699,7 @@
!holder().is_identical_to(it->GetHolder<JSObject>());
bool must_preserve_receiver_reg =
!receiver().is(holder_reg) &&
- (it->property_kind() == LookupIterator::ACCESSOR ||
- must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR ||
must_perform_prototype_check);
// Save necessary data before invoking an interceptor.
// Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/ic.cc Wed Sep 3 14:05:55 2014 UTC
+++ /branches/bleeding_edge/src/ic/ic.cc Thu Sep 4 12:28:13 2014 UTC
@@ -215,6 +215,7 @@
switch (it->state()) {
case LookupIterator::NOT_FOUND:
case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
case LookupIterator::JSPROXY:
return;
@@ -234,9 +235,9 @@
break;
}
return;
- case LookupIterator::PROPERTY:
- if (it->HasProperty()) return; // Yay!
- break;
+ case LookupIterator::ACCESSOR:
+ case LookupIterator::DATA:
+ return;
}
}
}
@@ -285,7 +286,7 @@
Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
if (it.state() == LookupIterator::ACCESS_CHECK) return false;
- if (!it.IsFound() || !it.HasProperty()) return false;
+ if (!it.IsFound()) return false;
Handle<PropertyCell> cell = it.GetPropertyCell();
return cell->type()->IsConstant();
}
@@ -976,8 +977,7 @@
}
// -------------- Accessors --------------
- DCHECK(lookup->state() == LookupIterator::PROPERTY);
- if (lookup->property_kind() == LookupIterator::ACCESSOR) {
+ if (lookup->state() == LookupIterator::ACCESSOR) {
// Use simple field loads for some well-known callback properties.
if (receiver_is_holder) {
DCHECK(receiver->IsJSObject());
@@ -1032,7 +1032,7 @@
}
// -------------- Dictionary properties --------------
- DCHECK(lookup->property_kind() == LookupIterator::DATA);
+ DCHECK(lookup->state() == LookupIterator::DATA);
if (lookup->property_encoding() == LookupIterator::DICTIONARY) {
if (kind() != Code::LOAD_IC) return slow_stub();
if (holder->IsGlobalObject()) {
@@ -1223,6 +1223,7 @@
switch (it->state()) {
case LookupIterator::NOT_FOUND:
case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
case LookupIterator::JSPROXY:
return false;
@@ -1240,11 +1241,12 @@
case LookupIterator::ACCESS_CHECK:
if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false;
break;
- case LookupIterator::PROPERTY:
- if (!it->HasProperty()) break;
+ case LookupIterator::ACCESSOR:
+ return !it->IsReadOnly();
+ case LookupIterator::DATA: {
if (it->IsReadOnly()) return false;
- if (it->property_kind() == LookupIterator::ACCESSOR) return true;
- if (it->GetHolder<Object>().is_identical_to(receiver)) {
+ Handle<JSObject> holder = it->GetHolder<JSObject>();
+ if (receiver.is_identical_to(holder)) {
it->PrepareForDataProperty(value);
// The previous receiver map might just have been deprecated,
// so reload it.
@@ -1253,14 +1255,15 @@
}
// Receiver != holder.
+ PrototypeIterator iter(it->isolate(), receiver);
if (receiver->IsJSGlobalProxy()) {
- PrototypeIterator iter(it->isolate(), receiver);
return it->GetHolder<Object>().is_identical_to(
PrototypeIterator::GetCurrent(iter));
}
it->PrepareTransitionToDataProperty(value, NONE, store_mode);
return it->IsCacheableTransition();
+ }
}
}
@@ -1417,8 +1420,7 @@
}
// -------------- Accessors --------------
- DCHECK(lookup->state() == LookupIterator::PROPERTY);
- if (lookup->property_kind() == LookupIterator::ACCESSOR) {
+ if (lookup->state() == LookupIterator::ACCESSOR) {
if (!holder->HasFastProperties()) return slow_stub();
Handle<Object> accessors = lookup->GetAccessors();
if (accessors->IsExecutableAccessorInfo()) {
@@ -1452,7 +1454,7 @@
}
// -------------- Dictionary properties --------------
- DCHECK(lookup->property_kind() == LookupIterator::DATA);
+ DCHECK(lookup->state() == LookupIterator::DATA);
if (lookup->property_encoding() == LookupIterator::DICTIONARY) {
if (holder->IsGlobalObject()) {
Handle<PropertyCell> cell = lookup->GetPropertyCell();
=======================================
--- /branches/bleeding_edge/src/ic/mips/handler-compiler-mips.cc Thu Sep 4
08:59:42 2014 UTC
+++ /branches/bleeding_edge/src/ic/mips/handler-compiler-mips.cc Thu Sep 4
12:28:13 2014 UTC
@@ -710,8 +710,7 @@
!holder().is_identical_to(it->GetHolder<JSObject>());
bool must_preserve_receiver_reg =
!receiver().is(holder_reg) &&
- (it->property_kind() == LookupIterator::ACCESSOR ||
- must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR ||
must_perform_prototype_check);
// Save necessary data before invoking an interceptor.
// Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/mips64/handler-compiler-mips64.cc Thu
Sep 4 08:59:42 2014 UTC
+++ /branches/bleeding_edge/src/ic/mips64/handler-compiler-mips64.cc Thu
Sep 4 12:28:13 2014 UTC
@@ -710,8 +710,7 @@
!holder().is_identical_to(it->GetHolder<JSObject>());
bool must_preserve_receiver_reg =
!receiver().is(holder_reg) &&
- (it->property_kind() == LookupIterator::ACCESSOR ||
- must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR ||
must_perform_prototype_check);
// Save necessary data before invoking an interceptor.
// Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/x64/handler-compiler-x64.cc Wed Sep 3
13:14:55 2014 UTC
+++ /branches/bleeding_edge/src/ic/x64/handler-compiler-x64.cc Thu Sep 4
12:28:13 2014 UTC
@@ -694,8 +694,7 @@
!holder().is_identical_to(it->GetHolder<JSObject>());
bool must_preserve_receiver_reg =
!receiver().is(holder_reg) &&
- (it->property_kind() == LookupIterator::ACCESSOR ||
- must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR ||
must_perform_prototype_check);
// Save necessary data before invoking an interceptor.
// Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/x87/handler-compiler-x87.cc Wed Aug 27
04:49:41 2014 UTC
+++ /branches/bleeding_edge/src/ic/x87/handler-compiler-x87.cc Thu Sep 4
12:28:13 2014 UTC
@@ -747,8 +747,7 @@
!holder().is_identical_to(it->GetHolder<JSObject>());
bool must_preserve_receiver_reg =
!receiver().is(holder_reg) &&
- (it->property_kind() == LookupIterator::ACCESSOR ||
- must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR ||
must_perform_prototype_check);
// Save necessary data before invoking an interceptor.
// Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/lookup-inl.h Wed Sep 3 14:05:55 2014 UTC
+++ /branches/bleeding_edge/src/lookup-inl.h Thu Sep 4 12:28:13 2014 UTC
@@ -31,7 +31,8 @@
}
-LookupIterator::State LookupIterator::LookupInHolder(Map* map) {
+LookupIterator::State LookupIterator::LookupInHolder(Map* map,
+ JSReceiver* holder) {
STATIC_ASSERT(INTERCEPTOR == BEFORE_PROPERTY);
DisallowHeapAllocation no_gc;
switch (state_) {
@@ -47,14 +48,35 @@
case INTERCEPTOR:
if (map->is_dictionary_map()) {
property_encoding_ = DICTIONARY;
+ if (holder == NULL) return UNKNOWN;
+ NameDictionary* dict =
JSObject::cast(holder)->property_dictionary();
+ number_ = dict->FindEntry(name_);
+ if (number_ == NameDictionary::kNotFound) return NOT_FOUND;
+ property_details_ = dict->DetailsAt(number_);
+ if (holder->IsGlobalObject()) {
+ if (property_details_.IsDeleted()) return NOT_FOUND;
+ PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_));
+ if (cell->value()->IsTheHole()) return NOT_FOUND;
+ }
} else {
DescriptorArray* descriptors = map->instance_descriptors();
number_ = descriptors->SearchWithCache(*name_, map);
if (number_ == DescriptorArray::kNotFound) return NOT_FOUND;
property_encoding_ = DESCRIPTOR;
+ property_details_ = descriptors->GetDetails(number_);
}
- return PROPERTY;
- case PROPERTY:
+ has_property_ = true;
+ switch (property_details_.type()) {
+ case v8::internal::CONSTANT:
+ case v8::internal::FIELD:
+ case v8::internal::NORMAL:
+ return DATA;
+ case v8::internal::CALLBACKS:
+ return ACCESSOR;
+ }
+ case ACCESSOR:
+ case DATA:
+ case UNKNOWN:
return NOT_FOUND;
case JSPROXY:
case TRANSITION:
=======================================
--- /branches/bleeding_edge/src/lookup.cc Tue Aug 26 16:32:51 2014 UTC
+++ /branches/bleeding_edge/src/lookup.cc Thu Sep 4 12:28:13 2014 UTC
@@ -14,25 +14,28 @@
void LookupIterator::Next() {
+ DCHECK_NE(JSPROXY, state_);
+ DCHECK_NE(TRANSITION, state_);
DisallowHeapAllocation no_gc;
has_property_ = false;
- JSReceiver* holder = NULL;
+ JSReceiver* holder =
+ maybe_holder_.is_null() ? NULL : *maybe_holder_.ToHandleChecked();
Map* map = *holder_map_;
// Perform lookup on current holder.
- state_ = LookupInHolder(map);
+ state_ = LookupInHolder(map, holder);
+ if (IsFound()) return;
// Continue lookup if lookup on current holder failed.
- while (!IsFound()) {
+ do {
JSReceiver* maybe_holder = NextHolder(map);
if (maybe_holder == NULL) break;
holder = maybe_holder;
map = holder->map();
- state_ = LookupInHolder(map);
- }
+ state_ = LookupInHolder(map, holder);
+ } while (!IsFound());
- // Either was found in the receiver, or the receiver has no prototype.
if (holder == NULL) return;
maybe_holder_ = handle(holder, isolate_);
@@ -79,60 +82,17 @@
DCHECK(is_guaranteed_to_have_holder());
return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_,
access_type);
}
-
-
-bool LookupIterator::HasProperty() {
- DCHECK_EQ(PROPERTY, state_);
- DCHECK(is_guaranteed_to_have_holder());
-
- if (property_encoding_ == DICTIONARY) {
- Handle<JSObject> holder = GetHolder<JSObject>();
- number_ = holder->property_dictionary()->FindEntry(name_);
- if (number_ == NameDictionary::kNotFound) return false;
-
- property_details_ = holder->property_dictionary()->DetailsAt(number_);
- // Holes in dictionary cells are absent values.
- if (holder->IsGlobalObject() &&
- (property_details_.IsDeleted() || FetchValue()->IsTheHole())) {
- return false;
- }
- } else {
- // Can't use descriptor_number() yet because has_property_ is still
false.
- property_details_ =
- holder_map_->instance_descriptors()->GetDetails(number_);
- }
-
- LoadPropertyKind();
-
- has_property_ = true;
- return true;
-}
-
-
-void LookupIterator::LoadPropertyKind() {
- switch (property_details_.type()) {
- case v8::internal::FIELD:
- case v8::internal::NORMAL:
- case v8::internal::CONSTANT:
- property_kind_ = DATA;
- break;
- case v8::internal::CALLBACKS:
- property_kind_ = ACCESSOR;
- break;
- }
-}
void LookupIterator::ReloadPropertyInformation() {
state_ = BEFORE_PROPERTY;
- state_ = LookupInHolder(*holder_map_);
- DCHECK(IsFound());
- HasProperty();
+ state_ = LookupInHolder(*holder_map_, *maybe_holder_.ToHandleChecked());
+ DCHECK(IsFound() || holder_map_->is_dictionary_map());
}
void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
- DCHECK(has_property_);
+ DCHECK(state_ == DATA || state_ == ACCESSOR);
DCHECK(HolderIsReceiverOrHiddenPrototype());
if (property_encoding_ == DICTIONARY) return;
holder_map_ =
@@ -144,7 +104,7 @@
void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
PropertyAttributes
attributes) {
- DCHECK(has_property_);
+ DCHECK(state_ == DATA || state_ == ACCESSOR);
DCHECK(HolderIsReceiverOrHiddenPrototype());
Handle<JSObject> holder = GetHolder<JSObject>();
if (property_encoding_ != DICTIONARY) {
@@ -166,9 +126,9 @@
Handle<Object> value, PropertyAttributes attributes,
Object::StoreFromKeyed store_mode) {
if (state_ == TRANSITION) return;
- DCHECK(!has_property_ || property_kind_ != ACCESSOR);
- DCHECK(!(has_property_ || state_ == JSPROXY) ||
- !HolderIsReceiverOrHiddenPrototype());
+ DCHECK(state_ != LookupIterator::ACCESSOR ||
+ GetAccessors()->IsDeclaredAccessorInfo());
+ DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype());
// Can only be called when the receiver is a JSObject. JSProxy has to be
// handled via a trap. Adding properties to primitive values is not
@@ -224,8 +184,7 @@
// Install the accessor into the dictionary-mode object.
PropertyDetails details(attributes, CALLBACKS, 0);
Handle<AccessorPair> pair;
- if (IsFound() && HasProperty() && property_kind() == ACCESSOR &&
- GetAccessors()->IsAccessorPair()) {
+ if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) {
pair = Handle<AccessorPair>::cast(GetAccessors());
// If the component and attributes are identical, nothing has to be
done.
if (pair->get(component) == *accessor) {
@@ -331,15 +290,13 @@
Handle<Object> LookupIterator::GetAccessors() const {
- DCHECK(has_property_);
- DCHECK_EQ(ACCESSOR, property_kind_);
+ DCHECK_EQ(ACCESSOR, state_);
return FetchValue();
}
Handle<Object> LookupIterator::GetDataValue() const {
- DCHECK(has_property_);
- DCHECK_EQ(DATA, property_kind_);
+ DCHECK_EQ(DATA, state_);
Handle<Object> value = FetchValue();
return value;
}
@@ -347,7 +304,7 @@
void LookupIterator::WriteDataValue(Handle<Object> value) {
DCHECK(is_guaranteed_to_have_holder());
- DCHECK(has_property_);
+ DCHECK_EQ(DATA, state_);
Handle<JSObject> holder = GetHolder<JSObject>();
if (property_encoding_ == DICTIONARY) {
NameDictionary* property_dictionary = holder->property_dictionary();
=======================================
--- /branches/bleeding_edge/src/lookup.h Wed Sep 3 14:05:55 2014 UTC
+++ /branches/bleeding_edge/src/lookup.h Thu Sep 4 12:28:13 2014 UTC
@@ -34,18 +34,15 @@
INTERCEPTOR,
JSPROXY,
NOT_FOUND,
- PROPERTY,
+ UNKNOWN, // Dictionary-mode holder map without a holder.
+ ACCESSOR,
+ DATA,
TRANSITION,
// Set state_ to BEFORE_PROPERTY to ensure that the next lookup will
be a
// PROPERTY lookup.
BEFORE_PROPERTY = INTERCEPTOR
};
- enum PropertyKind {
- DATA,
- ACCESSOR
- };
-
enum PropertyEncoding {
DICTIONARY,
DESCRIPTOR
@@ -55,7 +52,6 @@
Configuration configuration = PROTOTYPE_CHAIN)
: configuration_(ComputeConfiguration(configuration, name)),
state_(NOT_FOUND),
- property_kind_(DATA),
property_encoding_(DESCRIPTOR),
property_details_(NONE, NORMAL, Representation::None()),
isolate_(name->GetIsolate()),
@@ -73,7 +69,6 @@
Configuration configuration = PROTOTYPE_CHAIN)
: configuration_(ComputeConfiguration(configuration, name)),
state_(NOT_FOUND),
- property_kind_(DATA),
property_encoding_(DESCRIPTOR),
property_details_(NONE, NORMAL, Representation::None()),
isolate_(name->GetIsolate()),
@@ -118,10 +113,6 @@
bool HasAccess(v8::AccessType access_type) const;
/* PROPERTY */
- // HasProperty needs to be called before any of the other PROPERTY
methods
- // below can be used. It ensures that we are able to provide a definite
- // answer, and loads extra information about the property.
- bool HasProperty();
void PrepareForDataProperty(Handle<Object> value);
void PrepareTransitionToDataProperty(Handle<Object> value,
PropertyAttributes attributes,
@@ -131,7 +122,6 @@
state_ == TRANSITION &&
transition_map()->GetBackPointer()->IsMap();
if (cacheable) {
property_details_ = transition_map_->GetLastDescriptorDetails();
- LoadPropertyKind();
has_property_ = true;
}
return cacheable;
@@ -142,10 +132,6 @@
void TransitionToAccessorProperty(AccessorComponent component,
Handle<Object> accessor,
PropertyAttributes attributes);
- PropertyKind property_kind() const {
- DCHECK(has_property_);
- return property_kind_;
- }
PropertyEncoding property_encoding() const {
DCHECK(has_property_);
return property_encoding_;
@@ -173,10 +159,9 @@
Handle<Map> GetReceiverMap() const;
MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map);
- inline State LookupInHolder(Map* map);
+ inline State LookupInHolder(Map* map, JSReceiver* holder);
Handle<Object> FetchValue() const;
void ReloadPropertyInformation();
- void LoadPropertyKind();
bool IsBootstrapping() const;
@@ -219,7 +204,6 @@
Configuration configuration_;
State state_;
bool has_property_;
- PropertyKind property_kind_;
PropertyEncoding property_encoding_;
PropertyDetails property_details_;
Isolate* isolate_;
=======================================
--- /branches/bleeding_edge/src/objects.cc Thu Sep 4 11:27:20 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Thu Sep 4 12:28:13 2014 UTC
@@ -110,6 +110,7 @@
switch (it->state()) {
case LookupIterator::NOT_FOUND:
case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
case LookupIterator::JSPROXY:
return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(),
@@ -124,18 +125,12 @@
case LookupIterator::ACCESS_CHECK:
if (it->HasAccess(v8::ACCESS_GET)) break;
return JSObject::GetPropertyWithFailedAccessCheck(it);
- case LookupIterator::PROPERTY:
- if (it->HasProperty()) {
- switch (it->property_kind()) {
- case LookupIterator::ACCESSOR:
- return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
- it->GetHolder<JSObject>(),
- it->GetAccessors());
- case LookupIterator::DATA:
- return it->GetDataValue();
- }
- }
- break;
+ case LookupIterator::ACCESSOR:
+ return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
+ it->GetHolder<JSObject>(),
+ it->GetAccessors());
+ case LookupIterator::DATA:
+ return it->GetDataValue();
}
}
return it->factory()->undefined_value();
@@ -156,6 +151,7 @@
case LookupIterator::INTERCEPTOR:
case LookupIterator::NOT_FOUND:
case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
case LookupIterator::ACCESS_CHECK:
if (it->HasAccess(v8::ACCESS_GET)) continue;
@@ -163,18 +159,14 @@
case LookupIterator::JSPROXY:
it->NotFound();
return it->isolate()->factory()->undefined_value();
- case LookupIterator::PROPERTY:
- if (!it->HasProperty()) continue;
- switch (it->property_kind()) {
- case LookupIterator::DATA:
- return it->GetDataValue();
- case LookupIterator::ACCESSOR:
- // TODO(verwaest): For now this doesn't call into
- // ExecutableAccessorInfo, since clients don't need it. Update
once
- // relevant.
- it->NotFound();
- return it->isolate()->factory()->undefined_value();
- }
+ case LookupIterator::ACCESSOR:
+ // TODO(verwaest): For now this doesn't call into
+ // ExecutableAccessorInfo, since clients don't need it. Update once
+ // relevant.
+ it->NotFound();
+ return it->isolate()->factory()->undefined_value();
+ case LookupIterator::DATA:
+ return it->GetDataValue();
}
}
return it->isolate()->factory()->undefined_value();
@@ -582,9 +574,7 @@
static bool FindAllCanReadHolder(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
- if (it->state() == LookupIterator::PROPERTY &&
- it->HasProperty() &&
- it->property_kind() == LookupIterator::ACCESSOR) {
+ if (it->state() == LookupIterator::ACCESSOR) {
Handle<Object> accessors = it->GetAccessors();
if (accessors->IsAccessorInfo()) {
if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
@@ -623,8 +613,7 @@
static bool FindAllCanWriteHolder(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
- if (it->state() == LookupIterator::PROPERTY && it->HasProperty() &&
- it->property_kind() == LookupIterator::ACCESSOR) {
+ if (it->state() == LookupIterator::ACCESSOR) {
Handle<Object> accessors = it->GetAccessors();
if (accessors->IsAccessorInfo()) {
if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
@@ -2830,6 +2819,7 @@
for (; it->IsFound(); it->Next()) {
switch (it->state()) {
case LookupIterator::NOT_FOUND:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
case LookupIterator::ACCESS_CHECK:
@@ -2875,24 +2865,25 @@
}
break;
- case LookupIterator::PROPERTY:
- if (!it->HasProperty()) break;
+ case LookupIterator::ACCESSOR:
if (it->property_details().IsReadOnly()) {
return WriteToReadOnlyProperty(it, value, strict_mode);
}
- switch (it->property_kind()) {
- case LookupIterator::ACCESSOR:
- if (it->HolderIsReceiverOrHiddenPrototype() ||
- !it->GetAccessors()->IsDeclaredAccessorInfo()) {
- return SetPropertyWithAccessor(it->GetReceiver(), it->name(),
- value,
it->GetHolder<JSObject>(),
- it->GetAccessors(),
strict_mode);
- }
- break;
- case LookupIterator::DATA:
- if (it->HolderIsReceiverOrHiddenPrototype()) {
- return SetDataProperty(it, value);
- }
+ if (it->HolderIsReceiverOrHiddenPrototype() ||
+ !it->GetAccessors()->IsDeclaredAccessorInfo()) {
+ return SetPropertyWithAccessor(it->GetReceiver(), it->name(),
value,
+ it->GetHolder<JSObject>(),
+ it->GetAccessors(), strict_mode);
+ }
+ done = true;
+ break;
+
+ case LookupIterator::DATA:
+ if (it->property_details().IsReadOnly()) {
+ return WriteToReadOnlyProperty(it, value, strict_mode);
+ }
+ if (it->HolderIsReceiverOrHiddenPrototype()) {
+ return SetDataProperty(it, value);
}
done = true;
break;
@@ -3825,6 +3816,7 @@
case LookupIterator::JSPROXY:
case LookupIterator::NOT_FOUND:
case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
case LookupIterator::ACCESS_CHECK:
@@ -3833,87 +3825,92 @@
}
break;
- case LookupIterator::PROPERTY: {
- if (!it.HasProperty()) break;
+ case LookupIterator::ACCESSOR: {
PropertyDetails details = it.property_details();
Handle<Object> old_value =
it.isolate()->factory()->the_hole_value();
- switch (it.property_kind()) {
- case LookupIterator::ACCESSOR: {
- // Ensure the context isn't changed after calling into
accessors.
- AssertNoContextChange ncc(it.isolate());
+ // Ensure the context isn't changed after calling into accessors.
+ AssertNoContextChange ncc(it.isolate());
- Handle<Object> accessors = it.GetAccessors();
+ Handle<Object> accessors = it.GetAccessors();
- if (is_observed && accessors->IsAccessorInfo()) {
- ASSIGN_RETURN_ON_EXCEPTION(
- it.isolate(), old_value,
- GetPropertyWithAccessor(it.GetReceiver(), it.name(),
- it.GetHolder<JSObject>(),
accessors),
- Object);
- }
+ if (is_observed && accessors->IsAccessorInfo()) {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ it.isolate(), old_value,
+ GetPropertyWithAccessor(it.GetReceiver(), it.name(),
+ it.GetHolder<JSObject>(), accessors),
+ Object);
+ }
- // Special handling for ExecutableAccessorInfo, which behaves
like a
- // data property.
- if (handling == DONT_FORCE_FIELD &&
- accessors->IsExecutableAccessorInfo()) {
- Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- it.isolate(), result,
- JSObject::SetPropertyWithAccessor(
- it.GetReceiver(), it.name(), value,
- it.GetHolder<JSObject>(), accessors, STRICT),
- Object);
- DCHECK(result->SameValue(*value));
+ // Special handling for ExecutableAccessorInfo, which behaves like
a
+ // data property.
+ if (handling == DONT_FORCE_FIELD &&
+ accessors->IsExecutableAccessorInfo()) {
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ it.isolate(), result,
+ JSObject::SetPropertyWithAccessor(it.GetReceiver(),
it.name(),
+ value,
it.GetHolder<JSObject>(),
+ accessors, STRICT),
+ Object);
+ DCHECK(result->SameValue(*value));
- if (details.attributes() == attributes) {
- // Regular property update if the attributes match.
- if (is_observed && !old_value->SameValue(*value)) {
- // If we are setting the prototype of a function and are
- // observed, don't send change records because the
prototype
- // handles that itself.
- if (!object->IsJSFunction() ||
-
!Name::Equals(it.isolate()->factory()->prototype_string(),
- name) ||
- !Handle<JSFunction>::cast(object)
- ->should_have_prototype()) {
- EnqueueChangeRecord(object, "update", name, old_value);
- }
- }
- return value;
+ if (details.attributes() == attributes) {
+ // Regular property update if the attributes match.
+ if (is_observed && !old_value->SameValue(*value)) {
+ // If we are setting the prototype of a function and are
+ // observed, don't send change records because the prototype
+ // handles that itself.
+ if (!object->IsJSFunction() ||
+ !Name::Equals(it.isolate()->factory()->prototype_string(),
+ name) ||
+ !Handle<JSFunction>::cast(object)->should_have_prototype())
{
+ EnqueueChangeRecord(object, "update", name, old_value);
}
+ }
+ return value;
+ }
- // Reconfigure the accessor if attributes mismatch.
- Handle<ExecutableAccessorInfo> new_data =
- Accessors::CloneAccessor(
- it.isolate(),
- Handle<ExecutableAccessorInfo>::cast(accessors));
- new_data->set_property_attributes(attributes);
- // By clearing the setter we don't have to introduce a
lookup to
- // the setter, simply make it unavailable to reflect the
- // attributes.
- if (attributes & READ_ONLY) new_data->clear_setter();
- SetPropertyCallback(object, name, new_data, attributes);
- if (is_observed) {
- if (old_value->SameValue(*value)) {
- old_value = it.isolate()->factory()->the_hole_value();
- }
- EnqueueChangeRecord(object, "reconfigure", name,
old_value);
- }
- return value;
+ // Reconfigure the accessor if attributes mismatch.
+ Handle<ExecutableAccessorInfo> new_data =
Accessors::CloneAccessor(
+ it.isolate(),
Handle<ExecutableAccessorInfo>::cast(accessors));
+ new_data->set_property_attributes(attributes);
+ // By clearing the setter we don't have to introduce a lookup to
+ // the setter, simply make it unavailable to reflect the
+ // attributes.
+ if (attributes & READ_ONLY) new_data->clear_setter();
+ SetPropertyCallback(object, name, new_data, attributes);
+ if (is_observed) {
+ if (old_value->SameValue(*value)) {
+ old_value = it.isolate()->factory()->the_hole_value();
}
+ EnqueueChangeRecord(object, "reconfigure", name, old_value);
+ }
+ return value;
+ }
- // Regular accessor. Reconfigure to data property.
- break;
+ it.ReconfigureDataProperty(value, attributes);
+ it.PrepareForDataProperty(value);
+ it.WriteDataValue(value);
+
+ if (is_observed) {
+ if (old_value->SameValue(*value)) {
+ old_value = it.isolate()->factory()->the_hole_value();
}
+ EnqueueChangeRecord(object, "reconfigure", name, old_value);
+ }
- case LookupIterator::DATA:
- // Regular property update if the attributes match.
- if (details.attributes() == attributes) {
- return SetDataProperty(&it, value);
- }
- // Reconfigure the data property if the attributes mismatch.
- if (is_observed) old_value = it.GetDataValue();
+ return value;
+ }
+
+ case LookupIterator::DATA: {
+ PropertyDetails details = it.property_details();
+ Handle<Object> old_value =
it.isolate()->factory()->the_hole_value();
+ // Regular property update if the attributes match.
+ if (details.attributes() == attributes) {
+ return SetDataProperty(&it, value);
}
+ // Reconfigure the data property if the attributes mismatch.
+ if (is_observed) old_value = it.GetDataValue();
it.ReconfigureDataProperty(value, attributes);
it.PrepareForDataProperty(value);
@@ -3996,6 +3993,7 @@
for (; it->IsFound(); it->Next()) {
switch (it->state()) {
case LookupIterator::NOT_FOUND:
+ case LookupIterator::UNKNOWN:
case LookupIterator::TRANSITION:
UNREACHABLE();
case LookupIterator::JSPROXY:
@@ -4012,11 +4010,9 @@
case LookupIterator::ACCESS_CHECK:
if (it->HasAccess(v8::ACCESS_HAS)) break;
return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
- case LookupIterator::PROPERTY:
- if (it->HasProperty()) {
- return maybe(it->property_details().attributes());
- }
- break;
+ case LookupIterator::ACCESSOR:
+ case LookupIterator::DATA:
+ return maybe(it->property_details().attributes());
}
}
return maybe(ABSENT);
@@ -4693,7 +4689,7 @@
Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string();
LookupIterator it(object, hidden, LookupIterator::OWN_SKIP_INTERCEPTOR);
CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
- return it.IsFound() && it.HasProperty();
+ return it.IsFound();
}
@@ -4726,10 +4722,10 @@
LookupIterator it(handle(this), isolate->factory()->hidden_string(),
LookupIterator::OWN_SKIP_INTERCEPTOR);
CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
- if (it.IsFound() && it.HasProperty()) {
- DCHECK_EQ(LookupIterator::DATA, it.property_kind());
+ if (it.state() == LookupIterator::DATA) {
return *it.GetDataValue();
}
+ DCHECK(!it.IsFound());
return GetHeap()->undefined_value();
}
}
@@ -4926,12 +4922,14 @@
bool is_observed = object->map()->is_observed() &&
*name != it.isolate()->heap()->hidden_string();
+ Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
for (; it.IsFound(); it.Next()) {
switch (it.state()) {
case LookupIterator::JSPROXY:
case LookupIterator::NOT_FOUND:
case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
case LookupIterator::ACCESS_CHECK:
if (it.HasAccess(v8::ACCESS_DELETE)) break;
@@ -4949,8 +4947,12 @@
if (it.isolate()->has_pending_exception()) return maybe_result;
break;
}
- case LookupIterator::PROPERTY: {
- if (!it.HasProperty()) continue;
+ case LookupIterator::DATA:
+ if (is_observed) {
+ old_value = it.GetDataValue();
+ }
+ // Fall through.
+ case LookupIterator::ACCESSOR: {
if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) {
// Fail if the property is not configurable.
if (delete_mode == STRICT_DELETION) {
@@ -4962,17 +4964,6 @@
}
return it.isolate()->factory()->false_value();
}
-
- Handle<Object> old_value;
- if (is_observed) {
- switch (it.property_kind()) {
- case LookupIterator::ACCESSOR:
- old_value = it.isolate()->factory()->the_hole_value();
- break;
- case LookupIterator::DATA:
- old_value = it.GetDataValue();
- }
- }
PropertyNormalizationMode mode = object->map()->is_prototype_map()
? KEEP_INOBJECT_PROPERTIES
@@ -6150,7 +6141,7 @@
LookupIterator it(object, name,
LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
CHECK(GetPropertyAttributes(&it).has_value);
preexists = it.IsFound();
- if (preexists && (it.property_kind() == LookupIterator::DATA ||
+ if (preexists && (it.state() == LookupIterator::DATA ||
it.GetAccessors()->IsAccessorInfo())) {
old_value = GetProperty(&it).ToHandleChecked();
}
@@ -6314,6 +6305,7 @@
case LookupIterator::INTERCEPTOR:
case LookupIterator::NOT_FOUND:
case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
case LookupIterator::ACCESS_CHECK:
@@ -6326,20 +6318,16 @@
case LookupIterator::JSPROXY:
return isolate->factory()->undefined_value();
- case LookupIterator::PROPERTY:
- if (!it.HasProperty()) continue;
- switch (it.property_kind()) {
- case LookupIterator::DATA:
- continue;
- case LookupIterator::ACCESSOR: {
- Handle<Object> maybe_pair = it.GetAccessors();
- if (maybe_pair->IsAccessorPair()) {
- return handle(
-
AccessorPair::cast(*maybe_pair)->GetComponent(component),
- isolate);
- }
- }
+ case LookupIterator::DATA:
+ continue;
+ case LookupIterator::ACCESSOR: {
+ Handle<Object> maybe_pair = it.GetAccessors();
+ if (maybe_pair->IsAccessorPair()) {
+ return handle(
+ AccessorPair::cast(*maybe_pair)->GetComponent(component),
+ isolate);
}
+ }
}
}
}
@@ -12849,7 +12837,7 @@
LookupIterator::OWN_SKIP_INTERCEPTOR);
CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
CHECK(it.IsFound());
- CHECK(it.HasProperty());
+ CHECK_EQ(LookupIterator::ACCESSOR, it.state());
return it.IsReadOnly();
}
return false;
@@ -13275,7 +13263,7 @@
LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
if (!maybe_result.has_value) return Maybe<bool>();
- return maybe(it.IsFound() && it.property_kind() ==
LookupIterator::ACCESSOR);
+ return maybe(it.state() == LookupIterator::ACCESSOR);
}
=======================================
--- /branches/bleeding_edge/src/runtime.cc Thu Sep 4 11:27:20 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc Thu Sep 4 12:28:13 2014 UTC
@@ -1990,8 +1990,7 @@
if (attrs == ABSENT) return factory->undefined_value();
// Get AccessorPair if present.
- if (it.state() == LookupIterator::PROPERTY &&
- it.property_kind() == LookupIterator::ACCESSOR &&
+ if (it.state() == LookupIterator::ACCESSOR &&
it.GetAccessors()->IsAccessorPair()) {
maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
}
@@ -2323,7 +2322,7 @@
// Ignore if we can't reconfigure the value.
if ((old_attributes & DONT_DELETE) != 0) {
if ((old_attributes & READ_ONLY) != 0 ||
- it.property_kind() == LookupIterator::ACCESSOR) {
+ it.state() == LookupIterator::ACCESSOR) {
return *value;
}
attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
@@ -2468,7 +2467,7 @@
// Ignore if we can't reconfigure the value.
if ((old_attributes & DONT_DELETE) != 0) {
if ((old_attributes & READ_ONLY) != 0 ||
- it.property_kind() == LookupIterator::ACCESSOR) {
+ it.state() == LookupIterator::ACCESSOR) {
return *value;
}
attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
@@ -4891,8 +4890,8 @@
// Lookup cache miss. Perform lookup and update the cache if
// appropriate.
LookupIterator it(receiver, key, LookupIterator::OWN);
- if (it.IsFound() && it.state() == LookupIterator::PROPERTY &&
- it.HasProperty() && it.property_details().type() == FIELD) {
+ if (it.state() == LookupIterator::DATA &&
+ it.property_details().type() == FIELD) {
FieldIndex field_index = it.GetFieldIndex();
// Do not track double fields in the keyed lookup cache. Reading
// double values requires boxing.
@@ -5050,8 +5049,7 @@
// Take special care when attributes are different and there is already
// a property.
- if (it.IsFound() && it.HasProperty() &&
- it.property_kind() == LookupIterator::ACCESSOR) {
+ if (it.state() == LookupIterator::ACCESSOR) {
// Use IgnoreAttributes version since a readonly property may be
// overridden and SetProperty does not allow this.
Handle<Object> result;
@@ -10898,6 +10896,7 @@
switch (it->state()) {
case LookupIterator::NOT_FOUND:
case LookupIterator::TRANSITION:
+ case LookupIterator::UNKNOWN:
UNREACHABLE();
case LookupIterator::ACCESS_CHECK:
// Ignore access checks.
@@ -10905,30 +10904,25 @@
case LookupIterator::INTERCEPTOR:
case LookupIterator::JSPROXY:
return it->isolate()->factory()->undefined_value();
- case LookupIterator::PROPERTY:
- if (!it->HasProperty()) continue;
- switch (it->property_kind()) {
- case LookupIterator::ACCESSOR: {
- Handle<Object> accessors = it->GetAccessors();
- if (!accessors->IsAccessorInfo()) {
- return it->isolate()->factory()->undefined_value();
- }
- MaybeHandle<Object> maybe_result =
- JSObject::GetPropertyWithAccessor(it->GetReceiver(),
it->name(),
-
it->GetHolder<JSObject>(),
- accessors);
- Handle<Object> result;
- if (!maybe_result.ToHandle(&result)) {
- result =
- handle(it->isolate()->pending_exception(),
it->isolate());
- it->isolate()->clear_pending_exception();
- if (has_caught != NULL) *has_caught = true;
- }
- return result;
- }
- case LookupIterator::DATA:
- return it->GetDataValue();
+ case LookupIterator::ACCESSOR: {
+ Handle<Object> accessors = it->GetAccessors();
+ if (!accessors->IsAccessorInfo()) {
+ return it->isolate()->factory()->undefined_value();
+ }
+ MaybeHandle<Object> maybe_result =
JSObject::GetPropertyWithAccessor(
+ it->GetReceiver(), it->name(), it->GetHolder<JSObject>(),
+ accessors);
+ Handle<Object> result;
+ if (!maybe_result.ToHandle(&result)) {
+ result = handle(it->isolate()->pending_exception(),
it->isolate());
+ it->isolate()->clear_pending_exception();
+ if (has_caught != NULL) *has_caught = true;
}
+ return result;
+ }
+
+ case LookupIterator::DATA:
+ return it->GetDataValue();
}
}
@@ -10983,8 +10977,7 @@
if (!it.IsFound()) return isolate->heap()->undefined_value();
Handle<Object> maybe_pair;
- if (it.state() == LookupIterator::PROPERTY &&
- it.property_kind() == LookupIterator::ACCESSOR) {
+ if (it.state() == LookupIterator::ACCESSOR) {
maybe_pair = it.GetAccessors();
}
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Wed Sep 3 14:05:55
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-api.cc Thu Sep 4 12:28:13
2014 UTC
@@ -2045,8 +2045,7 @@
i::LookupResult lookup(i_isolate);
i::Handle<i::String> name(v8::Utils::OpenHandle(*v8_str("length")));
i::LookupIterator it(a, name, i::LookupIterator::OWN_SKIP_INTERCEPTOR);
- CHECK_NE(i::LookupIterator::ACCESS_CHECK, it.state());
- CHECK(it.HasProperty());
+ CHECK_EQ(i::LookupIterator::ACCESSOR, it.state());
CHECK(it.GetAccessors()->IsExecutableAccessorInfo());
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.