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 6699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6710 LookupIterator it = LookupIterator::PropertyOrElement( | 6710 LookupIterator it = LookupIterator::PropertyOrElement( |
6711 isolate, object, key, &success, LookupIterator::HIDDEN); | 6711 isolate, object, key, &success, LookupIterator::HIDDEN); |
6712 DCHECK(success); // ...so creating a LookupIterator can't fail. | 6712 DCHECK(success); // ...so creating a LookupIterator can't fail. |
6713 return GetOwnPropertyDescriptor(&it, desc); | 6713 return GetOwnPropertyDescriptor(&it, desc); |
6714 } | 6714 } |
6715 | 6715 |
6716 | 6716 |
6717 // TODO(jkummerow): Any chance to unify this with | 6717 // TODO(jkummerow): Any chance to unify this with |
6718 // "MaybeHandle<Object> GetOwnProperty()" in runtime-object.cc? | 6718 // "MaybeHandle<Object> GetOwnProperty()" in runtime-object.cc? |
6719 | 6719 |
6720 // TODO(jkummerow/verwaest): Proxy support: call getOwnPropertyDescriptor trap | |
6721 // and convert the result (if it's an object) with ToPropertyDescriptor. | |
6722 | |
6723 // ES6 9.1.5.1 | 6720 // ES6 9.1.5.1 |
6724 // Returns true on success; false if there was an exception or no property. | 6721 // Returns true on success; false if there was an exception or no property. |
6725 // static | 6722 // static |
6726 bool JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it, | 6723 bool JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it, |
6727 PropertyDescriptor* desc) { | 6724 PropertyDescriptor* desc) { |
| 6725 // "Virtual" dispatch. |
| 6726 if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) { |
| 6727 return JSProxy::GetOwnPropertyDescriptor(it, desc); |
| 6728 } |
| 6729 |
6728 Isolate* isolate = it->isolate(); | 6730 Isolate* isolate = it->isolate(); |
6729 // 1. (Assert) | 6731 // 1. (Assert) |
6730 // 2. If O does not have an own property with key P, return undefined. | 6732 // 2. If O does not have an own property with key P, return undefined. |
6731 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it); | 6733 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it); |
6732 | 6734 |
6733 if (!maybe.IsJust()) return false; | 6735 if (!maybe.IsJust()) return false; |
6734 PropertyAttributes attrs = maybe.FromJust(); | 6736 PropertyAttributes attrs = maybe.FromJust(); |
6735 if (attrs == ABSENT) return false; | 6737 if (attrs == ABSENT) return false; |
6736 DCHECK(!isolate->has_pending_exception()); | 6738 DCHECK(!isolate->has_pending_exception()); |
6737 | 6739 |
(...skipping 27 matching lines...) Expand all Loading... |
6765 desc->set_enumerable((attrs & DONT_ENUM) == 0); | 6767 desc->set_enumerable((attrs & DONT_ENUM) == 0); |
6766 // 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute. | 6768 // 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute. |
6767 desc->set_configurable((attrs & DONT_DELETE) == 0); | 6769 desc->set_configurable((attrs & DONT_DELETE) == 0); |
6768 // 9. Return D. | 6770 // 9. Return D. |
6769 DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) != | 6771 DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) != |
6770 PropertyDescriptor::IsDataDescriptor(desc)); | 6772 PropertyDescriptor::IsDataDescriptor(desc)); |
6771 return true; | 6773 return true; |
6772 } | 6774 } |
6773 | 6775 |
6774 | 6776 |
| 6777 // ES6 9.5.5 |
| 6778 // static |
| 6779 bool JSProxy::GetOwnPropertyDescriptor(LookupIterator* it, |
| 6780 PropertyDescriptor* desc) { |
| 6781 DCHECK(it->GetHolder<Object>()->IsJSProxy()); |
| 6782 Isolate* isolate = it->isolate(); |
| 6783 Handle<Name> property_name = it->GetName(); |
| 6784 // 1. (Assert) |
| 6785 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| 6786 Handle<Object> handler(it->GetHolder<JSProxy>()->handler(), isolate); |
| 6787 // 3. If handler is null, throw a TypeError exception. |
| 6788 if (handler->IsNull()) { |
| 6789 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6790 MessageTemplate::kProxyHandlerNonObject)); |
| 6791 return false; |
| 6792 } |
| 6793 // 4. Assert: Type(handler) is Object. |
| 6794 DCHECK(handler->IsSpecObject()); |
| 6795 // If the handler is not null, the target can't be null either. |
| 6796 DCHECK(it->GetHolder<JSProxy>()->target()->IsSpecObject()); |
| 6797 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O. |
| 6798 Handle<JSReceiver> target( |
| 6799 JSReceiver::cast(it->GetHolder<JSProxy>()->target()), isolate); |
| 6800 // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor"). |
| 6801 Handle<Object> trap; |
| 6802 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 6803 isolate, trap, |
| 6804 Object::GetMethod(Handle<JSReceiver>::cast(handler), |
| 6805 isolate->factory()->getOwnPropertyDescriptor_string()), |
| 6806 false); |
| 6807 // 7. If trap is undefined, then |
| 6808 if (trap->IsUndefined()) { |
| 6809 // 7a. Return target.[[GetOwnProperty]](P). |
| 6810 return JSReceiver::GetOwnPropertyDescriptor(isolate, target, property_name, |
| 6811 desc); |
| 6812 } |
| 6813 // 8. Let trapResultObj be ? Call(trap, handler, «target, P»). |
| 6814 Handle<Object> trap_result_obj; |
| 6815 Handle<Object> args[] = {target, property_name}; |
| 6816 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 6817 isolate, trap_result_obj, |
| 6818 Execution::Call(isolate, trap, handler, arraysize(args), args), false); |
| 6819 // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a |
| 6820 // TypeError exception. |
| 6821 if (!trap_result_obj->IsSpecObject() && !trap_result_obj->IsUndefined()) { |
| 6822 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6823 MessageTemplate::kProxyHandlerReturned, handler, trap_result_obj, |
| 6824 property_name)); |
| 6825 return false; |
| 6826 } |
| 6827 // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). |
| 6828 PropertyDescriptor target_desc; |
| 6829 JSReceiver::GetOwnPropertyDescriptor(isolate, target, property_name, |
| 6830 &target_desc); |
| 6831 if (isolate->has_pending_exception()) return false; |
| 6832 // 11. If trapResultObj is undefined, then |
| 6833 if (trap_result_obj->IsUndefined()) { |
| 6834 // 11a. If targetDesc is undefined, return undefined. |
| 6835 if (target_desc.is_empty()) return false; |
| 6836 // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError |
| 6837 // exception. |
| 6838 if (!target_desc.configurable()) { |
| 6839 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6840 MessageTemplate::kProxyTargetPropNotConfigurable, property_name)); |
| 6841 return false; |
| 6842 } |
| 6843 // 11c. Let extensibleTarget be ? IsExtensible(target). |
| 6844 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); |
| 6845 if (maybe_extensible.IsNothing()) return false; |
| 6846 bool extensible_target = maybe_extensible.FromJust(); |
| 6847 // 11d. (Assert) |
| 6848 // 11e. If extensibleTarget is false, throw a TypeError exception. |
| 6849 if (!extensible_target) { |
| 6850 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6851 MessageTemplate::kProxyTargetNotExtensible)); |
| 6852 return false; |
| 6853 } |
| 6854 // 11f. Return undefined. |
| 6855 return false; // |desc->is_empty()| is what JavaScript calls "undefined". |
| 6856 } |
| 6857 // 12. Let extensibleTarget be ? IsExtensible(target). |
| 6858 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); |
| 6859 if (maybe_extensible.IsNothing()) return false; |
| 6860 bool extensible_target = maybe_extensible.FromJust(); |
| 6861 // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj). |
| 6862 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj, |
| 6863 desc)) { |
| 6864 DCHECK(isolate->has_pending_exception()); |
| 6865 return false; |
| 6866 } |
| 6867 // 14. Call CompletePropertyDescriptor(resultDesc). |
| 6868 PropertyDescriptor::CompletePropertyDescriptor(isolate, desc); |
| 6869 // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget, |
| 6870 // resultDesc, targetDesc). |
| 6871 bool valid = IsCompatiblePropertyDescriptor(extensible_target, desc, |
| 6872 &target_desc, property_name); |
| 6873 // 16. If valid is false, throw a TypeError exception. |
| 6874 if (!valid) { |
| 6875 DCHECK(isolate->has_pending_exception()); |
| 6876 return false; |
| 6877 } |
| 6878 // 17. If resultDesc.[[Configurable]] is false, then |
| 6879 if (!desc->configurable()) { |
| 6880 // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true: |
| 6881 if (target_desc.is_empty() || target_desc.configurable()) { |
| 6882 // 17a i. Throw a TypeError exception. |
| 6883 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6884 MessageTemplate::kRedefineDisallowed, property_name)); |
| 6885 return false; |
| 6886 } |
| 6887 } |
| 6888 // 18. Return resultDesc. |
| 6889 return true; |
| 6890 } |
| 6891 |
| 6892 |
6775 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 6893 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
6776 ElementsKind kind, | 6894 ElementsKind kind, |
6777 Object* object) { | 6895 Object* object) { |
6778 DCHECK(IsFastObjectElementsKind(kind) || | 6896 DCHECK(IsFastObjectElementsKind(kind) || |
6779 kind == DICTIONARY_ELEMENTS); | 6897 kind == DICTIONARY_ELEMENTS); |
6780 if (IsFastObjectElementsKind(kind)) { | 6898 if (IsFastObjectElementsKind(kind)) { |
6781 int length = IsJSArray() | 6899 int length = IsJSArray() |
6782 ? Smi::cast(JSArray::cast(this)->length())->value() | 6900 ? Smi::cast(JSArray::cast(this)->length())->value() |
6783 : elements->length(); | 6901 : elements->length(); |
6784 for (int i = 0; i < length; ++i) { | 6902 for (int i = 0; i < length; ++i) { |
(...skipping 11206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17991 if (cell->value() != *new_value) { | 18109 if (cell->value() != *new_value) { |
17992 cell->set_value(*new_value); | 18110 cell->set_value(*new_value); |
17993 Isolate* isolate = cell->GetIsolate(); | 18111 Isolate* isolate = cell->GetIsolate(); |
17994 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18112 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17995 isolate, DependentCode::kPropertyCellChangedGroup); | 18113 isolate, DependentCode::kPropertyCellChangedGroup); |
17996 } | 18114 } |
17997 } | 18115 } |
17998 | 18116 |
17999 } // namespace internal | 18117 } // namespace internal |
18000 } // namespace v8 | 18118 } // namespace v8 |
OLD | NEW |