| 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 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4885 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); | 4900 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); |
| 4886 } | 4901 } |
| 4887 Handle<Object> result; | 4902 Handle<Object> result; |
| 4888 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); | 4903 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); |
| 4889 | 4904 |
| 4890 if (should_enqueue_change_record) { | 4905 if (should_enqueue_change_record) { |
| 4891 Maybe<bool> maybe = HasOwnElement(object, index); | 4906 Maybe<bool> maybe = HasOwnElement(object, index); |
| 4892 if (!maybe.has_value) return MaybeHandle<Object>(); | 4907 if (!maybe.has_value) return MaybeHandle<Object>(); |
| 4893 if (!maybe.value) { | 4908 if (!maybe.value) { |
| 4894 Handle<String> name = factory->Uint32ToString(index); | 4909 Handle<String> name = factory->Uint32ToString(index); |
| 4895 EnqueueChangeRecord(object, "delete", name, old_value); | 4910 RETURN_ON_EXCEPTION( |
| 4911 isolate, EnqueueChangeRecord(object, "delete", name, old_value), |
| 4912 Object); |
| 4896 } | 4913 } |
| 4897 } | 4914 } |
| 4898 | 4915 |
| 4899 return result; | 4916 return result; |
| 4900 } | 4917 } |
| 4901 | 4918 |
| 4902 | 4919 |
| 4903 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 4920 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
| 4904 Handle<Name> name, | 4921 Handle<Name> name, |
| 4905 DeleteMode delete_mode) { | 4922 DeleteMode delete_mode) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4971 if (!holder.is_identical_to(object) && | 4988 if (!holder.is_identical_to(object) && |
| 4972 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { | 4989 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { |
| 4973 return it.isolate()->factory()->true_value(); | 4990 return it.isolate()->factory()->true_value(); |
| 4974 } | 4991 } |
| 4975 NormalizeProperties(holder, mode, 0); | 4992 NormalizeProperties(holder, mode, 0); |
| 4976 Handle<Object> result = | 4993 Handle<Object> result = |
| 4977 DeleteNormalizedProperty(holder, name, delete_mode); | 4994 DeleteNormalizedProperty(holder, name, delete_mode); |
| 4978 ReoptimizeIfPrototype(holder); | 4995 ReoptimizeIfPrototype(holder); |
| 4979 | 4996 |
| 4980 if (is_observed) { | 4997 if (is_observed) { |
| 4981 EnqueueChangeRecord(object, "delete", name, old_value); | 4998 RETURN_ON_EXCEPTION( |
| 4999 it.isolate(), |
| 5000 EnqueueChangeRecord(object, "delete", name, old_value), Object); |
| 4982 } | 5001 } |
| 4983 | 5002 |
| 4984 return result; | 5003 return result; |
| 4985 } | 5004 } |
| 4986 } | 5005 } |
| 4987 } | 5006 } |
| 4988 | 5007 |
| 4989 return it.isolate()->factory()->true_value(); | 5008 return it.isolate()->factory()->true_value(); |
| 4990 } | 5009 } |
| 4991 | 5010 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5188 // Do a map transition, other objects with this map may still | 5207 // Do a map transition, other objects with this map may still |
| 5189 // be extensible. | 5208 // be extensible. |
| 5190 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5209 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
| 5191 Handle<Map> new_map = Map::Copy(handle(object->map())); | 5210 Handle<Map> new_map = Map::Copy(handle(object->map())); |
| 5192 | 5211 |
| 5193 new_map->set_is_extensible(false); | 5212 new_map->set_is_extensible(false); |
| 5194 JSObject::MigrateToMap(object, new_map); | 5213 JSObject::MigrateToMap(object, new_map); |
| 5195 DCHECK(!object->map()->is_extensible()); | 5214 DCHECK(!object->map()->is_extensible()); |
| 5196 | 5215 |
| 5197 if (object->map()->is_observed()) { | 5216 if (object->map()->is_observed()) { |
| 5198 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 5217 RETURN_ON_EXCEPTION( |
| 5199 isolate->factory()->the_hole_value()); | 5218 isolate, |
| 5219 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
| 5220 isolate->factory()->the_hole_value()), |
| 5221 Object); |
| 5200 } | 5222 } |
| 5201 return object; | 5223 return object; |
| 5202 } | 5224 } |
| 5203 | 5225 |
| 5204 | 5226 |
| 5205 template<typename Dictionary> | 5227 template<typename Dictionary> |
| 5206 static void FreezeDictionary(Dictionary* dictionary) { | 5228 static void FreezeDictionary(Dictionary* dictionary) { |
| 5207 int capacity = dictionary->Capacity(); | 5229 int capacity = dictionary->Capacity(); |
| 5208 for (int i = 0; i < capacity; i++) { | 5230 for (int i = 0; i < capacity; i++) { |
| 5209 Object* k = dictionary->KeyAt(i); | 5231 Object* k = dictionary->KeyAt(i); |
| (...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6162 if (!getter->IsNull()) { | 6184 if (!getter->IsNull()) { |
| 6163 it.TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes); | 6185 it.TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes); |
| 6164 } | 6186 } |
| 6165 if (!setter->IsNull()) { | 6187 if (!setter->IsNull()) { |
| 6166 it.TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes); | 6188 it.TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes); |
| 6167 } | 6189 } |
| 6168 } | 6190 } |
| 6169 | 6191 |
| 6170 if (is_observed) { | 6192 if (is_observed) { |
| 6171 const char* type = preexists ? "reconfigure" : "add"; | 6193 const char* type = preexists ? "reconfigure" : "add"; |
| 6172 EnqueueChangeRecord(object, type, name, old_value); | 6194 RETURN_ON_EXCEPTION( |
| 6195 isolate, EnqueueChangeRecord(object, type, name, old_value), Object); |
| 6173 } | 6196 } |
| 6174 | 6197 |
| 6175 return isolate->factory()->undefined_value(); | 6198 return isolate->factory()->undefined_value(); |
| 6176 } | 6199 } |
| 6177 | 6200 |
| 6178 | 6201 |
| 6179 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, | 6202 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, |
| 6180 Handle<AccessorInfo> info) { | 6203 Handle<AccessorInfo> info) { |
| 6181 Isolate* isolate = object->GetIsolate(); | 6204 Isolate* isolate = object->GetIsolate(); |
| 6182 Factory* factory = isolate->factory(); | 6205 Factory* factory = isolate->factory(); |
| (...skipping 5048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11231 | 11254 |
| 11232 CHECK(array->length()->ToArrayIndex(&new_length)); | 11255 CHECK(array->length()->ToArrayIndex(&new_length)); |
| 11233 if (old_length == new_length) return hresult; | 11256 if (old_length == new_length) return hresult; |
| 11234 | 11257 |
| 11235 BeginPerformSplice(array); | 11258 BeginPerformSplice(array); |
| 11236 | 11259 |
| 11237 for (int i = 0; i < indices.length(); ++i) { | 11260 for (int i = 0; i < indices.length(); ++i) { |
| 11238 // For deletions where the property was an accessor, old_values[i] | 11261 // For deletions where the property was an accessor, old_values[i] |
| 11239 // will be the hole, which instructs EnqueueChangeRecord to elide | 11262 // will be the hole, which instructs EnqueueChangeRecord to elide |
| 11240 // the "oldValue" property. | 11263 // the "oldValue" property. |
| 11241 JSObject::EnqueueChangeRecord( | 11264 RETURN_ON_EXCEPTION( |
| 11242 array, "delete", isolate->factory()->Uint32ToString(indices[i]), | 11265 isolate, |
| 11243 old_values[i]); | 11266 JSObject::EnqueueChangeRecord( |
| 11267 array, "delete", isolate->factory()->Uint32ToString(indices[i]), |
| 11268 old_values[i]), |
| 11269 Object); |
| 11244 } | 11270 } |
| 11245 JSObject::EnqueueChangeRecord( | 11271 RETURN_ON_EXCEPTION(isolate, |
| 11246 array, "update", isolate->factory()->length_string(), | 11272 JSObject::EnqueueChangeRecord( |
| 11247 old_length_handle); | 11273 array, "update", isolate->factory()->length_string(), |
| 11274 old_length_handle), |
| 11275 Object); |
| 11248 | 11276 |
| 11249 EndPerformSplice(array); | 11277 EndPerformSplice(array); |
| 11250 | 11278 |
| 11251 uint32_t index = Min(old_length, new_length); | 11279 uint32_t index = Min(old_length, new_length); |
| 11252 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; | 11280 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; |
| 11253 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; | 11281 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; |
| 11254 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 11282 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 11255 if (delete_count > 0) { | 11283 if (delete_count > 0) { |
| 11256 for (int i = indices.length() - 1; i >= 0; i--) { | 11284 for (int i = indices.length() - 1; i >= 0; i--) { |
| 11257 // Skip deletions where the property was an accessor, leaving holes | 11285 // Skip deletions where the property was an accessor, leaving holes |
| (...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12445 !old_length_handle->SameValue( | 12473 !old_length_handle->SameValue( |
| 12446 Handle<JSArray>::cast(object)->length())) { | 12474 Handle<JSArray>::cast(object)->length())) { |
| 12447 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), | 12475 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
| 12448 isolate); | 12476 isolate); |
| 12449 uint32_t old_length = 0; | 12477 uint32_t old_length = 0; |
| 12450 uint32_t new_length = 0; | 12478 uint32_t new_length = 0; |
| 12451 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 12479 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
| 12452 CHECK(new_length_handle->ToArrayIndex(&new_length)); | 12480 CHECK(new_length_handle->ToArrayIndex(&new_length)); |
| 12453 | 12481 |
| 12454 BeginPerformSplice(Handle<JSArray>::cast(object)); | 12482 BeginPerformSplice(Handle<JSArray>::cast(object)); |
| 12455 EnqueueChangeRecord(object, "add", name, old_value); | 12483 RETURN_ON_EXCEPTION( |
| 12456 EnqueueChangeRecord(object, "update", isolate->factory()->length_string(), | 12484 isolate, EnqueueChangeRecord(object, "add", name, old_value), Object); |
| 12457 old_length_handle); | 12485 RETURN_ON_EXCEPTION( |
| 12486 isolate, EnqueueChangeRecord(object, "update", |
| 12487 isolate->factory()->length_string(), |
| 12488 old_length_handle), |
| 12489 Object); |
| 12458 EndPerformSplice(Handle<JSArray>::cast(object)); | 12490 EndPerformSplice(Handle<JSArray>::cast(object)); |
| 12459 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12491 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 12460 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, | 12492 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, |
| 12461 new_length - old_length); | 12493 new_length - old_length); |
| 12462 } else { | 12494 } else { |
| 12463 EnqueueChangeRecord(object, "add", name, old_value); | 12495 RETURN_ON_EXCEPTION( |
| 12496 isolate, EnqueueChangeRecord(object, "add", name, old_value), Object); |
| 12464 } | 12497 } |
| 12465 } else if (old_value->IsTheHole()) { | 12498 } else if (old_value->IsTheHole()) { |
| 12466 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 12499 RETURN_ON_EXCEPTION( |
| 12500 isolate, EnqueueChangeRecord(object, "reconfigure", name, old_value), |
| 12501 Object); |
| 12467 } else { | 12502 } else { |
| 12468 Handle<Object> new_value = | 12503 Handle<Object> new_value = |
| 12469 Object::GetElement(isolate, object, index).ToHandleChecked(); | 12504 Object::GetElement(isolate, object, index).ToHandleChecked(); |
| 12470 bool value_changed = !old_value->SameValue(*new_value); | 12505 bool value_changed = !old_value->SameValue(*new_value); |
| 12471 if (old_attributes != new_attributes) { | 12506 if (old_attributes != new_attributes) { |
| 12472 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | 12507 if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
| 12473 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 12508 RETURN_ON_EXCEPTION( |
| 12509 isolate, EnqueueChangeRecord(object, "reconfigure", name, old_value), |
| 12510 Object); |
| 12474 } else if (value_changed) { | 12511 } else if (value_changed) { |
| 12475 EnqueueChangeRecord(object, "update", name, old_value); | 12512 RETURN_ON_EXCEPTION( |
| 12513 isolate, EnqueueChangeRecord(object, "update", name, old_value), |
| 12514 Object); |
| 12476 } | 12515 } |
| 12477 } | 12516 } |
| 12478 | 12517 |
| 12479 return result; | 12518 return result; |
| 12480 } | 12519 } |
| 12481 | 12520 |
| 12482 | 12521 |
| 12483 MaybeHandle<Object> JSObject::SetElementWithoutInterceptor( | 12522 MaybeHandle<Object> JSObject::SetElementWithoutInterceptor( |
| 12484 Handle<JSObject> object, | 12523 Handle<JSObject> object, |
| 12485 uint32_t index, | 12524 uint32_t index, |
| (...skipping 3902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16388 Handle<DependentCode> codes = | 16427 Handle<DependentCode> codes = |
| 16389 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16428 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16390 DependentCode::kPropertyCellChangedGroup, | 16429 DependentCode::kPropertyCellChangedGroup, |
| 16391 info->object_wrapper()); | 16430 info->object_wrapper()); |
| 16392 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16431 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16393 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16432 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16394 cell, info->zone()); | 16433 cell, info->zone()); |
| 16395 } | 16434 } |
| 16396 | 16435 |
| 16397 } } // namespace v8::internal | 16436 } } // namespace v8::internal |
| OLD | NEW |