OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |