| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 3715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3726 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); | 3726 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); |
| 3727 } | 3727 } |
| 3728 | 3728 |
| 3729 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); | 3729 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); |
| 3730 if (result.IsEmpty()) return Just(false); | 3730 if (result.IsEmpty()) return Just(false); |
| 3731 #ifdef DEBUG | 3731 #ifdef DEBUG |
| 3732 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 3732 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
| 3733 result_internal->VerifyApiCallResultType(); | 3733 result_internal->VerifyApiCallResultType(); |
| 3734 #endif | 3734 #endif |
| 3735 return Just(true); | 3735 return Just(true); |
| 3736 // TODO(neis): In the future, we may want to actually return the interceptor's |
| 3737 // result, which then should be a boolean. |
| 3736 } | 3738 } |
| 3737 | 3739 |
| 3738 | 3740 |
| 3739 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, | 3741 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, |
| 3740 Handle<Name> name, Handle<Object> value, | 3742 Handle<Name> name, Handle<Object> value, |
| 3741 LanguageMode language_mode, | 3743 LanguageMode language_mode, |
| 3742 StoreFromKeyed store_mode) { | 3744 StoreFromKeyed store_mode) { |
| 3743 LookupIterator it(object, name); | 3745 LookupIterator it(object, name); |
| 3744 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); | 3746 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); |
| 3745 return value; | 3747 return value; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3767 UNREACHABLE(); | 3769 UNREACHABLE(); |
| 3768 | 3770 |
| 3769 case LookupIterator::ACCESS_CHECK: | 3771 case LookupIterator::ACCESS_CHECK: |
| 3770 if (it->HasAccess()) break; | 3772 if (it->HasAccess()) break; |
| 3771 // Check whether it makes sense to reuse the lookup iterator. Here it | 3773 // Check whether it makes sense to reuse the lookup iterator. Here it |
| 3772 // might still call into setters up the prototype chain. | 3774 // might still call into setters up the prototype chain. |
| 3773 return JSObject::SetPropertyWithFailedAccessCheck(it, value, | 3775 return JSObject::SetPropertyWithFailedAccessCheck(it, value, |
| 3774 should_throw); | 3776 should_throw); |
| 3775 | 3777 |
| 3776 case LookupIterator::JSPROXY: | 3778 case LookupIterator::JSPROXY: |
| 3777 if (it->HolderIsReceiverOrHiddenPrototype()) { | 3779 return JSProxy::SetProperty(it->GetHolder<JSProxy>(), it->GetName(), |
| 3778 return JSProxy::SetPropertyWithHandler( | 3780 value, it->GetReceiver(), language_mode); |
| 3779 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value, | |
| 3780 should_throw); | |
| 3781 } else { | |
| 3782 // TODO(verwaest): Use the MaybeHandle to indicate result. | |
| 3783 bool has_result = false; | |
| 3784 Maybe<bool> maybe_result = | |
| 3785 JSProxy::SetPropertyViaPrototypesWithHandler( | |
| 3786 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), | |
| 3787 value, should_throw, &has_result); | |
| 3788 if (has_result) return maybe_result; | |
| 3789 done = true; | |
| 3790 } | |
| 3791 break; | |
| 3792 | 3781 |
| 3793 case LookupIterator::INTERCEPTOR: | 3782 case LookupIterator::INTERCEPTOR: |
| 3794 if (it->HolderIsReceiverOrHiddenPrototype()) { | 3783 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 3795 Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value); | 3784 Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value); |
| 3796 if (result.IsNothing() || result.FromJust()) return result; | 3785 if (result.IsNothing() || result.FromJust()) return result; |
| 3797 } else { | 3786 } else { |
| 3798 Maybe<PropertyAttributes> maybe_attributes = | 3787 Maybe<PropertyAttributes> maybe_attributes = |
| 3799 JSObject::GetPropertyAttributesWithInterceptor(it); | 3788 JSObject::GetPropertyAttributesWithInterceptor(it); |
| 3800 if (!maybe_attributes.IsJust()) return Nothing<bool>(); | 3789 if (!maybe_attributes.IsJust()) return Nothing<bool>(); |
| 3801 done = maybe_attributes.FromJust() != ABSENT; | 3790 done = maybe_attributes.FromJust() != ABSENT; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3865 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 3854 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 3866 return AddDataProperty(it, value, NONE, should_throw, store_mode); | 3855 return AddDataProperty(it, value, NONE, should_throw, store_mode); |
| 3867 } | 3856 } |
| 3868 | 3857 |
| 3869 | 3858 |
| 3870 Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, | 3859 Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, |
| 3871 LanguageMode language_mode, | 3860 LanguageMode language_mode, |
| 3872 StoreFromKeyed store_mode) { | 3861 StoreFromKeyed store_mode) { |
| 3873 ShouldThrow should_throw = | 3862 ShouldThrow should_throw = |
| 3874 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 3863 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 3864 Isolate* isolate = it->isolate(); |
| 3875 | 3865 |
| 3876 bool found = false; | 3866 bool found = false; |
| 3877 Maybe<bool> result = | 3867 Maybe<bool> result = |
| 3878 SetPropertyInternal(it, value, language_mode, store_mode, &found); | 3868 SetPropertyInternal(it, value, language_mode, store_mode, &found); |
| 3879 if (found) return result; | 3869 if (found) return result; |
| 3880 | 3870 |
| 3881 // The property either doesn't exist on the holder or exists there as a data | 3871 // The property either doesn't exist on the holder or exists there as a data |
| 3882 // property. | 3872 // property. |
| 3883 | 3873 |
| 3884 if (!it->GetReceiver()->IsJSReceiver()) { | 3874 if (!it->GetReceiver()->IsJSReceiver()) { |
| 3885 return WriteToReadOnlyProperty(it, value, should_throw); | 3875 return WriteToReadOnlyProperty(it, value, should_throw); |
| 3886 } | 3876 } |
| 3877 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); |
| 3887 | 3878 |
| 3888 LookupIterator::Configuration c = LookupIterator::OWN; | 3879 LookupIterator::Configuration c = LookupIterator::OWN; |
| 3889 LookupIterator own_lookup = | 3880 LookupIterator own_lookup = |
| 3890 it->IsElement() | 3881 it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c) |
| 3891 ? LookupIterator(it->isolate(), it->GetReceiver(), it->index(), c) | 3882 : LookupIterator(receiver, it->name(), c); |
| 3892 : LookupIterator(it->GetReceiver(), it->name(), c); | |
| 3893 | 3883 |
| 3894 for (; own_lookup.IsFound(); own_lookup.Next()) { | 3884 for (; own_lookup.IsFound(); own_lookup.Next()) { |
| 3895 switch (own_lookup.state()) { | 3885 switch (own_lookup.state()) { |
| 3896 case LookupIterator::ACCESS_CHECK: | 3886 case LookupIterator::ACCESS_CHECK: |
| 3897 if (!own_lookup.HasAccess()) { | 3887 if (!own_lookup.HasAccess()) { |
| 3898 return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value, | 3888 return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value, |
| 3899 should_throw); | 3889 should_throw); |
| 3900 } | 3890 } |
| 3901 break; | 3891 break; |
| 3902 | 3892 |
| 3903 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 3893 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
| 3904 return RedefineIncompatibleProperty(it->isolate(), it->GetName(), value, | 3894 case LookupIterator::ACCESSOR: |
| 3895 return RedefineIncompatibleProperty(isolate, it->GetName(), value, |
| 3905 should_throw); | 3896 should_throw); |
| 3906 | 3897 |
| 3907 case LookupIterator::DATA: { | 3898 case LookupIterator::DATA: { |
| 3908 PropertyDetails details = own_lookup.property_details(); | 3899 PropertyDetails details = own_lookup.property_details(); |
| 3909 if (details.IsReadOnly()) { | 3900 if (details.IsReadOnly()) { |
| 3910 return WriteToReadOnlyProperty(&own_lookup, value, should_throw); | 3901 return WriteToReadOnlyProperty(&own_lookup, value, should_throw); |
| 3911 } | 3902 } |
| 3912 return SetDataProperty(&own_lookup, value); | 3903 return SetDataProperty(&own_lookup, value); |
| 3913 } | 3904 } |
| 3914 | 3905 |
| 3915 case LookupIterator::ACCESSOR: { | |
| 3916 return RedefineIncompatibleProperty(it->isolate(), it->GetName(), value, | |
| 3917 should_throw); | |
| 3918 } | |
| 3919 | |
| 3920 case LookupIterator::INTERCEPTOR: | 3906 case LookupIterator::INTERCEPTOR: |
| 3921 case LookupIterator::JSPROXY: { | 3907 case LookupIterator::JSPROXY: { |
| 3922 bool found = false; | 3908 PropertyDescriptor desc; |
| 3923 Maybe<bool> result = SetPropertyInternal( | 3909 bool owned = JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc); |
| 3924 &own_lookup, value, language_mode, store_mode, &found); | 3910 if (isolate->has_pending_exception()) return Nothing<bool>(); |
| 3925 if (found) return result; | 3911 if (!owned) { |
| 3926 break; | 3912 return JSReceiver::CreateDataProperty(&own_lookup, value, |
| 3913 should_throw); |
| 3914 } |
| 3915 if (PropertyDescriptor::IsAccessorDescriptor(&desc) || |
| 3916 !desc.writable()) { |
| 3917 return RedefineIncompatibleProperty(isolate, it->GetName(), value, |
| 3918 should_throw); |
| 3919 } |
| 3920 |
| 3921 PropertyDescriptor value_desc; |
| 3922 value_desc.set_value(value); |
| 3923 bool result = JSReceiver::DefineOwnProperty( |
| 3924 isolate, receiver, it->GetName(), &value_desc, should_throw); |
| 3925 if (isolate->has_pending_exception()) return Nothing<bool>(); |
| 3926 return Just(result); |
| 3927 } | 3927 } |
| 3928 | 3928 |
| 3929 case LookupIterator::NOT_FOUND: | 3929 case LookupIterator::NOT_FOUND: |
| 3930 case LookupIterator::TRANSITION: | 3930 case LookupIterator::TRANSITION: |
| 3931 UNREACHABLE(); | 3931 UNREACHABLE(); |
| 3932 } | 3932 } |
| 3933 } | 3933 } |
| 3934 | 3934 |
| 3935 return JSObject::AddDataProperty(&own_lookup, value, NONE, should_throw, | 3935 return JSObject::AddDataProperty(&own_lookup, value, NONE, should_throw, |
| 3936 store_mode); | 3936 store_mode); |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4582 isolate->Throw(*isolate->factory()->NewTypeError( | 4582 isolate->Throw(*isolate->factory()->NewTypeError( |
| 4583 MessageTemplate::kProxyTargetNotExtensible)); | 4583 MessageTemplate::kProxyTargetNotExtensible)); |
| 4584 } | 4584 } |
| 4585 } | 4585 } |
| 4586 } | 4586 } |
| 4587 // 10. Return booleanTrapResult. | 4587 // 10. Return booleanTrapResult. |
| 4588 return Just(boolean_trap_result); | 4588 return Just(boolean_trap_result); |
| 4589 } | 4589 } |
| 4590 | 4590 |
| 4591 | 4591 |
| 4592 Maybe<bool> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, | 4592 Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name, |
| 4593 Handle<Object> receiver, | 4593 Handle<Object> value, Handle<Object> receiver, |
| 4594 Handle<Name> name, | 4594 LanguageMode language_mode) { |
| 4595 Handle<Object> value, | |
| 4596 ShouldThrow should_throw) { | |
| 4597 Isolate* isolate = proxy->GetIsolate(); | 4595 Isolate* isolate = proxy->GetIsolate(); |
| 4596 Factory* factory = isolate->factory(); |
| 4597 Handle<String> trap_name = factory->set_string(); |
| 4598 ShouldThrow should_throw = |
| 4599 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 4598 | 4600 |
| 4599 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 4601 if (proxy->IsRevoked()) { |
| 4600 if (name->IsSymbol()) return Just(true); | 4602 isolate->Throw( |
| 4603 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name)); |
| 4604 return Nothing<bool>(); |
| 4605 } |
| 4601 | 4606 |
| 4602 Handle<Object> args[] = { receiver, name, value }; | 4607 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); |
| 4603 RETURN_ON_EXCEPTION_VALUE(isolate, | 4608 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate); |
| 4604 CallTrap(proxy, "set", isolate->derived_set_trap(), | |
| 4605 arraysize(args), args), | |
| 4606 Nothing<bool>()); | |
| 4607 | 4609 |
| 4610 Handle<Object> trap; |
| 4611 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, trap, GetTrap(proxy, trap_name), |
| 4612 Nothing<bool>()); |
| 4613 if (trap->IsUndefined()) { |
| 4614 LookupIterator it = |
| 4615 LookupIterator::PropertyOrElement(isolate, receiver, name, target); |
| 4616 return Object::SetSuperProperty(&it, value, language_mode, |
| 4617 Object::MAY_BE_STORE_FROM_KEYED); |
| 4618 } |
| 4619 |
| 4620 Handle<Object> trap_result; |
| 4621 Handle<Object> args[] = {target, name, value, receiver}; |
| 4622 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 4623 isolate, trap_result, |
| 4624 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 4625 Nothing<bool>()); |
| 4626 if (!trap_result->BooleanValue()) { |
| 4627 RETURN_FAILURE(isolate, should_throw, |
| 4628 NewTypeError(MessageTemplate::kProxyHandlerReturned, handler, |
| 4629 factory->false_string(), trap_name)); |
| 4630 } |
| 4631 |
| 4632 // Enforce the invariant. |
| 4633 PropertyDescriptor target_desc; |
| 4634 bool owned = |
| 4635 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); |
| 4636 if (isolate->has_pending_exception()) return Nothing<bool>(); |
| 4637 if (owned) { |
| 4638 bool inconsistent = |
| 4639 (PropertyDescriptor::IsDataDescriptor(&target_desc) && |
| 4640 !target_desc.configurable() && !target_desc.writable() && |
| 4641 !value->SameValue(*target_desc.value())) || |
| 4642 (PropertyDescriptor::IsAccessorDescriptor(&target_desc) && |
| 4643 !target_desc.configurable() && target_desc.set()->IsUndefined()); |
| 4644 if (inconsistent) { |
| 4645 isolate->Throw(*isolate->factory()->NewTypeError( |
| 4646 MessageTemplate::kProxyTrapViolatesInvariant, trap_name)); |
| 4647 return Nothing<bool>(); |
| 4648 } |
| 4649 } |
| 4608 return Just(true); | 4650 return Just(true); |
| 4609 // TODO(neis): This needs to be made spec-conformant by looking at the | |
| 4610 // trap's result. | |
| 4611 } | 4651 } |
| 4612 | 4652 |
| 4613 | 4653 |
| 4614 Maybe<bool> JSProxy::SetPropertyViaPrototypesWithHandler( | |
| 4615 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, | |
| 4616 Handle<Object> value, ShouldThrow should_throw, bool* done) { | |
| 4617 Isolate* isolate = proxy->GetIsolate(); | |
| 4618 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. | |
| 4619 | |
| 4620 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | |
| 4621 if (name->IsSymbol()) { | |
| 4622 *done = false; // Return value will be ignored. | |
| 4623 return Nothing<bool>(); | |
| 4624 } | |
| 4625 | |
| 4626 *done = true; // except where redefined... | |
| 4627 Handle<Object> args[] = { name }; | |
| 4628 Handle<Object> result; | |
| 4629 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 4630 isolate, result, CallTrap(proxy, "getPropertyDescriptor", | |
| 4631 Handle<Object>(), arraysize(args), args), | |
| 4632 Nothing<bool>()); | |
| 4633 | |
| 4634 if (result->IsUndefined()) { | |
| 4635 *done = false; // Return value will be ignored. | |
| 4636 return Nothing<bool>(); | |
| 4637 } | |
| 4638 | |
| 4639 // Emulate [[GetProperty]] semantics for proxies. | |
| 4640 Handle<Object> argv[] = { result }; | |
| 4641 Handle<Object> desc; | |
| 4642 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 4643 isolate, desc, | |
| 4644 Execution::Call(isolate, isolate->to_complete_property_descriptor(), | |
| 4645 result, arraysize(argv), argv), | |
| 4646 Nothing<bool>()); | |
| 4647 | |
| 4648 // [[GetProperty]] requires to check that all properties are configurable. | |
| 4649 Handle<String> configurable_name = | |
| 4650 isolate->factory()->InternalizeOneByteString( | |
| 4651 STATIC_CHAR_VECTOR("configurable_")); | |
| 4652 Handle<Object> configurable = | |
| 4653 Object::GetProperty(desc, configurable_name).ToHandleChecked(); | |
| 4654 DCHECK(configurable->IsBoolean()); | |
| 4655 if (configurable->IsFalse()) { | |
| 4656 isolate->Throw(*isolate->factory()->NewTypeError( | |
| 4657 MessageTemplate::kProxyPropNotConfigurable, handler, name, | |
| 4658 isolate->factory()->NewStringFromAsciiChecked( | |
| 4659 "getPropertyDescriptor"))); | |
| 4660 return Nothing<bool>(); | |
| 4661 } | |
| 4662 DCHECK(configurable->IsTrue()); | |
| 4663 | |
| 4664 // Check for DataDescriptor. | |
| 4665 Handle<String> hasWritable_name = | |
| 4666 isolate->factory()->InternalizeOneByteString( | |
| 4667 STATIC_CHAR_VECTOR("hasWritable_")); | |
| 4668 Handle<Object> hasWritable = | |
| 4669 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); | |
| 4670 DCHECK(hasWritable->IsBoolean()); | |
| 4671 if (hasWritable->IsTrue()) { | |
| 4672 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( | |
| 4673 STATIC_CHAR_VECTOR("writable_")); | |
| 4674 Handle<Object> writable = | |
| 4675 Object::GetProperty(desc, writable_name).ToHandleChecked(); | |
| 4676 DCHECK(writable->IsBoolean()); | |
| 4677 *done = writable->IsFalse(); | |
| 4678 if (!*done) return Nothing<bool>(); // Return value will be ignored. | |
| 4679 return WriteToReadOnlyProperty(isolate, receiver, name, value, | |
| 4680 should_throw); | |
| 4681 } | |
| 4682 | |
| 4683 // We have an AccessorDescriptor. | |
| 4684 Handle<String> set_name = | |
| 4685 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); | |
| 4686 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); | |
| 4687 if (!setter->IsUndefined()) { | |
| 4688 // TODO(rossberg): nicer would be to cast to some JSCallable here... | |
| 4689 return SetPropertyWithDefinedSetter( | |
| 4690 receiver, Handle<JSReceiver>::cast(setter), value, should_throw); | |
| 4691 } | |
| 4692 | |
| 4693 RETURN_FAILURE( | |
| 4694 isolate, should_throw, | |
| 4695 NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy)); | |
| 4696 } | |
| 4697 | |
| 4698 | |
| 4699 Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy, | 4654 Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy, |
| 4700 Handle<Name> name, | 4655 Handle<Name> name, |
| 4701 LanguageMode language_mode) { | 4656 LanguageMode language_mode) { |
| 4702 ShouldThrow should_throw = | 4657 ShouldThrow should_throw = |
| 4703 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 4658 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 4704 Isolate* isolate = proxy->GetIsolate(); | 4659 Isolate* isolate = proxy->GetIsolate(); |
| 4705 Factory* factory = isolate->factory(); | 4660 Factory* factory = isolate->factory(); |
| 4706 Handle<String> trap_name = factory->deleteProperty_string(); | 4661 Handle<String> trap_name = factory->deleteProperty_string(); |
| 4707 | 4662 |
| 4708 if (proxy->IsRevoked()) { | 4663 if (proxy->IsRevoked()) { |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5082 MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes( | 5037 MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes( |
| 5083 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, | 5038 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, |
| 5084 PropertyAttributes attributes, ExecutableAccessorInfoHandling handling) { | 5039 PropertyAttributes attributes, ExecutableAccessorInfoHandling handling) { |
| 5085 Isolate* isolate = object->GetIsolate(); | 5040 Isolate* isolate = object->GetIsolate(); |
| 5086 LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name, | 5041 LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name, |
| 5087 LookupIterator::OWN); | 5042 LookupIterator::OWN); |
| 5088 return DefineOwnPropertyIgnoreAttributes(&it, value, attributes, handling); | 5043 return DefineOwnPropertyIgnoreAttributes(&it, value, attributes, handling); |
| 5089 } | 5044 } |
| 5090 | 5045 |
| 5091 | 5046 |
| 5092 Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it, | |
| 5093 Handle<Object> value) { | |
| 5094 DCHECK(it->GetReceiver()->IsJSObject()); | |
| 5095 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(it); | |
| 5096 if (maybe.IsNothing()) return Nothing<bool>(); | |
| 5097 | |
| 5098 if (it->IsFound()) { | |
| 5099 if (!it->IsConfigurable()) return Just(false); | |
| 5100 } else { | |
| 5101 if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) | |
| 5102 return Just(false); | |
| 5103 } | |
| 5104 | |
| 5105 RETURN_ON_EXCEPTION_VALUE( | |
| 5106 it->isolate(), | |
| 5107 DefineOwnPropertyIgnoreAttributes(it, value, NONE, DONT_FORCE_FIELD), | |
| 5108 Nothing<bool>()); | |
| 5109 | |
| 5110 return Just(true); | |
| 5111 } | |
| 5112 | |
| 5113 | |
| 5114 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( | 5047 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
| 5115 LookupIterator* it) { | 5048 LookupIterator* it) { |
| 5116 Isolate* isolate = it->isolate(); | 5049 Isolate* isolate = it->isolate(); |
| 5117 // Make sure that the top context does not change when doing | 5050 // Make sure that the top context does not change when doing |
| 5118 // callbacks or interceptor calls. | 5051 // callbacks or interceptor calls. |
| 5119 AssertNoContextChange ncc(isolate); | 5052 AssertNoContextChange ncc(isolate); |
| 5120 HandleScope scope(isolate); | 5053 HandleScope scope(isolate); |
| 5121 | 5054 |
| 5122 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 5055 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 5123 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | 5056 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| (...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6560 } | 6493 } |
| 6561 } | 6494 } |
| 6562 | 6495 |
| 6563 // 11. Return true. | 6496 // 11. Return true. |
| 6564 return true; | 6497 return true; |
| 6565 } | 6498 } |
| 6566 | 6499 |
| 6567 | 6500 |
| 6568 // static | 6501 // static |
| 6569 Maybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it, | 6502 Maybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it, |
| 6570 Handle<Object> value) { | 6503 Handle<Object> value, |
| 6571 // TODO(rossberg): Support proxies. | 6504 ShouldThrow should_throw) { |
| 6572 if (!it->GetReceiver()->IsJSObject()) return Nothing<bool>(); | 6505 DCHECK(!it->check_prototype_chain()); |
| 6573 return JSObject::CreateDataProperty(it, value); | 6506 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); |
| 6507 Isolate* isolate = receiver->GetIsolate(); |
| 6508 |
| 6509 if (receiver->IsJSObject()) { |
| 6510 return JSObject::CreateDataProperty(it, value); // Shortcut. |
| 6511 } |
| 6512 |
| 6513 PropertyDescriptor new_desc; |
| 6514 new_desc.set_value(value); |
| 6515 new_desc.set_writable(true); |
| 6516 new_desc.set_enumerable(true); |
| 6517 new_desc.set_configurable(true); |
| 6518 |
| 6519 bool result = JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(), |
| 6520 &new_desc, should_throw); |
| 6521 if (isolate->has_pending_exception()) return Nothing<bool>(); |
| 6522 return Just(result); |
| 6574 } | 6523 } |
| 6575 | 6524 |
| 6576 | 6525 |
| 6526 Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it, |
| 6527 Handle<Object> value) { |
| 6528 DCHECK(it->GetReceiver()->IsJSObject()); |
| 6529 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(it); |
| 6530 if (maybe.IsNothing()) return Nothing<bool>(); |
| 6531 |
| 6532 if (it->IsFound()) { |
| 6533 if (!it->IsConfigurable()) return Just(false); |
| 6534 } else { |
| 6535 if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) |
| 6536 return Just(false); |
| 6537 } |
| 6538 |
| 6539 RETURN_ON_EXCEPTION_VALUE( |
| 6540 it->isolate(), |
| 6541 DefineOwnPropertyIgnoreAttributes(it, value, NONE, DONT_FORCE_FIELD), |
| 6542 Nothing<bool>()); |
| 6543 |
| 6544 return Just(true); |
| 6545 } |
| 6546 |
| 6547 |
| 6577 // TODO(jkummerow): Consider unification with FastAsArrayLength() in | 6548 // TODO(jkummerow): Consider unification with FastAsArrayLength() in |
| 6578 // accessors.cc. | 6549 // accessors.cc. |
| 6579 bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) { | 6550 bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) { |
| 6580 DCHECK(value->IsNumber() || value->IsName()); | 6551 DCHECK(value->IsNumber() || value->IsName()); |
| 6581 if (value->ToArrayLength(length)) return true; | 6552 if (value->ToArrayLength(length)) return true; |
| 6582 if (value->IsString()) return String::cast(*value)->AsArrayIndex(length); | 6553 if (value->IsString()) return String::cast(*value)->AsArrayIndex(length); |
| 6583 return false; | 6554 return false; |
| 6584 } | 6555 } |
| 6585 | 6556 |
| 6586 | 6557 |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7362 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 7333 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 7363 isolate, trap_result, | 7334 isolate, trap_result, |
| 7364 Execution::Call(isolate, trap, handler, arraysize(args), args), | 7335 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 7365 Nothing<bool>()); | 7336 Nothing<bool>()); |
| 7366 | 7337 |
| 7367 // Enforce the invariant. | 7338 // Enforce the invariant. |
| 7368 Maybe<bool> target_result = JSReceiver::IsExtensible(target); | 7339 Maybe<bool> target_result = JSReceiver::IsExtensible(target); |
| 7369 MAYBE_RETURN(target_result, Nothing<bool>()); | 7340 MAYBE_RETURN(target_result, Nothing<bool>()); |
| 7370 if (target_result.FromJust() != trap_result->BooleanValue()) { | 7341 if (target_result.FromJust() != trap_result->BooleanValue()) { |
| 7371 isolate->Throw(*factory->NewTypeError( | 7342 isolate->Throw(*factory->NewTypeError( |
| 7372 MessageTemplate::kProxyIsExtensibleViolatesInvariant)); | 7343 MessageTemplate::kProxyTrapViolatesInvariant, trap_name)); |
| 7373 return Nothing<bool>(); | 7344 return Nothing<bool>(); |
| 7374 } | 7345 } |
| 7375 return target_result; | 7346 return target_result; |
| 7376 } | 7347 } |
| 7377 | 7348 |
| 7378 | 7349 |
| 7379 bool JSObject::IsExtensible(Handle<JSObject> object) { | 7350 bool JSObject::IsExtensible(Handle<JSObject> object) { |
| 7380 Isolate* isolate = object->GetIsolate(); | 7351 Isolate* isolate = object->GetIsolate(); |
| 7381 if (object->IsAccessCheckNeeded() && | 7352 if (object->IsAccessCheckNeeded() && |
| 7382 !isolate->MayAccess(handle(isolate->context()), object)) { | 7353 !isolate->MayAccess(handle(isolate->context()), object)) { |
| (...skipping 11605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18988 if (cell->value() != *new_value) { | 18959 if (cell->value() != *new_value) { |
| 18989 cell->set_value(*new_value); | 18960 cell->set_value(*new_value); |
| 18990 Isolate* isolate = cell->GetIsolate(); | 18961 Isolate* isolate = cell->GetIsolate(); |
| 18991 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18962 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18992 isolate, DependentCode::kPropertyCellChangedGroup); | 18963 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18993 } | 18964 } |
| 18994 } | 18965 } |
| 18995 | 18966 |
| 18996 } // namespace internal | 18967 } // namespace internal |
| 18997 } // namespace v8 | 18968 } // namespace v8 |
| OLD | NEW |