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 // 1. (Assert) | |
6784 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. | |
6785 Handle<Object> handler(it->GetHolder<JSProxy>()->handler(), isolate); | |
6786 // 3. If handler is null, throw a TypeError exception. | |
6787 if (handler->IsNull()) { | |
6788 isolate->Throw(*isolate->factory()->NewTypeError( | |
6789 MessageTemplate::kProxyHandlerNonObject)); | |
6790 return false; | |
6791 } | |
6792 // 4. Assert: Type(handler) is Object. | |
6793 DCHECK(handler->IsSpecObject()); | |
6794 // If the handler is not null, the target can't be null either. | |
6795 DCHECK(it->GetHolder<JSProxy>()->target()->IsSpecObject()); | |
6796 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O. | |
6797 Handle<JSReceiver> target( | |
6798 JSReceiver::cast(it->GetHolder<JSProxy>()->target()), isolate); | |
6799 // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor"). | |
6800 Handle<Object> trap; | |
6801 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
6802 isolate, trap, | |
6803 Object::GetMethod(Handle<JSReceiver>::cast(handler), | |
6804 isolate->factory()->getOwnPropertyDescriptor_string()), | |
6805 false); | |
6806 // 7. If trap is undefined, then | |
6807 if (trap->IsUndefined()) { | |
6808 // 7a. Return target.[[GetOwnProperty]](P). | |
6809 return JSReceiver::GetOwnPropertyDescriptor(isolate, target, it->GetName(), | |
6810 desc); | |
6811 } | |
6812 // 8. Let trapResultObj be ? Call(trap, handler, «target, P»). | |
6813 Handle<Object> trap_result_obj; | |
6814 Handle<Object> args[] = {target, it->GetName()}; | |
Camillo Bruni
2015/11/16 10:54:06
this time probably a temp var for GetName() would
Jakob Kummerow
2015/11/16 11:40:34
Aiight, as you wish.
| |
6815 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
6816 isolate, trap_result_obj, | |
6817 Execution::Call(isolate, trap, handler, arraysize(args), args), false); | |
6818 // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a | |
6819 // TypeError exception. | |
6820 if (!trap_result_obj->IsSpecObject() && !trap_result_obj->IsUndefined()) { | |
6821 isolate->Throw(*isolate->factory()->NewTypeError( | |
6822 MessageTemplate::kProxyHandlerReturned, handler, trap_result_obj, | |
6823 it->GetName())); | |
6824 return false; | |
6825 } | |
6826 // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). | |
6827 PropertyDescriptor target_desc; | |
6828 JSReceiver::GetOwnPropertyDescriptor(isolate, target, it->GetName(), | |
6829 &target_desc); | |
6830 if (isolate->has_pending_exception()) return false; | |
6831 // 11. If trapResultObj is undefined, then | |
6832 if (trap_result_obj->IsUndefined()) { | |
6833 // 11a. If targetDesc is undefined, return undefined. | |
6834 if (target_desc.is_empty()) return false; | |
6835 // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError | |
6836 // exception. | |
6837 if (!target_desc.configurable()) { | |
6838 isolate->Throw(*isolate->factory()->NewTypeError( | |
6839 MessageTemplate::kProxyTargetPropNotConfigurable, it->GetName())); | |
6840 return false; | |
6841 } | |
6842 // 11c. Let extensibleTarget be ? IsExtensible(target). | |
6843 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); | |
6844 if (maybe_extensible.IsNothing()) return false; | |
6845 bool extensible_target = maybe_extensible.FromJust(); | |
6846 // 11d. (Assert) | |
6847 // 11e. If extensibleTarget is false, throw a TypeError exception. | |
6848 if (!extensible_target) { | |
6849 isolate->Throw(*isolate->factory()->NewTypeError( | |
6850 MessageTemplate::kProxyTargetNotExtensible)); | |
6851 return false; | |
6852 } | |
6853 // 11f. Return undefined. | |
6854 return false; // |desc->is_empty()| is what JavaScript calls "undefined". | |
6855 } | |
6856 // 12. Let extensibleTarget be ? IsExtensible(target). | |
6857 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); | |
6858 if (maybe_extensible.IsNothing()) return false; | |
6859 bool extensible_target = maybe_extensible.FromJust(); | |
6860 // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj). | |
6861 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj, | |
6862 desc)) { | |
6863 DCHECK(isolate->has_pending_exception()); | |
6864 return false; | |
6865 } | |
6866 // 14. Call CompletePropertyDescriptor(resultDesc). | |
6867 PropertyDescriptor::CompletePropertyDescriptor(isolate, desc); | |
6868 // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget, | |
6869 // resultDesc, targetDesc). | |
6870 bool valid = IsCompatiblePropertyDescriptor(extensible_target, desc, | |
6871 &target_desc, it->GetName()); | |
6872 // 16. If valid is false, throw a TypeError exception. | |
6873 if (!valid) { | |
6874 DCHECK(isolate->has_pending_exception()); | |
6875 return false; | |
6876 } | |
6877 // 17. If resultDesc.[[Configurable]] is false, then | |
6878 if (!desc->configurable()) { | |
6879 // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true: | |
6880 if (target_desc.is_empty() || target_desc.configurable()) { | |
6881 // 17a i. Throw a TypeError exception. | |
6882 isolate->Throw(*isolate->factory()->NewTypeError( | |
6883 MessageTemplate::kRedefineDisallowed, it->GetName())); | |
6884 return false; | |
6885 } | |
6886 } | |
6887 // 18. Return resultDesc. | |
6888 return true; | |
6889 } | |
6890 | |
6891 | |
6775 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 6892 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
6776 ElementsKind kind, | 6893 ElementsKind kind, |
6777 Object* object) { | 6894 Object* object) { |
6778 DCHECK(IsFastObjectElementsKind(kind) || | 6895 DCHECK(IsFastObjectElementsKind(kind) || |
6779 kind == DICTIONARY_ELEMENTS); | 6896 kind == DICTIONARY_ELEMENTS); |
6780 if (IsFastObjectElementsKind(kind)) { | 6897 if (IsFastObjectElementsKind(kind)) { |
6781 int length = IsJSArray() | 6898 int length = IsJSArray() |
6782 ? Smi::cast(JSArray::cast(this)->length())->value() | 6899 ? Smi::cast(JSArray::cast(this)->length())->value() |
6783 : elements->length(); | 6900 : elements->length(); |
6784 for (int i = 0; i < length; ++i) { | 6901 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) { | 18108 if (cell->value() != *new_value) { |
17992 cell->set_value(*new_value); | 18109 cell->set_value(*new_value); |
17993 Isolate* isolate = cell->GetIsolate(); | 18110 Isolate* isolate = cell->GetIsolate(); |
17994 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18111 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17995 isolate, DependentCode::kPropertyCellChangedGroup); | 18112 isolate, DependentCode::kPropertyCellChangedGroup); |
17996 } | 18113 } |
17997 } | 18114 } |
17998 | 18115 |
17999 } // namespace internal | 18116 } // namespace internal |
18000 } // namespace v8 | 18117 } // namespace v8 |
OLD | NEW |