Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index a5da88a0b3b2e0b5e44b17e0918d17655ea38e09..91180e238c46a4c74b0d21c10f4df6dbcc387f0e 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -1357,20 +1357,49 @@ bool JSObject::AllCanRead(LookupIterator* it) { |
return false; |
} |
+Handle<InterceptorInfo> JSObject::GetInterceptorForFailedAccessCheck( |
Toon Verwaest
2016/06/22 11:30:16
Seems like this belongs on the LookupIterator, but
|
+ LookupIterator* it) { |
+ Isolate* isolate = it->isolate(); |
+ Handle<JSObject> checked = it->GetHolder<JSObject>(); |
+ DisallowHeapAllocation no_gc; |
+ AccessCheckInfo* access_check_info = AccessCheckInfo::Get(isolate, checked); |
+ if (access_check_info) { |
+ if (it->IsElement()) { |
+ return handle( |
+ InterceptorInfo::cast(access_check_info->indexed_interceptor()), |
+ isolate); |
+ } else { |
+ return handle( |
+ InterceptorInfo::cast(access_check_info->named_interceptor()), |
+ isolate); |
+ } |
+ } |
+ return Handle<InterceptorInfo>(); |
+} |
MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( |
LookupIterator* it) { |
+ Isolate* isolate = it->isolate(); |
Handle<JSObject> checked = it->GetHolder<JSObject>(); |
- while (AllCanRead(it)) { |
- if (it->state() == LookupIterator::ACCESSOR) { |
- return GetPropertyWithAccessor(it); |
- } |
- DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
+ Handle<InterceptorInfo> interceptor = GetInterceptorForFailedAccessCheck(it); |
+ if (!interceptor.is_null()) { |
Toon Verwaest
2016/06/22 11:30:16
if (interceptor.is_null())? Negation just confuses
|
+ MaybeHandle<Object> result; |
bool done; |
- Handle<Object> result; |
- ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), result, |
- GetPropertyWithInterceptor(it, &done), Object); |
+ result = GetPropertyWithInterceptorInternal(it, interceptor, &done); |
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
if (done) return result; |
+ } else { |
+ while (AllCanRead(it)) { |
+ if (it->state() == LookupIterator::ACCESSOR) { |
+ return GetPropertyWithAccessor(it); |
+ } |
+ DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
+ bool done; |
+ Handle<Object> result; |
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, result, |
+ GetPropertyWithInterceptor(it, &done), Object); |
+ if (done) return result; |
+ } |
} |
// Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns |
@@ -1380,27 +1409,35 @@ MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( |
return it->factory()->undefined_value(); |
} |
- it->isolate()->ReportFailedAccessCheck(checked); |
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
+ isolate->ReportFailedAccessCheck(checked); |
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
return it->factory()->undefined_value(); |
} |
Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck( |
LookupIterator* it) { |
+ Isolate* isolate = it->isolate(); |
Handle<JSObject> checked = it->GetHolder<JSObject>(); |
- while (AllCanRead(it)) { |
- if (it->state() == LookupIterator::ACCESSOR) { |
- return Just(it->property_attributes()); |
+ Handle<InterceptorInfo> interceptor = GetInterceptorForFailedAccessCheck(it); |
+ if (!interceptor.is_null()) { |
+ Maybe<PropertyAttributes> result = |
+ GetPropertyAttributesWithInterceptorInternal(it, interceptor); |
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); |
+ if (result.FromMaybe(ABSENT) != ABSENT) return result; |
+ } else { |
+ while (AllCanRead(it)) { |
+ if (it->state() == LookupIterator::ACCESSOR) { |
+ return Just(it->property_attributes()); |
+ } |
+ DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
+ auto result = GetPropertyAttributesWithInterceptor(it); |
+ if (isolate->has_scheduled_exception()) break; |
+ if (result.IsJust() && result.FromJust() != ABSENT) return result; |
} |
- DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
- auto result = GetPropertyAttributesWithInterceptor(it); |
- if (it->isolate()->has_scheduled_exception()) break; |
- if (result.IsJust() && result.FromJust() != ABSENT) return result; |
} |
- it->isolate()->ReportFailedAccessCheck(checked); |
- RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), |
- Nothing<PropertyAttributes>()); |
+ isolate->ReportFailedAccessCheck(checked); |
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); |
return Just(ABSENT); |
} |
@@ -1421,13 +1458,20 @@ bool JSObject::AllCanWrite(LookupIterator* it) { |
Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck( |
LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) { |
+ Isolate* isolate = it->isolate(); |
Handle<JSObject> checked = it->GetHolder<JSObject>(); |
- if (AllCanWrite(it)) { |
+ Handle<InterceptorInfo> interceptor = GetInterceptorForFailedAccessCheck(it); |
+ if (!interceptor.is_null()) { |
+ Maybe<bool> result = SetPropertyWithInterceptorInternal( |
+ it, interceptor, should_throw, value); |
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
+ if (result.IsJust()) return result; |
+ } else if (AllCanWrite(it)) { |
return SetPropertyWithAccessor(it, value, should_throw); |
} |
- it->isolate()->ReportFailedAccessCheck(checked); |
- RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); |
+ isolate->ReportFailedAccessCheck(checked); |
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
return Just(true); |
} |
@@ -4217,17 +4261,14 @@ Handle<Map> Map::Update(Handle<Map> map) { |
ALLOW_IN_DESCRIPTOR); |
} |
- |
-Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, |
- ShouldThrow should_throw, |
- Handle<Object> value) { |
+Maybe<bool> JSObject::SetPropertyWithInterceptorInternal( |
Toon Verwaest
2016/06/22 11:30:16
namespace {} helper method?
|
+ LookupIterator* it, Handle<InterceptorInfo> interceptor, |
+ ShouldThrow should_throw, Handle<Object> value) { |
Isolate* isolate = it->isolate(); |
// Make sure that the top context does not change when doing callbacks or |
// interceptor calls. |
AssertNoContextChange ncc(isolate); |
- DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
- Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
if (interceptor->setter()->IsUndefined(isolate)) return Just(false); |
Handle<JSObject> holder = it->GetHolder<JSObject>(); |
@@ -4266,6 +4307,13 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, |
return Just(result); |
} |
+Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, |
+ ShouldThrow should_throw, |
+ Handle<Object> value) { |
+ DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
+ return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(), |
+ should_throw, value); |
+} |
MaybeHandle<Object> Object::SetProperty(Handle<Object> object, |
Handle<Name> name, Handle<Object> value, |
@@ -5525,9 +5573,9 @@ MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes( |
return DefineOwnPropertyIgnoreAttributes(&it, value, attributes); |
} |
- |
-Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
- LookupIterator* it) { |
+Maybe<PropertyAttributes> |
+JSObject::GetPropertyAttributesWithInterceptorInternal( |
Toon Verwaest
2016/06/22 11:30:16
Same here?
|
+ LookupIterator* it, Handle<InterceptorInfo> interceptor) { |
Isolate* isolate = it->isolate(); |
// Make sure that the top context does not change when doing |
// callbacks or interceptor calls. |
@@ -5535,7 +5583,6 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
HandleScope scope(isolate); |
Handle<JSObject> holder = it->GetHolder<JSObject>(); |
- Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
if (!it->IsElement() && it->name()->IsSymbol() && |
!interceptor->can_intercept_symbols()) { |
return Just(ABSENT); |
@@ -5591,6 +5638,10 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
return Just(ABSENT); |
} |
+Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
+ LookupIterator* it) { |
+ return GetPropertyAttributesWithInterceptorInternal(it, it->GetInterceptor()); |
+} |
Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( |
LookupIterator* it) { |
@@ -15455,17 +15506,14 @@ void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { |
DCHECK(pos == elements->length()); |
} |
- |
-MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, |
- bool* done) { |
+MaybeHandle<Object> JSObject::GetPropertyWithInterceptorInternal( |
+ LookupIterator* it, Handle<InterceptorInfo> interceptor, bool* done) { |
*done = false; |
Isolate* isolate = it->isolate(); |
// Make sure that the top context does not change when doing callbacks or |
// interceptor calls. |
AssertNoContextChange ncc(isolate); |
- DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
- Handle<InterceptorInfo> interceptor = it->GetInterceptor(); |
if (interceptor->getter()->IsUndefined(isolate)) { |
return isolate->factory()->undefined_value(); |
} |
@@ -15506,6 +15554,11 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, |
return handle(*result, isolate); |
} |
+MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, |
+ bool* done) { |
+ DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
+ return GetPropertyWithInterceptorInternal(it, it->GetInterceptor(), done); |
+} |
Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object, |
Handle<Name> name) { |
@@ -18863,5 +18916,20 @@ void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
} |
} |
+// static |
+AccessCheckInfo* AccessCheckInfo::Get(Isolate* isolate, |
+ Handle<JSObject> receiver) { |
+ Object* maybe_constructor = receiver->map()->GetConstructor(); |
+ if (!maybe_constructor->IsJSFunction()) return NULL; |
Toon Verwaest
2016/06/22 11:30:16
Shouldn't this be a DCHECK; in addition to a DCHEC
jochen (gone - plz use gerrit)
2016/06/22 12:28:22
it's null for detached global proxies
|
+ JSFunction* constructor = JSFunction::cast(maybe_constructor); |
+ if (!constructor->shared()->IsApiFunction()) return NULL; |
Toon Verwaest
2016/06/22 11:30:16
In which case this has to be an API function, so a
jochen (gone - plz use gerrit)
2016/06/22 12:28:22
it's not for the debug context.
|
+ |
+ Object* data_obj = |
+ constructor->shared()->get_api_func_data()->access_check_info(); |
Toon Verwaest
2016/06/22 11:30:16
Unrelated to this particular CL, but we should pro
|
+ if (data_obj->IsUndefined(isolate)) return NULL; |
+ |
+ return AccessCheckInfo::cast(data_obj); |
+} |
+ |
} // namespace internal |
} // namespace v8 |