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

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: Address comments. 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 3715 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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