| 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 |