| Index: src/keys.cc
|
| diff --git a/src/keys.cc b/src/keys.cc
|
| index eee015075a584871fcb0aba448d63aca94601740..793460c6455c24b7d27462d56c6189a02c510477 100644
|
| --- a/src/keys.cc
|
| +++ b/src/keys.cc
|
| @@ -430,6 +430,29 @@ enum IndexedOrNamed { kIndexed, kNamed };
|
|
|
| // Returns |true| on success, |nothing| on exception.
|
| template <class Callback, IndexedOrNamed type>
|
| +Maybe<bool> CollectInterceptorKeysInternal(Handle<JSReceiver> receiver,
|
| + Handle<JSObject> object,
|
| + Handle<InterceptorInfo> interceptor,
|
| + KeyAccumulator* accumulator) {
|
| + Isolate* isolate = accumulator->isolate();
|
| + PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
|
| + *object, Object::DONT_THROW);
|
| + Handle<JSObject> result;
|
| + if (!interceptor->enumerator()->IsUndefined(isolate)) {
|
| + Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator());
|
| + const char* log_tag = type == kIndexed ? "interceptor-indexed-enum"
|
| + : "interceptor-named-enum";
|
| + LOG(isolate, ApiObjectAccess(log_tag, *object));
|
| + result = args.Call(enum_fun);
|
| + }
|
| + RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
|
| + if (result.is_null()) return Just(true);
|
| + accumulator->AddKeys(
|
| + result, type == kIndexed ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT);
|
| + return Just(true);
|
| +}
|
| +
|
| +template <class Callback, IndexedOrNamed type>
|
| Maybe<bool> CollectInterceptorKeys(Handle<JSReceiver> receiver,
|
| Handle<JSObject> object,
|
| KeyAccumulator* accumulator) {
|
| @@ -447,21 +470,8 @@ Maybe<bool> CollectInterceptorKeys(Handle<JSReceiver> receiver,
|
| !interceptor->all_can_read()) {
|
| return Just(true);
|
| }
|
| - PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
|
| - *object, Object::DONT_THROW);
|
| - Handle<JSObject> result;
|
| - if (!interceptor->enumerator()->IsUndefined(isolate)) {
|
| - Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator());
|
| - const char* log_tag = type == kIndexed ? "interceptor-indexed-enum"
|
| - : "interceptor-named-enum";
|
| - LOG(isolate, ApiObjectAccess(log_tag, *object));
|
| - result = args.Call(enum_fun);
|
| - }
|
| - RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
|
| - if (result.is_null()) return Just(true);
|
| - accumulator->AddKeys(
|
| - result, type == kIndexed ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT);
|
| - return Just(true);
|
| + return CollectInterceptorKeysInternal<Callback, type>(
|
| + receiver, object, interceptor, accumulator);
|
| }
|
|
|
| } // namespace
|
| @@ -539,6 +549,29 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver,
|
| kNamed>(receiver, object, this);
|
| }
|
|
|
| +Maybe<bool> KeyAccumulator::CollectAccessCheckInterceptorKeys(
|
| + Handle<AccessCheckInfo> access_check_info, Handle<JSReceiver> receiver,
|
| + Handle<JSObject> object) {
|
| + MAYBE_RETURN(
|
| + (CollectInterceptorKeysInternal<v8::IndexedPropertyEnumeratorCallback,
|
| + kIndexed>(
|
| + receiver, object,
|
| + handle(
|
| + InterceptorInfo::cast(access_check_info->indexed_interceptor()),
|
| + isolate_),
|
| + this)),
|
| + Nothing<bool>());
|
| + MAYBE_RETURN(
|
| + (CollectInterceptorKeysInternal<
|
| + v8::GenericNamedPropertyEnumeratorCallback, kNamed>(
|
| + receiver, object,
|
| + handle(InterceptorInfo::cast(access_check_info->named_interceptor()),
|
| + isolate_),
|
| + this)),
|
| + Nothing<bool>());
|
| + return Just(true);
|
| +}
|
| +
|
| // Returns |true| on success, |false| if prototype walking should be stopped,
|
| // |nothing| if an exception was thrown.
|
| Maybe<bool> KeyAccumulator::CollectOwnKeys(Handle<JSReceiver> receiver,
|
| @@ -553,6 +586,20 @@ Maybe<bool> KeyAccumulator::CollectOwnKeys(Handle<JSReceiver> receiver,
|
| }
|
| // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties.
|
| DCHECK(KeyCollectionMode::kOwnOnly == mode_);
|
| + Handle<AccessCheckInfo> access_check_info;
|
| + {
|
| + DisallowHeapAllocation no_gc;
|
| + AccessCheckInfo* maybe_info = AccessCheckInfo::Get(isolate_, object);
|
| + if (maybe_info) access_check_info = handle(maybe_info, isolate_);
|
| + }
|
| + // We always have both kinds of interceptors or none.
|
| + if (!access_check_info.is_null() &&
|
| + access_check_info->named_interceptor()) {
|
| + MAYBE_RETURN(CollectAccessCheckInterceptorKeys(access_check_info,
|
| + receiver, object),
|
| + Nothing<bool>());
|
| + return Just(false);
|
| + }
|
| filter_ = static_cast<PropertyFilter>(filter_ | ONLY_ALL_CAN_READ);
|
| }
|
| MAYBE_RETURN(CollectOwnElementIndices(receiver, object), Nothing<bool>());
|
|
|