| 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 <sstream> | 5 #include <sstream> |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 3979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3990 UNREACHABLE(); | 3990 UNREACHABLE(); |
| 3991 | 3991 |
| 3992 case LookupIterator::ACCESS_CHECK: | 3992 case LookupIterator::ACCESS_CHECK: |
| 3993 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 3993 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 3994 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); | 3994 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); |
| 3995 } | 3995 } |
| 3996 break; | 3996 break; |
| 3997 | 3997 |
| 3998 case LookupIterator::ACCESSOR: { | 3998 case LookupIterator::ACCESSOR: { |
| 3999 PropertyDetails details = it.property_details(); | 3999 PropertyDetails details = it.property_details(); |
| 4000 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); | |
| 4001 // Ensure the context isn't changed after calling into accessors. | 4000 // Ensure the context isn't changed after calling into accessors. |
| 4002 AssertNoContextChange ncc(it.isolate()); | 4001 AssertNoContextChange ncc(it.isolate()); |
| 4003 | 4002 |
| 4004 Handle<Object> accessors = it.GetAccessors(); | 4003 Handle<Object> accessors = it.GetAccessors(); |
| 4005 | 4004 |
| 4006 if (is_observed && accessors->IsAccessorInfo()) { | |
| 4007 ASSIGN_RETURN_ON_EXCEPTION( | |
| 4008 it.isolate(), old_value, | |
| 4009 GetPropertyWithAccessor(it.GetReceiver(), it.name(), | |
| 4010 it.GetHolder<JSObject>(), accessors), | |
| 4011 Object); | |
| 4012 } | |
| 4013 | |
| 4014 // Special handling for ExecutableAccessorInfo, which behaves like a | 4005 // Special handling for ExecutableAccessorInfo, which behaves like a |
| 4015 // data property. | 4006 // data property. |
| 4016 if (handling == DONT_FORCE_FIELD && | 4007 if (handling == DONT_FORCE_FIELD && |
| 4017 accessors->IsExecutableAccessorInfo()) { | 4008 accessors->IsExecutableAccessorInfo()) { |
| 4018 Handle<Object> result; | 4009 Handle<Object> result; |
| 4019 ASSIGN_RETURN_ON_EXCEPTION( | 4010 ASSIGN_RETURN_ON_EXCEPTION( |
| 4020 it.isolate(), result, | 4011 it.isolate(), result, |
| 4021 JSObject::SetPropertyWithAccessor(it.GetReceiver(), it.name(), | 4012 JSObject::SetPropertyWithAccessor(it.GetReceiver(), it.name(), |
| 4022 value, it.GetHolder<JSObject>(), | 4013 value, it.GetHolder<JSObject>(), |
| 4023 accessors, STRICT), | 4014 accessors, STRICT), |
| 4024 Object); | 4015 Object); |
| 4025 DCHECK(result->SameValue(*value)); | 4016 DCHECK(result->SameValue(*value)); |
| 4026 | 4017 |
| 4027 if (details.attributes() == attributes) { | 4018 if (details.attributes() == attributes) { |
| 4028 // Regular property update if the attributes match. | |
| 4029 if (is_observed && !old_value->SameValue(*value)) { | |
| 4030 // If we are setting the prototype of a function and are | |
| 4031 // observed, don't send change records because the prototype | |
| 4032 // handles that itself. | |
| 4033 if (!object->IsJSFunction() || | |
| 4034 !Name::Equals(it.isolate()->factory()->prototype_string(), | |
| 4035 name) || | |
| 4036 !Handle<JSFunction>::cast(object)->should_have_prototype()) { | |
| 4037 RETURN_ON_EXCEPTION( | |
| 4038 it.isolate(), | |
| 4039 EnqueueChangeRecord(object, "update", name, old_value), | |
| 4040 Object); | |
| 4041 } | |
| 4042 } | |
| 4043 return value; | 4019 return value; |
| 4044 } | 4020 } |
| 4045 | 4021 |
| 4046 // Reconfigure the accessor if attributes mismatch. | 4022 // Reconfigure the accessor if attributes mismatch. |
| 4047 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( | 4023 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( |
| 4048 it.isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); | 4024 it.isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); |
| 4049 new_data->set_property_attributes(attributes); | 4025 new_data->set_property_attributes(attributes); |
| 4050 // By clearing the setter we don't have to introduce a lookup to | 4026 // By clearing the setter we don't have to introduce a lookup to |
| 4051 // the setter, simply make it unavailable to reflect the | 4027 // the setter, simply make it unavailable to reflect the |
| 4052 // attributes. | 4028 // attributes. |
| 4053 if (attributes & READ_ONLY) new_data->clear_setter(); | 4029 if (attributes & READ_ONLY) new_data->clear_setter(); |
| 4054 SetPropertyCallback(object, name, new_data, attributes); | 4030 SetPropertyCallback(object, name, new_data, attributes); |
| 4055 if (is_observed) { | 4031 if (is_observed) { |
| 4056 if (old_value->SameValue(*value)) { | |
| 4057 old_value = it.isolate()->factory()->the_hole_value(); | |
| 4058 } | |
| 4059 RETURN_ON_EXCEPTION( | 4032 RETURN_ON_EXCEPTION( |
| 4060 it.isolate(), | 4033 it.isolate(), |
| 4061 EnqueueChangeRecord(object, "reconfigure", name, old_value), | 4034 EnqueueChangeRecord(object, "reconfigure", name, |
| 4035 it.isolate()->factory()->the_hole_value()), |
| 4062 Object); | 4036 Object); |
| 4063 } | 4037 } |
| 4064 return value; | 4038 return value; |
| 4065 } | 4039 } |
| 4066 | 4040 |
| 4067 it.ReconfigureDataProperty(value, attributes); | 4041 it.ReconfigureDataProperty(value, attributes); |
| 4068 it.PrepareForDataProperty(value); | 4042 it.PrepareForDataProperty(value); |
| 4069 it.WriteDataValue(value); | 4043 it.WriteDataValue(value); |
| 4070 | 4044 |
| 4071 if (is_observed) { | 4045 if (is_observed) { |
| 4072 if (old_value->SameValue(*value)) { | |
| 4073 old_value = it.isolate()->factory()->the_hole_value(); | |
| 4074 } | |
| 4075 RETURN_ON_EXCEPTION( | 4046 RETURN_ON_EXCEPTION( |
| 4076 it.isolate(), | 4047 it.isolate(), |
| 4077 EnqueueChangeRecord(object, "reconfigure", name, old_value), | 4048 EnqueueChangeRecord(object, "reconfigure", name, |
| 4049 it.isolate()->factory()->the_hole_value()), |
| 4078 Object); | 4050 Object); |
| 4079 } | 4051 } |
| 4080 | 4052 |
| 4081 return value; | 4053 return value; |
| 4082 } | 4054 } |
| 4083 | 4055 |
| 4084 case LookupIterator::DATA: { | 4056 case LookupIterator::DATA: { |
| 4085 PropertyDetails details = it.property_details(); | 4057 PropertyDetails details = it.property_details(); |
| 4086 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); | 4058 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); |
| 4087 // Regular property update if the attributes match. | 4059 // Regular property update if the attributes match. |
| (...skipping 12843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16931 Handle<DependentCode> codes = | 16903 Handle<DependentCode> codes = |
| 16932 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16904 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16933 DependentCode::kPropertyCellChangedGroup, | 16905 DependentCode::kPropertyCellChangedGroup, |
| 16934 info->object_wrapper()); | 16906 info->object_wrapper()); |
| 16935 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16907 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16936 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16908 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16937 cell, info->zone()); | 16909 cell, info->zone()); |
| 16938 } | 16910 } |
| 16939 | 16911 |
| 16940 } } // namespace v8::internal | 16912 } } // namespace v8::internal |
| OLD | NEW |