| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index fce862b2579627425f2f17c208520df8fc2f27b0..db4d9b5a0cb544bb43f51a088e57eb69eef520d7 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -1677,6 +1677,71 @@ Maybe<bool> SetPropertyWithInterceptorInternal(
|
| return Just(result);
|
| }
|
|
|
| +Maybe<bool> DefinePropertyWithInterceptorInternal(
|
| + LookupIterator* it, Handle<InterceptorInfo> interceptor,
|
| + Object::ShouldThrow should_throw, PropertyDescriptor& desc) {
|
| + Isolate* isolate = it->isolate();
|
| + // Make sure that the top context does not change when doing callbacks or
|
| + // interceptor calls.
|
| + AssertNoContextChange ncc(isolate);
|
| +
|
| + if (interceptor->definer()->IsUndefined(isolate)) return Just(false);
|
| +
|
| + Handle<JSObject> holder = it->GetHolder<JSObject>();
|
| + bool result;
|
| + Handle<Object> receiver = it->GetReceiver();
|
| + if (!receiver->IsJSReceiver()) {
|
| + ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
|
| + Object::ConvertReceiver(isolate, receiver),
|
| + Nothing<bool>());
|
| + }
|
| + PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
|
| + *holder, should_throw);
|
| +
|
| + std::unique_ptr<v8::PropertyDescriptor> descriptor(
|
| + new v8::PropertyDescriptor());
|
| + if (PropertyDescriptor::IsAccessorDescriptor(&desc)) {
|
| + descriptor.reset(new v8::PropertyDescriptor(
|
| + v8::Utils::ToLocal(desc.get()), v8::Utils::ToLocal(desc.set())));
|
| + } else if (PropertyDescriptor::IsDataDescriptor(&desc)) {
|
| + if (desc.has_writable()) {
|
| + descriptor.reset(new v8::PropertyDescriptor(
|
| + v8::Utils::ToLocal(desc.value()), desc.writable()));
|
| + } else {
|
| + descriptor.reset(
|
| + new v8::PropertyDescriptor(v8::Utils::ToLocal(desc.value())));
|
| + }
|
| + }
|
| + if (desc.has_enumerable()) {
|
| + descriptor->set_enumerable(desc.enumerable());
|
| + }
|
| + if (desc.has_configurable()) {
|
| + descriptor->set_configurable(desc.configurable());
|
| + }
|
| +
|
| + if (it->IsElement()) {
|
| + uint32_t index = it->index();
|
| + v8::IndexedPropertyDefinerCallback definer =
|
| + v8::ToCData<v8::IndexedPropertyDefinerCallback>(interceptor->definer());
|
| + result = !args.Call(definer, index, *descriptor).is_null();
|
| + } else {
|
| + Handle<Name> name = it->name();
|
| + DCHECK(!name->IsPrivate());
|
| +
|
| + if (name->IsSymbol() && !interceptor->can_intercept_symbols()) {
|
| + return Just(false);
|
| + }
|
| +
|
| + v8::GenericNamedPropertyDefinerCallback definer =
|
| + v8::ToCData<v8::GenericNamedPropertyDefinerCallback>(
|
| + interceptor->definer());
|
| + result = !args.Call(definer, name, *descriptor).is_null();
|
| + }
|
| +
|
| + RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
|
| + return Just(result);
|
| +}
|
| +
|
| } // namespace
|
|
|
| MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
|
| @@ -6535,6 +6600,34 @@ Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate,
|
| it.Next();
|
| }
|
|
|
| + // Handle interceptor
|
| + if (it.state() == LookupIterator::INTERCEPTOR) {
|
| + Handle<Map> store_target_map;
|
| + if (it.GetReceiver()->IsJSObject()) {
|
| + store_target_map = handle(it.GetStoreTarget()->map(), it.isolate());
|
| + }
|
| + if (it.HolderIsReceiverOrHiddenPrototype()) {
|
| + Maybe<bool> result = DefinePropertyWithInterceptorInternal(
|
| + &it, it.GetInterceptor(), should_throw, *desc);
|
| + if (result.IsNothing() || result.FromJust()) {
|
| + return result;
|
| + }
|
| + // Interceptor modified the store target but failed to set the
|
| + // property.
|
| + if (!store_target_map.is_null() &&
|
| + *store_target_map != it.GetStoreTarget()->map()) {
|
| + it.isolate()->PushStackTraceAndDie(
|
| + 0xabababaa, v8::ToCData<void*>(it.GetInterceptor()->setter()),
|
| + nullptr, 0xabababab);
|
| + }
|
| + Utils::ApiCheck(store_target_map.is_null() ||
|
| + *store_target_map == it.GetStoreTarget()->map(),
|
| + it.IsElement() ? "v8::IndexedPropertySetterCallback"
|
| + : "v8::NamedPropertySetterCallback",
|
| + "Interceptor silently changed store target.");
|
| + }
|
| + }
|
| +
|
| return OrdinaryDefineOwnProperty(&it, desc, should_throw);
|
| }
|
|
|
|
|