Chromium Code Reviews| 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 3713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3724 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); | 3724 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); |
| 3725 } | 3725 } |
| 3726 | 3726 |
| 3727 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); | 3727 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); |
| 3728 if (result.IsEmpty()) return Just(false); | 3728 if (result.IsEmpty()) return Just(false); |
| 3729 #ifdef DEBUG | 3729 #ifdef DEBUG |
| 3730 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 3730 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
| 3731 result_internal->VerifyApiCallResultType(); | 3731 result_internal->VerifyApiCallResultType(); |
| 3732 #endif | 3732 #endif |
| 3733 return Just(true); | 3733 return Just(true); |
| 3734 // TODO(neis): In the future, we may want to actually return the interceptor's | |
| 3735 // result, which then should be a boolean. | |
| 3734 } | 3736 } |
| 3735 | 3737 |
| 3736 | 3738 |
| 3737 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, | 3739 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, |
| 3738 Handle<Name> name, Handle<Object> value, | 3740 Handle<Name> name, Handle<Object> value, |
| 3739 LanguageMode language_mode, | 3741 LanguageMode language_mode, |
| 3740 StoreFromKeyed store_mode) { | 3742 StoreFromKeyed store_mode) { |
| 3741 LookupIterator it(object, name); | 3743 LookupIterator it(object, name); |
| 3742 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); | 3744 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); |
| 3743 return value; | 3745 return value; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 3765 UNREACHABLE(); | 3767 UNREACHABLE(); |
| 3766 | 3768 |
| 3767 case LookupIterator::ACCESS_CHECK: | 3769 case LookupIterator::ACCESS_CHECK: |
| 3768 if (it->HasAccess()) break; | 3770 if (it->HasAccess()) break; |
| 3769 // Check whether it makes sense to reuse the lookup iterator. Here it | 3771 // Check whether it makes sense to reuse the lookup iterator. Here it |
| 3770 // might still call into setters up the prototype chain. | 3772 // might still call into setters up the prototype chain. |
| 3771 return JSObject::SetPropertyWithFailedAccessCheck(it, value, | 3773 return JSObject::SetPropertyWithFailedAccessCheck(it, value, |
| 3772 should_throw); | 3774 should_throw); |
| 3773 | 3775 |
| 3774 case LookupIterator::JSPROXY: | 3776 case LookupIterator::JSPROXY: |
| 3775 if (it->HolderIsReceiverOrHiddenPrototype()) { | 3777 return JSProxy::SetProperty(it->GetHolder<JSProxy>(), it->GetName(), |
| 3776 return JSProxy::SetPropertyWithHandler( | 3778 value, it->GetReceiver(), language_mode); |
| 3777 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value, | |
| 3778 should_throw); | |
| 3779 } else { | |
| 3780 // TODO(verwaest): Use the MaybeHandle to indicate result. | |
| 3781 bool has_result = false; | |
| 3782 Maybe<bool> maybe_result = | |
| 3783 JSProxy::SetPropertyViaPrototypesWithHandler( | |
| 3784 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), | |
| 3785 value, should_throw, &has_result); | |
| 3786 if (has_result) return maybe_result; | |
| 3787 done = true; | |
| 3788 } | |
| 3789 break; | |
| 3790 | 3779 |
| 3791 case LookupIterator::INTERCEPTOR: | 3780 case LookupIterator::INTERCEPTOR: |
| 3792 if (it->HolderIsReceiverOrHiddenPrototype()) { | 3781 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 3793 Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value); | 3782 Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value); |
| 3794 if (result.IsNothing() || result.FromJust()) return result; | 3783 if (result.IsNothing() || result.FromJust()) return result; |
| 3795 } else { | 3784 } else { |
| 3796 Maybe<PropertyAttributes> maybe_attributes = | 3785 Maybe<PropertyAttributes> maybe_attributes = |
| 3797 JSObject::GetPropertyAttributesWithInterceptor(it); | 3786 JSObject::GetPropertyAttributesWithInterceptor(it); |
| 3798 if (!maybe_attributes.IsJust()) return Nothing<bool>(); | 3787 if (!maybe_attributes.IsJust()) return Nothing<bool>(); |
| 3799 done = maybe_attributes.FromJust() != ABSENT; | 3788 done = maybe_attributes.FromJust() != ABSENT; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3863 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 3852 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 3864 return AddDataProperty(it, value, NONE, should_throw, store_mode); | 3853 return AddDataProperty(it, value, NONE, should_throw, store_mode); |
| 3865 } | 3854 } |
| 3866 | 3855 |
| 3867 | 3856 |
| 3868 Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, | 3857 Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, |
| 3869 LanguageMode language_mode, | 3858 LanguageMode language_mode, |
| 3870 StoreFromKeyed store_mode) { | 3859 StoreFromKeyed store_mode) { |
| 3871 ShouldThrow should_throw = | 3860 ShouldThrow should_throw = |
| 3872 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 3861 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 3862 Isolate* isolate = it->isolate(); | |
| 3873 | 3863 |
| 3874 bool found = false; | 3864 bool found = false; |
| 3875 Maybe<bool> result = | 3865 Maybe<bool> result = |
| 3876 SetPropertyInternal(it, value, language_mode, store_mode, &found); | 3866 SetPropertyInternal(it, value, language_mode, store_mode, &found); |
| 3877 if (found) return result; | 3867 if (found) return result; |
| 3878 | 3868 |
| 3879 // The property either doesn't exist on the holder or exists there as a data | 3869 // The property either doesn't exist on the holder or exists there as a data |
| 3880 // property. | 3870 // property. |
| 3881 | 3871 |
| 3882 if (!it->GetReceiver()->IsJSReceiver()) { | 3872 if (!it->GetReceiver()->IsJSReceiver()) { |
| 3883 return WriteToReadOnlyProperty(it, value, should_throw); | 3873 return WriteToReadOnlyProperty(it, value, should_throw); |
| 3884 } | 3874 } |
| 3875 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); | |
| 3885 | 3876 |
| 3886 LookupIterator::Configuration c = LookupIterator::OWN; | 3877 LookupIterator::Configuration c = LookupIterator::OWN; |
| 3887 LookupIterator own_lookup = | 3878 LookupIterator own_lookup = |
| 3888 it->IsElement() | 3879 it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c) |
| 3889 ? LookupIterator(it->isolate(), it->GetReceiver(), it->index(), c) | 3880 : LookupIterator(receiver, it->name(), c); |
| 3890 : LookupIterator(it->GetReceiver(), it->name(), c); | |
| 3891 | 3881 |
| 3892 for (; own_lookup.IsFound(); own_lookup.Next()) { | 3882 for (; own_lookup.IsFound(); own_lookup.Next()) { |
| 3893 switch (own_lookup.state()) { | 3883 switch (own_lookup.state()) { |
| 3894 case LookupIterator::ACCESS_CHECK: | 3884 case LookupIterator::ACCESS_CHECK: |
| 3895 if (!own_lookup.HasAccess()) { | 3885 if (!own_lookup.HasAccess()) { |
| 3896 return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value, | 3886 return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value, |
| 3897 should_throw); | 3887 should_throw); |
| 3898 } | 3888 } |
| 3899 break; | 3889 break; |
| 3900 | 3890 |
| 3901 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 3891 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
| 3902 return RedefineIncompatibleProperty(it->isolate(), it->GetName(), value, | 3892 case LookupIterator::ACCESSOR: |
| 3893 return RedefineIncompatibleProperty(isolate, it->GetName(), value, | |
| 3903 should_throw); | 3894 should_throw); |
| 3904 | 3895 |
| 3905 case LookupIterator::DATA: { | 3896 case LookupIterator::DATA: { |
| 3906 PropertyDetails details = own_lookup.property_details(); | 3897 PropertyDetails details = own_lookup.property_details(); |
| 3907 if (details.IsReadOnly()) { | 3898 if (details.IsReadOnly()) { |
| 3908 return WriteToReadOnlyProperty(&own_lookup, value, should_throw); | 3899 return WriteToReadOnlyProperty(&own_lookup, value, should_throw); |
| 3909 } | 3900 } |
| 3910 return SetDataProperty(&own_lookup, value); | 3901 return SetDataProperty(&own_lookup, value); |
| 3911 } | 3902 } |
| 3912 | 3903 |
| 3913 case LookupIterator::ACCESSOR: { | |
| 3914 return RedefineIncompatibleProperty(it->isolate(), it->GetName(), value, | |
| 3915 should_throw); | |
| 3916 } | |
| 3917 | |
| 3918 case LookupIterator::INTERCEPTOR: | 3904 case LookupIterator::INTERCEPTOR: |
| 3919 case LookupIterator::JSPROXY: { | 3905 case LookupIterator::JSPROXY: { |
| 3920 bool found = false; | 3906 PropertyDescriptor desc; |
| 3921 Maybe<bool> result = SetPropertyInternal( | 3907 bool owned = JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc); |
| 3922 &own_lookup, value, language_mode, store_mode, &found); | 3908 if (isolate->has_pending_exception()) return Nothing<bool>(); |
| 3923 if (found) return result; | 3909 if (!owned) |
| 3924 break; | 3910 return JSReceiver::CreateDataProperty(it, value, should_throw); |
| 3911 if (PropertyDescriptor::IsAccessorDescriptor(&desc) || !desc.writable()) | |
| 3912 return RedefineIncompatibleProperty(isolate, it->GetName(), value, | |
| 3913 should_throw); | |
| 3914 | |
| 3915 PropertyDescriptor value_desc; | |
| 3916 value_desc.set_value(value); | |
| 3917 bool result = JSReceiver::DefineOwnProperty( | |
| 3918 isolate, receiver, it->GetName(), &value_desc, should_throw); | |
| 3919 if (isolate->has_pending_exception()) return Nothing<bool>(); | |
| 3920 return Just(result); | |
| 3925 } | 3921 } |
| 3926 | 3922 |
| 3927 case LookupIterator::NOT_FOUND: | 3923 case LookupIterator::NOT_FOUND: |
| 3928 case LookupIterator::TRANSITION: | 3924 case LookupIterator::TRANSITION: |
| 3929 UNREACHABLE(); | 3925 UNREACHABLE(); |
| 3930 } | 3926 } |
| 3931 } | 3927 } |
| 3932 | 3928 |
| 3933 return JSObject::AddDataProperty(&own_lookup, value, NONE, should_throw, | 3929 return JSObject::AddDataProperty(&own_lookup, value, NONE, should_throw, |
| 3934 store_mode); | 3930 store_mode); |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4532 Handle<Object> result; | 4528 Handle<Object> result; |
| 4533 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 4529 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 4534 isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(), | 4530 isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(), |
| 4535 arraysize(args), args), | 4531 arraysize(args), args), |
| 4536 Nothing<bool>()); | 4532 Nothing<bool>()); |
| 4537 | 4533 |
| 4538 return Just(result->BooleanValue()); | 4534 return Just(result->BooleanValue()); |
| 4539 } | 4535 } |
| 4540 | 4536 |
| 4541 | 4537 |
| 4542 Maybe<bool> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, | 4538 Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name, |
| 4543 Handle<Object> receiver, | 4539 Handle<Object> value, Handle<Object> receiver, |
| 4544 Handle<Name> name, | 4540 LanguageMode language_mode) { |
| 4545 Handle<Object> value, | |
| 4546 ShouldThrow should_throw) { | |
| 4547 Isolate* isolate = proxy->GetIsolate(); | 4541 Isolate* isolate = proxy->GetIsolate(); |
| 4542 Factory* factory = isolate->factory(); | |
| 4543 Handle<String> trap_name = factory->set_string(); | |
| 4544 ShouldThrow should_throw = | |
| 4545 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | |
| 4548 | 4546 |
| 4549 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 4547 if (IsRevoked(proxy)) { |
| 4550 if (name->IsSymbol()) return Just(true); | 4548 isolate->Throw( |
| 4549 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name)); | |
| 4550 return Nothing<bool>(); | |
| 4551 } | |
| 4551 | 4552 |
| 4552 Handle<Object> args[] = { receiver, name, value }; | 4553 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); |
| 4553 RETURN_ON_EXCEPTION_VALUE(isolate, | 4554 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate); |
| 4554 CallTrap(proxy, "set", isolate->derived_set_trap(), | |
| 4555 arraysize(args), args), | |
| 4556 Nothing<bool>()); | |
| 4557 | 4555 |
| 4556 Handle<Object> trap; | |
| 4557 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, trap, GetTrap(proxy, trap_name), | |
| 4558 Nothing<bool>()); | |
| 4559 if (trap->IsUndefined()) { | |
| 4560 LookupIterator it = | |
| 4561 LookupIterator::PropertyOrElement(isolate, receiver, name, target); | |
| 4562 return Object::SetSuperProperty(&it, value, language_mode, | |
| 4563 Object::MAY_BE_STORE_FROM_KEYED); | |
| 4564 } | |
| 4565 | |
| 4566 Handle<Object> trap_result; | |
| 4567 Handle<Object> args[] = {target, name, value, receiver}; | |
| 4568 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 4569 isolate, trap_result, | |
| 4570 Execution::Call(isolate, trap, handler, arraysize(args), args), | |
| 4571 Nothing<bool>()); | |
| 4572 if (!trap_result->BooleanValue()) { | |
| 4573 RETURN_FAILURE(isolate, should_throw, | |
| 4574 NewTypeError(MessageTemplate::kProxyHandlerReturned, handler, | |
| 4575 factory->false_string(), trap_name)); | |
| 4576 } | |
| 4577 | |
| 4578 // Enforce the invariant. | |
| 4579 PropertyDescriptor target_desc; | |
| 4580 bool owned = | |
| 4581 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); | |
| 4582 if (isolate->has_pending_exception()) return Nothing<bool>(); | |
| 4583 if (owned) { | |
| 4584 bool inconsistent = | |
| 4585 (PropertyDescriptor::IsDataDescriptor(&target_desc) && | |
| 4586 !target_desc.configurable() && !target_desc.writable() && | |
| 4587 !value->SameValue(*target_desc.value())) || | |
| 4588 (PropertyDescriptor::IsAccessorDescriptor(&target_desc) && | |
| 4589 !target_desc.configurable() && !target_desc.set()->IsUndefined()); | |
|
Camillo Bruni
2015/11/30 10:57:59
Spec says: "If targetDesc.[[Set]] is undefined" :)
| |
| 4590 if (inconsistent) { | |
| 4591 isolate->Throw(*isolate->factory()->NewTypeError( | |
| 4592 MessageTemplate::kProxyTrapViolatesInvariant, trap_name)); | |
| 4593 return Nothing<bool>(); | |
| 4594 } | |
| 4595 } | |
| 4558 return Just(true); | 4596 return Just(true); |
| 4559 // TODO(neis): This needs to be made spec-conformant by looking at the | |
| 4560 // trap's result. | |
| 4561 } | 4597 } |
| 4562 | 4598 |
| 4563 | 4599 |
| 4564 Maybe<bool> JSProxy::SetPropertyViaPrototypesWithHandler( | |
| 4565 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, | |
| 4566 Handle<Object> value, ShouldThrow should_throw, bool* done) { | |
| 4567 Isolate* isolate = proxy->GetIsolate(); | |
| 4568 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. | |
| 4569 | |
| 4570 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | |
| 4571 if (name->IsSymbol()) { | |
| 4572 *done = false; // Return value will be ignored. | |
| 4573 return Nothing<bool>(); | |
| 4574 } | |
| 4575 | |
| 4576 *done = true; // except where redefined... | |
| 4577 Handle<Object> args[] = { name }; | |
| 4578 Handle<Object> result; | |
| 4579 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 4580 isolate, result, CallTrap(proxy, "getPropertyDescriptor", | |
| 4581 Handle<Object>(), arraysize(args), args), | |
| 4582 Nothing<bool>()); | |
| 4583 | |
| 4584 if (result->IsUndefined()) { | |
| 4585 *done = false; // Return value will be ignored. | |
| 4586 return Nothing<bool>(); | |
| 4587 } | |
| 4588 | |
| 4589 // Emulate [[GetProperty]] semantics for proxies. | |
| 4590 Handle<Object> argv[] = { result }; | |
| 4591 Handle<Object> desc; | |
| 4592 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 4593 isolate, desc, | |
| 4594 Execution::Call(isolate, isolate->to_complete_property_descriptor(), | |
| 4595 result, arraysize(argv), argv), | |
| 4596 Nothing<bool>()); | |
| 4597 | |
| 4598 // [[GetProperty]] requires to check that all properties are configurable. | |
| 4599 Handle<String> configurable_name = | |
| 4600 isolate->factory()->InternalizeOneByteString( | |
| 4601 STATIC_CHAR_VECTOR("configurable_")); | |
| 4602 Handle<Object> configurable = | |
| 4603 Object::GetProperty(desc, configurable_name).ToHandleChecked(); | |
| 4604 DCHECK(configurable->IsBoolean()); | |
| 4605 if (configurable->IsFalse()) { | |
| 4606 isolate->Throw(*isolate->factory()->NewTypeError( | |
| 4607 MessageTemplate::kProxyPropNotConfigurable, handler, name, | |
| 4608 isolate->factory()->NewStringFromAsciiChecked( | |
| 4609 "getPropertyDescriptor"))); | |
| 4610 return Nothing<bool>(); | |
| 4611 } | |
| 4612 DCHECK(configurable->IsTrue()); | |
| 4613 | |
| 4614 // Check for DataDescriptor. | |
| 4615 Handle<String> hasWritable_name = | |
| 4616 isolate->factory()->InternalizeOneByteString( | |
| 4617 STATIC_CHAR_VECTOR("hasWritable_")); | |
| 4618 Handle<Object> hasWritable = | |
| 4619 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); | |
| 4620 DCHECK(hasWritable->IsBoolean()); | |
| 4621 if (hasWritable->IsTrue()) { | |
| 4622 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( | |
| 4623 STATIC_CHAR_VECTOR("writable_")); | |
| 4624 Handle<Object> writable = | |
| 4625 Object::GetProperty(desc, writable_name).ToHandleChecked(); | |
| 4626 DCHECK(writable->IsBoolean()); | |
| 4627 *done = writable->IsFalse(); | |
| 4628 if (!*done) return Nothing<bool>(); // Return value will be ignored. | |
| 4629 return WriteToReadOnlyProperty(isolate, receiver, name, value, | |
| 4630 should_throw); | |
| 4631 } | |
| 4632 | |
| 4633 // We have an AccessorDescriptor. | |
| 4634 Handle<String> set_name = | |
| 4635 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); | |
| 4636 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); | |
| 4637 if (!setter->IsUndefined()) { | |
| 4638 // TODO(rossberg): nicer would be to cast to some JSCallable here... | |
| 4639 return SetPropertyWithDefinedSetter( | |
| 4640 receiver, Handle<JSReceiver>::cast(setter), value, should_throw); | |
| 4641 } | |
| 4642 | |
| 4643 RETURN_FAILURE( | |
| 4644 isolate, should_throw, | |
| 4645 NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy)); | |
| 4646 } | |
| 4647 | |
| 4648 | |
| 4649 Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy, | 4600 Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy, |
| 4650 Handle<Name> name, | 4601 Handle<Name> name, |
| 4651 LanguageMode language_mode) { | 4602 LanguageMode language_mode) { |
| 4652 ShouldThrow should_throw = | 4603 ShouldThrow should_throw = |
| 4653 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 4604 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 4654 Isolate* isolate = proxy->GetIsolate(); | 4605 Isolate* isolate = proxy->GetIsolate(); |
| 4655 Factory* factory = isolate->factory(); | 4606 Factory* factory = isolate->factory(); |
| 4656 Handle<String> trap_name = factory->deleteProperty_string(); | 4607 Handle<String> trap_name = factory->deleteProperty_string(); |
| 4657 | 4608 |
| 4658 if (IsRevoked(proxy)) { | 4609 if (IsRevoked(proxy)) { |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5032 MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes( | 4983 MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes( |
| 5033 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, | 4984 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, |
| 5034 PropertyAttributes attributes, ExecutableAccessorInfoHandling handling) { | 4985 PropertyAttributes attributes, ExecutableAccessorInfoHandling handling) { |
| 5035 Isolate* isolate = object->GetIsolate(); | 4986 Isolate* isolate = object->GetIsolate(); |
| 5036 LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name, | 4987 LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name, |
| 5037 LookupIterator::OWN); | 4988 LookupIterator::OWN); |
| 5038 return DefineOwnPropertyIgnoreAttributes(&it, value, attributes, handling); | 4989 return DefineOwnPropertyIgnoreAttributes(&it, value, attributes, handling); |
| 5039 } | 4990 } |
| 5040 | 4991 |
| 5041 | 4992 |
| 5042 Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it, | |
| 5043 Handle<Object> value) { | |
| 5044 DCHECK(it->GetReceiver()->IsJSObject()); | |
| 5045 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(it); | |
| 5046 if (maybe.IsNothing()) return Nothing<bool>(); | |
| 5047 | |
| 5048 if (it->IsFound()) { | |
| 5049 if (!it->IsConfigurable()) return Just(false); | |
| 5050 } else { | |
| 5051 if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) | |
| 5052 return Just(false); | |
| 5053 } | |
| 5054 | |
| 5055 RETURN_ON_EXCEPTION_VALUE( | |
| 5056 it->isolate(), | |
| 5057 DefineOwnPropertyIgnoreAttributes(it, value, NONE, DONT_FORCE_FIELD), | |
| 5058 Nothing<bool>()); | |
| 5059 | |
| 5060 return Just(true); | |
| 5061 } | |
| 5062 | |
| 5063 | |
| 5064 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( | 4993 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
| 5065 LookupIterator* it) { | 4994 LookupIterator* it) { |
| 5066 Isolate* isolate = it->isolate(); | 4995 Isolate* isolate = it->isolate(); |
| 5067 // Make sure that the top context does not change when doing | 4996 // Make sure that the top context does not change when doing |
| 5068 // callbacks or interceptor calls. | 4997 // callbacks or interceptor calls. |
| 5069 AssertNoContextChange ncc(isolate); | 4998 AssertNoContextChange ncc(isolate); |
| 5070 HandleScope scope(isolate); | 4999 HandleScope scope(isolate); |
| 5071 | 5000 |
| 5072 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 5001 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 5073 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | 5002 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| (...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6510 } | 6439 } |
| 6511 } | 6440 } |
| 6512 | 6441 |
| 6513 // 11. Return true. | 6442 // 11. Return true. |
| 6514 return true; | 6443 return true; |
| 6515 } | 6444 } |
| 6516 | 6445 |
| 6517 | 6446 |
| 6518 // static | 6447 // static |
| 6519 Maybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it, | 6448 Maybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it, |
| 6520 Handle<Object> value) { | 6449 Handle<Object> value, |
| 6521 // TODO(rossberg): Support proxies. | 6450 ShouldThrow should_throw) { |
| 6522 if (!it->GetReceiver()->IsJSObject()) return Nothing<bool>(); | 6451 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); |
| 6523 return JSObject::CreateDataProperty(it, value); | 6452 Isolate* isolate = receiver->GetIsolate(); |
| 6453 | |
| 6454 if (receiver->IsJSObject()) | |
| 6455 return JSObject::CreateDataProperty(it, value); // Shortcut. | |
| 6456 | |
| 6457 PropertyDescriptor new_desc; | |
| 6458 new_desc.set_value(value); | |
| 6459 new_desc.set_writable(true); | |
| 6460 new_desc.set_enumerable(true); | |
| 6461 new_desc.set_configurable(true); | |
| 6462 | |
| 6463 bool result = JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(), | |
| 6464 &new_desc, should_throw); | |
| 6465 if (isolate->has_pending_exception()) return Nothing<bool>(); | |
| 6466 return Just(result); | |
| 6524 } | 6467 } |
| 6525 | 6468 |
| 6526 | 6469 |
| 6470 Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it, | |
| 6471 Handle<Object> value) { | |
| 6472 DCHECK(it->GetReceiver()->IsJSObject()); | |
| 6473 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(it); | |
| 6474 if (maybe.IsNothing()) return Nothing<bool>(); | |
| 6475 | |
| 6476 if (it->IsFound()) { | |
| 6477 if (!it->IsConfigurable()) return Just(false); | |
| 6478 } else { | |
| 6479 if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) | |
| 6480 return Just(false); | |
| 6481 } | |
| 6482 | |
| 6483 RETURN_ON_EXCEPTION_VALUE( | |
| 6484 it->isolate(), | |
| 6485 DefineOwnPropertyIgnoreAttributes(it, value, NONE, DONT_FORCE_FIELD), | |
| 6486 Nothing<bool>()); | |
| 6487 | |
| 6488 return Just(true); | |
| 6489 } | |
| 6490 | |
| 6491 | |
| 6527 // TODO(jkummerow): Consider unification with FastAsArrayLength() in | 6492 // TODO(jkummerow): Consider unification with FastAsArrayLength() in |
| 6528 // accessors.cc. | 6493 // accessors.cc. |
| 6529 bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) { | 6494 bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) { |
| 6530 DCHECK(value->IsNumber() || value->IsName()); | 6495 DCHECK(value->IsNumber() || value->IsName()); |
| 6531 if (value->ToArrayLength(length)) return true; | 6496 if (value->ToArrayLength(length)) return true; |
| 6532 if (value->IsString()) return String::cast(*value)->AsArrayIndex(length); | 6497 if (value->IsString()) return String::cast(*value)->AsArrayIndex(length); |
| 6533 return false; | 6498 return false; |
| 6534 } | 6499 } |
| 6535 | 6500 |
| 6536 | 6501 |
| (...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7314 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 7279 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 7315 isolate, trap_result, | 7280 isolate, trap_result, |
| 7316 Execution::Call(isolate, trap, handler, arraysize(args), args), | 7281 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 7317 Nothing<bool>()); | 7282 Nothing<bool>()); |
| 7318 | 7283 |
| 7319 // Enforce the invariant. | 7284 // Enforce the invariant. |
| 7320 Maybe<bool> target_result = JSReceiver::IsExtensible(target); | 7285 Maybe<bool> target_result = JSReceiver::IsExtensible(target); |
| 7321 MAYBE_RETURN(target_result, Nothing<bool>()); | 7286 MAYBE_RETURN(target_result, Nothing<bool>()); |
| 7322 if (target_result.FromJust() != trap_result->BooleanValue()) { | 7287 if (target_result.FromJust() != trap_result->BooleanValue()) { |
| 7323 isolate->Throw(*factory->NewTypeError( | 7288 isolate->Throw(*factory->NewTypeError( |
| 7324 MessageTemplate::kProxyIsExtensibleViolatesInvariant)); | 7289 MessageTemplate::kProxyTrapViolatesInvariant, trap_name)); |
| 7325 return Nothing<bool>(); | 7290 return Nothing<bool>(); |
| 7326 } | 7291 } |
| 7327 return target_result; | 7292 return target_result; |
| 7328 } | 7293 } |
| 7329 | 7294 |
| 7330 | 7295 |
| 7331 bool JSObject::IsExtensible(Handle<JSObject> object) { | 7296 bool JSObject::IsExtensible(Handle<JSObject> object) { |
| 7332 Isolate* isolate = object->GetIsolate(); | 7297 Isolate* isolate = object->GetIsolate(); |
| 7333 if (object->IsAccessCheckNeeded() && | 7298 if (object->IsAccessCheckNeeded() && |
| 7334 !isolate->MayAccess(handle(isolate->context()), object)) { | 7299 !isolate->MayAccess(handle(isolate->context()), object)) { |
| (...skipping 11312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18647 if (cell->value() != *new_value) { | 18612 if (cell->value() != *new_value) { |
| 18648 cell->set_value(*new_value); | 18613 cell->set_value(*new_value); |
| 18649 Isolate* isolate = cell->GetIsolate(); | 18614 Isolate* isolate = cell->GetIsolate(); |
| 18650 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18615 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18651 isolate, DependentCode::kPropertyCellChangedGroup); | 18616 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18652 } | 18617 } |
| 18653 } | 18618 } |
| 18654 | 18619 |
| 18655 } // namespace internal | 18620 } // namespace internal |
| 18656 } // namespace v8 | 18621 } // namespace v8 |
| OLD | NEW |