Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/objects.cc

Issue 2272383002: [api] Add interceptor for defineProperty(). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@DefineProperty
Patch Set: Add test for intercepting Object.freeze(). Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <memory> 9 #include <memory>
10 #include <sstream> 10 #include <sstream>
(...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 v8::GenericNamedPropertySetterCallback setter = 1670 v8::GenericNamedPropertySetterCallback setter =
1671 v8::ToCData<v8::GenericNamedPropertySetterCallback>( 1671 v8::ToCData<v8::GenericNamedPropertySetterCallback>(
1672 interceptor->setter()); 1672 interceptor->setter());
1673 result = !args.Call(setter, name, value).is_null(); 1673 result = !args.Call(setter, name, value).is_null();
1674 } 1674 }
1675 1675
1676 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); 1676 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
1677 return Just(result); 1677 return Just(result);
1678 } 1678 }
1679 1679
1680 Maybe<bool> DefinePropertyWithInterceptorInternal(
1681 LookupIterator* it, Handle<InterceptorInfo> interceptor,
1682 Object::ShouldThrow should_throw, PropertyDescriptor& desc) {
1683 Isolate* isolate = it->isolate();
1684 // Make sure that the top context does not change when doing callbacks or
1685 // interceptor calls.
1686 AssertNoContextChange ncc(isolate);
1687
1688 if (interceptor->definer()->IsUndefined(isolate)) return Just(false);
1689
1690 Handle<JSObject> holder = it->GetHolder<JSObject>();
1691 bool result;
1692 Handle<Object> receiver = it->GetReceiver();
1693 if (!receiver->IsJSReceiver()) {
1694 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
jochen (gone - plz use gerrit) 2016/08/26 18:18:46 btw, is it a problem for your usecase that our int
Franzi 2016/09/01 06:38:18 So far, nobody has complained about it :)
1695 Object::ConvertReceiver(isolate, receiver),
1696 Nothing<bool>());
1697 }
1698 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
1699 *holder, should_throw);
1700
1701 std::unique_ptr<v8::PropertyDescriptor> propDescriptor(
jochen (gone - plz use gerrit) 2016/08/26 18:18:46 nit. property_descriptor
Franzi 2016/09/01 06:38:18 Done.
1702 new v8::PropertyDescriptor());
1703 if (PropertyDescriptor::IsAccessorDescriptor(&desc)) {
1704 Handle<JSReceiver> getter = Handle<JSReceiver>();
1705 if (desc.has_get() && desc.get()->IsCallable()) {
1706 getter = Handle<JSReceiver>::cast(desc.get());
1707 }
1708 Handle<JSReceiver> setter = Handle<JSReceiver>();
1709 if (desc.has_set() && desc.set()->IsCallable()) {
1710 setter = Handle<JSReceiver>::cast(desc.set());
1711 }
1712 propDescriptor.reset(new v8::PropertyDescriptor(
1713 v8::Utils::CallableToLocal(getter), desc.has_get(),
1714 v8::Utils::CallableToLocal(setter), desc.has_set()));
1715 } else if (PropertyDescriptor::IsDataDescriptor(&desc)) {
1716 propDescriptor.reset(new v8::PropertyDescriptor(
1717 v8::Utils::ToLocal(desc.value()), desc.has_value(), desc.writable(),
1718 desc.has_writable()));
1719 }
1720 if (desc.has_enumerable()) {
1721 propDescriptor->set_enumerable(desc.enumerable());
1722 }
1723 if (desc.has_configurable()) {
1724 propDescriptor->set_configurable(desc.configurable());
1725 }
1726
1727 if (it->IsElement()) {
1728 uint32_t index = it->index();
1729 v8::IndexedPropertyDefinerCallback definer =
1730 v8::ToCData<v8::IndexedPropertyDefinerCallback>(interceptor->definer());
1731 result = !args.Call(definer, index, *propDescriptor).is_null();
1732 } else {
1733 Handle<Name> name = it->name();
1734 DCHECK(!name->IsPrivate());
1735
1736 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) {
1737 return Just(false);
1738 }
1739
1740 v8::GenericNamedPropertyDefinerCallback definer =
1741 v8::ToCData<v8::GenericNamedPropertyDefinerCallback>(
1742 interceptor->definer());
1743 result = !args.Call(definer, name, *propDescriptor).is_null();
1744 }
1745
1746 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
1747 return Just(result);
1748 }
1749
1680 } // namespace 1750 } // namespace
1681 1751
1682 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( 1752 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
1683 LookupIterator* it) { 1753 LookupIterator* it) {
1684 Isolate* isolate = it->isolate(); 1754 Isolate* isolate = it->isolate();
1685 Handle<JSObject> checked = it->GetHolder<JSObject>(); 1755 Handle<JSObject> checked = it->GetHolder<JSObject>();
1686 Handle<InterceptorInfo> interceptor = 1756 Handle<InterceptorInfo> interceptor =
1687 it->GetInterceptorForFailedAccessCheck(); 1757 it->GetInterceptorForFailedAccessCheck();
1688 if (interceptor.is_null()) { 1758 if (interceptor.is_null()) {
1689 while (AllCanRead(it)) { 1759 while (AllCanRead(it)) {
(...skipping 2828 matching lines...) Expand 10 before | Expand all | Expand 10 after
4518 } 4588 }
4519 4589
4520 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, 4590 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
4521 ShouldThrow should_throw, 4591 ShouldThrow should_throw,
4522 Handle<Object> value) { 4592 Handle<Object> value) {
4523 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); 4593 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
4524 return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(), 4594 return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(),
4525 should_throw, value); 4595 should_throw, value);
4526 } 4596 }
4527 4597
4598 Maybe<bool> JSObject::DefinePropertyWithInterceptor(LookupIterator* it,
4599 ShouldThrow should_throw,
4600 PropertyDescriptor& desc) {
4601 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
4602 return DefinePropertyWithInterceptorInternal(it, it->GetInterceptor(),
jochen (gone - plz use gerrit) 2016/08/26 18:18:46 just inline this method, as it's not used from any
Franzi 2016/09/01 06:38:18 Done.
4603 should_throw, desc);
4604 }
4605
4528 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, 4606 MaybeHandle<Object> Object::SetProperty(Handle<Object> object,
4529 Handle<Name> name, Handle<Object> value, 4607 Handle<Name> name, Handle<Object> value,
4530 LanguageMode language_mode, 4608 LanguageMode language_mode,
4531 StoreFromKeyed store_mode) { 4609 StoreFromKeyed store_mode) {
4532 LookupIterator it(object, name); 4610 LookupIterator it(object, name);
4533 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); 4611 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode));
4534 return value; 4612 return value;
4535 } 4613 }
4536 4614
4537 4615
(...skipping 1997 matching lines...) Expand 10 before | Expand all | Expand 10 after
6535 // Deal with access checks first. 6613 // Deal with access checks first.
6536 if (it.state() == LookupIterator::ACCESS_CHECK) { 6614 if (it.state() == LookupIterator::ACCESS_CHECK) {
6537 if (!it.HasAccess()) { 6615 if (!it.HasAccess()) {
6538 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>()); 6616 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
6539 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); 6617 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
6540 return Just(true); 6618 return Just(true);
6541 } 6619 }
6542 it.Next(); 6620 it.Next();
6543 } 6621 }
6544 6622
6623 // Handle interceptor
6624 if (it.state() == LookupIterator::INTERCEPTOR) {
6625 Handle<Map> store_target_map;
6626 if (it.GetReceiver()->IsJSObject()) {
6627 store_target_map = handle(it.GetStoreTarget()->map(), it.isolate());
6628 }
6629 if (it.HolderIsReceiverOrHiddenPrototype()) {
6630 Maybe<bool> result =
6631 JSObject::DefinePropertyWithInterceptor(&it, should_throw, *desc);
6632 if (result.IsNothing() || result.FromJust()) {
6633 return result;
6634 }
6635 // Interceptor modified the store target but failed to set the
6636 // property.
6637 if (!store_target_map.is_null() &&
6638 *store_target_map != it.GetStoreTarget()->map()) {
6639 it.isolate()->PushStackTraceAndDie(
6640 0xabababaa, v8::ToCData<void*>(it.GetInterceptor()->setter()),
6641 nullptr, 0xabababab);
6642 }
6643 Utils::ApiCheck(store_target_map.is_null() ||
6644 *store_target_map == it.GetStoreTarget()->map(),
6645 it.IsElement() ? "v8::IndexedPropertySetterCallback"
6646 : "v8::NamedPropertySetterCallback",
6647 "Interceptor silently changed store target.");
6648 }
6649 it.Next();
6650 }
6651
6545 return OrdinaryDefineOwnProperty(&it, desc, should_throw); 6652 return OrdinaryDefineOwnProperty(&it, desc, should_throw);
6546 } 6653 }
6547 6654
6548 6655
6549 // ES6 9.1.6.1 6656 // ES6 9.1.6.1
6550 // static 6657 // static
6551 Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, 6658 Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it,
6552 PropertyDescriptor* desc, 6659 PropertyDescriptor* desc,
6553 ShouldThrow should_throw) { 6660 ShouldThrow should_throw) {
6554 Isolate* isolate = it->isolate(); 6661 Isolate* isolate = it->isolate();
(...skipping 12775 matching lines...) Expand 10 before | Expand all | Expand 10 after
19330 for (PrototypeIterator iter(isolate, this, kStartAtReceiver, 19437 for (PrototypeIterator iter(isolate, this, kStartAtReceiver,
19331 PrototypeIterator::END_AT_NULL); 19438 PrototypeIterator::END_AT_NULL);
19332 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) { 19439 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) {
19333 if (iter.GetCurrent<Object>()->IsJSProxy()) return true; 19440 if (iter.GetCurrent<Object>()->IsJSProxy()) return true;
19334 } 19441 }
19335 return false; 19442 return false;
19336 } 19443 }
19337 19444
19338 } // namespace internal 19445 } // namespace internal
19339 } // namespace v8 19446 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698