| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 (fun->IsHeapObject() && | 103 (fun->IsHeapObject() && |
| 104 HeapObject::cast(fun)->map()->has_instance_call_handler()); | 104 HeapObject::cast(fun)->map()->has_instance_call_handler()); |
| 105 } | 105 } |
| 106 | 106 |
| 107 | 107 |
| 108 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { | 108 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { |
| 109 for (; it->IsFound(); it->Next()) { | 109 for (; it->IsFound(); it->Next()) { |
| 110 switch (it->state()) { | 110 switch (it->state()) { |
| 111 case LookupIterator::NOT_FOUND: | 111 case LookupIterator::NOT_FOUND: |
| 112 case LookupIterator::TRANSITION: | 112 case LookupIterator::TRANSITION: |
| 113 case LookupIterator::UNKNOWN: |
| 113 UNREACHABLE(); | 114 UNREACHABLE(); |
| 114 case LookupIterator::JSPROXY: | 115 case LookupIterator::JSPROXY: |
| 115 return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(), | 116 return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(), |
| 116 it->GetReceiver(), it->name()); | 117 it->GetReceiver(), it->name()); |
| 117 case LookupIterator::INTERCEPTOR: { | 118 case LookupIterator::INTERCEPTOR: { |
| 118 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor( | 119 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor( |
| 119 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); | 120 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); |
| 120 if (!maybe_result.is_null()) return maybe_result; | 121 if (!maybe_result.is_null()) return maybe_result; |
| 121 if (it->isolate()->has_pending_exception()) return maybe_result; | 122 if (it->isolate()->has_pending_exception()) return maybe_result; |
| 122 break; | 123 break; |
| 123 } | 124 } |
| 124 case LookupIterator::ACCESS_CHECK: | 125 case LookupIterator::ACCESS_CHECK: |
| 125 if (it->HasAccess(v8::ACCESS_GET)) break; | 126 if (it->HasAccess(v8::ACCESS_GET)) break; |
| 126 return JSObject::GetPropertyWithFailedAccessCheck(it); | 127 return JSObject::GetPropertyWithFailedAccessCheck(it); |
| 127 case LookupIterator::PROPERTY: | 128 case LookupIterator::ACCESSOR: |
| 128 if (it->HasProperty()) { | 129 return GetPropertyWithAccessor(it->GetReceiver(), it->name(), |
| 129 switch (it->property_kind()) { | 130 it->GetHolder<JSObject>(), |
| 130 case LookupIterator::ACCESSOR: | 131 it->GetAccessors()); |
| 131 return GetPropertyWithAccessor(it->GetReceiver(), it->name(), | 132 case LookupIterator::DATA: |
| 132 it->GetHolder<JSObject>(), | 133 return it->GetDataValue(); |
| 133 it->GetAccessors()); | |
| 134 case LookupIterator::DATA: | |
| 135 return it->GetDataValue(); | |
| 136 } | |
| 137 } | |
| 138 break; | |
| 139 } | 134 } |
| 140 } | 135 } |
| 141 return it->factory()->undefined_value(); | 136 return it->factory()->undefined_value(); |
| 142 } | 137 } |
| 143 | 138 |
| 144 | 139 |
| 145 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object, | 140 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object, |
| 146 Handle<Name> key) { | 141 Handle<Name> key) { |
| 147 LookupIterator it(object, key, | 142 LookupIterator it(object, key, |
| 148 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); | 143 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); |
| 149 return GetDataProperty(&it); | 144 return GetDataProperty(&it); |
| 150 } | 145 } |
| 151 | 146 |
| 152 | 147 |
| 153 Handle<Object> JSObject::GetDataProperty(LookupIterator* it) { | 148 Handle<Object> JSObject::GetDataProperty(LookupIterator* it) { |
| 154 for (; it->IsFound(); it->Next()) { | 149 for (; it->IsFound(); it->Next()) { |
| 155 switch (it->state()) { | 150 switch (it->state()) { |
| 156 case LookupIterator::INTERCEPTOR: | 151 case LookupIterator::INTERCEPTOR: |
| 157 case LookupIterator::NOT_FOUND: | 152 case LookupIterator::NOT_FOUND: |
| 158 case LookupIterator::TRANSITION: | 153 case LookupIterator::TRANSITION: |
| 154 case LookupIterator::UNKNOWN: |
| 159 UNREACHABLE(); | 155 UNREACHABLE(); |
| 160 case LookupIterator::ACCESS_CHECK: | 156 case LookupIterator::ACCESS_CHECK: |
| 161 if (it->HasAccess(v8::ACCESS_GET)) continue; | 157 if (it->HasAccess(v8::ACCESS_GET)) continue; |
| 162 // Fall through. | 158 // Fall through. |
| 163 case LookupIterator::JSPROXY: | 159 case LookupIterator::JSPROXY: |
| 164 it->NotFound(); | 160 it->NotFound(); |
| 165 return it->isolate()->factory()->undefined_value(); | 161 return it->isolate()->factory()->undefined_value(); |
| 166 case LookupIterator::PROPERTY: | 162 case LookupIterator::ACCESSOR: |
| 167 if (!it->HasProperty()) continue; | 163 // TODO(verwaest): For now this doesn't call into |
| 168 switch (it->property_kind()) { | 164 // ExecutableAccessorInfo, since clients don't need it. Update once |
| 169 case LookupIterator::DATA: | 165 // relevant. |
| 170 return it->GetDataValue(); | 166 it->NotFound(); |
| 171 case LookupIterator::ACCESSOR: | 167 return it->isolate()->factory()->undefined_value(); |
| 172 // TODO(verwaest): For now this doesn't call into | 168 case LookupIterator::DATA: |
| 173 // ExecutableAccessorInfo, since clients don't need it. Update once | 169 return it->GetDataValue(); |
| 174 // relevant. | |
| 175 it->NotFound(); | |
| 176 return it->isolate()->factory()->undefined_value(); | |
| 177 } | |
| 178 } | 170 } |
| 179 } | 171 } |
| 180 return it->isolate()->factory()->undefined_value(); | 172 return it->isolate()->factory()->undefined_value(); |
| 181 } | 173 } |
| 182 | 174 |
| 183 | 175 |
| 184 bool Object::ToInt32(int32_t* value) { | 176 bool Object::ToInt32(int32_t* value) { |
| 185 if (IsSmi()) { | 177 if (IsSmi()) { |
| 186 *value = Smi::cast(this)->value(); | 178 *value = Smi::cast(this)->value(); |
| 187 return true; | 179 return true; |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 Handle<Object> argv[] = { value }; | 567 Handle<Object> argv[] = { value }; |
| 576 RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver, | 568 RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver, |
| 577 arraysize(argv), argv, true), | 569 arraysize(argv), argv, true), |
| 578 Object); | 570 Object); |
| 579 return value; | 571 return value; |
| 580 } | 572 } |
| 581 | 573 |
| 582 | 574 |
| 583 static bool FindAllCanReadHolder(LookupIterator* it) { | 575 static bool FindAllCanReadHolder(LookupIterator* it) { |
| 584 for (; it->IsFound(); it->Next()) { | 576 for (; it->IsFound(); it->Next()) { |
| 585 if (it->state() == LookupIterator::PROPERTY && | 577 if (it->state() == LookupIterator::ACCESSOR) { |
| 586 it->HasProperty() && | |
| 587 it->property_kind() == LookupIterator::ACCESSOR) { | |
| 588 Handle<Object> accessors = it->GetAccessors(); | 578 Handle<Object> accessors = it->GetAccessors(); |
| 589 if (accessors->IsAccessorInfo()) { | 579 if (accessors->IsAccessorInfo()) { |
| 590 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; | 580 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; |
| 591 } | 581 } |
| 592 } | 582 } |
| 593 } | 583 } |
| 594 return false; | 584 return false; |
| 595 } | 585 } |
| 596 | 586 |
| 597 | 587 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 616 return maybe(it->property_details().attributes()); | 606 return maybe(it->property_details().attributes()); |
| 617 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS); | 607 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS); |
| 618 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), | 608 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), |
| 619 Maybe<PropertyAttributes>()); | 609 Maybe<PropertyAttributes>()); |
| 620 return maybe(ABSENT); | 610 return maybe(ABSENT); |
| 621 } | 611 } |
| 622 | 612 |
| 623 | 613 |
| 624 static bool FindAllCanWriteHolder(LookupIterator* it) { | 614 static bool FindAllCanWriteHolder(LookupIterator* it) { |
| 625 for (; it->IsFound(); it->Next()) { | 615 for (; it->IsFound(); it->Next()) { |
| 626 if (it->state() == LookupIterator::PROPERTY && it->HasProperty() && | 616 if (it->state() == LookupIterator::ACCESSOR) { |
| 627 it->property_kind() == LookupIterator::ACCESSOR) { | |
| 628 Handle<Object> accessors = it->GetAccessors(); | 617 Handle<Object> accessors = it->GetAccessors(); |
| 629 if (accessors->IsAccessorInfo()) { | 618 if (accessors->IsAccessorInfo()) { |
| 630 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; | 619 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; |
| 631 } | 620 } |
| 632 } | 621 } |
| 633 } | 622 } |
| 634 return false; | 623 return false; |
| 635 } | 624 } |
| 636 | 625 |
| 637 | 626 |
| (...skipping 2185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2823 StrictMode strict_mode, | 2812 StrictMode strict_mode, |
| 2824 StoreFromKeyed store_mode) { | 2813 StoreFromKeyed store_mode) { |
| 2825 // Make sure that the top context does not change when doing callbacks or | 2814 // Make sure that the top context does not change when doing callbacks or |
| 2826 // interceptor calls. | 2815 // interceptor calls. |
| 2827 AssertNoContextChange ncc(it->isolate()); | 2816 AssertNoContextChange ncc(it->isolate()); |
| 2828 | 2817 |
| 2829 bool done = false; | 2818 bool done = false; |
| 2830 for (; it->IsFound(); it->Next()) { | 2819 for (; it->IsFound(); it->Next()) { |
| 2831 switch (it->state()) { | 2820 switch (it->state()) { |
| 2832 case LookupIterator::NOT_FOUND: | 2821 case LookupIterator::NOT_FOUND: |
| 2822 case LookupIterator::UNKNOWN: |
| 2833 UNREACHABLE(); | 2823 UNREACHABLE(); |
| 2834 | 2824 |
| 2835 case LookupIterator::ACCESS_CHECK: | 2825 case LookupIterator::ACCESS_CHECK: |
| 2836 // TODO(verwaest): Remove the distinction. This is mostly bogus since we | 2826 // TODO(verwaest): Remove the distinction. This is mostly bogus since we |
| 2837 // don't know whether we'll want to fetch attributes or call a setter | 2827 // don't know whether we'll want to fetch attributes or call a setter |
| 2838 // until we find the property. | 2828 // until we find the property. |
| 2839 if (it->HasAccess(v8::ACCESS_SET)) break; | 2829 if (it->HasAccess(v8::ACCESS_SET)) break; |
| 2840 return JSObject::SetPropertyWithFailedAccessCheck(it, value, | 2830 return JSObject::SetPropertyWithFailedAccessCheck(it, value, |
| 2841 strict_mode); | 2831 strict_mode); |
| 2842 | 2832 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2868 JSObject::GetPropertyAttributesWithInterceptor( | 2858 JSObject::GetPropertyAttributesWithInterceptor( |
| 2869 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); | 2859 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); |
| 2870 if (!maybe_attributes.has_value) return MaybeHandle<Object>(); | 2860 if (!maybe_attributes.has_value) return MaybeHandle<Object>(); |
| 2871 done = maybe_attributes.value != ABSENT; | 2861 done = maybe_attributes.value != ABSENT; |
| 2872 if (done && (maybe_attributes.value & READ_ONLY) != 0) { | 2862 if (done && (maybe_attributes.value & READ_ONLY) != 0) { |
| 2873 return WriteToReadOnlyProperty(it, value, strict_mode); | 2863 return WriteToReadOnlyProperty(it, value, strict_mode); |
| 2874 } | 2864 } |
| 2875 } | 2865 } |
| 2876 break; | 2866 break; |
| 2877 | 2867 |
| 2878 case LookupIterator::PROPERTY: | 2868 case LookupIterator::ACCESSOR: |
| 2879 if (!it->HasProperty()) break; | |
| 2880 if (it->property_details().IsReadOnly()) { | 2869 if (it->property_details().IsReadOnly()) { |
| 2881 return WriteToReadOnlyProperty(it, value, strict_mode); | 2870 return WriteToReadOnlyProperty(it, value, strict_mode); |
| 2882 } | 2871 } |
| 2883 switch (it->property_kind()) { | 2872 if (it->HolderIsReceiverOrHiddenPrototype() || |
| 2884 case LookupIterator::ACCESSOR: | 2873 !it->GetAccessors()->IsDeclaredAccessorInfo()) { |
| 2885 if (it->HolderIsReceiverOrHiddenPrototype() || | 2874 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value, |
| 2886 !it->GetAccessors()->IsDeclaredAccessorInfo()) { | 2875 it->GetHolder<JSObject>(), |
| 2887 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), | 2876 it->GetAccessors(), strict_mode); |
| 2888 value, it->GetHolder<JSObject>(), | |
| 2889 it->GetAccessors(), strict_mode); | |
| 2890 } | |
| 2891 break; | |
| 2892 case LookupIterator::DATA: | |
| 2893 if (it->HolderIsReceiverOrHiddenPrototype()) { | |
| 2894 return SetDataProperty(it, value); | |
| 2895 } | |
| 2896 } | 2877 } |
| 2897 done = true; | 2878 done = true; |
| 2898 break; | 2879 break; |
| 2880 |
| 2881 case LookupIterator::DATA: |
| 2882 if (it->property_details().IsReadOnly()) { |
| 2883 return WriteToReadOnlyProperty(it, value, strict_mode); |
| 2884 } |
| 2885 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 2886 return SetDataProperty(it, value); |
| 2887 } |
| 2888 done = true; |
| 2889 break; |
| 2899 | 2890 |
| 2900 case LookupIterator::TRANSITION: | 2891 case LookupIterator::TRANSITION: |
| 2901 done = true; | 2892 done = true; |
| 2902 break; | 2893 break; |
| 2903 } | 2894 } |
| 2904 | 2895 |
| 2905 if (done) break; | 2896 if (done) break; |
| 2906 } | 2897 } |
| 2907 | 2898 |
| 2908 // If the receiver is the JSGlobalObject, the store was contextual. In case | 2899 // If the receiver is the JSGlobalObject, the store was contextual. In case |
| (...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3818 DCHECK(!value->IsTheHole()); | 3809 DCHECK(!value->IsTheHole()); |
| 3819 LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 3810 LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 3820 bool is_observed = object->map()->is_observed() && | 3811 bool is_observed = object->map()->is_observed() && |
| 3821 *name != it.isolate()->heap()->hidden_string(); | 3812 *name != it.isolate()->heap()->hidden_string(); |
| 3822 for (; it.IsFound(); it.Next()) { | 3813 for (; it.IsFound(); it.Next()) { |
| 3823 switch (it.state()) { | 3814 switch (it.state()) { |
| 3824 case LookupIterator::INTERCEPTOR: | 3815 case LookupIterator::INTERCEPTOR: |
| 3825 case LookupIterator::JSPROXY: | 3816 case LookupIterator::JSPROXY: |
| 3826 case LookupIterator::NOT_FOUND: | 3817 case LookupIterator::NOT_FOUND: |
| 3827 case LookupIterator::TRANSITION: | 3818 case LookupIterator::TRANSITION: |
| 3819 case LookupIterator::UNKNOWN: |
| 3828 UNREACHABLE(); | 3820 UNREACHABLE(); |
| 3829 | 3821 |
| 3830 case LookupIterator::ACCESS_CHECK: | 3822 case LookupIterator::ACCESS_CHECK: |
| 3831 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 3823 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 3832 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); | 3824 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); |
| 3833 } | 3825 } |
| 3834 break; | 3826 break; |
| 3835 | 3827 |
| 3836 case LookupIterator::PROPERTY: { | 3828 case LookupIterator::ACCESSOR: { |
| 3837 if (!it.HasProperty()) break; | |
| 3838 PropertyDetails details = it.property_details(); | 3829 PropertyDetails details = it.property_details(); |
| 3839 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); | 3830 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); |
| 3840 switch (it.property_kind()) { | 3831 // Ensure the context isn't changed after calling into accessors. |
| 3841 case LookupIterator::ACCESSOR: { | 3832 AssertNoContextChange ncc(it.isolate()); |
| 3842 // Ensure the context isn't changed after calling into accessors. | |
| 3843 AssertNoContextChange ncc(it.isolate()); | |
| 3844 | 3833 |
| 3845 Handle<Object> accessors = it.GetAccessors(); | 3834 Handle<Object> accessors = it.GetAccessors(); |
| 3846 | 3835 |
| 3847 if (is_observed && accessors->IsAccessorInfo()) { | 3836 if (is_observed && accessors->IsAccessorInfo()) { |
| 3848 ASSIGN_RETURN_ON_EXCEPTION( | 3837 ASSIGN_RETURN_ON_EXCEPTION( |
| 3849 it.isolate(), old_value, | 3838 it.isolate(), old_value, |
| 3850 GetPropertyWithAccessor(it.GetReceiver(), it.name(), | 3839 GetPropertyWithAccessor(it.GetReceiver(), it.name(), |
| 3851 it.GetHolder<JSObject>(), accessors), | 3840 it.GetHolder<JSObject>(), accessors), |
| 3852 Object); | 3841 Object); |
| 3842 } |
| 3843 |
| 3844 // Special handling for ExecutableAccessorInfo, which behaves like a |
| 3845 // data property. |
| 3846 if (handling == DONT_FORCE_FIELD && |
| 3847 accessors->IsExecutableAccessorInfo()) { |
| 3848 Handle<Object> result; |
| 3849 ASSIGN_RETURN_ON_EXCEPTION( |
| 3850 it.isolate(), result, |
| 3851 JSObject::SetPropertyWithAccessor(it.GetReceiver(), it.name(), |
| 3852 value, it.GetHolder<JSObject>(), |
| 3853 accessors, STRICT), |
| 3854 Object); |
| 3855 DCHECK(result->SameValue(*value)); |
| 3856 |
| 3857 if (details.attributes() == attributes) { |
| 3858 // Regular property update if the attributes match. |
| 3859 if (is_observed && !old_value->SameValue(*value)) { |
| 3860 // If we are setting the prototype of a function and are |
| 3861 // observed, don't send change records because the prototype |
| 3862 // handles that itself. |
| 3863 if (!object->IsJSFunction() || |
| 3864 !Name::Equals(it.isolate()->factory()->prototype_string(), |
| 3865 name) || |
| 3866 !Handle<JSFunction>::cast(object)->should_have_prototype()) { |
| 3867 EnqueueChangeRecord(object, "update", name, old_value); |
| 3868 } |
| 3853 } | 3869 } |
| 3854 | 3870 return value; |
| 3855 // Special handling for ExecutableAccessorInfo, which behaves like a | |
| 3856 // data property. | |
| 3857 if (handling == DONT_FORCE_FIELD && | |
| 3858 accessors->IsExecutableAccessorInfo()) { | |
| 3859 Handle<Object> result; | |
| 3860 ASSIGN_RETURN_ON_EXCEPTION( | |
| 3861 it.isolate(), result, | |
| 3862 JSObject::SetPropertyWithAccessor( | |
| 3863 it.GetReceiver(), it.name(), value, | |
| 3864 it.GetHolder<JSObject>(), accessors, STRICT), | |
| 3865 Object); | |
| 3866 DCHECK(result->SameValue(*value)); | |
| 3867 | |
| 3868 if (details.attributes() == attributes) { | |
| 3869 // Regular property update if the attributes match. | |
| 3870 if (is_observed && !old_value->SameValue(*value)) { | |
| 3871 // If we are setting the prototype of a function and are | |
| 3872 // observed, don't send change records because the prototype | |
| 3873 // handles that itself. | |
| 3874 if (!object->IsJSFunction() || | |
| 3875 !Name::Equals(it.isolate()->factory()->prototype_string(), | |
| 3876 name) || | |
| 3877 !Handle<JSFunction>::cast(object) | |
| 3878 ->should_have_prototype()) { | |
| 3879 EnqueueChangeRecord(object, "update", name, old_value); | |
| 3880 } | |
| 3881 } | |
| 3882 return value; | |
| 3883 } | |
| 3884 | |
| 3885 // Reconfigure the accessor if attributes mismatch. | |
| 3886 Handle<ExecutableAccessorInfo> new_data = | |
| 3887 Accessors::CloneAccessor( | |
| 3888 it.isolate(), | |
| 3889 Handle<ExecutableAccessorInfo>::cast(accessors)); | |
| 3890 new_data->set_property_attributes(attributes); | |
| 3891 // By clearing the setter we don't have to introduce a lookup to | |
| 3892 // the setter, simply make it unavailable to reflect the | |
| 3893 // attributes. | |
| 3894 if (attributes & READ_ONLY) new_data->clear_setter(); | |
| 3895 SetPropertyCallback(object, name, new_data, attributes); | |
| 3896 if (is_observed) { | |
| 3897 if (old_value->SameValue(*value)) { | |
| 3898 old_value = it.isolate()->factory()->the_hole_value(); | |
| 3899 } | |
| 3900 EnqueueChangeRecord(object, "reconfigure", name, old_value); | |
| 3901 } | |
| 3902 return value; | |
| 3903 } | |
| 3904 | |
| 3905 // Regular accessor. Reconfigure to data property. | |
| 3906 break; | |
| 3907 } | 3871 } |
| 3908 | 3872 |
| 3909 case LookupIterator::DATA: | 3873 // Reconfigure the accessor if attributes mismatch. |
| 3910 // Regular property update if the attributes match. | 3874 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( |
| 3911 if (details.attributes() == attributes) { | 3875 it.isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); |
| 3912 return SetDataProperty(&it, value); | 3876 new_data->set_property_attributes(attributes); |
| 3877 // By clearing the setter we don't have to introduce a lookup to |
| 3878 // the setter, simply make it unavailable to reflect the |
| 3879 // attributes. |
| 3880 if (attributes & READ_ONLY) new_data->clear_setter(); |
| 3881 SetPropertyCallback(object, name, new_data, attributes); |
| 3882 if (is_observed) { |
| 3883 if (old_value->SameValue(*value)) { |
| 3884 old_value = it.isolate()->factory()->the_hole_value(); |
| 3913 } | 3885 } |
| 3914 // Reconfigure the data property if the attributes mismatch. | 3886 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 3915 if (is_observed) old_value = it.GetDataValue(); | 3887 } |
| 3888 return value; |
| 3916 } | 3889 } |
| 3917 | 3890 |
| 3918 it.ReconfigureDataProperty(value, attributes); | 3891 it.ReconfigureDataProperty(value, attributes); |
| 3919 it.PrepareForDataProperty(value); | 3892 it.PrepareForDataProperty(value); |
| 3893 it.WriteDataValue(value); |
| 3894 |
| 3895 if (is_observed) { |
| 3896 if (old_value->SameValue(*value)) { |
| 3897 old_value = it.isolate()->factory()->the_hole_value(); |
| 3898 } |
| 3899 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 3900 } |
| 3901 |
| 3902 return value; |
| 3903 } |
| 3904 |
| 3905 case LookupIterator::DATA: { |
| 3906 PropertyDetails details = it.property_details(); |
| 3907 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); |
| 3908 // Regular property update if the attributes match. |
| 3909 if (details.attributes() == attributes) { |
| 3910 return SetDataProperty(&it, value); |
| 3911 } |
| 3912 // Reconfigure the data property if the attributes mismatch. |
| 3913 if (is_observed) old_value = it.GetDataValue(); |
| 3914 |
| 3915 it.ReconfigureDataProperty(value, attributes); |
| 3916 it.PrepareForDataProperty(value); |
| 3920 it.WriteDataValue(value); | 3917 it.WriteDataValue(value); |
| 3921 | 3918 |
| 3922 if (is_observed) { | 3919 if (is_observed) { |
| 3923 if (old_value->SameValue(*value)) { | 3920 if (old_value->SameValue(*value)) { |
| 3924 old_value = it.isolate()->factory()->the_hole_value(); | 3921 old_value = it.isolate()->factory()->the_hole_value(); |
| 3925 } | 3922 } |
| 3926 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 3923 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 3927 } | 3924 } |
| 3928 | 3925 |
| 3929 return value; | 3926 return value; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3989 LookupIterator it(object, name, LookupIterator::HIDDEN); | 3986 LookupIterator it(object, name, LookupIterator::HIDDEN); |
| 3990 return GetPropertyAttributes(&it); | 3987 return GetPropertyAttributes(&it); |
| 3991 } | 3988 } |
| 3992 | 3989 |
| 3993 | 3990 |
| 3994 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( | 3991 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( |
| 3995 LookupIterator* it) { | 3992 LookupIterator* it) { |
| 3996 for (; it->IsFound(); it->Next()) { | 3993 for (; it->IsFound(); it->Next()) { |
| 3997 switch (it->state()) { | 3994 switch (it->state()) { |
| 3998 case LookupIterator::NOT_FOUND: | 3995 case LookupIterator::NOT_FOUND: |
| 3996 case LookupIterator::UNKNOWN: |
| 3999 case LookupIterator::TRANSITION: | 3997 case LookupIterator::TRANSITION: |
| 4000 UNREACHABLE(); | 3998 UNREACHABLE(); |
| 4001 case LookupIterator::JSPROXY: | 3999 case LookupIterator::JSPROXY: |
| 4002 return JSProxy::GetPropertyAttributesWithHandler( | 4000 return JSProxy::GetPropertyAttributesWithHandler( |
| 4003 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name()); | 4001 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name()); |
| 4004 case LookupIterator::INTERCEPTOR: { | 4002 case LookupIterator::INTERCEPTOR: { |
| 4005 Maybe<PropertyAttributes> result = | 4003 Maybe<PropertyAttributes> result = |
| 4006 JSObject::GetPropertyAttributesWithInterceptor( | 4004 JSObject::GetPropertyAttributesWithInterceptor( |
| 4007 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); | 4005 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); |
| 4008 if (!result.has_value) return result; | 4006 if (!result.has_value) return result; |
| 4009 if (result.value != ABSENT) return result; | 4007 if (result.value != ABSENT) return result; |
| 4010 break; | 4008 break; |
| 4011 } | 4009 } |
| 4012 case LookupIterator::ACCESS_CHECK: | 4010 case LookupIterator::ACCESS_CHECK: |
| 4013 if (it->HasAccess(v8::ACCESS_HAS)) break; | 4011 if (it->HasAccess(v8::ACCESS_HAS)) break; |
| 4014 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it); | 4012 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it); |
| 4015 case LookupIterator::PROPERTY: | 4013 case LookupIterator::ACCESSOR: |
| 4016 if (it->HasProperty()) { | 4014 case LookupIterator::DATA: |
| 4017 return maybe(it->property_details().attributes()); | 4015 return maybe(it->property_details().attributes()); |
| 4018 } | |
| 4019 break; | |
| 4020 } | 4016 } |
| 4021 } | 4017 } |
| 4022 return maybe(ABSENT); | 4018 return maybe(ABSENT); |
| 4023 } | 4019 } |
| 4024 | 4020 |
| 4025 | 4021 |
| 4026 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithReceiver( | 4022 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithReceiver( |
| 4027 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index, | 4023 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index, |
| 4028 bool check_prototype) { | 4024 bool check_prototype) { |
| 4029 Isolate* isolate = object->GetIsolate(); | 4025 Isolate* isolate = object->GetIsolate(); |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4686 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 4682 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); |
| 4687 bool was_present = false; | 4683 bool was_present = false; |
| 4688 ObjectHashTable::Remove(hashtable, key, &was_present); | 4684 ObjectHashTable::Remove(hashtable, key, &was_present); |
| 4689 } | 4685 } |
| 4690 | 4686 |
| 4691 | 4687 |
| 4692 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { | 4688 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { |
| 4693 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); | 4689 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); |
| 4694 LookupIterator it(object, hidden, LookupIterator::OWN_SKIP_INTERCEPTOR); | 4690 LookupIterator it(object, hidden, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 4695 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); | 4691 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); |
| 4696 return it.IsFound() && it.HasProperty(); | 4692 return it.IsFound(); |
| 4697 } | 4693 } |
| 4698 | 4694 |
| 4699 | 4695 |
| 4700 Object* JSObject::GetHiddenPropertiesHashTable() { | 4696 Object* JSObject::GetHiddenPropertiesHashTable() { |
| 4701 DCHECK(!IsJSGlobalProxy()); | 4697 DCHECK(!IsJSGlobalProxy()); |
| 4702 if (HasFastProperties()) { | 4698 if (HasFastProperties()) { |
| 4703 // If the object has fast properties, check whether the first slot | 4699 // If the object has fast properties, check whether the first slot |
| 4704 // in the descriptor array matches the hidden string. Since the | 4700 // in the descriptor array matches the hidden string. Since the |
| 4705 // hidden strings hash code is zero (and no other name has hash | 4701 // hidden strings hash code is zero (and no other name has hash |
| 4706 // code zero) it will always occupy the first entry if present. | 4702 // code zero) it will always occupy the first entry if present. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4719 return GetHeap()->undefined_value(); | 4715 return GetHeap()->undefined_value(); |
| 4720 } | 4716 } |
| 4721 } else { | 4717 } else { |
| 4722 return GetHeap()->undefined_value(); | 4718 return GetHeap()->undefined_value(); |
| 4723 } | 4719 } |
| 4724 } else { | 4720 } else { |
| 4725 Isolate* isolate = GetIsolate(); | 4721 Isolate* isolate = GetIsolate(); |
| 4726 LookupIterator it(handle(this), isolate->factory()->hidden_string(), | 4722 LookupIterator it(handle(this), isolate->factory()->hidden_string(), |
| 4727 LookupIterator::OWN_SKIP_INTERCEPTOR); | 4723 LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 4728 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); | 4724 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); |
| 4729 if (it.IsFound() && it.HasProperty()) { | 4725 if (it.state() == LookupIterator::DATA) { |
| 4730 DCHECK_EQ(LookupIterator::DATA, it.property_kind()); | |
| 4731 return *it.GetDataValue(); | 4726 return *it.GetDataValue(); |
| 4732 } | 4727 } |
| 4728 DCHECK(!it.IsFound()); |
| 4733 return GetHeap()->undefined_value(); | 4729 return GetHeap()->undefined_value(); |
| 4734 } | 4730 } |
| 4735 } | 4731 } |
| 4736 | 4732 |
| 4737 Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable( | 4733 Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable( |
| 4738 Handle<JSObject> object) { | 4734 Handle<JSObject> object) { |
| 4739 Isolate* isolate = object->GetIsolate(); | 4735 Isolate* isolate = object->GetIsolate(); |
| 4740 | 4736 |
| 4741 static const int kInitialCapacity = 4; | 4737 static const int kInitialCapacity = 4; |
| 4742 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 4738 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4919 | 4915 |
| 4920 // Skip interceptors on FORCE_DELETION. | 4916 // Skip interceptors on FORCE_DELETION. |
| 4921 LookupIterator::Configuration config = | 4917 LookupIterator::Configuration config = |
| 4922 delete_mode == FORCE_DELETION ? LookupIterator::HIDDEN_SKIP_INTERCEPTOR | 4918 delete_mode == FORCE_DELETION ? LookupIterator::HIDDEN_SKIP_INTERCEPTOR |
| 4923 : LookupIterator::HIDDEN; | 4919 : LookupIterator::HIDDEN; |
| 4924 | 4920 |
| 4925 LookupIterator it(object, name, config); | 4921 LookupIterator it(object, name, config); |
| 4926 | 4922 |
| 4927 bool is_observed = object->map()->is_observed() && | 4923 bool is_observed = object->map()->is_observed() && |
| 4928 *name != it.isolate()->heap()->hidden_string(); | 4924 *name != it.isolate()->heap()->hidden_string(); |
| 4925 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); |
| 4929 | 4926 |
| 4930 for (; it.IsFound(); it.Next()) { | 4927 for (; it.IsFound(); it.Next()) { |
| 4931 switch (it.state()) { | 4928 switch (it.state()) { |
| 4932 case LookupIterator::JSPROXY: | 4929 case LookupIterator::JSPROXY: |
| 4933 case LookupIterator::NOT_FOUND: | 4930 case LookupIterator::NOT_FOUND: |
| 4934 case LookupIterator::TRANSITION: | 4931 case LookupIterator::TRANSITION: |
| 4932 case LookupIterator::UNKNOWN: |
| 4935 UNREACHABLE(); | 4933 UNREACHABLE(); |
| 4936 case LookupIterator::ACCESS_CHECK: | 4934 case LookupIterator::ACCESS_CHECK: |
| 4937 if (it.HasAccess(v8::ACCESS_DELETE)) break; | 4935 if (it.HasAccess(v8::ACCESS_DELETE)) break; |
| 4938 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(), | 4936 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(), |
| 4939 v8::ACCESS_DELETE); | 4937 v8::ACCESS_DELETE); |
| 4940 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object); | 4938 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object); |
| 4941 return it.isolate()->factory()->false_value(); | 4939 return it.isolate()->factory()->false_value(); |
| 4942 case LookupIterator::INTERCEPTOR: { | 4940 case LookupIterator::INTERCEPTOR: { |
| 4943 MaybeHandle<Object> maybe_result = | 4941 MaybeHandle<Object> maybe_result = |
| 4944 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(), | 4942 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(), |
| 4945 object, it.name()); | 4943 object, it.name()); |
| 4946 // Delete with interceptor succeeded. Return result. | 4944 // Delete with interceptor succeeded. Return result. |
| 4947 if (!maybe_result.is_null()) return maybe_result; | 4945 if (!maybe_result.is_null()) return maybe_result; |
| 4948 // An exception was thrown in the interceptor. Propagate. | 4946 // An exception was thrown in the interceptor. Propagate. |
| 4949 if (it.isolate()->has_pending_exception()) return maybe_result; | 4947 if (it.isolate()->has_pending_exception()) return maybe_result; |
| 4950 break; | 4948 break; |
| 4951 } | 4949 } |
| 4952 case LookupIterator::PROPERTY: { | 4950 case LookupIterator::DATA: |
| 4953 if (!it.HasProperty()) continue; | 4951 if (is_observed) { |
| 4952 old_value = it.GetDataValue(); |
| 4953 } |
| 4954 // Fall through. |
| 4955 case LookupIterator::ACCESSOR: { |
| 4954 if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) { | 4956 if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) { |
| 4955 // Fail if the property is not configurable. | 4957 // Fail if the property is not configurable. |
| 4956 if (delete_mode == STRICT_DELETION) { | 4958 if (delete_mode == STRICT_DELETION) { |
| 4957 Handle<Object> args[2] = {name, object}; | 4959 Handle<Object> args[2] = {name, object}; |
| 4958 THROW_NEW_ERROR(it.isolate(), | 4960 THROW_NEW_ERROR(it.isolate(), |
| 4959 NewTypeError("strict_delete_property", | 4961 NewTypeError("strict_delete_property", |
| 4960 HandleVector(args, arraysize(args))), | 4962 HandleVector(args, arraysize(args))), |
| 4961 Object); | 4963 Object); |
| 4962 } | 4964 } |
| 4963 return it.isolate()->factory()->false_value(); | 4965 return it.isolate()->factory()->false_value(); |
| 4964 } | 4966 } |
| 4965 | 4967 |
| 4966 Handle<Object> old_value; | |
| 4967 if (is_observed) { | |
| 4968 switch (it.property_kind()) { | |
| 4969 case LookupIterator::ACCESSOR: | |
| 4970 old_value = it.isolate()->factory()->the_hole_value(); | |
| 4971 break; | |
| 4972 case LookupIterator::DATA: | |
| 4973 old_value = it.GetDataValue(); | |
| 4974 } | |
| 4975 } | |
| 4976 | |
| 4977 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 4968 PropertyNormalizationMode mode = object->map()->is_prototype_map() |
| 4978 ? KEEP_INOBJECT_PROPERTIES | 4969 ? KEEP_INOBJECT_PROPERTIES |
| 4979 : CLEAR_INOBJECT_PROPERTIES; | 4970 : CLEAR_INOBJECT_PROPERTIES; |
| 4980 Handle<JSObject> holder = it.GetHolder<JSObject>(); | 4971 Handle<JSObject> holder = it.GetHolder<JSObject>(); |
| 4981 // TODO(verwaest): Remove this temporary compatibility hack when blink | 4972 // TODO(verwaest): Remove this temporary compatibility hack when blink |
| 4982 // tests are updated. | 4973 // tests are updated. |
| 4983 if (!holder.is_identical_to(object) && | 4974 if (!holder.is_identical_to(object) && |
| 4984 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { | 4975 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { |
| 4985 return it.isolate()->factory()->true_value(); | 4976 return it.isolate()->factory()->true_value(); |
| 4986 } | 4977 } |
| (...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6143 } | 6134 } |
| 6144 preexists = maybe.value; | 6135 preexists = maybe.value; |
| 6145 if (preexists && GetOwnElementAccessorPair(object, index).is_null()) { | 6136 if (preexists && GetOwnElementAccessorPair(object, index).is_null()) { |
| 6146 old_value = | 6137 old_value = |
| 6147 Object::GetElement(isolate, object, index).ToHandleChecked(); | 6138 Object::GetElement(isolate, object, index).ToHandleChecked(); |
| 6148 } | 6139 } |
| 6149 } else { | 6140 } else { |
| 6150 LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); | 6141 LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |
| 6151 CHECK(GetPropertyAttributes(&it).has_value); | 6142 CHECK(GetPropertyAttributes(&it).has_value); |
| 6152 preexists = it.IsFound(); | 6143 preexists = it.IsFound(); |
| 6153 if (preexists && (it.property_kind() == LookupIterator::DATA || | 6144 if (preexists && (it.state() == LookupIterator::DATA || |
| 6154 it.GetAccessors()->IsAccessorInfo())) { | 6145 it.GetAccessors()->IsAccessorInfo())) { |
| 6155 old_value = GetProperty(&it).ToHandleChecked(); | 6146 old_value = GetProperty(&it).ToHandleChecked(); |
| 6156 } | 6147 } |
| 6157 } | 6148 } |
| 6158 } | 6149 } |
| 6159 | 6150 |
| 6160 if (is_element) { | 6151 if (is_element) { |
| 6161 DefineElementAccessor(object, index, getter, setter, attributes); | 6152 DefineElementAccessor(object, index, getter, setter, attributes); |
| 6162 } else { | 6153 } else { |
| 6163 DCHECK(getter->IsSpecFunction() || getter->IsUndefined() || | 6154 DCHECK(getter->IsSpecFunction() || getter->IsUndefined() || |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6307 } | 6298 } |
| 6308 } | 6299 } |
| 6309 } else { | 6300 } else { |
| 6310 LookupIterator it(object, name, | 6301 LookupIterator it(object, name, |
| 6311 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); | 6302 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); |
| 6312 for (; it.IsFound(); it.Next()) { | 6303 for (; it.IsFound(); it.Next()) { |
| 6313 switch (it.state()) { | 6304 switch (it.state()) { |
| 6314 case LookupIterator::INTERCEPTOR: | 6305 case LookupIterator::INTERCEPTOR: |
| 6315 case LookupIterator::NOT_FOUND: | 6306 case LookupIterator::NOT_FOUND: |
| 6316 case LookupIterator::TRANSITION: | 6307 case LookupIterator::TRANSITION: |
| 6308 case LookupIterator::UNKNOWN: |
| 6317 UNREACHABLE(); | 6309 UNREACHABLE(); |
| 6318 | 6310 |
| 6319 case LookupIterator::ACCESS_CHECK: | 6311 case LookupIterator::ACCESS_CHECK: |
| 6320 if (it.HasAccess(v8::ACCESS_HAS)) continue; | 6312 if (it.HasAccess(v8::ACCESS_HAS)) continue; |
| 6321 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(), | 6313 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(), |
| 6322 v8::ACCESS_HAS); | 6314 v8::ACCESS_HAS); |
| 6323 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 6315 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 6324 return isolate->factory()->undefined_value(); | 6316 return isolate->factory()->undefined_value(); |
| 6325 | 6317 |
| 6326 case LookupIterator::JSPROXY: | 6318 case LookupIterator::JSPROXY: |
| 6327 return isolate->factory()->undefined_value(); | 6319 return isolate->factory()->undefined_value(); |
| 6328 | 6320 |
| 6329 case LookupIterator::PROPERTY: | 6321 case LookupIterator::DATA: |
| 6330 if (!it.HasProperty()) continue; | 6322 continue; |
| 6331 switch (it.property_kind()) { | 6323 case LookupIterator::ACCESSOR: { |
| 6332 case LookupIterator::DATA: | 6324 Handle<Object> maybe_pair = it.GetAccessors(); |
| 6333 continue; | 6325 if (maybe_pair->IsAccessorPair()) { |
| 6334 case LookupIterator::ACCESSOR: { | 6326 return handle( |
| 6335 Handle<Object> maybe_pair = it.GetAccessors(); | 6327 AccessorPair::cast(*maybe_pair)->GetComponent(component), |
| 6336 if (maybe_pair->IsAccessorPair()) { | 6328 isolate); |
| 6337 return handle( | |
| 6338 AccessorPair::cast(*maybe_pair)->GetComponent(component), | |
| 6339 isolate); | |
| 6340 } | |
| 6341 } | |
| 6342 } | 6329 } |
| 6330 } |
| 6343 } | 6331 } |
| 6344 } | 6332 } |
| 6345 } | 6333 } |
| 6346 return isolate->factory()->undefined_value(); | 6334 return isolate->factory()->undefined_value(); |
| 6347 } | 6335 } |
| 6348 | 6336 |
| 6349 | 6337 |
| 6350 Object* JSObject::SlowReverseLookup(Object* value) { | 6338 Object* JSObject::SlowReverseLookup(Object* value) { |
| 6351 if (HasFastProperties()) { | 6339 if (HasFastProperties()) { |
| 6352 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); | 6340 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); |
| (...skipping 6489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12842 | 12830 |
| 12843 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array, | 12831 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array, |
| 12844 uint32_t index) { | 12832 uint32_t index) { |
| 12845 uint32_t length = 0; | 12833 uint32_t length = 0; |
| 12846 CHECK(array->length()->ToArrayIndex(&length)); | 12834 CHECK(array->length()->ToArrayIndex(&length)); |
| 12847 if (length <= index) { | 12835 if (length <= index) { |
| 12848 LookupIterator it(array, array->GetIsolate()->factory()->length_string(), | 12836 LookupIterator it(array, array->GetIsolate()->factory()->length_string(), |
| 12849 LookupIterator::OWN_SKIP_INTERCEPTOR); | 12837 LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 12850 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); | 12838 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); |
| 12851 CHECK(it.IsFound()); | 12839 CHECK(it.IsFound()); |
| 12852 CHECK(it.HasProperty()); | 12840 CHECK_EQ(LookupIterator::ACCESSOR, it.state()); |
| 12853 return it.IsReadOnly(); | 12841 return it.IsReadOnly(); |
| 12854 } | 12842 } |
| 12855 return false; | 12843 return false; |
| 12856 } | 12844 } |
| 12857 | 12845 |
| 12858 | 12846 |
| 12859 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) { | 12847 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) { |
| 12860 Isolate* isolate = array->GetIsolate(); | 12848 Isolate* isolate = array->GetIsolate(); |
| 12861 Handle<Name> length = isolate->factory()->length_string(); | 12849 Handle<Name> length = isolate->factory()->length_string(); |
| 12862 Handle<Object> args[2] = { length, array }; | 12850 Handle<Object> args[2] = { length, array }; |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13268 if (!result.has_value) return Maybe<bool>(); | 13256 if (!result.has_value) return Maybe<bool>(); |
| 13269 return maybe(result.value != ABSENT); | 13257 return maybe(result.value != ABSENT); |
| 13270 } | 13258 } |
| 13271 | 13259 |
| 13272 | 13260 |
| 13273 Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object, | 13261 Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object, |
| 13274 Handle<Name> key) { | 13262 Handle<Name> key) { |
| 13275 LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR); | 13263 LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 13276 Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it); | 13264 Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it); |
| 13277 if (!maybe_result.has_value) return Maybe<bool>(); | 13265 if (!maybe_result.has_value) return Maybe<bool>(); |
| 13278 return maybe(it.IsFound() && it.property_kind() == LookupIterator::ACCESSOR); | 13266 return maybe(it.state() == LookupIterator::ACCESSOR); |
| 13279 } | 13267 } |
| 13280 | 13268 |
| 13281 | 13269 |
| 13282 int JSObject::NumberOfOwnProperties(PropertyAttributes filter) { | 13270 int JSObject::NumberOfOwnProperties(PropertyAttributes filter) { |
| 13283 if (HasFastProperties()) { | 13271 if (HasFastProperties()) { |
| 13284 Map* map = this->map(); | 13272 Map* map = this->map(); |
| 13285 if (filter == NONE) return map->NumberOfOwnDescriptors(); | 13273 if (filter == NONE) return map->NumberOfOwnDescriptors(); |
| 13286 if (filter & DONT_ENUM) { | 13274 if (filter & DONT_ENUM) { |
| 13287 int result = map->EnumLength(); | 13275 int result = map->EnumLength(); |
| 13288 if (result != kInvalidEnumCacheSentinel) return result; | 13276 if (result != kInvalidEnumCacheSentinel) return result; |
| (...skipping 3133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16422 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16410 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16423 static const char* error_messages_[] = { | 16411 static const char* error_messages_[] = { |
| 16424 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16412 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16425 }; | 16413 }; |
| 16426 #undef ERROR_MESSAGES_TEXTS | 16414 #undef ERROR_MESSAGES_TEXTS |
| 16427 return error_messages_[reason]; | 16415 return error_messages_[reason]; |
| 16428 } | 16416 } |
| 16429 | 16417 |
| 16430 | 16418 |
| 16431 } } // namespace v8::internal | 16419 } } // namespace v8::internal |
| OLD | NEW |