From 823682ea2c118f24eee774b9b0f205687c4e8b59 Mon Sep 17 00:00:00 2001 From: verwaest Date: Tue, 2 Jun 2015 04:10:50 -0700 Subject: [PATCH] Use LookupIterator for GetElementAttributes and friends BUG=v8:4137 LOG=n Review URL: https://codereview.chromium.org/1153583006 Cr-Commit-Position: refs/heads/master@{#28757} --- src/api.cc | 2 +- src/lookup-inl.h | 25 ++- src/lookup.cc | 7 + src/objects-inl.h | 125 ++++++------ src/objects.cc | 219 ++------------------- src/objects.h | 75 ++----- src/runtime/runtime-object.cc | 82 +++----- test/cctest/test-api-interceptors.cc | 22 ++- ...imitive-property-access-edge-cases-expected.txt | 6 +- 9 files changed, 166 insertions(+), 397 deletions(-) diff --git a/src/api.cc b/src/api.cc index 7361764..5140cd5 100644 --- a/src/api.cc +++ b/src/api.cc @@ -3565,7 +3565,7 @@ Maybe v8::Object::CreateDataProperty(v8::Local context, } Maybe attributes = - i::JSReceiver::GetOwnElementAttribute(self, index); + i::JSReceiver::GetOwnElementAttributes(self, index); if (attributes.IsJust() && attributes.FromJust() & DONT_DELETE) { return Just(false); } diff --git a/src/lookup-inl.h b/src/lookup-inl.h index bae910d..f06ef67 100644 --- a/src/lookup-inl.h +++ b/src/lookup-inl.h @@ -59,16 +59,23 @@ LookupIterator::State LookupIterator::LookupInHolder(Map* const map, case INTERCEPTOR: if (IsElement()) { // TODO(verwaest): Optimize. - JSObject* js_object = JSObject::cast(holder); - ElementsAccessor* accessor = js_object->GetElementsAccessor(); - FixedArrayBase* backing_store = js_object->elements(); - number_ = accessor->GetIndexForKey(backing_store, index_); - if (number_ == kMaxUInt32) return NOT_FOUND; - if (accessor->GetAttributes(js_object, index_, backing_store) == - ABSENT) { - return NOT_FOUND; + if (holder->IsStringObjectWithCharacterAt(index_)) { + PropertyAttributes attributes = + static_cast(READ_ONLY | DONT_DELETE); + property_details_ = PropertyDetails(attributes, v8::internal::DATA, 0, + PropertyCellType::kNoCell); + } else { + JSObject* js_object = JSObject::cast(holder); + ElementsAccessor* accessor = js_object->GetElementsAccessor(); + FixedArrayBase* backing_store = js_object->elements(); + number_ = accessor->GetIndexForKey(backing_store, index_); + if (number_ == kMaxUInt32) return NOT_FOUND; + if (accessor->GetAttributes(js_object, index_, backing_store) == + ABSENT) { + return NOT_FOUND; + } + property_details_ = accessor->GetDetails(backing_store, number_); } - property_details_ = accessor->GetDetails(backing_store, number_); } else if (holder->IsGlobalObject()) { GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); int number = dict->FindEntry(name_); diff --git a/src/lookup.cc b/src/lookup.cc index 38cc522..aa66d15 100644 --- a/src/lookup.cc +++ b/src/lookup.cc @@ -264,6 +264,13 @@ Handle LookupIterator::FetchValue() const { Handle holder = GetHolder(); if (IsElement()) { // TODO(verwaest): Optimize. + if (holder->IsStringObjectWithCharacterAt(index_)) { + Handle js_value = Handle::cast(holder); + Handle string(String::cast(js_value->value())); + return factory()->LookupSingleCharacterStringFromCode( + String::Flatten(string)->Get(index_)); + } + ElementsAccessor* accessor = holder->GetElementsAccessor(); return accessor->Get(holder, index_); } else if (holder_map_->IsGlobalObjectMap()) { diff --git a/src/objects-inl.h b/src/objects-inl.h index f8d5d1d..895d39f 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1189,15 +1189,6 @@ Handle Object::GetPrototypeSkipHiddenPrototypes( } -MaybeHandle Object::GetPropertyOrElement(Handle object, - Handle name) { - uint32_t index; - Isolate* isolate = name->GetIsolate(); - if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index); - return GetProperty(object, name); -} - - MaybeHandle Object::GetProperty(Isolate* isolate, Handle object, const char* name) { @@ -6962,12 +6953,24 @@ String* String::GetForwardedInternalizedString() { } +MaybeHandle Object::GetPropertyOrElement(Handle object, + Handle name) { + uint32_t index; + LookupIterator it = name->AsArrayIndex(&index) + ? LookupIterator(name->GetIsolate(), object, index) + : LookupIterator(object, name); + return GetProperty(&it); +} + + Maybe JSReceiver::HasProperty(Handle object, Handle name) { + // Call the "has" trap on proxies. if (object->IsJSProxy()) { Handle proxy = Handle::cast(object); return JSProxy::HasPropertyWithHandler(proxy, name); } + Maybe result = GetPropertyAttributes(object, name); return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing(); } @@ -6975,34 +6978,80 @@ Maybe JSReceiver::HasProperty(Handle object, Maybe JSReceiver::HasOwnProperty(Handle object, Handle name) { + // Call the "has" trap on proxies. if (object->IsJSProxy()) { Handle proxy = Handle::cast(object); return JSProxy::HasPropertyWithHandler(proxy, name); } + Maybe result = GetOwnPropertyAttributes(object, name); return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing(); } Maybe JSReceiver::GetPropertyAttributes( - Handle object, Handle key) { - uint32_t index; - if (object->IsJSObject() && key->AsArrayIndex(&index)) { - return GetElementAttribute(object, index); - } - LookupIterator it(object, key); + Handle object, Handle name) { + uint32_t index = 0; + LookupIterator it = name->AsArrayIndex(&index) + ? LookupIterator(name->GetIsolate(), object, index) + : LookupIterator(object, name); return GetPropertyAttributes(&it); } -Maybe JSReceiver::GetElementAttribute( - Handle object, uint32_t index) { +Maybe JSReceiver::GetOwnPropertyAttributes( + Handle object, Handle name) { + uint32_t index = 0; + LookupIterator::Configuration c = LookupIterator::HIDDEN; + LookupIterator it = name->AsArrayIndex(&index) + ? LookupIterator(name->GetIsolate(), object, index, c) + : LookupIterator(object, name, c); + return GetPropertyAttributes(&it); +} + + +Maybe JSReceiver::HasElement(Handle object, uint32_t index) { + // Call the "has" trap on proxies. + if (object->IsJSProxy()) { + Isolate* isolate = object->GetIsolate(); + Handle name = isolate->factory()->Uint32ToString(index); + Handle proxy = Handle::cast(object); + return JSProxy::HasPropertyWithHandler(proxy, name); + } + + Maybe result = GetElementAttributes(object, index); + return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing(); +} + + +Maybe JSReceiver::HasOwnElement(Handle object, + uint32_t index) { + // Call the "has" trap on proxies. if (object->IsJSProxy()) { - return JSProxy::GetElementAttributeWithHandler( - Handle::cast(object), object, index); + Isolate* isolate = object->GetIsolate(); + Handle name = isolate->factory()->Uint32ToString(index); + Handle proxy = Handle::cast(object); + return JSProxy::HasPropertyWithHandler(proxy, name); } - return JSObject::GetElementAttributeWithReceiver( - Handle::cast(object), object, index, true); + + Maybe result = GetOwnElementAttributes(object, index); + return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing(); +} + + +Maybe JSReceiver::GetElementAttributes( + Handle object, uint32_t index) { + Isolate* isolate = object->GetIsolate(); + LookupIterator it(isolate, object, index); + return GetPropertyAttributes(&it); +} + + +Maybe JSReceiver::GetOwnElementAttributes( + Handle object, uint32_t index) { + Isolate* isolate = object->GetIsolate(); + LookupIterator it(isolate, object, index, LookupIterator::HIDDEN); + return GetPropertyAttributes(&it); } @@ -7032,40 +7081,6 @@ Object* JSReceiver::GetIdentityHash() { } -Maybe JSReceiver::HasElement(Handle object, uint32_t index) { - if (object->IsJSProxy()) { - Handle proxy = Handle::cast(object); - return JSProxy::HasElementWithHandler(proxy, index); - } - Maybe result = JSObject::GetElementAttributeWithReceiver( - Handle::cast(object), object, index, true); - return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing(); -} - - -Maybe JSReceiver::HasOwnElement(Handle object, - uint32_t index) { - if (object->IsJSProxy()) { - Handle proxy = Handle::cast(object); - return JSProxy::HasElementWithHandler(proxy, index); - } - Maybe result = JSObject::GetElementAttributeWithReceiver( - Handle::cast(object), object, index, false); - return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing(); -} - - -Maybe JSReceiver::GetOwnElementAttribute( - Handle object, uint32_t index) { - if (object->IsJSProxy()) { - return JSProxy::GetElementAttributeWithHandler( - Handle::cast(object), object, index); - } - return JSObject::GetElementAttributeWithReceiver( - Handle::cast(object), object, index, false); -} - - bool AccessorInfo::all_can_read() { return BooleanBit::get(flag(), kAllCanReadBit); } diff --git a/src/objects.cc b/src/objects.cc index db30fe9..79ea1b1 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -158,8 +158,8 @@ MaybeHandle Object::GetProperty(LookupIterator* it) { Handle JSReceiver::GetDataProperty(Handle object, - Handle key) { - LookupIterator it(object, key, + Handle name) { + LookupIterator it(object, name, LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); return GetDataProperty(&it); } @@ -596,43 +596,6 @@ void JSObject::SetNormalizedProperty(Handle object, } -static MaybeHandle FindIndexedAllCanReadHolder( - Isolate* isolate, Handle js_object, - PrototypeIterator::WhereToStart where_to_start) { - for (PrototypeIterator iter(isolate, js_object, where_to_start); - !iter.IsAtEnd(); iter.Advance()) { - auto curr = PrototypeIterator::GetCurrent(iter); - if (!curr->IsJSObject()) break; - auto obj = Handle::cast(curr); - if (!obj->HasIndexedInterceptor()) continue; - if (obj->GetIndexedInterceptor()->all_can_read()) return obj; - } - return MaybeHandle(); -} - - -Maybe JSObject::GetElementAttributesWithFailedAccessCheck( - Isolate* isolate, Handle object, Handle receiver, - uint32_t index) { - Handle holder = object; - PrototypeIterator::WhereToStart where_to_start = - PrototypeIterator::START_AT_RECEIVER; - while (true) { - auto all_can_read_holder = - FindIndexedAllCanReadHolder(isolate, holder, where_to_start); - if (!all_can_read_holder.ToHandle(&holder)) break; - auto result = - JSObject::GetElementAttributeFromInterceptor(holder, receiver, index); - if (isolate->has_scheduled_exception()) break; - if (result.IsJust() && result.FromJust() != ABSENT) return result; - where_to_start = PrototypeIterator::START_AT_PROTOTYPE; - } - isolate->ReportFailedAccessCheck(object); - RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing()); - return Just(ABSENT); -} - - MaybeHandle Object::SetElementWithReceiver( Isolate* isolate, Handle object, Handle receiver, uint32_t index, Handle value, LanguageMode language_mode) { @@ -663,9 +626,10 @@ MaybeHandle Object::SetElementWithReceiver( } if (js_object->HasIndexedInterceptor()) { + LookupIterator it(isolate, receiver, index, js_object, + LookupIterator::OWN); Maybe from_interceptor = - JSObject::GetElementAttributeFromInterceptor(js_object, receiver, - index); + JSObject::GetPropertyAttributes(&it); if (!from_interceptor.IsJust()) return MaybeHandle(); if ((from_interceptor.FromJust() & READ_ONLY) != 0) { return WriteToReadOnlyElement(isolate, receiver, index, value, @@ -4057,14 +4021,6 @@ Maybe JSProxy::GetPropertyAttributesWithHandler( } -Maybe JSProxy::GetElementAttributeWithHandler( - Handle proxy, Handle receiver, uint32_t index) { - Isolate* isolate = proxy->GetIsolate(); - Handle name = isolate->factory()->Uint32ToString(index); - return GetPropertyAttributesWithHandler(proxy, receiver, name); -} - - void JSProxy::Fix(Handle proxy) { Isolate* isolate = proxy->GetIsolate(); @@ -4372,18 +4328,6 @@ Maybe JSObject::GetPropertyAttributesWithInterceptor( } -Maybe JSReceiver::GetOwnPropertyAttributes( - Handle object, Handle name) { - // Check whether the name is an array index. - uint32_t index = 0; - if (object->IsJSObject() && name->AsArrayIndex(&index)) { - return GetOwnElementAttribute(object, index); - } - LookupIterator it(object, name, LookupIterator::HIDDEN); - return GetPropertyAttributes(&it); -} - - Maybe JSReceiver::GetPropertyAttributes( LookupIterator* it) { for (; it->IsFound(); it->Next()) { @@ -4415,118 +4359,6 @@ Maybe JSReceiver::GetPropertyAttributes( } -Maybe JSObject::GetElementAttributeWithReceiver( - Handle object, Handle receiver, uint32_t index, - bool check_prototype) { - Isolate* isolate = object->GetIsolate(); - - // Check access rights if needed. - if (object->IsAccessCheckNeeded()) { - if (!isolate->MayAccess(object)) { - return GetElementAttributesWithFailedAccessCheck(isolate, object, - receiver, index); - } - } - - if (object->IsJSGlobalProxy()) { - PrototypeIterator iter(isolate, object); - if (iter.IsAtEnd()) return Just(ABSENT); - DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); - return JSObject::GetElementAttributeWithReceiver( - Handle::cast(PrototypeIterator::GetCurrent(iter)), receiver, - index, check_prototype); - } - - // Check for lookup interceptor except when bootstrapping. - if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { - return JSObject::GetElementAttributeWithInterceptor( - object, receiver, index, check_prototype); - } - - return GetElementAttributeWithoutInterceptor( - object, receiver, index, check_prototype); -} - - -Maybe JSObject::GetElementAttributeWithInterceptor( - Handle object, Handle receiver, uint32_t index, - bool check_prototype) { - Isolate* isolate = object->GetIsolate(); - HandleScope scope(isolate); - - // Make sure that the top context does not change when doing - // callbacks or interceptor calls. - AssertNoContextChange ncc(isolate); - - Maybe from_interceptor = - GetElementAttributeFromInterceptor(object, receiver, index); - if (!from_interceptor.IsJust()) return Nothing(); - if (from_interceptor.FromJust() != ABSENT) - return Just(from_interceptor.FromJust()); - - return GetElementAttributeWithoutInterceptor(object, receiver, index, - check_prototype); -} - - -Maybe JSObject::GetElementAttributeFromInterceptor( - Handle object, Handle receiver, uint32_t index) { - Isolate* isolate = object->GetIsolate(); - AssertNoContextChange ncc(isolate); - - Handle interceptor(object->GetIndexedInterceptor()); - PropertyCallbackArguments args( - isolate, interceptor->data(), *receiver, *object); - if (!interceptor->query()->IsUndefined()) { - v8::IndexedPropertyQueryCallback query = - v8::ToCData(interceptor->query()); - LOG(isolate, - ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index)); - v8::Handle result = args.Call(query, index); - if (!result.IsEmpty()) - return Just(static_cast(result->Int32Value())); - } else if (!interceptor->getter()->IsUndefined()) { - v8::IndexedPropertyGetterCallback getter = - v8::ToCData(interceptor->getter()); - LOG(isolate, - ApiIndexedPropertyAccess( - "interceptor-indexed-get-has", *object, index)); - v8::Handle result = args.Call(getter, index); - if (!result.IsEmpty()) return Just(NONE); - } - RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing()); - return Just(ABSENT); -} - - -Maybe JSObject::GetElementAttributeWithoutInterceptor( - Handle object, Handle receiver, uint32_t index, - bool check_prototype) { - PropertyAttributes attr = - object->GetElementsAccessor()->GetAttributes(object, index); - if (attr != ABSENT) return Just(attr); - - // Handle [] on String objects. - if (object->IsStringObjectWithCharacterAt(index)) { - return Just(static_cast(READ_ONLY | DONT_DELETE)); - } - - if (!check_prototype) return Just(ABSENT); - - PrototypeIterator iter(object->GetIsolate(), object); - if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { - // We need to follow the spec and simulate a call to [[GetOwnProperty]]. - return JSProxy::GetElementAttributeWithHandler( - Handle::cast(PrototypeIterator::GetCurrent(iter)), receiver, - index); - } - if (iter.IsAtEnd()) return Just(ABSENT); - return GetElementAttributeWithReceiver( - Handle::cast(PrototypeIterator::GetCurrent(iter)), receiver, - index, true); -} - - Handle NormalizedMapCache::New(Isolate* isolate) { Handle array( isolate->factory()->NewFixedArray(kEntries, TENURED)); @@ -12147,7 +11979,7 @@ static bool GetOldValue(Isolate* isolate, List >* old_values, List* indices) { Maybe maybe = - JSReceiver::GetOwnElementAttribute(object, index); + JSReceiver::GetOwnElementAttributes(object, index); DCHECK(maybe.IsJust()); DCHECK(maybe.FromJust() != ABSENT); if (maybe.FromJust() == DONT_DELETE) return false; @@ -13273,7 +13105,7 @@ MaybeHandle JSObject::SetElement(Handle object, } Maybe maybe = - JSReceiver::GetOwnElementAttribute(object, index); + JSReceiver::GetOwnElementAttributes(object, index); if (!maybe.IsJust()) return MaybeHandle(); PropertyAttributes old_attributes = maybe.FromJust(); @@ -13304,7 +13136,7 @@ MaybeHandle JSObject::SetElement(Handle object, Object); Handle name = isolate->factory()->Uint32ToString(index); - maybe = GetOwnElementAttribute(object, index); + maybe = GetOwnElementAttributes(object, index); if (!maybe.IsJust()) return MaybeHandle(); PropertyAttributes new_attributes = maybe.FromJust(); @@ -14036,8 +13868,8 @@ MaybeHandle JSObject::GetKeysForIndexedInterceptor( Maybe JSObject::HasRealNamedProperty(Handle object, - Handle key) { - LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR); + Handle name) { + LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); Maybe maybe_result = GetPropertyAttributes(&it); if (!maybe_result.IsJust()) return Nothing(); return Just(it.IsFound()); @@ -14047,34 +13879,17 @@ Maybe JSObject::HasRealNamedProperty(Handle object, Maybe JSObject::HasRealElementProperty(Handle object, uint32_t index) { Isolate* isolate = object->GetIsolate(); - HandleScope scope(isolate); - // Check access rights if needed. - if (object->IsAccessCheckNeeded()) { - if (!isolate->MayAccess(object)) { - isolate->ReportFailedAccessCheck(object); - RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing()); - return Just(false); - } - } - - if (object->IsJSGlobalProxy()) { - HandleScope scope(isolate); - PrototypeIterator iter(isolate, object); - if (iter.IsAtEnd()) return Just(false); - DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); - return HasRealElementProperty( - Handle::cast(PrototypeIterator::GetCurrent(iter)), index); - } - - Maybe result = - GetElementAttributeWithoutInterceptor(object, object, index, false); - return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing(); + LookupIterator it(isolate, object, index, + LookupIterator::OWN_SKIP_INTERCEPTOR); + Maybe maybe_result = GetPropertyAttributes(&it); + if (!maybe_result.IsJust()) return Nothing(); + return Just(it.IsFound()); } Maybe JSObject::HasRealNamedCallbackProperty(Handle object, - Handle key) { - LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR); + Handle name) { + LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); Maybe maybe_result = GetPropertyAttributes(&it); return maybe_result.IsJust() ? Just(it.state() == LookupIterator::ACCESSOR) : Nothing(); diff --git a/src/objects.h b/src/objects.h index 5e4272f..0828952 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1155,7 +1155,7 @@ class Object { // Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5. MUST_USE_RESULT static MaybeHandle SetProperty( - Handle object, Handle key, Handle value, + Handle object, Handle name, Handle value, LanguageMode language_mode, StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED); @@ -1184,15 +1184,13 @@ class Object { LookupIterator* it, Handle value, PropertyAttributes attributes, LanguageMode language_mode, StoreFromKeyed store_mode); MUST_USE_RESULT static inline MaybeHandle GetPropertyOrElement( - Handle object, - Handle key); + Handle object, Handle name); MUST_USE_RESULT static inline MaybeHandle GetProperty( Isolate* isolate, Handle object, const char* key); MUST_USE_RESULT static inline MaybeHandle GetProperty( - Handle object, - Handle key); + Handle object, Handle name); MUST_USE_RESULT static MaybeHandle GetPropertyWithAccessor( LookupIterator* it); @@ -1676,18 +1674,20 @@ class JSReceiver: public HeapObject { MUST_USE_RESULT static inline Maybe GetPropertyAttributes( Handle object, Handle name); - MUST_USE_RESULT static Maybe GetPropertyAttributes( - LookupIterator* it); - MUST_USE_RESULT static Maybe GetOwnPropertyAttributes( - Handle object, Handle name); + MUST_USE_RESULT static inline Maybe + GetOwnPropertyAttributes(Handle object, Handle name); - MUST_USE_RESULT static inline Maybe GetElementAttribute( + MUST_USE_RESULT static inline Maybe GetElementAttributes( Handle object, uint32_t index); MUST_USE_RESULT static inline Maybe - GetOwnElementAttribute(Handle object, uint32_t index); + GetOwnElementAttributes(Handle object, uint32_t index); + + MUST_USE_RESULT static Maybe GetPropertyAttributes( + LookupIterator* it); + static Handle GetDataProperty(Handle object, - Handle key); + Handle name); static Handle GetDataProperty(LookupIterator* it); @@ -1831,13 +1831,11 @@ class JSObject: public JSReceiver { }; MUST_USE_RESULT static MaybeHandle SetOwnPropertyIgnoreAttributes( - Handle object, - Handle key, - Handle value, + Handle object, Handle name, Handle value, PropertyAttributes attributes, ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING); - static void AddProperty(Handle object, Handle key, + static void AddProperty(Handle object, Handle name, Handle value, PropertyAttributes attributes); // Extend the receiver with a single fast property appeared first in the @@ -1854,8 +1852,7 @@ class JSObject: public JSReceiver { // Sets the property value in a normalized object given (key, value, details). // Handles the special representation of JS global objects. - static void SetNormalizedProperty(Handle object, - Handle key, + static void SetNormalizedProperty(Handle object, Handle name, Handle value, PropertyDetails details); @@ -1879,10 +1876,6 @@ class JSObject: public JSReceiver { GetPropertyAttributesWithInterceptor(LookupIterator* it); MUST_USE_RESULT static Maybe GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it); - MUST_USE_RESULT static Maybe - GetElementAttributeWithReceiver(Handle object, - Handle receiver, - uint32_t index, bool check_prototype); // Retrieves an AccessorPair property from the given object. Might return // undefined if the property doesn't exist or is of a different kind. @@ -2041,11 +2034,11 @@ class JSObject: public JSReceiver { // Support functions for v8 api (needed for correct interceptor behavior). MUST_USE_RESULT static Maybe HasRealNamedProperty( - Handle object, Handle key); + Handle object, Handle name); MUST_USE_RESULT static Maybe HasRealElementProperty( Handle object, uint32_t index); MUST_USE_RESULT static Maybe HasRealNamedCallbackProperty( - Handle object, Handle key); + Handle object, Handle name); // Get the header size for a JSObject. Used to compute the index of // internal fields as well as the number of internal fields. @@ -2299,31 +2292,6 @@ class JSObject: public JSReceiver { MUST_USE_RESULT static MaybeHandle GetPropertyWithFailedAccessCheck( LookupIterator* it); - MUST_USE_RESULT static Maybe - GetElementAttributeWithInterceptor(Handle object, - Handle receiver, - uint32_t index, bool continue_search); - - // Queries indexed interceptor on an object for property attributes. - // - // We determine property attributes as follows: - // - if interceptor has a query callback, then the property attributes are - // the result of query callback for index. - // - otherwise if interceptor has a getter callback and it returns - // non-empty value on index, then the property attributes is NONE - // (property is present, and it is enumerable, configurable, writable) - // - otherwise there are no property attributes that can be inferred for - // interceptor, and this function returns ABSENT. - MUST_USE_RESULT static Maybe - GetElementAttributeFromInterceptor(Handle object, - Handle receiver, - uint32_t index); - - MUST_USE_RESULT static Maybe - GetElementAttributeWithoutInterceptor(Handle object, - Handle receiver, - uint32_t index, - bool continue_search); MUST_USE_RESULT static MaybeHandle SetElementWithCallback( Handle object, Handle structure, uint32_t index, Handle value, Handle holder, @@ -2347,11 +2315,6 @@ class JSObject: public JSReceiver { MUST_USE_RESULT static MaybeHandle SetFastDoubleElement( Handle object, uint32_t index, Handle value, LanguageMode language_mode, bool check_prototype = true); - MUST_USE_RESULT static Maybe - GetElementAttributesWithFailedAccessCheck(Isolate* isolate, - Handle object, - Handle receiver, - uint32_t index); MUST_USE_RESULT static MaybeHandle SetPropertyWithFailedAccessCheck( LookupIterator* it, Handle value, LanguageMode language_mode); @@ -10017,10 +9980,6 @@ class JSProxy: public JSReceiver { GetPropertyAttributesWithHandler(Handle proxy, Handle receiver, Handle name); - MUST_USE_RESULT static Maybe - GetElementAttributeWithHandler(Handle proxy, - Handle receiver, - uint32_t index); MUST_USE_RESULT static MaybeHandle SetPropertyWithHandler( Handle proxy, Handle receiver, Handle name, Handle value, LanguageMode language_mode); diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc index e37807e..69af11c 100644 --- a/src/runtime/runtime-object.cc +++ b/src/runtime/runtime-object.cc @@ -35,22 +35,7 @@ MaybeHandle Runtime::GetElementOrCharAt(Isolate* isolate, if (!result->IsUndefined()) return result; } - // Handle [] indexing on String objects - if (object->IsStringObjectWithCharacterAt(index)) { - Handle js_value = Handle::cast(object); - Handle result = - GetCharAt(Handle(String::cast(js_value->value())), index); - if (!result->IsUndefined()) return result; - } - - Handle result; - if (object->IsString() || object->IsNumber() || object->IsBoolean()) { - PrototypeIterator iter(isolate, object); - return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter), - index); - } else { - return Object::GetElement(isolate, object, index); - } + return Object::GetElement(isolate, object, index); } @@ -360,61 +345,38 @@ MUST_USE_RESULT static MaybeHandle GetOwnProperty(Isolate* isolate, Factory* factory = isolate->factory(); PropertyAttributes attrs; - uint32_t index = 0; - Handle value; - MaybeHandle maybe_accessors; - // TODO(verwaest): Unify once indexed properties can be handled by the - // LookupIterator. - if (name->AsArrayIndex(&index)) { - // Get attributes. - Maybe maybe = - JSReceiver::GetOwnElementAttribute(obj, index); - if (!maybe.IsJust()) return MaybeHandle(); - attrs = maybe.FromJust(); - if (attrs == ABSENT) return factory->undefined_value(); - - // Get AccessorPair if present. - maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index); - - // Get value if not an AccessorPair. - if (maybe_accessors.is_null()) { - ASSIGN_RETURN_ON_EXCEPTION( - isolate, value, Runtime::GetElementOrCharAt(isolate, obj, index), - Object); - } - } else { - // Get attributes. - LookupIterator it(obj, name, LookupIterator::HIDDEN); - Maybe maybe = JSObject::GetPropertyAttributes(&it); - if (!maybe.IsJust()) return MaybeHandle(); - attrs = maybe.FromJust(); - if (attrs == ABSENT) return factory->undefined_value(); - - // Get AccessorPair if present. - if (it.state() == LookupIterator::ACCESSOR && - it.GetAccessors()->IsAccessorPair()) { - maybe_accessors = Handle::cast(it.GetAccessors()); - } + uint32_t index; + // Get attributes. + LookupIterator it = + name->AsArrayIndex(&index) + ? LookupIterator(isolate, obj, index, LookupIterator::HIDDEN) + : LookupIterator(obj, name, LookupIterator::HIDDEN); + Maybe maybe = JSObject::GetPropertyAttributes(&it); + + if (!maybe.IsJust()) return MaybeHandle(); + attrs = maybe.FromJust(); + if (attrs == ABSENT) return factory->undefined_value(); - // Get value if not an AccessorPair. - if (maybe_accessors.is_null()) { - ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::GetProperty(&it), - Object); - } - } DCHECK(!isolate->has_pending_exception()); Handle elms = factory->NewFixedArray(DESCRIPTOR_SIZE); elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); - elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null())); - Handle accessors; - if (maybe_accessors.ToHandle(&accessors)) { + bool is_accessor_pair = it.state() == LookupIterator::ACCESSOR && + it.GetAccessors()->IsAccessorPair(); + elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(is_accessor_pair)); + + if (is_accessor_pair) { + Handle accessors = + Handle::cast(it.GetAccessors()); Handle getter(accessors->GetComponent(ACCESSOR_GETTER), isolate); Handle setter(accessors->GetComponent(ACCESSOR_SETTER), isolate); elms->set(GETTER_INDEX, *getter); elms->set(SETTER_INDEX, *setter); } else { + Handle value; + ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::GetProperty(&it), + Object); elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); elms->set(VALUE_INDEX, *value); } diff --git a/test/cctest/test-api-interceptors.cc b/test/cctest/test-api-interceptors.cc index 982a4fe..f0f817f 100644 --- a/test/cctest/test-api-interceptors.cc +++ b/test/cctest/test-api-interceptors.cc @@ -3103,21 +3103,25 @@ THREADED_TEST(IndexedAllCanReadInterceptor) { ExpectInt32("checked[15]", 17); CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')") ->IsUndefined()); - CHECK_EQ(3, access_check_data.count); + CHECK_EQ(2, access_check_data.count); access_check_data.result = false; ExpectInt32("checked[15]", intercept_data_0.value); - // Note: this should throw but without a LookupIterator it's complicated. - CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')") - ->IsUndefined()); - CHECK_EQ(6, access_check_data.count); + { + v8::TryCatch try_catch(isolate); + CompileRun("Object.getOwnPropertyDescriptor(checked, '15')"); + CHECK(try_catch.HasCaught()); + } + CHECK_EQ(4, access_check_data.count); intercept_data_1.should_intercept = true; ExpectInt32("checked[15]", intercept_data_1.value); - // Note: this should throw but without a LookupIterator it's complicated. - CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')") - ->IsUndefined()); - CHECK_EQ(9, access_check_data.count); + { + v8::TryCatch try_catch(isolate); + CompileRun("Object.getOwnPropertyDescriptor(checked, '15')"); + CHECK(try_catch.HasCaught()); + } + CHECK_EQ(6, access_check_data.count); } diff --git a/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt b/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt index cc273df..df66f4e 100644 --- a/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt +++ b/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt @@ -56,9 +56,9 @@ PASS checkNumericGet(true, Boolean) is true FAIL checkNumericSet(1, Number) should be true. Was false. FAIL checkNumericSet('hello', String) should be true. Was false. FAIL checkNumericSet(true, Boolean) should be true. Was false. -FAIL checkNumericGetStrict(1, Number) should be true. Was false. -FAIL checkNumericGetStrict('hello', String) should be true. Was false. -FAIL checkNumericGetStrict(true, Boolean) should be true. Was false. +PASS checkNumericGetStrict(1, Number) is true +PASS checkNumericGetStrict('hello', String) is true +PASS checkNumericGetStrict(true, Boolean) is true FAIL checkNumericSetStrict(1, Number) should be true. Was false. FAIL checkNumericSetStrict('hello', String) should be true. Was false. FAIL checkNumericSetStrict(true, Boolean) should be true. Was false. -- 2.7.4