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 4646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |