OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 <memory> | 9 #include <memory> |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 4465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4476 } | 4476 } |
4477 if (PropertyDescriptor::IsAccessorDescriptor(&desc) || | 4477 if (PropertyDescriptor::IsAccessorDescriptor(&desc) || |
4478 !desc.writable()) { | 4478 !desc.writable()) { |
4479 return RedefineIncompatibleProperty(isolate, it->GetName(), value, | 4479 return RedefineIncompatibleProperty(isolate, it->GetName(), value, |
4480 should_throw); | 4480 should_throw); |
4481 } | 4481 } |
4482 | 4482 |
4483 PropertyDescriptor value_desc; | 4483 PropertyDescriptor value_desc; |
4484 value_desc.set_value(value); | 4484 value_desc.set_value(value); |
4485 return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(), | 4485 return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(), |
4486 &value_desc, should_throw); | 4486 &value_desc, should_throw, false); |
4487 } | 4487 } |
4488 | 4488 |
4489 case LookupIterator::NOT_FOUND: | 4489 case LookupIterator::NOT_FOUND: |
4490 case LookupIterator::TRANSITION: | 4490 case LookupIterator::TRANSITION: |
4491 UNREACHABLE(); | 4491 UNREACHABLE(); |
4492 } | 4492 } |
4493 } | 4493 } |
4494 | 4494 |
4495 return AddDataProperty(&own_lookup, value, NONE, should_throw, store_mode); | 4495 return AddDataProperty(&own_lookup, value, NONE, should_throw, store_mode); |
4496 } | 4496 } |
(...skipping 1597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6094 LanguageMode language_mode) { | 6094 LanguageMode language_mode) { |
6095 LookupIterator it = LookupIterator::PropertyOrElement( | 6095 LookupIterator it = LookupIterator::PropertyOrElement( |
6096 name->GetIsolate(), object, name, object, LookupIterator::OWN); | 6096 name->GetIsolate(), object, name, object, LookupIterator::OWN); |
6097 return DeleteProperty(&it, language_mode); | 6097 return DeleteProperty(&it, language_mode); |
6098 } | 6098 } |
6099 | 6099 |
6100 // ES6 19.1.2.4 | 6100 // ES6 19.1.2.4 |
6101 // static | 6101 // static |
6102 Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object, | 6102 Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object, |
6103 Handle<Object> key, | 6103 Handle<Object> key, |
6104 Handle<Object> attributes) { | 6104 Handle<Object> attributes, |
6105 bool bypass_interceptor) { | |
6105 // 1. If Type(O) is not Object, throw a TypeError exception. | 6106 // 1. If Type(O) is not Object, throw a TypeError exception. |
6106 if (!object->IsJSReceiver()) { | 6107 if (!object->IsJSReceiver()) { |
6107 Handle<String> fun_name = | 6108 Handle<String> fun_name = |
6108 isolate->factory()->InternalizeUtf8String("Object.defineProperty"); | 6109 isolate->factory()->InternalizeUtf8String("Object.defineProperty"); |
6109 THROW_NEW_ERROR_RETURN_FAILURE( | 6110 THROW_NEW_ERROR_RETURN_FAILURE( |
6110 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name)); | 6111 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name)); |
6111 } | 6112 } |
6112 // 2. Let key be ToPropertyKey(P). | 6113 // 2. Let key be ToPropertyKey(P). |
6113 // 3. ReturnIfAbrupt(key). | 6114 // 3. ReturnIfAbrupt(key). |
6114 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, ToPropertyKey(isolate, key)); | 6115 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, ToPropertyKey(isolate, key)); |
6115 // 4. Let desc be ToPropertyDescriptor(Attributes). | 6116 // 4. Let desc be ToPropertyDescriptor(Attributes). |
6116 // 5. ReturnIfAbrupt(desc). | 6117 // 5. ReturnIfAbrupt(desc). |
6117 PropertyDescriptor desc; | 6118 PropertyDescriptor desc; |
6118 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) { | 6119 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) { |
6119 return isolate->heap()->exception(); | 6120 return isolate->heap()->exception(); |
6120 } | 6121 } |
6121 // 6. Let success be DefinePropertyOrThrow(O,key, desc). | 6122 // 6. Let success be DefinePropertyOrThrow(O,key, desc). |
6122 Maybe<bool> success = DefineOwnProperty( | 6123 Maybe<bool> success = |
6123 isolate, Handle<JSReceiver>::cast(object), key, &desc, THROW_ON_ERROR); | 6124 DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object), key, &desc, |
6125 THROW_ON_ERROR, bypass_interceptor); | |
6124 // 7. ReturnIfAbrupt(success). | 6126 // 7. ReturnIfAbrupt(success). |
6125 MAYBE_RETURN(success, isolate->heap()->exception()); | 6127 MAYBE_RETURN(success, isolate->heap()->exception()); |
6126 CHECK(success.FromJust()); | 6128 CHECK(success.FromJust()); |
6127 // 8. Return O. | 6129 // 8. Return O. |
6128 return *object; | 6130 return *object; |
6129 } | 6131 } |
6130 | 6132 |
6131 | |
6132 // ES6 19.1.2.3.1 | 6133 // ES6 19.1.2.3.1 |
6133 // static | 6134 // static |
6134 MaybeHandle<Object> JSReceiver::DefineProperties(Isolate* isolate, | 6135 MaybeHandle<Object> JSReceiver::DefineProperties(Isolate* isolate, |
6135 Handle<Object> object, | 6136 Handle<Object> object, |
6136 Handle<Object> properties) { | 6137 Handle<Object> properties) { |
6137 // 1. If Type(O) is not Object, throw a TypeError exception. | 6138 // 1. If Type(O) is not Object, throw a TypeError exception. |
6138 if (!object->IsJSReceiver()) { | 6139 if (!object->IsJSReceiver()) { |
6139 Handle<String> fun_name = | 6140 Handle<String> fun_name = |
6140 isolate->factory()->InternalizeUtf8String("Object.defineProperties"); | 6141 isolate->factory()->InternalizeUtf8String("Object.defineProperties"); |
6141 THROW_NEW_ERROR(isolate, | 6142 THROW_NEW_ERROR(isolate, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6205 // 9. Return o. | 6206 // 9. Return o. |
6206 return object; | 6207 return object; |
6207 } | 6208 } |
6208 | 6209 |
6209 | 6210 |
6210 // static | 6211 // static |
6211 Maybe<bool> JSReceiver::DefineOwnProperty(Isolate* isolate, | 6212 Maybe<bool> JSReceiver::DefineOwnProperty(Isolate* isolate, |
6212 Handle<JSReceiver> object, | 6213 Handle<JSReceiver> object, |
6213 Handle<Object> key, | 6214 Handle<Object> key, |
6214 PropertyDescriptor* desc, | 6215 PropertyDescriptor* desc, |
6215 ShouldThrow should_throw) { | 6216 ShouldThrow should_throw, |
6217 bool bypass_interceptor) { | |
6216 if (object->IsJSArray()) { | 6218 if (object->IsJSArray()) { |
6217 return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object), | 6219 return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object), |
6218 key, desc, should_throw); | 6220 key, desc, should_throw, |
6221 bypass_interceptor); | |
6219 } | 6222 } |
6220 if (object->IsJSProxy()) { | 6223 if (object->IsJSProxy()) { |
6221 return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object), | 6224 return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object), |
6222 key, desc, should_throw); | 6225 key, desc, should_throw, |
6226 bypass_interceptor); | |
6223 } | 6227 } |
6224 if (object->IsJSTypedArray()) { | 6228 if (object->IsJSTypedArray()) { |
6225 return JSTypedArray::DefineOwnProperty( | 6229 return JSTypedArray::DefineOwnProperty( |
6226 isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw); | 6230 isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw, |
6231 bypass_interceptor); | |
6227 } | 6232 } |
6228 // TODO(neis): Special case for JSModuleNamespace? | 6233 // TODO(neis): Special case for JSModuleNamespace? |
6229 | 6234 |
6230 // OrdinaryDefineOwnProperty, by virtue of calling | 6235 // OrdinaryDefineOwnProperty, by virtue of calling |
6231 // DefineOwnPropertyIgnoreAttributes, can handle arguments | 6236 // DefineOwnPropertyIgnoreAttributes, can handle arguments |
6232 // (ES#sec-arguments-exotic-objects-defineownproperty-p-desc). | 6237 // (ES#sec-arguments-exotic-objects-defineownproperty-p-desc). |
6233 return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key, | 6238 return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key, |
6234 desc, should_throw); | 6239 desc, should_throw, bypass_interceptor); |
6235 } | 6240 } |
6236 | 6241 |
6237 | |
6238 // static | 6242 // static |
6239 Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate, | 6243 Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate, |
6240 Handle<JSObject> object, | 6244 Handle<JSObject> object, |
6241 Handle<Object> key, | 6245 Handle<Object> key, |
6242 PropertyDescriptor* desc, | 6246 PropertyDescriptor* desc, |
6243 ShouldThrow should_throw) { | 6247 ShouldThrow should_throw, |
6248 bool bypass_interceptor) { | |
6244 bool success = false; | 6249 bool success = false; |
6245 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey... | 6250 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey... |
6246 LookupIterator it = LookupIterator::PropertyOrElement( | 6251 |
6247 isolate, object, key, &success, LookupIterator::OWN); | 6252 LookupIterator::Configuration ItBase = LookupIterator::OWN; |
Franzi
2017/05/10 09:17:52
Can we name this iterator_config or config?
| |
6253 if (bypass_interceptor) { | |
6254 ItBase = LookupIterator::OWN_SKIP_INTERCEPTOR; | |
6255 } | |
6256 | |
6257 LookupIterator it = | |
6258 LookupIterator::PropertyOrElement(isolate, object, key, &success, ItBase); | |
6259 | |
6248 DCHECK(success); // ...so creating a LookupIterator can't fail. | 6260 DCHECK(success); // ...so creating a LookupIterator can't fail. |
6249 | 6261 |
6250 // Deal with access checks first. | 6262 // Deal with access checks first. |
6251 if (it.state() == LookupIterator::ACCESS_CHECK) { | 6263 if (it.state() == LookupIterator::ACCESS_CHECK) { |
6252 if (!it.HasAccess()) { | 6264 if (!it.HasAccess()) { |
6253 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>()); | 6265 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>()); |
6254 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 6266 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
6255 return Just(true); | 6267 return Just(true); |
6256 } | 6268 } |
6257 it.Next(); | 6269 it.Next(); |
6258 } | 6270 } |
6259 | 6271 |
Franzi
2017/05/10 09:17:52
I think if OWN_SKIP_INTERCEPTOR was used, the stat
| |
6260 // Handle interceptor | 6272 if (!bypass_interceptor) { |
6261 if (it.state() == LookupIterator::INTERCEPTOR) { | 6273 // Handle interceptor |
6262 if (it.HolderIsReceiverOrHiddenPrototype()) { | 6274 if (it.state() == LookupIterator::INTERCEPTOR) { |
6263 Maybe<bool> result = DefinePropertyWithInterceptorInternal( | 6275 if (it.HolderIsReceiverOrHiddenPrototype()) { |
6264 &it, it.GetInterceptor(), should_throw, *desc); | 6276 Maybe<bool> result = DefinePropertyWithInterceptorInternal( |
6265 if (result.IsNothing() || result.FromJust()) { | 6277 &it, it.GetInterceptor(), should_throw, *desc); |
6266 return result; | 6278 if (result.IsNothing() || result.FromJust()) { |
6279 return result; | |
6280 } | |
6267 } | 6281 } |
6268 } | 6282 } |
6269 } | 6283 } |
6270 | 6284 |
6271 return OrdinaryDefineOwnProperty(&it, desc, should_throw); | 6285 return OrdinaryDefineOwnProperty(&it, desc, should_throw); |
6272 } | 6286 } |
6273 | 6287 |
6274 | 6288 |
6275 // ES6 9.1.6.1 | 6289 // ES6 9.1.6.1 |
6276 // static | 6290 // static |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6580 return JSObject::CreateDataProperty(it, value, should_throw); // Shortcut. | 6594 return JSObject::CreateDataProperty(it, value, should_throw); // Shortcut. |
6581 } | 6595 } |
6582 | 6596 |
6583 PropertyDescriptor new_desc; | 6597 PropertyDescriptor new_desc; |
6584 new_desc.set_value(value); | 6598 new_desc.set_value(value); |
6585 new_desc.set_writable(true); | 6599 new_desc.set_writable(true); |
6586 new_desc.set_enumerable(true); | 6600 new_desc.set_enumerable(true); |
6587 new_desc.set_configurable(true); | 6601 new_desc.set_configurable(true); |
6588 | 6602 |
6589 return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(), | 6603 return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(), |
6590 &new_desc, should_throw); | 6604 &new_desc, should_throw, false); |
Franzi
2017/05/10 09:17:52
Do we need the last parameter? I thought it has a
| |
6591 } | 6605 } |
6592 | 6606 |
6593 Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it, | 6607 Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it, |
6594 Handle<Object> value, | 6608 Handle<Object> value, |
6595 ShouldThrow should_throw) { | 6609 ShouldThrow should_throw) { |
6596 DCHECK(it->GetReceiver()->IsJSObject()); | 6610 DCHECK(it->GetReceiver()->IsJSObject()); |
6597 MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>()); | 6611 MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>()); |
6598 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); | 6612 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); |
6599 Isolate* isolate = receiver->GetIsolate(); | 6613 Isolate* isolate = receiver->GetIsolate(); |
6600 | 6614 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6634 bool PropertyKeyToArrayIndex(Handle<Object> index_obj, uint32_t* output) { | 6648 bool PropertyKeyToArrayIndex(Handle<Object> index_obj, uint32_t* output) { |
6635 return PropertyKeyToArrayLength(index_obj, output) && *output != kMaxUInt32; | 6649 return PropertyKeyToArrayLength(index_obj, output) && *output != kMaxUInt32; |
6636 } | 6650 } |
6637 | 6651 |
6638 | 6652 |
6639 // ES6 9.4.2.1 | 6653 // ES6 9.4.2.1 |
6640 // static | 6654 // static |
6641 Maybe<bool> JSArray::DefineOwnProperty(Isolate* isolate, Handle<JSArray> o, | 6655 Maybe<bool> JSArray::DefineOwnProperty(Isolate* isolate, Handle<JSArray> o, |
6642 Handle<Object> name, | 6656 Handle<Object> name, |
6643 PropertyDescriptor* desc, | 6657 PropertyDescriptor* desc, |
6644 ShouldThrow should_throw) { | 6658 ShouldThrow should_throw, |
6659 bool bypass_interceptor) { | |
6645 // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.) | 6660 // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.) |
6646 // 2. If P is "length", then: | 6661 // 2. If P is "length", then: |
6647 // TODO(jkummerow): Check if we need slow string comparison. | 6662 // TODO(jkummerow): Check if we need slow string comparison. |
6648 if (*name == isolate->heap()->length_string()) { | 6663 if (*name == isolate->heap()->length_string()) { |
6649 // 2a. Return ArraySetLength(A, Desc). | 6664 // 2a. Return ArraySetLength(A, Desc). |
6650 return ArraySetLength(isolate, o, desc, should_throw); | 6665 return ArraySetLength(isolate, o, desc, should_throw, bypass_interceptor); |
6651 } | 6666 } |
6652 // 3. Else if P is an array index, then: | 6667 // 3. Else if P is an array index, then: |
6653 uint32_t index = 0; | 6668 uint32_t index = 0; |
6654 if (PropertyKeyToArrayIndex(name, &index)) { | 6669 if (PropertyKeyToArrayIndex(name, &index)) { |
6655 // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length"). | 6670 // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length"). |
6656 PropertyDescriptor old_len_desc; | 6671 PropertyDescriptor old_len_desc; |
6657 Maybe<bool> success = GetOwnPropertyDescriptor( | 6672 Maybe<bool> success = GetOwnPropertyDescriptor( |
6658 isolate, o, isolate->factory()->length_string(), &old_len_desc); | 6673 isolate, o, isolate->factory()->length_string(), &old_len_desc); |
6659 // 3b. (Assert) | 6674 // 3b. (Assert) |
6660 DCHECK(success.FromJust()); | 6675 DCHECK(success.FromJust()); |
6661 USE(success); | 6676 USE(success); |
6662 // 3c. Let oldLen be oldLenDesc.[[Value]]. | 6677 // 3c. Let oldLen be oldLenDesc.[[Value]]. |
6663 uint32_t old_len = 0; | 6678 uint32_t old_len = 0; |
6664 CHECK(old_len_desc.value()->ToArrayLength(&old_len)); | 6679 CHECK(old_len_desc.value()->ToArrayLength(&old_len)); |
6665 // 3d. Let index be ToUint32(P). | 6680 // 3d. Let index be ToUint32(P). |
6666 // (Already done above.) | 6681 // (Already done above.) |
6667 // 3e. (Assert) | 6682 // 3e. (Assert) |
6668 // 3f. If index >= oldLen and oldLenDesc.[[Writable]] is false, | 6683 // 3f. If index >= oldLen and oldLenDesc.[[Writable]] is false, |
6669 // return false. | 6684 // return false. |
6670 if (index >= old_len && old_len_desc.has_writable() && | 6685 if (index >= old_len && old_len_desc.has_writable() && |
6671 !old_len_desc.writable()) { | 6686 !old_len_desc.writable()) { |
6672 RETURN_FAILURE(isolate, should_throw, | 6687 RETURN_FAILURE(isolate, should_throw, |
6673 NewTypeError(MessageTemplate::kDefineDisallowed, name)); | 6688 NewTypeError(MessageTemplate::kDefineDisallowed, name)); |
6674 } | 6689 } |
6675 // 3g. Let succeeded be OrdinaryDefineOwnProperty(A, P, Desc). | 6690 // 3g. Let succeeded be OrdinaryDefineOwnProperty(A, P, Desc). |
6676 Maybe<bool> succeeded = | 6691 Maybe<bool> succeeded = OrdinaryDefineOwnProperty( |
6677 OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw); | 6692 isolate, o, name, desc, should_throw, bypass_interceptor); |
6678 // 3h. Assert: succeeded is not an abrupt completion. | 6693 // 3h. Assert: succeeded is not an abrupt completion. |
6679 // In our case, if should_throw == THROW_ON_ERROR, it can be! | 6694 // In our case, if should_throw == THROW_ON_ERROR, it can be! |
6680 // 3i. If succeeded is false, return false. | 6695 // 3i. If succeeded is false, return false. |
6681 if (succeeded.IsNothing() || !succeeded.FromJust()) return succeeded; | 6696 if (succeeded.IsNothing() || !succeeded.FromJust()) return succeeded; |
6682 // 3j. If index >= oldLen, then: | 6697 // 3j. If index >= oldLen, then: |
6683 if (index >= old_len) { | 6698 if (index >= old_len) { |
6684 // 3j i. Set oldLenDesc.[[Value]] to index + 1. | 6699 // 3j i. Set oldLenDesc.[[Value]] to index + 1. |
6685 old_len_desc.set_value(isolate->factory()->NewNumberFromUint(index + 1)); | 6700 old_len_desc.set_value(isolate->factory()->NewNumberFromUint(index + 1)); |
6686 // 3j ii. Let succeeded be | 6701 // 3j ii. Let succeeded be |
6687 // OrdinaryDefineOwnProperty(A, "length", oldLenDesc). | 6702 // OrdinaryDefineOwnProperty(A, "length", oldLenDesc). |
6688 succeeded = OrdinaryDefineOwnProperty(isolate, o, | 6703 succeeded = OrdinaryDefineOwnProperty( |
6689 isolate->factory()->length_string(), | 6704 isolate, o, isolate->factory()->length_string(), &old_len_desc, |
6690 &old_len_desc, should_throw); | 6705 should_throw, bypass_interceptor); |
6691 // 3j iii. Assert: succeeded is true. | 6706 // 3j iii. Assert: succeeded is true. |
6692 DCHECK(succeeded.FromJust()); | 6707 DCHECK(succeeded.FromJust()); |
6693 USE(succeeded); | 6708 USE(succeeded); |
6694 } | 6709 } |
6695 // 3k. Return true. | 6710 // 3k. Return true. |
6696 return Just(true); | 6711 return Just(true); |
6697 } | 6712 } |
6698 | 6713 |
6699 // 4. Return OrdinaryDefineOwnProperty(A, P, Desc). | 6714 // 4. Return OrdinaryDefineOwnProperty(A, P, Desc). |
6700 return OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw); | 6715 return OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw, |
6716 bypass_interceptor); | |
6701 } | 6717 } |
6702 | 6718 |
6703 | 6719 |
6704 // Part of ES6 9.4.2.4 ArraySetLength. | 6720 // Part of ES6 9.4.2.4 ArraySetLength. |
6705 // static | 6721 // static |
6706 bool JSArray::AnythingToArrayLength(Isolate* isolate, | 6722 bool JSArray::AnythingToArrayLength(Isolate* isolate, |
6707 Handle<Object> length_object, | 6723 Handle<Object> length_object, |
6708 uint32_t* output) { | 6724 uint32_t* output) { |
6709 // Fast path: check numbers and strings that can be converted directly | 6725 // Fast path: check numbers and strings that can be converted directly |
6710 // and unobservably. | 6726 // and unobservably. |
(...skipping 24 matching lines...) Expand all Loading... | |
6735 } | 6751 } |
6736 CHECK(uint32_v->ToArrayLength(output)); | 6752 CHECK(uint32_v->ToArrayLength(output)); |
6737 return true; | 6753 return true; |
6738 } | 6754 } |
6739 | 6755 |
6740 | 6756 |
6741 // ES6 9.4.2.4 | 6757 // ES6 9.4.2.4 |
6742 // static | 6758 // static |
6743 Maybe<bool> JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a, | 6759 Maybe<bool> JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a, |
6744 PropertyDescriptor* desc, | 6760 PropertyDescriptor* desc, |
6745 ShouldThrow should_throw) { | 6761 ShouldThrow should_throw, |
6762 bool bypass_interceptor = false) { | |
6746 // 1. If the [[Value]] field of Desc is absent, then | 6763 // 1. If the [[Value]] field of Desc is absent, then |
6747 if (!desc->has_value()) { | 6764 if (!desc->has_value()) { |
6748 // 1a. Return OrdinaryDefineOwnProperty(A, "length", Desc). | 6765 // 1a. Return OrdinaryDefineOwnProperty(A, "length", Desc). |
6749 return OrdinaryDefineOwnProperty( | 6766 return OrdinaryDefineOwnProperty(isolate, a, |
6750 isolate, a, isolate->factory()->length_string(), desc, should_throw); | 6767 isolate->factory()->length_string(), desc, |
6768 should_throw, bypass_interceptor); | |
6751 } | 6769 } |
6752 // 2. Let newLenDesc be a copy of Desc. | 6770 // 2. Let newLenDesc be a copy of Desc. |
6753 // (Actual copying is not necessary.) | 6771 // (Actual copying is not necessary.) |
6754 PropertyDescriptor* new_len_desc = desc; | 6772 PropertyDescriptor* new_len_desc = desc; |
6755 // 3. - 7. Convert Desc.[[Value]] to newLen. | 6773 // 3. - 7. Convert Desc.[[Value]] to newLen. |
6756 uint32_t new_len = 0; | 6774 uint32_t new_len = 0; |
6757 if (!AnythingToArrayLength(isolate, desc->value(), &new_len)) { | 6775 if (!AnythingToArrayLength(isolate, desc->value(), &new_len)) { |
6758 DCHECK(isolate->has_pending_exception()); | 6776 DCHECK(isolate->has_pending_exception()); |
6759 return Nothing<bool>(); | 6777 return Nothing<bool>(); |
6760 } | 6778 } |
6761 // 8. Set newLenDesc.[[Value]] to newLen. | 6779 // 8. Set newLenDesc.[[Value]] to newLen. |
6762 // (Done below, if needed.) | 6780 // (Done below, if needed.) |
6763 // 9. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length"). | 6781 // 9. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length"). |
6764 PropertyDescriptor old_len_desc; | 6782 PropertyDescriptor old_len_desc; |
6765 Maybe<bool> success = GetOwnPropertyDescriptor( | 6783 Maybe<bool> success = GetOwnPropertyDescriptor( |
6766 isolate, a, isolate->factory()->length_string(), &old_len_desc); | 6784 isolate, a, isolate->factory()->length_string(), &old_len_desc); |
6767 // 10. (Assert) | 6785 // 10. (Assert) |
6768 DCHECK(success.FromJust()); | 6786 DCHECK(success.FromJust()); |
6769 USE(success); | 6787 USE(success); |
6770 // 11. Let oldLen be oldLenDesc.[[Value]]. | 6788 // 11. Let oldLen be oldLenDesc.[[Value]]. |
6771 uint32_t old_len = 0; | 6789 uint32_t old_len = 0; |
6772 CHECK(old_len_desc.value()->ToArrayLength(&old_len)); | 6790 CHECK(old_len_desc.value()->ToArrayLength(&old_len)); |
6773 // 12. If newLen >= oldLen, then | 6791 // 12. If newLen >= oldLen, then |
6774 if (new_len >= old_len) { | 6792 if (new_len >= old_len) { |
6775 // 8. Set newLenDesc.[[Value]] to newLen. | 6793 // 8. Set newLenDesc.[[Value]] to newLen. |
6776 // 12a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc). | 6794 // 12a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc). |
6777 new_len_desc->set_value(isolate->factory()->NewNumberFromUint(new_len)); | 6795 new_len_desc->set_value(isolate->factory()->NewNumberFromUint(new_len)); |
6778 return OrdinaryDefineOwnProperty(isolate, a, | 6796 return OrdinaryDefineOwnProperty( |
6779 isolate->factory()->length_string(), | 6797 isolate, a, isolate->factory()->length_string(), new_len_desc, |
6780 new_len_desc, should_throw); | 6798 should_throw, bypass_interceptor); |
6781 } | 6799 } |
6782 // 13. If oldLenDesc.[[Writable]] is false, return false. | 6800 // 13. If oldLenDesc.[[Writable]] is false, return false. |
6783 if (!old_len_desc.writable()) { | 6801 if (!old_len_desc.writable()) { |
6784 RETURN_FAILURE(isolate, should_throw, | 6802 RETURN_FAILURE(isolate, should_throw, |
6785 NewTypeError(MessageTemplate::kRedefineDisallowed, | 6803 NewTypeError(MessageTemplate::kRedefineDisallowed, |
6786 isolate->factory()->length_string())); | 6804 isolate->factory()->length_string())); |
6787 } | 6805 } |
6788 // 14. If newLenDesc.[[Writable]] is absent or has the value true, | 6806 // 14. If newLenDesc.[[Writable]] is absent or has the value true, |
6789 // let newWritable be true. | 6807 // let newWritable be true. |
6790 bool new_writable = false; | 6808 bool new_writable = false; |
6791 if (!new_len_desc->has_writable() || new_len_desc->writable()) { | 6809 if (!new_len_desc->has_writable() || new_len_desc->writable()) { |
6792 new_writable = true; | 6810 new_writable = true; |
6793 } else { | 6811 } else { |
6794 // 15. Else, | 6812 // 15. Else, |
6795 // 15a. Need to defer setting the [[Writable]] attribute to false in case | 6813 // 15a. Need to defer setting the [[Writable]] attribute to false in case |
6796 // any elements cannot be deleted. | 6814 // any elements cannot be deleted. |
6797 // 15b. Let newWritable be false. (It's initialized as "false" anyway.) | 6815 // 15b. Let newWritable be false. (It's initialized as "false" anyway.) |
6798 // 15c. Set newLenDesc.[[Writable]] to true. | 6816 // 15c. Set newLenDesc.[[Writable]] to true. |
6799 // (Not needed.) | 6817 // (Not needed.) |
6800 } | 6818 } |
6801 // Most of steps 16 through 19 is implemented by JSArray::SetLength. | 6819 // Most of steps 16 through 19 is implemented by JSArray::SetLength. |
6802 JSArray::SetLength(a, new_len); | 6820 JSArray::SetLength(a, new_len); |
6803 // Steps 19d-ii, 20. | 6821 // Steps 19d-ii, 20. |
6804 if (!new_writable) { | 6822 if (!new_writable) { |
6805 PropertyDescriptor readonly; | 6823 PropertyDescriptor readonly; |
6806 readonly.set_writable(false); | 6824 readonly.set_writable(false); |
6807 Maybe<bool> success = OrdinaryDefineOwnProperty( | 6825 Maybe<bool> success = OrdinaryDefineOwnProperty( |
6808 isolate, a, isolate->factory()->length_string(), &readonly, | 6826 isolate, a, isolate->factory()->length_string(), &readonly, |
6809 should_throw); | 6827 should_throw, bypass_interceptor); |
6810 DCHECK(success.FromJust()); | 6828 DCHECK(success.FromJust()); |
6811 USE(success); | 6829 USE(success); |
6812 } | 6830 } |
6813 uint32_t actual_new_len = 0; | 6831 uint32_t actual_new_len = 0; |
6814 CHECK(a->length()->ToArrayLength(&actual_new_len)); | 6832 CHECK(a->length()->ToArrayLength(&actual_new_len)); |
6815 // Steps 19d-v, 21. Return false if there were non-deletable elements. | 6833 // Steps 19d-v, 21. Return false if there were non-deletable elements. |
6816 bool result = actual_new_len == new_len; | 6834 bool result = actual_new_len == new_len; |
6817 if (!result) { | 6835 if (!result) { |
6818 RETURN_FAILURE( | 6836 RETURN_FAILURE( |
6819 isolate, should_throw, | 6837 isolate, should_throw, |
6820 NewTypeError(MessageTemplate::kStrictDeleteProperty, | 6838 NewTypeError(MessageTemplate::kStrictDeleteProperty, |
6821 isolate->factory()->NewNumberFromUint(actual_new_len - 1), | 6839 isolate->factory()->NewNumberFromUint(actual_new_len - 1), |
6822 a)); | 6840 a)); |
6823 } | 6841 } |
6824 return Just(result); | 6842 return Just(result); |
6825 } | 6843 } |
6826 | 6844 |
6827 | 6845 |
6828 // ES6 9.5.6 | 6846 // ES6 9.5.6 |
6829 // static | 6847 // static |
6830 Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy, | 6848 Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy, |
6831 Handle<Object> key, | 6849 Handle<Object> key, |
6832 PropertyDescriptor* desc, | 6850 PropertyDescriptor* desc, |
6833 ShouldThrow should_throw) { | 6851 ShouldThrow should_throw, |
6852 bool bypass_interceptor) { | |
6834 STACK_CHECK(isolate, Nothing<bool>()); | 6853 STACK_CHECK(isolate, Nothing<bool>()); |
6835 if (key->IsSymbol() && Handle<Symbol>::cast(key)->IsPrivate()) { | 6854 if (key->IsSymbol() && Handle<Symbol>::cast(key)->IsPrivate()) { |
6836 return SetPrivateProperty(isolate, proxy, Handle<Symbol>::cast(key), desc, | 6855 return SetPrivateProperty(isolate, proxy, Handle<Symbol>::cast(key), desc, |
6837 should_throw); | 6856 should_throw); |
6838 } | 6857 } |
6839 Handle<String> trap_name = isolate->factory()->defineProperty_string(); | 6858 Handle<String> trap_name = isolate->factory()->defineProperty_string(); |
6840 // 1. Assert: IsPropertyKey(P) is true. | 6859 // 1. Assert: IsPropertyKey(P) is true. |
6841 DCHECK(key->IsName() || key->IsNumber()); | 6860 DCHECK(key->IsName() || key->IsNumber()); |
6842 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. | 6861 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
6843 Handle<Object> handler(proxy->handler(), isolate); | 6862 Handle<Object> handler(proxy->handler(), isolate); |
6844 // 3. If handler is null, throw a TypeError exception. | 6863 // 3. If handler is null, throw a TypeError exception. |
6845 // 4. Assert: Type(handler) is Object. | 6864 // 4. Assert: Type(handler) is Object. |
6846 if (proxy->IsRevoked()) { | 6865 if (proxy->IsRevoked()) { |
6847 isolate->Throw(*isolate->factory()->NewTypeError( | 6866 isolate->Throw(*isolate->factory()->NewTypeError( |
6848 MessageTemplate::kProxyRevoked, trap_name)); | 6867 MessageTemplate::kProxyRevoked, trap_name)); |
6849 return Nothing<bool>(); | 6868 return Nothing<bool>(); |
6850 } | 6869 } |
6851 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O. | 6870 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O. |
6852 Handle<JSReceiver> target(proxy->target(), isolate); | 6871 Handle<JSReceiver> target(proxy->target(), isolate); |
6853 // 6. Let trap be ? GetMethod(handler, "defineProperty"). | 6872 // 6. Let trap be ? GetMethod(handler, "defineProperty"). |
6854 Handle<Object> trap; | 6873 Handle<Object> trap; |
6855 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 6874 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
6856 isolate, trap, | 6875 isolate, trap, |
6857 Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), | 6876 Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), |
6858 Nothing<bool>()); | 6877 Nothing<bool>()); |
6859 // 7. If trap is undefined, then: | 6878 // 7. If trap is undefined, then: |
6860 if (trap->IsUndefined(isolate)) { | 6879 if (trap->IsUndefined(isolate)) { |
6861 // 7a. Return target.[[DefineOwnProperty]](P, Desc). | 6880 // 7a. Return target.[[DefineOwnProperty]](P, Desc). |
6862 return JSReceiver::DefineOwnProperty(isolate, target, key, desc, | 6881 return JSReceiver::DefineOwnProperty(isolate, target, key, desc, |
6863 should_throw); | 6882 should_throw, bypass_interceptor); |
6864 } | 6883 } |
6865 // 8. Let descObj be FromPropertyDescriptor(Desc). | 6884 // 8. Let descObj be FromPropertyDescriptor(Desc). |
6866 Handle<Object> desc_obj = desc->ToObject(isolate); | 6885 Handle<Object> desc_obj = desc->ToObject(isolate); |
6867 // 9. Let booleanTrapResult be | 6886 // 9. Let booleanTrapResult be |
6868 // ToBoolean(? Call(trap, handler, «target, P, descObj»)). | 6887 // ToBoolean(? Call(trap, handler, «target, P, descObj»)). |
6869 Handle<Name> property_name = | 6888 Handle<Name> property_name = |
6870 key->IsName() | 6889 key->IsName() |
6871 ? Handle<Name>::cast(key) | 6890 ? Handle<Name>::cast(key) |
6872 : Handle<Name>::cast(isolate->factory()->NumberToString(key)); | 6891 : Handle<Name>::cast(isolate->factory()->NumberToString(key)); |
6873 // Do not leak private property names. | 6892 // Do not leak private property names. |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7396 PropertyDescriptor no_conf; | 7415 PropertyDescriptor no_conf; |
7397 no_conf.set_configurable(false); | 7416 no_conf.set_configurable(false); |
7398 | 7417 |
7399 PropertyDescriptor no_conf_no_write; | 7418 PropertyDescriptor no_conf_no_write; |
7400 no_conf_no_write.set_configurable(false); | 7419 no_conf_no_write.set_configurable(false); |
7401 no_conf_no_write.set_writable(false); | 7420 no_conf_no_write.set_writable(false); |
7402 | 7421 |
7403 if (level == SEALED) { | 7422 if (level == SEALED) { |
7404 for (int i = 0; i < keys->length(); ++i) { | 7423 for (int i = 0; i < keys->length(); ++i) { |
7405 Handle<Object> key(keys->get(i), isolate); | 7424 Handle<Object> key(keys->get(i), isolate); |
7406 MAYBE_RETURN( | 7425 MAYBE_RETURN(DefineOwnProperty(isolate, receiver, key, &no_conf, |
7407 DefineOwnProperty(isolate, receiver, key, &no_conf, THROW_ON_ERROR), | 7426 THROW_ON_ERROR, false), |
7408 Nothing<bool>()); | 7427 Nothing<bool>()); |
7409 } | 7428 } |
7410 return Just(true); | 7429 return Just(true); |
7411 } | 7430 } |
7412 | 7431 |
7413 for (int i = 0; i < keys->length(); ++i) { | 7432 for (int i = 0; i < keys->length(); ++i) { |
7414 Handle<Object> key(keys->get(i), isolate); | 7433 Handle<Object> key(keys->get(i), isolate); |
7415 PropertyDescriptor current_desc; | 7434 PropertyDescriptor current_desc; |
7416 Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor( | 7435 Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor( |
7417 isolate, receiver, key, ¤t_desc); | 7436 isolate, receiver, key, ¤t_desc); |
7418 MAYBE_RETURN(owned, Nothing<bool>()); | 7437 MAYBE_RETURN(owned, Nothing<bool>()); |
7419 if (owned.FromJust()) { | 7438 if (owned.FromJust()) { |
7420 PropertyDescriptor desc = | 7439 PropertyDescriptor desc = |
7421 PropertyDescriptor::IsAccessorDescriptor(¤t_desc) | 7440 PropertyDescriptor::IsAccessorDescriptor(¤t_desc) |
7422 ? no_conf | 7441 ? no_conf |
7423 : no_conf_no_write; | 7442 : no_conf_no_write; |
7424 MAYBE_RETURN( | 7443 MAYBE_RETURN(DefineOwnProperty(isolate, receiver, key, &desc, |
7425 DefineOwnProperty(isolate, receiver, key, &desc, THROW_ON_ERROR), | 7444 THROW_ON_ERROR, false), |
7426 Nothing<bool>()); | 7445 Nothing<bool>()); |
7427 } | 7446 } |
7428 } | 7447 } |
7429 return Just(true); | 7448 return Just(true); |
7430 } | 7449 } |
7431 | 7450 |
7432 | 7451 |
7433 Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> object, | 7452 Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> object, |
7434 IntegrityLevel level) { | 7453 IntegrityLevel level) { |
7435 DCHECK(level == SEALED || level == FROZEN); | 7454 DCHECK(level == SEALED || level == FROZEN); |
7436 Isolate* isolate = object->GetIsolate(); | 7455 Isolate* isolate = object->GetIsolate(); |
(...skipping 9719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17156 } | 17175 } |
17157 | 17176 |
17158 } // anonymous namespace | 17177 } // anonymous namespace |
17159 | 17178 |
17160 // ES#sec-integer-indexed-exotic-objects-defineownproperty-p-desc | 17179 // ES#sec-integer-indexed-exotic-objects-defineownproperty-p-desc |
17161 // static | 17180 // static |
17162 Maybe<bool> JSTypedArray::DefineOwnProperty(Isolate* isolate, | 17181 Maybe<bool> JSTypedArray::DefineOwnProperty(Isolate* isolate, |
17163 Handle<JSTypedArray> o, | 17182 Handle<JSTypedArray> o, |
17164 Handle<Object> key, | 17183 Handle<Object> key, |
17165 PropertyDescriptor* desc, | 17184 PropertyDescriptor* desc, |
17166 ShouldThrow should_throw) { | 17185 ShouldThrow should_throw, |
17186 bool bypass_interceptor) { | |
17167 // 1. Assert: IsPropertyKey(P) is true. | 17187 // 1. Assert: IsPropertyKey(P) is true. |
17168 DCHECK(key->IsName() || key->IsNumber()); | 17188 DCHECK(key->IsName() || key->IsNumber()); |
17169 // 2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot. | 17189 // 2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot. |
17170 // 3. If Type(P) is String, then | 17190 // 3. If Type(P) is String, then |
17171 if (key->IsString() || key->IsSmi()) { | 17191 if (key->IsString() || key->IsSmi()) { |
17172 // 3a. Let numericIndex be ! CanonicalNumericIndexString(P) | 17192 // 3a. Let numericIndex be ! CanonicalNumericIndexString(P) |
17173 // 3b. If numericIndex is not undefined, then | 17193 // 3b. If numericIndex is not undefined, then |
17174 Handle<Object> numeric_index; | 17194 Handle<Object> numeric_index; |
17175 if (CanonicalNumericIndexString(isolate, key, &numeric_index)) { | 17195 if (CanonicalNumericIndexString(isolate, key, &numeric_index)) { |
17176 // 3b i. If IsInteger(numericIndex) is false, return false. | 17196 // 3b i. If IsInteger(numericIndex) is false, return false. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17217 RETURN_ON_EXCEPTION_VALUE(isolate, | 17237 RETURN_ON_EXCEPTION_VALUE(isolate, |
17218 SetOwnElementIgnoreAttributes( | 17238 SetOwnElementIgnoreAttributes( |
17219 o, index, value, desc->ToAttributes()), | 17239 o, index, value, desc->ToAttributes()), |
17220 Nothing<bool>()); | 17240 Nothing<bool>()); |
17221 } | 17241 } |
17222 // 3b xi. Return true. | 17242 // 3b xi. Return true. |
17223 return Just(true); | 17243 return Just(true); |
17224 } | 17244 } |
17225 } | 17245 } |
17226 // 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc). | 17246 // 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc). |
17227 return OrdinaryDefineOwnProperty(isolate, o, key, desc, should_throw); | 17247 return OrdinaryDefineOwnProperty(isolate, o, key, desc, should_throw, |
17248 bypass_interceptor); | |
17228 } | 17249 } |
17229 | 17250 |
17230 ExternalArrayType JSTypedArray::type() { | 17251 ExternalArrayType JSTypedArray::type() { |
17231 switch (elements()->map()->instance_type()) { | 17252 switch (elements()->map()->instance_type()) { |
17232 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ | 17253 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ |
17233 case FIXED_##TYPE##_ARRAY_TYPE: \ | 17254 case FIXED_##TYPE##_ARRAY_TYPE: \ |
17234 return kExternal##Type##Array; | 17255 return kExternal##Type##Array; |
17235 | 17256 |
17236 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) | 17257 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) |
17237 #undef INSTANCE_TYPE_TO_ARRAY_TYPE | 17258 #undef INSTANCE_TYPE_TO_ARRAY_TYPE |
(...skipping 3182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
20420 // depend on this. | 20441 // depend on this. |
20421 return DICTIONARY_ELEMENTS; | 20442 return DICTIONARY_ELEMENTS; |
20422 } | 20443 } |
20423 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20444 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
20424 return kind; | 20445 return kind; |
20425 } | 20446 } |
20426 } | 20447 } |
20427 | 20448 |
20428 } // namespace internal | 20449 } // namespace internal |
20429 } // namespace v8 | 20450 } // namespace v8 |
OLD | NEW |