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

Side by Side Diff: src/objects.cc

Issue 1456613002: [proxies] Update Object.defineProperty/ies for JSProxies (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: addressed comments Created 5 years, 1 month 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-define-property.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 4646 matching lines...) Expand 10 before | Expand all | Expand 10 after
4657 Handle<Object> handler(proxy->handler(), isolate); 4657 Handle<Object> handler(proxy->handler(), isolate);
4658 THROW_NEW_ERROR( 4658 THROW_NEW_ERROR(
4659 isolate, 4659 isolate,
4660 NewTypeError(MessageTemplate::kProxyHandlerDeleteFailed, handler), 4660 NewTypeError(MessageTemplate::kProxyHandlerDeleteFailed, handler),
4661 Object); 4661 Object);
4662 } 4662 }
4663 return isolate->factory()->ToBoolean(result_bool); 4663 return isolate->factory()->ToBoolean(result_bool);
4664 } 4664 }
4665 4665
4666 4666
4667 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler( 4667 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributes(LookupIterator* it) {
4668 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) { 4668 Isolate* isolate = it->isolate();
4669 Isolate* isolate = proxy->GetIsolate();
4670 HandleScope scope(isolate); 4669 HandleScope scope(isolate);
4671 4670 PropertyDescriptor desc;
4672 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 4671 bool found = JSProxy::GetOwnPropertyDescriptor(it, &desc);
4673 if (name->IsSymbol()) return Just(ABSENT); 4672 if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>();
4674 4673 if (!found) return Just(ABSENT);
4675 Handle<Object> args[] = { name }; 4674 return Just(desc.ToAttributes());
4676 Handle<Object> result;
4677 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4678 isolate, result, proxy->CallTrap(proxy, "getPropertyDescriptor",
4679 Handle<Object>(), arraysize(args), args),
4680 Nothing<PropertyAttributes>());
4681
4682 if (result->IsUndefined()) return Just(ABSENT);
4683
4684 Handle<Object> argv[] = { result };
4685 Handle<Object> desc;
4686 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4687 isolate, desc,
4688 Execution::Call(isolate, isolate->to_complete_property_descriptor(),
4689 result, arraysize(argv), argv),
4690 Nothing<PropertyAttributes>());
4691
4692 // Convert result to PropertyAttributes.
4693 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString(
4694 STATIC_CHAR_VECTOR("enumerable_"));
4695 Handle<Object> enumerable;
4696 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, enumerable,
4697 Object::GetProperty(desc, enum_n),
4698 Nothing<PropertyAttributes>());
4699 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString(
4700 STATIC_CHAR_VECTOR("configurable_"));
4701 Handle<Object> configurable;
4702 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, configurable,
4703 Object::GetProperty(desc, conf_n),
4704 Nothing<PropertyAttributes>());
4705 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString(
4706 STATIC_CHAR_VECTOR("writable_"));
4707 Handle<Object> writable;
4708 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, writable,
4709 Object::GetProperty(desc, writ_n),
4710 Nothing<PropertyAttributes>());
4711 if (!writable->BooleanValue()) {
4712 Handle<String> set_n = isolate->factory()->InternalizeOneByteString(
4713 STATIC_CHAR_VECTOR("set_"));
4714 Handle<Object> setter;
4715 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, setter,
4716 Object::GetProperty(desc, set_n),
4717 Nothing<PropertyAttributes>());
4718 writable = isolate->factory()->ToBoolean(!setter->IsUndefined());
4719 }
4720
4721 if (configurable->IsFalse()) {
4722 Handle<Object> handler(proxy->handler(), isolate);
4723 Handle<String> trap = isolate->factory()->InternalizeOneByteString(
4724 STATIC_CHAR_VECTOR("getPropertyDescriptor"));
4725 Handle<Object> error = isolate->factory()->NewTypeError(
4726 MessageTemplate::kProxyPropNotConfigurable, handler, name, trap);
4727 isolate->Throw(*error);
4728 return Nothing<PropertyAttributes>();
4729 }
4730
4731 int attributes = NONE;
4732 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM;
4733 if (!configurable->BooleanValue()) attributes |= DONT_DELETE;
4734 if (!writable->BooleanValue()) attributes |= READ_ONLY;
4735 return Just(static_cast<PropertyAttributes>(attributes));
4736 } 4675 }
4737 4676
4738 4677
4739 MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, 4678 MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy,
4740 const char* name, 4679 const char* name,
4741 Handle<Object> derived, 4680 Handle<Object> derived,
4742 int argc, 4681 int argc,
4743 Handle<Object> argv[]) { 4682 Handle<Object> argv[]) {
4744 Isolate* isolate = proxy->GetIsolate(); 4683 Isolate* isolate = proxy->GetIsolate();
4745 Handle<Object> handler(proxy->handler(), isolate); 4684 Handle<Object> handler(proxy->handler(), isolate);
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
5108 5047
5109 5048
5110 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( 5049 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
5111 LookupIterator* it) { 5050 LookupIterator* it) {
5112 for (; it->IsFound(); it->Next()) { 5051 for (; it->IsFound(); it->Next()) {
5113 switch (it->state()) { 5052 switch (it->state()) {
5114 case LookupIterator::NOT_FOUND: 5053 case LookupIterator::NOT_FOUND:
5115 case LookupIterator::TRANSITION: 5054 case LookupIterator::TRANSITION:
5116 UNREACHABLE(); 5055 UNREACHABLE();
5117 case LookupIterator::JSPROXY: 5056 case LookupIterator::JSPROXY:
5118 return JSProxy::GetPropertyAttributesWithHandler( 5057 return JSProxy::GetPropertyAttributes(it);
5119 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName());
5120 case LookupIterator::INTERCEPTOR: { 5058 case LookupIterator::INTERCEPTOR: {
5121 Maybe<PropertyAttributes> result = 5059 Maybe<PropertyAttributes> result =
5122 JSObject::GetPropertyAttributesWithInterceptor(it); 5060 JSObject::GetPropertyAttributesWithInterceptor(it);
5123 if (!result.IsJust()) return result; 5061 if (!result.IsJust()) return result;
5124 if (result.FromJust() != ABSENT) return result; 5062 if (result.FromJust() != ABSENT) return result;
5125 break; 5063 break;
5126 } 5064 }
5127 case LookupIterator::ACCESS_CHECK: 5065 case LookupIterator::ACCESS_CHECK:
5128 if (it->HasAccess()) break; 5066 if (it->HasAccess()) break;
5129 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it); 5067 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
6007 return Object::ToString(isolate, key); 5945 return Object::ToString(isolate, key);
6008 } 5946 }
6009 5947
6010 5948
6011 // ES6 19.1.2.4 5949 // ES6 19.1.2.4
6012 // static 5950 // static
6013 Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object, 5951 Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object,
6014 Handle<Object> key, 5952 Handle<Object> key,
6015 Handle<Object> attributes) { 5953 Handle<Object> attributes) {
6016 // 1. If Type(O) is not Object, throw a TypeError exception. 5954 // 1. If Type(O) is not Object, throw a TypeError exception.
6017 // TODO(jkummerow): Implement Proxy support, change to "IsSpecObject". 5955 if (!object->IsSpecObject()) {
6018 if (!object->IsJSObject()) {
6019 Handle<String> fun_name = 5956 Handle<String> fun_name =
6020 isolate->factory()->InternalizeUtf8String("Object.defineProperty"); 5957 isolate->factory()->InternalizeUtf8String("Object.defineProperty");
6021 THROW_NEW_ERROR_RETURN_FAILURE( 5958 THROW_NEW_ERROR_RETURN_FAILURE(
6022 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name)); 5959 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name));
6023 } 5960 }
6024 // 2. Let key be ToPropertyKey(P). 5961 // 2. Let key be ToPropertyKey(P).
6025 // 3. ReturnIfAbrupt(key). 5962 // 3. ReturnIfAbrupt(key).
6026 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, ToPropertyKey(isolate, key)); 5963 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, ToPropertyKey(isolate, key));
6027 // 4. Let desc be ToPropertyDescriptor(Attributes). 5964 // 4. Let desc be ToPropertyDescriptor(Attributes).
6028 // 5. ReturnIfAbrupt(desc). 5965 // 5. ReturnIfAbrupt(desc).
6029 PropertyDescriptor desc; 5966 PropertyDescriptor desc;
6030 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) { 5967 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
6031 return isolate->heap()->exception(); 5968 return isolate->heap()->exception();
6032 } 5969 }
6033 // 6. Let success be DefinePropertyOrThrow(O,key, desc). 5970 // 6. Let success be DefinePropertyOrThrow(O,key, desc).
6034 bool success = DefineOwnProperty(isolate, Handle<JSObject>::cast(object), key, 5971 bool success = DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object),
6035 &desc, THROW_ON_ERROR); 5972 key, &desc, THROW_ON_ERROR);
6036 // 7. ReturnIfAbrupt(success). 5973 // 7. ReturnIfAbrupt(success).
6037 if (isolate->has_pending_exception()) return isolate->heap()->exception(); 5974 if (isolate->has_pending_exception()) return isolate->heap()->exception();
6038 CHECK(success == true); 5975 CHECK(success == true);
6039 // 8. Return O. 5976 // 8. Return O.
6040 return *object; 5977 return *object;
6041 } 5978 }
6042 5979
6043 5980
6044 // ES6 19.1.2.3.1 5981 // ES6 19.1.2.3.1
6045 // static 5982 // static
6046 Object* JSReceiver::DefineProperties(Isolate* isolate, Handle<Object> object, 5983 Object* JSReceiver::DefineProperties(Isolate* isolate, Handle<Object> object,
6047 Handle<Object> properties) { 5984 Handle<Object> properties) {
6048 // 1. If Type(O) is not Object, throw a TypeError exception. 5985 // 1. If Type(O) is not Object, throw a TypeError exception.
6049 // TODO(jkummerow): Implement Proxy support, change to "IsSpecObject". 5986 if (!object->IsSpecObject()) {
6050 if (!object->IsJSObject()) {
6051 Handle<String> fun_name = 5987 Handle<String> fun_name =
6052 isolate->factory()->InternalizeUtf8String("Object.defineProperties"); 5988 isolate->factory()->InternalizeUtf8String("Object.defineProperties");
6053 THROW_NEW_ERROR_RETURN_FAILURE( 5989 THROW_NEW_ERROR_RETURN_FAILURE(
6054 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name)); 5990 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name));
6055 } 5991 }
6056 // 2. Let props be ToObject(Properties). 5992 // 2. Let props be ToObject(Properties).
6057 // 3. ReturnIfAbrupt(props). 5993 // 3. ReturnIfAbrupt(props).
6058 Handle<JSReceiver> props; 5994 Handle<JSReceiver> props;
6059 if (!Object::ToObject(isolate, properties).ToHandle(&props)) { 5995 if (!Object::ToObject(isolate, properties).ToHandle(&props)) {
6060 THROW_NEW_ERROR_RETURN_FAILURE( 5996 THROW_NEW_ERROR_RETURN_FAILURE(
(...skipping 10 matching lines...) Expand all
6071 std::vector<PropertyDescriptor> descriptors(capacity); 6007 std::vector<PropertyDescriptor> descriptors(capacity);
6072 // 7. Repeat for each element nextKey of keys in List order, 6008 // 7. Repeat for each element nextKey of keys in List order,
6073 for (int i = 0; i < keys->length(); ++i) { 6009 for (int i = 0; i < keys->length(); ++i) {
6074 Handle<Object> next_key(keys->get(i), isolate); 6010 Handle<Object> next_key(keys->get(i), isolate);
6075 // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey). 6011 // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey).
6076 // 7b. ReturnIfAbrupt(propDesc). 6012 // 7b. ReturnIfAbrupt(propDesc).
6077 bool success = false; 6013 bool success = false;
6078 LookupIterator it = LookupIterator::PropertyOrElement( 6014 LookupIterator it = LookupIterator::PropertyOrElement(
6079 isolate, props, next_key, &success, LookupIterator::HIDDEN); 6015 isolate, props, next_key, &success, LookupIterator::HIDDEN);
6080 DCHECK(success); 6016 DCHECK(success);
6081 // TODO(jkummerow): Support JSProxies. Make sure we call the correct 6017 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
6082 // getOwnPropertyDescriptor trap, and convert the result object to a
6083 // PropertyDescriptor.
6084 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
6085 if (!maybe.IsJust()) return isolate->heap()->exception(); 6018 if (!maybe.IsJust()) return isolate->heap()->exception();
6086 PropertyAttributes attrs = maybe.FromJust(); 6019 PropertyAttributes attrs = maybe.FromJust();
6087 // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true: 6020 // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true:
6088 if (attrs == ABSENT) continue; 6021 if (attrs == ABSENT) continue;
6089 // GetKeys() only returns enumerable keys. 6022 // GetKeys() only returns enumerable keys.
6090 DCHECK((attrs & DONT_ENUM) == 0); 6023 DCHECK((attrs & DONT_ENUM) == 0);
6091 // 7c i. Let descObj be Get(props, nextKey). 6024 // 7c i. Let descObj be Get(props, nextKey).
6092 // 7c ii. ReturnIfAbrupt(descObj). 6025 // 7c ii. ReturnIfAbrupt(descObj).
6093 Handle<Object> desc_obj; 6026 Handle<Object> desc_obj;
6094 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, desc_obj, 6027 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, desc_obj,
6095 JSObject::GetProperty(&it)); 6028 Object::GetProperty(&it));
6096 // 7c iii. Let desc be ToPropertyDescriptor(descObj). 6029 // 7c iii. Let desc be ToPropertyDescriptor(descObj).
6097 success = PropertyDescriptor::ToPropertyDescriptor(isolate, desc_obj, 6030 success = PropertyDescriptor::ToPropertyDescriptor(isolate, desc_obj,
6098 &descriptors[i]); 6031 &descriptors[i]);
6099 // 7c iv. ReturnIfAbrupt(desc). 6032 // 7c iv. ReturnIfAbrupt(desc).
6100 if (!success) return isolate->heap()->exception(); 6033 if (!success) return isolate->heap()->exception();
6101 // 7c v. Append the pair (a two element List) consisting of nextKey and 6034 // 7c v. Append the pair (a two element List) consisting of nextKey and
6102 // desc to the end of descriptors. 6035 // desc to the end of descriptors.
6103 descriptors[i].set_name(next_key); 6036 descriptors[i].set_name(next_key);
6104 } 6037 }
6105 // 8. For each pair from descriptors in list order, 6038 // 8. For each pair from descriptors in list order,
6106 for (size_t i = 0; i < descriptors.size(); ++i) { 6039 for (size_t i = 0; i < descriptors.size(); ++i) {
6107 PropertyDescriptor* desc = &descriptors[i]; 6040 PropertyDescriptor* desc = &descriptors[i];
6108 // 8a. Let P be the first element of pair. 6041 // 8a. Let P be the first element of pair.
6109 // 8b. Let desc be the second element of pair. 6042 // 8b. Let desc be the second element of pair.
6110 // 8c. Let status be DefinePropertyOrThrow(O, P, desc). 6043 // 8c. Let status be DefinePropertyOrThrow(O, P, desc).
6111 bool status = DefineOwnProperty(isolate, Handle<JSObject>::cast(object), 6044 bool status = DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object),
6112 desc->name(), desc, THROW_ON_ERROR); 6045 desc->name(), desc, THROW_ON_ERROR);
6113 // 8d. ReturnIfAbrupt(status). 6046 // 8d. ReturnIfAbrupt(status).
6114 if (isolate->has_pending_exception()) return isolate->heap()->exception(); 6047 if (isolate->has_pending_exception()) return isolate->heap()->exception();
6115 CHECK(status == true); 6048 CHECK(status == true);
6116 } 6049 }
6117 // 9. Return o. 6050 // 9. Return o.
6118 return *object; 6051 return *object;
6119 } 6052 }
6120 6053
6121 6054
6122 // static 6055 // static
6123 bool JSReceiver::DefineOwnProperty(Isolate* isolate, Handle<JSReceiver> object, 6056 bool JSReceiver::DefineOwnProperty(Isolate* isolate, Handle<JSReceiver> object,
6124 Handle<Object> key, PropertyDescriptor* desc, 6057 Handle<Object> key, PropertyDescriptor* desc,
6125 ShouldThrow should_throw) { 6058 ShouldThrow should_throw) {
6126 if (object->IsJSArray()) { 6059 if (object->IsJSArray()) {
6127 return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object), 6060 return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object),
6128 key, desc, should_throw); 6061 key, desc, should_throw);
6129 } 6062 }
6063 if (object->IsJSProxy()) {
6064 return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object),
6065 key, desc, should_throw);
6066 }
6130 // TODO(jkummerow): Support Modules (ES6 9.4.6.6) 6067 // TODO(jkummerow): Support Modules (ES6 9.4.6.6)
6131 // TODO(jkummerow): Support Proxies (ES6 9.5.6)
6132 if (!object->IsJSObject()) return true;
6133 6068
6134 // OrdinaryDefineOwnProperty, by virtue of calling 6069 // OrdinaryDefineOwnProperty, by virtue of calling
6135 // DefineOwnPropertyIgnoreAttributes, can handle arguments (ES6 9.4.4.2) 6070 // DefineOwnPropertyIgnoreAttributes, can handle arguments (ES6 9.4.4.2)
6136 // and IntegerIndexedExotics (ES6 9.4.5.3), with one exception: 6071 // and IntegerIndexedExotics (ES6 9.4.5.3), with one exception:
6137 // TODO(jkummerow): Setting an indexed accessor on a typed array should throw. 6072 // TODO(jkummerow): Setting an indexed accessor on a typed array should throw.
6138 return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key, 6073 return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key,
6139 desc, should_throw); 6074 desc, should_throw);
6140 } 6075 }
6141 6076
6142 6077
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
6703 success = actual_new_len == new_len; 6638 success = actual_new_len == new_len;
6704 if (!success && should_throw == THROW_ON_ERROR) { 6639 if (!success && should_throw == THROW_ON_ERROR) {
6705 isolate->Throw(*isolate->factory()->NewTypeError( 6640 isolate->Throw(*isolate->factory()->NewTypeError(
6706 MessageTemplate::kStrictDeleteProperty, 6641 MessageTemplate::kStrictDeleteProperty,
6707 isolate->factory()->NewNumberFromUint(actual_new_len - 1), a)); 6642 isolate->factory()->NewNumberFromUint(actual_new_len - 1), a));
6708 } 6643 }
6709 return success; 6644 return success;
6710 } 6645 }
6711 6646
6712 6647
6648 // ES6 9.5.6
6649 // static
6650 bool JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> object,
6651 Handle<Object> key, PropertyDescriptor* desc,
6652 ShouldThrow should_throw) {
6653 // 1. Assert: IsPropertyKey(P) is true.
6654 DCHECK(key->IsName() || key->IsNumber());
6655 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
6656 Handle<Object> handler(object->handler(), isolate);
6657 // 3. If handler is null, throw a TypeError exception.
6658 // TODO(jkummerow): Use "IsRevoked()" instead once we have it.
6659 if (handler->IsNull()) {
6660 isolate->Throw(*isolate->factory()->NewTypeError(
6661 MessageTemplate::kProxyHandlerNonObject));
6662 return false;
6663 }
6664 // 4. Assert: Type(handler) is Object.
6665 DCHECK(handler->IsJSReceiver());
6666 // If the handler is not null, the target can't be null either.
6667 DCHECK(object->target()->IsSpecObject());
6668 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
6669 Handle<JSReceiver> target(JSReceiver::cast(object->target()), isolate);
6670 // 6. Let trap be ? GetMethod(handler, "defineProperty").
6671 Handle<Object> trap;
6672 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
6673 isolate, trap,
6674 Object::GetMethod(Handle<JSReceiver>::cast(handler),
6675 isolate->factory()->defineProperty_string()),
6676 false);
6677 // 7. If trap is undefined, then:
6678 if (trap->IsUndefined()) {
6679 // 7a. Return target.[[DefineOwnProperty]](P, Desc).
6680 return JSReceiver::DefineOwnProperty(isolate, target, key, desc,
6681 should_throw);
6682 }
6683 // 8. Let descObj be FromPropertyDescriptor(Desc).
6684 Handle<Object> desc_obj = desc->ToObject(isolate);
6685 // 9. Let booleanTrapResult be
6686 // ToBoolean(? Call(trap, handler, «target, P, descObj»)).
6687 Handle<Name> property_name =
6688 key->IsName()
6689 ? Handle<Name>::cast(key)
6690 : Handle<Name>::cast(isolate->factory()->NumberToString(key));
6691 Handle<Object> trap_result_obj;
6692 Handle<Object> args[] = {target, property_name, desc_obj};
6693 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
6694 isolate, trap_result_obj,
6695 Execution::Call(isolate, trap, handler, arraysize(args), args), false);
6696 // 10. If booleanTrapResult is false, return false.
6697 if (!trap_result_obj->BooleanValue()) {
6698 if (should_throw == THROW_ON_ERROR) {
6699 // TODO(jkummerow): Better error message?
6700 isolate->Throw(*isolate->factory()->NewTypeError(
6701 MessageTemplate::kProxyHandlerReturned, handler, trap_result_obj,
6702 key));
6703 }
6704 return false;
6705 }
6706 // 11. Let targetDesc be ? target.[[GetOwnProperty]](P).
6707 PropertyDescriptor target_desc;
6708 bool target_found =
6709 JSReceiver::GetOwnPropertyDescriptor(isolate, target, key, &target_desc);
6710 if (isolate->has_pending_exception()) return false;
6711 // 12. Let extensibleTarget be ? IsExtensible(target).
6712 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
6713 if (maybe_extensible.IsNothing()) return false;
6714 bool extensible_target = maybe_extensible.FromJust();
6715 // 13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]]
6716 // is false, then:
6717 // 13a. Let settingConfigFalse be true.
6718 // 14. Else let settingConfigFalse be false.
6719 bool setting_config_false = desc->has_configurable() && !desc->configurable();
6720 // 15. If targetDesc is undefined, then
6721 if (!target_found) {
6722 // 15a. If extensibleTarget is false, throw a TypeError exception.
6723 if (!extensible_target) {
6724 isolate->Throw(*isolate->factory()->NewTypeError(
6725 MessageTemplate::kProxyTargetNotExtensible));
6726 return false;
6727 }
6728 // 15b. If settingConfigFalse is true, throw a TypeError exception.
6729 if (setting_config_false) {
6730 // TODO(jkummerow): Better error message?
6731 isolate->Throw(*isolate->factory()->NewTypeError(
6732 MessageTemplate::kRedefineDisallowed, key));
6733 return false;
6734 }
6735 } else {
6736 // 16. Else targetDesc is not undefined,
6737 // 16a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc,
6738 // targetDesc) is false, throw a TypeError exception.
6739 bool valid = IsCompatiblePropertyDescriptor(
6740 isolate, extensible_target, desc, &target_desc, property_name);
6741 if (!valid) {
6742 DCHECK(isolate->has_pending_exception());
6743 return false;
6744 }
6745 // 16b. If settingConfigFalse is true and targetDesc.[[Configurable]] is
6746 // true, throw a TypeError exception.
6747 if (setting_config_false && target_desc.configurable()) {
6748 // TODO(jkummerow): Better error message?
6749 isolate->Throw(*isolate->factory()->NewTypeError(
6750 MessageTemplate::kRedefineDisallowed, key));
6751 return false;
6752 }
6753 }
6754 // 17. Return true.
6755 return true;
6756 }
6757
6758
6713 // static 6759 // static
6714 bool JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate, 6760 bool JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate,
6715 Handle<JSReceiver> object, 6761 Handle<JSReceiver> object,
6716 Handle<Object> key, 6762 Handle<Object> key,
6717 PropertyDescriptor* desc) { 6763 PropertyDescriptor* desc) {
6718 bool success = false; 6764 bool success = false;
6719 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey... 6765 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey...
6720 LookupIterator it = LookupIterator::PropertyOrElement( 6766 LookupIterator it = LookupIterator::PropertyOrElement(
6721 isolate, object, key, &success, LookupIterator::HIDDEN); 6767 isolate, object, key, &success, LookupIterator::HIDDEN);
6722 DCHECK(success); // ...so creating a LookupIterator can't fail. 6768 DCHECK(success); // ...so creating a LookupIterator can't fail.
(...skipping 11471 matching lines...) Expand 10 before | Expand all | Expand 10 after
18194 if (cell->value() != *new_value) { 18240 if (cell->value() != *new_value) {
18195 cell->set_value(*new_value); 18241 cell->set_value(*new_value);
18196 Isolate* isolate = cell->GetIsolate(); 18242 Isolate* isolate = cell->GetIsolate();
18197 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18243 cell->dependent_code()->DeoptimizeDependentCodeGroup(
18198 isolate, DependentCode::kPropertyCellChangedGroup); 18244 isolate, DependentCode::kPropertyCellChangedGroup);
18199 } 18245 }
18200 } 18246 }
18201 18247
18202 } // namespace internal 18248 } // namespace internal
18203 } // namespace v8 18249 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/harmony/proxies-define-property.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698