Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 1f6624453db67507b3a243f31b05ede3a231a8c9..e4e1554122e0b9d0ac765790e16f11e159ee8fa9 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -1887,86 +1887,6 @@ RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) { |
} |
-static bool CheckAccessException(Object* callback, |
- v8::AccessType access_type) { |
- DisallowHeapAllocation no_gc; |
- ASSERT(!callback->IsForeign()); |
- if (callback->IsAccessorInfo()) { |
- AccessorInfo* info = AccessorInfo::cast(callback); |
- return |
- (access_type == v8::ACCESS_HAS && |
- (info->all_can_read() || info->all_can_write())) || |
- (access_type == v8::ACCESS_GET && info->all_can_read()) || |
- (access_type == v8::ACCESS_SET && info->all_can_write()); |
- } |
- return false; |
-} |
- |
- |
-template<class Key> |
-static bool CheckGenericAccess( |
- Handle<JSObject> receiver, |
- Handle<Object> end, |
- Key key, |
- v8::AccessType access_type, |
- bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) { |
- Isolate* isolate = receiver->GetIsolate(); |
- for (Handle<Object> current = receiver; |
- !current.is_identical_to(end); |
- current = Object::GetPrototype(isolate, current)) { |
- if (current->IsAccessCheckNeeded() && |
- !(isolate->*mayAccess)( |
- Handle<JSObject>::cast(current), key, access_type)) { |
- return false; |
- } |
- } |
- return true; |
-} |
- |
- |
-static void CheckPropertyAccess(Handle<JSObject> obj, |
- Handle<Name> name, |
- v8::AccessType access_type) { |
- Isolate* isolate = obj->GetIsolate(); |
- uint32_t index; |
- if (name->AsArrayIndex(&index)) { |
- Handle<Object> next(obj->GetPrototype(), isolate); |
- // TODO(1095): we should traverse hidden prototype hierachy as well. |
- if (!CheckGenericAccess( |
- obj, next, index, access_type, &Isolate::MayIndexedAccess)) { |
- obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); |
- } |
- return; |
- } |
- |
- LookupResult lookup(isolate); |
- obj->LookupOwn(name, &lookup, true); |
- |
- Handle<Object> next = lookup.IsProperty() |
- ? handle(lookup.holder()->GetPrototype(), isolate) |
- : Handle<Object>::cast(isolate->factory()->null_value()); |
- if (CheckGenericAccess<Handle<Object> >( |
- obj, next, name, access_type, &Isolate::MayNamedAccess)) { |
- return; |
- } |
- |
- // Access check callback denied the access, but some properties |
- // can have a special permissions which override callbacks decision |
- // (see v8::AccessControl). |
- // API callbacks can have per callback access exceptions. |
- if (lookup.IsFound() && lookup.type() == INTERCEPTOR) { |
- lookup.holder()->LookupOwnRealNamedProperty(name, &lookup); |
- } |
- |
- if (lookup.IsPropertyCallbacks() && |
- CheckAccessException(lookup.GetCallbackObject(), access_type)) { |
- return; |
- } |
- |
- isolate->ReportFailedAccessCheck(obj, access_type); |
-} |
- |
- |
// Enumerator used as indices into the array returned from GetOwnProperty |
enum PropertyDescriptorIndices { |
IS_ACCESSOR_INDEX, |
@@ -1986,36 +1906,65 @@ MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate, |
Heap* heap = isolate->heap(); |
Factory* factory = isolate->factory(); |
- CheckPropertyAccess(obj, name, v8::ACCESS_HAS); |
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
+ PropertyAttributes attrs; |
+ uint32_t index = 0; |
+ Handle<Object> value; |
+ MaybeHandle<AccessorPair> maybe_accessors; |
+ // TODO(verwaest): Unify once indexed properties can be handled by the |
+ // LookupIterator. |
+ if (name->AsArrayIndex(&index)) { |
+ // Get attributes. |
+ attrs = JSReceiver::GetOwnElementAttribute(obj, index); |
+ if (attrs == ABSENT) { |
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
+ 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::CHECK_OWN); |
+ attrs = JSObject::GetPropertyAttributes(&it); |
+ if (attrs == ABSENT) { |
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
+ return factory->undefined_value(); |
+ } |
+ |
+ // Get AccessorPair if present. |
+ if (it.state() == LookupIterator::PROPERTY && |
+ it.property_kind() == LookupIterator::ACCESSOR && |
+ it.GetAccessors()->IsAccessorPair()) { |
+ maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors()); |
+ } |
- PropertyAttributes attrs = JSReceiver::GetOwnPropertyAttributes(obj, name); |
- if (attrs == ABSENT) { |
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
- 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); |
+ } |
} |
ASSERT(!isolate->has_scheduled_exception()); |
- Handle<AccessorPair> accessors; |
- bool has_accessors = |
- JSObject::GetOwnPropertyAccessorPair(obj, name).ToHandle(&accessors); |
Handle<FixedArray> 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(has_accessors)); |
+ elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null())); |
- if (!has_accessors) { |
- elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); |
- // Runtime::GetObjectProperty does access check. |
- Handle<Object> value; |
- ASSIGN_RETURN_ON_EXCEPTION( |
- isolate, value, Runtime::GetObjectProperty(isolate, obj, name), |
- Object); |
- elms->set(VALUE_INDEX, *value); |
- } else { |
+ Handle<AccessorPair> accessors; |
+ if (maybe_accessors.ToHandle(&accessors)) { |
Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate); |
Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate); |
elms->set(GETTER_INDEX, *getter); |
elms->set(SETTER_INDEX, *setter); |
+ } else { |
+ elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); |
+ elms->set(VALUE_INDEX, *value); |
} |
return factory->NewJSArrayWithElements(elms); |