Chromium Code Reviews| 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 |