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

Side by Side Diff: src/objects.cc

Issue 1481103002: [proxies] Implement [[Set]]. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/harmony/proxies-set.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/harmony/proxies-set.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698