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) |
Toon Verwaest
2015/12/01 11:30:08
{} if multiline
| |
3924 break; | 3910 return JSReceiver::CreateDataProperty(it, value, should_throw); |
3911 if (PropertyDescriptor::IsAccessorDescriptor(&desc) || !desc.writable()) | |
Toon Verwaest
2015/12/01 11:30:08
same here
| |
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)); | |
Toon Verwaest
2015/12/01 11:30:08
Funny how right after a potential "DONT_THROW" it
| |
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()); | |
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) { |
Toon Verwaest
2015/12/01 11:30:08
Perhaps we should add it->AssertOwnLookup() which
| |
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()) | |
Toon Verwaest
2015/12/01 11:30:08
{}
| |
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 |