| 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 1790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1801 // but any JSFunction knows its context immediately. | 1801 // but any JSFunction knows its context immediately. |
| 1802 function = JSFunction::cast(this); | 1802 function = JSFunction::cast(this); |
| 1803 } else { | 1803 } else { |
| 1804 function = JSFunction::cast(constructor); | 1804 function = JSFunction::cast(constructor); |
| 1805 } | 1805 } |
| 1806 | 1806 |
| 1807 return function->context()->native_context(); | 1807 return function->context()->native_context(); |
| 1808 } | 1808 } |
| 1809 | 1809 |
| 1810 | 1810 |
| 1811 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, | 1811 MaybeHandle<Object> JSObject::EnqueueChangeRecord(Handle<JSObject> object, |
| 1812 const char* type_str, | 1812 const char* type_str, |
| 1813 Handle<Name> name, | 1813 Handle<Name> name, |
| 1814 Handle<Object> old_value) { | 1814 Handle<Object> old_value) { |
| 1815 DCHECK(!object->IsJSGlobalProxy()); | 1815 DCHECK(!object->IsJSGlobalProxy()); |
| 1816 DCHECK(!object->IsJSGlobalObject()); | 1816 DCHECK(!object->IsJSGlobalObject()); |
| 1817 Isolate* isolate = object->GetIsolate(); | 1817 Isolate* isolate = object->GetIsolate(); |
| 1818 HandleScope scope(isolate); | 1818 HandleScope scope(isolate); |
| 1819 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); | 1819 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); |
| 1820 Handle<Object> args[] = { type, object, name, old_value }; | 1820 Handle<Object> args[] = { type, object, name, old_value }; |
| 1821 int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4; | 1821 int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4; |
| 1822 | 1822 |
| 1823 Execution::Call(isolate, | 1823 return Execution::Call(isolate, |
| 1824 Handle<JSFunction>(isolate->observers_notify_change()), | 1824 Handle<JSFunction>(isolate->observers_notify_change()), |
| 1825 isolate->factory()->undefined_value(), | 1825 isolate->factory()->undefined_value(), argc, args); |
| 1826 argc, args).Assert(); | |
| 1827 } | 1826 } |
| 1828 | 1827 |
| 1829 | 1828 |
| 1830 const char* Representation::Mnemonic() const { | 1829 const char* Representation::Mnemonic() const { |
| 1831 switch (kind_) { | 1830 switch (kind_) { |
| 1832 case kNone: return "v"; | 1831 case kNone: return "v"; |
| 1833 case kTagged: return "t"; | 1832 case kTagged: return "t"; |
| 1834 case kSmi: return "s"; | 1833 case kSmi: return "s"; |
| 1835 case kDouble: return "d"; | 1834 case kDouble: return "d"; |
| 1836 case kInteger32: return "i"; | 1835 case kInteger32: return "i"; |
| (...skipping 1086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2923 if (strict_mode != STRICT) return value; | 2922 if (strict_mode != STRICT) return value; |
| 2924 | 2923 |
| 2925 Handle<Object> args[] = {it->name(), it->GetReceiver()}; | 2924 Handle<Object> args[] = {it->name(), it->GetReceiver()}; |
| 2926 THROW_NEW_ERROR(it->isolate(), | 2925 THROW_NEW_ERROR(it->isolate(), |
| 2927 NewTypeError("strict_read_only_property", | 2926 NewTypeError("strict_read_only_property", |
| 2928 HandleVector(args, arraysize(args))), | 2927 HandleVector(args, arraysize(args))), |
| 2929 Object); | 2928 Object); |
| 2930 } | 2929 } |
| 2931 | 2930 |
| 2932 | 2931 |
| 2933 Handle<Object> Object::SetDataProperty(LookupIterator* it, | 2932 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, |
| 2934 Handle<Object> value) { | 2933 Handle<Object> value) { |
| 2935 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot | 2934 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot |
| 2936 // have own properties. | 2935 // have own properties. |
| 2937 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 2936 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
| 2938 | 2937 |
| 2939 // Store on the holder which may be hidden behind the receiver. | 2938 // Store on the holder which may be hidden behind the receiver. |
| 2940 DCHECK(it->HolderIsReceiverOrHiddenPrototype()); | 2939 DCHECK(it->HolderIsReceiverOrHiddenPrototype()); |
| 2941 | 2940 |
| 2942 // Old value for the observation change record. | 2941 // Old value for the observation change record. |
| 2943 // Fetch before transforming the object since the encoding may become | 2942 // Fetch before transforming the object since the encoding may become |
| 2944 // incompatible with what's cached in |it|. | 2943 // incompatible with what's cached in |it|. |
| 2945 bool is_observed = | 2944 bool is_observed = |
| 2946 receiver->map()->is_observed() && | 2945 receiver->map()->is_observed() && |
| 2947 !it->name().is_identical_to(it->factory()->hidden_string()); | 2946 !it->name().is_identical_to(it->factory()->hidden_string()); |
| 2948 MaybeHandle<Object> maybe_old; | 2947 MaybeHandle<Object> maybe_old; |
| 2949 if (is_observed) maybe_old = it->GetDataValue(); | 2948 if (is_observed) maybe_old = it->GetDataValue(); |
| 2950 | 2949 |
| 2951 // Possibly migrate to the most up-to-date map that will be able to store | 2950 // Possibly migrate to the most up-to-date map that will be able to store |
| 2952 // |value| under it->name(). | 2951 // |value| under it->name(). |
| 2953 it->PrepareForDataProperty(value); | 2952 it->PrepareForDataProperty(value); |
| 2954 | 2953 |
| 2955 // Write the property value. | 2954 // Write the property value. |
| 2956 it->WriteDataValue(value); | 2955 it->WriteDataValue(value); |
| 2957 | 2956 |
| 2958 // Send the change record if there are observers. | 2957 // Send the change record if there are observers. |
| 2959 if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) { | 2958 if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) { |
| 2960 JSObject::EnqueueChangeRecord(receiver, "update", it->name(), | 2959 RETURN_ON_EXCEPTION(it->isolate(), JSObject::EnqueueChangeRecord( |
| 2961 maybe_old.ToHandleChecked()); | 2960 receiver, "update", it->name(), |
| 2961 maybe_old.ToHandleChecked()), |
| 2962 Object); |
| 2962 } | 2963 } |
| 2963 | 2964 |
| 2964 return value; | 2965 return value; |
| 2965 } | 2966 } |
| 2966 | 2967 |
| 2967 | 2968 |
| 2968 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, | 2969 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, |
| 2969 Handle<Object> value, | 2970 Handle<Object> value, |
| 2970 PropertyAttributes attributes, | 2971 PropertyAttributes attributes, |
| 2971 StrictMode strict_mode, | 2972 StrictMode strict_mode, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3002 it->InternalizeName(); | 3003 it->InternalizeName(); |
| 3003 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); | 3004 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); |
| 3004 } else { | 3005 } else { |
| 3005 // Write the property value. | 3006 // Write the property value. |
| 3006 it->WriteDataValue(value); | 3007 it->WriteDataValue(value); |
| 3007 } | 3008 } |
| 3008 | 3009 |
| 3009 // Send the change record if there are observers. | 3010 // Send the change record if there are observers. |
| 3010 if (receiver->map()->is_observed() && | 3011 if (receiver->map()->is_observed() && |
| 3011 !it->name().is_identical_to(it->factory()->hidden_string())) { | 3012 !it->name().is_identical_to(it->factory()->hidden_string())) { |
| 3012 JSObject::EnqueueChangeRecord(receiver, "add", it->name(), | 3013 RETURN_ON_EXCEPTION(it->isolate(), JSObject::EnqueueChangeRecord( |
| 3013 it->factory()->the_hole_value()); | 3014 receiver, "add", it->name(), |
| 3015 it->factory()->the_hole_value()), |
| 3016 Object); |
| 3014 } | 3017 } |
| 3015 | 3018 |
| 3016 return value; | 3019 return value; |
| 3017 } | 3020 } |
| 3018 | 3021 |
| 3019 | 3022 |
| 3020 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( | 3023 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
| 3021 Handle<JSObject> object, | 3024 Handle<JSObject> object, |
| 3022 uint32_t index, | 3025 uint32_t index, |
| 3023 Handle<Object> value, | 3026 Handle<Object> value, |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3852 if (details.attributes() == attributes) { | 3855 if (details.attributes() == attributes) { |
| 3853 // Regular property update if the attributes match. | 3856 // Regular property update if the attributes match. |
| 3854 if (is_observed && !old_value->SameValue(*value)) { | 3857 if (is_observed && !old_value->SameValue(*value)) { |
| 3855 // If we are setting the prototype of a function and are | 3858 // If we are setting the prototype of a function and are |
| 3856 // observed, don't send change records because the prototype | 3859 // observed, don't send change records because the prototype |
| 3857 // handles that itself. | 3860 // handles that itself. |
| 3858 if (!object->IsJSFunction() || | 3861 if (!object->IsJSFunction() || |
| 3859 !Name::Equals(it.isolate()->factory()->prototype_string(), | 3862 !Name::Equals(it.isolate()->factory()->prototype_string(), |
| 3860 name) || | 3863 name) || |
| 3861 !Handle<JSFunction>::cast(object)->should_have_prototype()) { | 3864 !Handle<JSFunction>::cast(object)->should_have_prototype()) { |
| 3862 EnqueueChangeRecord(object, "update", name, old_value); | 3865 RETURN_ON_EXCEPTION( |
| 3866 it.isolate(), |
| 3867 EnqueueChangeRecord(object, "update", name, old_value), |
| 3868 Object); |
| 3863 } | 3869 } |
| 3864 } | 3870 } |
| 3865 return value; | 3871 return value; |
| 3866 } | 3872 } |
| 3867 | 3873 |
| 3868 // Reconfigure the accessor if attributes mismatch. | 3874 // Reconfigure the accessor if attributes mismatch. |
| 3869 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( | 3875 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( |
| 3870 it.isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); | 3876 it.isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); |
| 3871 new_data->set_property_attributes(attributes); | 3877 new_data->set_property_attributes(attributes); |
| 3872 // By clearing the setter we don't have to introduce a lookup to | 3878 // By clearing the setter we don't have to introduce a lookup to |
| 3873 // the setter, simply make it unavailable to reflect the | 3879 // the setter, simply make it unavailable to reflect the |
| 3874 // attributes. | 3880 // attributes. |
| 3875 if (attributes & READ_ONLY) new_data->clear_setter(); | 3881 if (attributes & READ_ONLY) new_data->clear_setter(); |
| 3876 SetPropertyCallback(object, name, new_data, attributes); | 3882 SetPropertyCallback(object, name, new_data, attributes); |
| 3877 if (is_observed) { | 3883 if (is_observed) { |
| 3878 if (old_value->SameValue(*value)) { | 3884 if (old_value->SameValue(*value)) { |
| 3879 old_value = it.isolate()->factory()->the_hole_value(); | 3885 old_value = it.isolate()->factory()->the_hole_value(); |
| 3880 } | 3886 } |
| 3881 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 3887 RETURN_ON_EXCEPTION( |
| 3888 it.isolate(), |
| 3889 EnqueueChangeRecord(object, "reconfigure", name, old_value), |
| 3890 Object); |
| 3882 } | 3891 } |
| 3883 return value; | 3892 return value; |
| 3884 } | 3893 } |
| 3885 | 3894 |
| 3886 it.ReconfigureDataProperty(value, attributes); | 3895 it.ReconfigureDataProperty(value, attributes); |
| 3887 it.PrepareForDataProperty(value); | 3896 it.PrepareForDataProperty(value); |
| 3888 it.WriteDataValue(value); | 3897 it.WriteDataValue(value); |
| 3889 | 3898 |
| 3890 if (is_observed) { | 3899 if (is_observed) { |
| 3891 if (old_value->SameValue(*value)) { | 3900 if (old_value->SameValue(*value)) { |
| 3892 old_value = it.isolate()->factory()->the_hole_value(); | 3901 old_value = it.isolate()->factory()->the_hole_value(); |
| 3893 } | 3902 } |
| 3894 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 3903 RETURN_ON_EXCEPTION( |
| 3904 it.isolate(), |
| 3905 EnqueueChangeRecord(object, "reconfigure", name, old_value), |
| 3906 Object); |
| 3895 } | 3907 } |
| 3896 | 3908 |
| 3897 return value; | 3909 return value; |
| 3898 } | 3910 } |
| 3899 | 3911 |
| 3900 case LookupIterator::DATA: { | 3912 case LookupIterator::DATA: { |
| 3901 PropertyDetails details = it.property_details(); | 3913 PropertyDetails details = it.property_details(); |
| 3902 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); | 3914 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); |
| 3903 // Regular property update if the attributes match. | 3915 // Regular property update if the attributes match. |
| 3904 if (details.attributes() == attributes) { | 3916 if (details.attributes() == attributes) { |
| 3905 return SetDataProperty(&it, value); | 3917 return SetDataProperty(&it, value); |
| 3906 } | 3918 } |
| 3907 // Reconfigure the data property if the attributes mismatch. | 3919 // Reconfigure the data property if the attributes mismatch. |
| 3908 if (is_observed) old_value = it.GetDataValue(); | 3920 if (is_observed) old_value = it.GetDataValue(); |
| 3909 | 3921 |
| 3910 it.ReconfigureDataProperty(value, attributes); | 3922 it.ReconfigureDataProperty(value, attributes); |
| 3911 it.PrepareForDataProperty(value); | 3923 it.PrepareForDataProperty(value); |
| 3912 it.WriteDataValue(value); | 3924 it.WriteDataValue(value); |
| 3913 | 3925 |
| 3914 if (is_observed) { | 3926 if (is_observed) { |
| 3915 if (old_value->SameValue(*value)) { | 3927 if (old_value->SameValue(*value)) { |
| 3916 old_value = it.isolate()->factory()->the_hole_value(); | 3928 old_value = it.isolate()->factory()->the_hole_value(); |
| 3917 } | 3929 } |
| 3918 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 3930 RETURN_ON_EXCEPTION( |
| 3931 it.isolate(), |
| 3932 EnqueueChangeRecord(object, "reconfigure", name, old_value), |
| 3933 Object); |
| 3919 } | 3934 } |
| 3920 | 3935 |
| 3921 return value; | 3936 return value; |
| 3922 } | 3937 } |
| 3923 } | 3938 } |
| 3924 } | 3939 } |
| 3925 | 3940 |
| 3926 return AddDataProperty(&it, value, attributes, STRICT, | 3941 return AddDataProperty(&it, value, attributes, STRICT, |
| 3927 CERTAINLY_NOT_STORE_FROM_KEYED); | 3942 CERTAINLY_NOT_STORE_FROM_KEYED); |
| 3928 } | 3943 } |
| (...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4881 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); | 4896 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); |
| 4882 } | 4897 } |
| 4883 Handle<Object> result; | 4898 Handle<Object> result; |
| 4884 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); | 4899 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); |
| 4885 | 4900 |
| 4886 if (should_enqueue_change_record) { | 4901 if (should_enqueue_change_record) { |
| 4887 Maybe<bool> maybe = HasOwnElement(object, index); | 4902 Maybe<bool> maybe = HasOwnElement(object, index); |
| 4888 if (!maybe.has_value) return MaybeHandle<Object>(); | 4903 if (!maybe.has_value) return MaybeHandle<Object>(); |
| 4889 if (!maybe.value) { | 4904 if (!maybe.value) { |
| 4890 Handle<String> name = factory->Uint32ToString(index); | 4905 Handle<String> name = factory->Uint32ToString(index); |
| 4891 EnqueueChangeRecord(object, "delete", name, old_value); | 4906 RETURN_ON_EXCEPTION( |
| 4907 isolate, EnqueueChangeRecord(object, "delete", name, old_value), |
| 4908 Object); |
| 4892 } | 4909 } |
| 4893 } | 4910 } |
| 4894 | 4911 |
| 4895 return result; | 4912 return result; |
| 4896 } | 4913 } |
| 4897 | 4914 |
| 4898 | 4915 |
| 4899 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 4916 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
| 4900 Handle<Name> name, | 4917 Handle<Name> name, |
| 4901 DeleteMode delete_mode) { | 4918 DeleteMode delete_mode) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4967 if (!holder.is_identical_to(object) && | 4984 if (!holder.is_identical_to(object) && |
| 4968 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { | 4985 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { |
| 4969 return it.isolate()->factory()->true_value(); | 4986 return it.isolate()->factory()->true_value(); |
| 4970 } | 4987 } |
| 4971 NormalizeProperties(holder, mode, 0); | 4988 NormalizeProperties(holder, mode, 0); |
| 4972 Handle<Object> result = | 4989 Handle<Object> result = |
| 4973 DeleteNormalizedProperty(holder, name, delete_mode); | 4990 DeleteNormalizedProperty(holder, name, delete_mode); |
| 4974 ReoptimizeIfPrototype(holder); | 4991 ReoptimizeIfPrototype(holder); |
| 4975 | 4992 |
| 4976 if (is_observed) { | 4993 if (is_observed) { |
| 4977 EnqueueChangeRecord(object, "delete", name, old_value); | 4994 RETURN_ON_EXCEPTION( |
| 4995 it.isolate(), |
| 4996 EnqueueChangeRecord(object, "delete", name, old_value), Object); |
| 4978 } | 4997 } |
| 4979 | 4998 |
| 4980 return result; | 4999 return result; |
| 4981 } | 5000 } |
| 4982 } | 5001 } |
| 4983 } | 5002 } |
| 4984 | 5003 |
| 4985 return it.isolate()->factory()->true_value(); | 5004 return it.isolate()->factory()->true_value(); |
| 4986 } | 5005 } |
| 4987 | 5006 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5184 // Do a map transition, other objects with this map may still | 5203 // Do a map transition, other objects with this map may still |
| 5185 // be extensible. | 5204 // be extensible. |
| 5186 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5205 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
| 5187 Handle<Map> new_map = Map::Copy(handle(object->map())); | 5206 Handle<Map> new_map = Map::Copy(handle(object->map())); |
| 5188 | 5207 |
| 5189 new_map->set_is_extensible(false); | 5208 new_map->set_is_extensible(false); |
| 5190 JSObject::MigrateToMap(object, new_map); | 5209 JSObject::MigrateToMap(object, new_map); |
| 5191 DCHECK(!object->map()->is_extensible()); | 5210 DCHECK(!object->map()->is_extensible()); |
| 5192 | 5211 |
| 5193 if (object->map()->is_observed()) { | 5212 if (object->map()->is_observed()) { |
| 5194 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 5213 RETURN_ON_EXCEPTION( |
| 5195 isolate->factory()->the_hole_value()); | 5214 isolate, |
| 5215 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
| 5216 isolate->factory()->the_hole_value()), |
| 5217 Object); |
| 5196 } | 5218 } |
| 5197 return object; | 5219 return object; |
| 5198 } | 5220 } |
| 5199 | 5221 |
| 5200 | 5222 |
| 5201 template<typename Dictionary> | 5223 template<typename Dictionary> |
| 5202 static void FreezeDictionary(Dictionary* dictionary) { | 5224 static void FreezeDictionary(Dictionary* dictionary) { |
| 5203 int capacity = dictionary->Capacity(); | 5225 int capacity = dictionary->Capacity(); |
| 5204 for (int i = 0; i < capacity; i++) { | 5226 for (int i = 0; i < capacity; i++) { |
| 5205 Object* k = dictionary->KeyAt(i); | 5227 Object* k = dictionary->KeyAt(i); |
| (...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6158 if (!getter->IsNull()) { | 6180 if (!getter->IsNull()) { |
| 6159 it.TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes); | 6181 it.TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes); |
| 6160 } | 6182 } |
| 6161 if (!setter->IsNull()) { | 6183 if (!setter->IsNull()) { |
| 6162 it.TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes); | 6184 it.TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes); |
| 6163 } | 6185 } |
| 6164 } | 6186 } |
| 6165 | 6187 |
| 6166 if (is_observed) { | 6188 if (is_observed) { |
| 6167 const char* type = preexists ? "reconfigure" : "add"; | 6189 const char* type = preexists ? "reconfigure" : "add"; |
| 6168 EnqueueChangeRecord(object, type, name, old_value); | 6190 RETURN_ON_EXCEPTION( |
| 6191 isolate, EnqueueChangeRecord(object, type, name, old_value), Object); |
| 6169 } | 6192 } |
| 6170 | 6193 |
| 6171 return isolate->factory()->undefined_value(); | 6194 return isolate->factory()->undefined_value(); |
| 6172 } | 6195 } |
| 6173 | 6196 |
| 6174 | 6197 |
| 6175 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, | 6198 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, |
| 6176 Handle<AccessorInfo> info) { | 6199 Handle<AccessorInfo> info) { |
| 6177 Isolate* isolate = object->GetIsolate(); | 6200 Isolate* isolate = object->GetIsolate(); |
| 6178 Factory* factory = isolate->factory(); | 6201 Factory* factory = isolate->factory(); |
| (...skipping 5048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11227 | 11250 |
| 11228 CHECK(array->length()->ToArrayIndex(&new_length)); | 11251 CHECK(array->length()->ToArrayIndex(&new_length)); |
| 11229 if (old_length == new_length) return hresult; | 11252 if (old_length == new_length) return hresult; |
| 11230 | 11253 |
| 11231 BeginPerformSplice(array); | 11254 BeginPerformSplice(array); |
| 11232 | 11255 |
| 11233 for (int i = 0; i < indices.length(); ++i) { | 11256 for (int i = 0; i < indices.length(); ++i) { |
| 11234 // For deletions where the property was an accessor, old_values[i] | 11257 // For deletions where the property was an accessor, old_values[i] |
| 11235 // will be the hole, which instructs EnqueueChangeRecord to elide | 11258 // will be the hole, which instructs EnqueueChangeRecord to elide |
| 11236 // the "oldValue" property. | 11259 // the "oldValue" property. |
| 11237 JSObject::EnqueueChangeRecord( | 11260 RETURN_ON_EXCEPTION( |
| 11238 array, "delete", isolate->factory()->Uint32ToString(indices[i]), | 11261 isolate, |
| 11239 old_values[i]); | 11262 JSObject::EnqueueChangeRecord( |
| 11263 array, "delete", isolate->factory()->Uint32ToString(indices[i]), |
| 11264 old_values[i]), |
| 11265 Object); |
| 11240 } | 11266 } |
| 11241 JSObject::EnqueueChangeRecord( | 11267 RETURN_ON_EXCEPTION(isolate, |
| 11242 array, "update", isolate->factory()->length_string(), | 11268 JSObject::EnqueueChangeRecord( |
| 11243 old_length_handle); | 11269 array, "update", isolate->factory()->length_string(), |
| 11270 old_length_handle), |
| 11271 Object); |
| 11244 | 11272 |
| 11245 EndPerformSplice(array); | 11273 EndPerformSplice(array); |
| 11246 | 11274 |
| 11247 uint32_t index = Min(old_length, new_length); | 11275 uint32_t index = Min(old_length, new_length); |
| 11248 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; | 11276 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; |
| 11249 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; | 11277 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; |
| 11250 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 11278 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 11251 if (delete_count > 0) { | 11279 if (delete_count > 0) { |
| 11252 for (int i = indices.length() - 1; i >= 0; i--) { | 11280 for (int i = indices.length() - 1; i >= 0; i--) { |
| 11253 // Skip deletions where the property was an accessor, leaving holes | 11281 // Skip deletions where the property was an accessor, leaving holes |
| (...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12441 !old_length_handle->SameValue( | 12469 !old_length_handle->SameValue( |
| 12442 Handle<JSArray>::cast(object)->length())) { | 12470 Handle<JSArray>::cast(object)->length())) { |
| 12443 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), | 12471 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
| 12444 isolate); | 12472 isolate); |
| 12445 uint32_t old_length = 0; | 12473 uint32_t old_length = 0; |
| 12446 uint32_t new_length = 0; | 12474 uint32_t new_length = 0; |
| 12447 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 12475 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
| 12448 CHECK(new_length_handle->ToArrayIndex(&new_length)); | 12476 CHECK(new_length_handle->ToArrayIndex(&new_length)); |
| 12449 | 12477 |
| 12450 BeginPerformSplice(Handle<JSArray>::cast(object)); | 12478 BeginPerformSplice(Handle<JSArray>::cast(object)); |
| 12451 EnqueueChangeRecord(object, "add", name, old_value); | 12479 RETURN_ON_EXCEPTION( |
| 12452 EnqueueChangeRecord(object, "update", isolate->factory()->length_string(), | 12480 isolate, EnqueueChangeRecord(object, "add", name, old_value), Object); |
| 12453 old_length_handle); | 12481 RETURN_ON_EXCEPTION( |
| 12482 isolate, EnqueueChangeRecord(object, "update", |
| 12483 isolate->factory()->length_string(), |
| 12484 old_length_handle), |
| 12485 Object); |
| 12454 EndPerformSplice(Handle<JSArray>::cast(object)); | 12486 EndPerformSplice(Handle<JSArray>::cast(object)); |
| 12455 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12487 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 12456 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, | 12488 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, |
| 12457 new_length - old_length); | 12489 new_length - old_length); |
| 12458 } else { | 12490 } else { |
| 12459 EnqueueChangeRecord(object, "add", name, old_value); | 12491 RETURN_ON_EXCEPTION( |
| 12492 isolate, EnqueueChangeRecord(object, "add", name, old_value), Object); |
| 12460 } | 12493 } |
| 12461 } else if (old_value->IsTheHole()) { | 12494 } else if (old_value->IsTheHole()) { |
| 12462 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 12495 RETURN_ON_EXCEPTION( |
| 12496 isolate, EnqueueChangeRecord(object, "reconfigure", name, old_value), |
| 12497 Object); |
| 12463 } else { | 12498 } else { |
| 12464 Handle<Object> new_value = | 12499 Handle<Object> new_value = |
| 12465 Object::GetElement(isolate, object, index).ToHandleChecked(); | 12500 Object::GetElement(isolate, object, index).ToHandleChecked(); |
| 12466 bool value_changed = !old_value->SameValue(*new_value); | 12501 bool value_changed = !old_value->SameValue(*new_value); |
| 12467 if (old_attributes != new_attributes) { | 12502 if (old_attributes != new_attributes) { |
| 12468 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | 12503 if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
| 12469 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 12504 RETURN_ON_EXCEPTION( |
| 12505 isolate, EnqueueChangeRecord(object, "reconfigure", name, old_value), |
| 12506 Object); |
| 12470 } else if (value_changed) { | 12507 } else if (value_changed) { |
| 12471 EnqueueChangeRecord(object, "update", name, old_value); | 12508 RETURN_ON_EXCEPTION( |
| 12509 isolate, EnqueueChangeRecord(object, "update", name, old_value), |
| 12510 Object); |
| 12472 } | 12511 } |
| 12473 } | 12512 } |
| 12474 | 12513 |
| 12475 return result; | 12514 return result; |
| 12476 } | 12515 } |
| 12477 | 12516 |
| 12478 | 12517 |
| 12479 MaybeHandle<Object> JSObject::SetElementWithoutInterceptor( | 12518 MaybeHandle<Object> JSObject::SetElementWithoutInterceptor( |
| 12480 Handle<JSObject> object, | 12519 Handle<JSObject> object, |
| 12481 uint32_t index, | 12520 uint32_t index, |
| (...skipping 3911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16393 Handle<DependentCode> codes = | 16432 Handle<DependentCode> codes = |
| 16394 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16433 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16395 DependentCode::kPropertyCellChangedGroup, | 16434 DependentCode::kPropertyCellChangedGroup, |
| 16396 info->object_wrapper()); | 16435 info->object_wrapper()); |
| 16397 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16436 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16398 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16437 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16399 cell, info->zone()); | 16438 cell, info->zone()); |
| 16400 } | 16439 } |
| 16401 | 16440 |
| 16402 } } // namespace v8::internal | 16441 } } // namespace v8::internal |
| OLD | NEW |