OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1671 | 1671 |
1672 MaybeObject* JSObject::AddProperty(String* name, | 1672 MaybeObject* JSObject::AddProperty(String* name, |
1673 Object* value, | 1673 Object* value, |
1674 PropertyAttributes attributes, | 1674 PropertyAttributes attributes, |
1675 StrictModeFlag strict_mode, | 1675 StrictModeFlag strict_mode, |
1676 JSReceiver::StoreFromKeyed store_mode, | 1676 JSReceiver::StoreFromKeyed store_mode, |
1677 ExtensibilityCheck extensibility_check) { | 1677 ExtensibilityCheck extensibility_check) { |
1678 ASSERT(!IsJSGlobalProxy()); | 1678 ASSERT(!IsJSGlobalProxy()); |
1679 Map* map_of_this = map(); | 1679 Map* map_of_this = map(); |
1680 Heap* heap = GetHeap(); | 1680 Heap* heap = GetHeap(); |
| 1681 Isolate* isolate = heap->isolate(); |
1681 MaybeObject* result; | 1682 MaybeObject* result; |
1682 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 1683 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
1683 !map_of_this->is_extensible()) { | 1684 !map_of_this->is_extensible()) { |
1684 if (strict_mode == kNonStrictMode) { | 1685 if (strict_mode == kNonStrictMode) { |
1685 return value; | 1686 return value; |
1686 } else { | 1687 } else { |
1687 Handle<Object> args[1] = {Handle<String>(name)}; | 1688 Handle<Object> args[1] = {Handle<String>(name)}; |
1688 return heap->isolate()->Throw( | 1689 return isolate->Throw( |
1689 *FACTORY->NewTypeError("object_not_extensible", | 1690 *FACTORY->NewTypeError("object_not_extensible", |
1690 HandleVector(args, 1))); | 1691 HandleVector(args, 1))); |
1691 } | 1692 } |
1692 } | 1693 } |
1693 | 1694 |
1694 if (HasFastProperties()) { | 1695 if (HasFastProperties()) { |
1695 // Ensure the descriptor array does not get too big. | 1696 // Ensure the descriptor array does not get too big. |
1696 if (map_of_this->NumberOfOwnDescriptors() < | 1697 if (map_of_this->NumberOfOwnDescriptors() < |
1697 DescriptorArray::kMaxNumberOfDescriptors) { | 1698 DescriptorArray::kMaxNumberOfDescriptors) { |
1698 if (value->IsJSFunction()) { | 1699 if (value->IsJSFunction()) { |
1699 result = AddConstantFunctionProperty(name, | 1700 result = AddConstantFunctionProperty(name, |
1700 JSFunction::cast(value), | 1701 JSFunction::cast(value), |
1701 attributes); | 1702 attributes); |
1702 } else { | 1703 } else { |
1703 result = AddFastProperty(name, value, attributes, store_mode); | 1704 result = AddFastProperty(name, value, attributes, store_mode); |
1704 } | 1705 } |
1705 } else { | 1706 } else { |
1706 // Normalize the object to prevent very large instance descriptors. | 1707 // Normalize the object to prevent very large instance descriptors. |
1707 // This eliminates unwanted N^2 allocation and lookup behavior. | 1708 // This eliminates unwanted N^2 allocation and lookup behavior. |
1708 Object* obj; | 1709 Object* obj; |
1709 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1710 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
1710 if (!maybe->To(&obj)) return maybe; | 1711 if (!maybe->To(&obj)) return maybe; |
1711 result = AddSlowProperty(name, value, attributes); | 1712 result = AddSlowProperty(name, value, attributes); |
1712 } | 1713 } |
1713 } else { | 1714 } else { |
1714 result = AddSlowProperty(name, value, attributes); | 1715 result = AddSlowProperty(name, value, attributes); |
1715 } | 1716 } |
1716 | 1717 |
1717 Handle<Object> hresult; | 1718 Handle<Object> hresult; |
1718 if (!result->ToHandle(&hresult)) return result; | 1719 if (!result->ToHandle(&hresult, isolate)) return result; |
1719 | 1720 |
1720 if (FLAG_harmony_observation && map()->is_observed()) { | 1721 if (FLAG_harmony_observation && map()->is_observed()) { |
1721 EnqueueChangeRecord(handle(this), "new", handle(name), | 1722 EnqueueChangeRecord(handle(this, isolate), |
1722 handle(heap->the_hole_value())); | 1723 "new", |
| 1724 handle(name, isolate), |
| 1725 handle(heap->the_hole_value(), isolate)); |
1723 } | 1726 } |
1724 | 1727 |
1725 return *hresult; | 1728 return *hresult; |
1726 } | 1729 } |
1727 | 1730 |
1728 | 1731 |
1729 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, | 1732 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, |
1730 const char* type_str, | 1733 const char* type_str, |
1731 Handle<String> name, | 1734 Handle<String> name, |
1732 Handle<Object> old_value) { | 1735 Handle<Object> old_value) { |
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2848 } | 2851 } |
2849 | 2852 |
2850 | 2853 |
2851 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, | 2854 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, |
2852 String* name_raw, | 2855 String* name_raw, |
2853 Object* value_raw, | 2856 Object* value_raw, |
2854 PropertyAttributes attributes, | 2857 PropertyAttributes attributes, |
2855 StrictModeFlag strict_mode, | 2858 StrictModeFlag strict_mode, |
2856 StoreFromKeyed store_mode) { | 2859 StoreFromKeyed store_mode) { |
2857 Heap* heap = GetHeap(); | 2860 Heap* heap = GetHeap(); |
| 2861 Isolate* isolate = heap->isolate(); |
2858 // Make sure that the top context does not change when doing callbacks or | 2862 // Make sure that the top context does not change when doing callbacks or |
2859 // interceptor calls. | 2863 // interceptor calls. |
2860 AssertNoContextChange ncc; | 2864 AssertNoContextChange ncc; |
2861 | 2865 |
2862 // Optimization for 2-byte strings often used as keys in a decompression | 2866 // Optimization for 2-byte strings often used as keys in a decompression |
2863 // dictionary. We make these short keys into symbols to avoid constantly | 2867 // dictionary. We make these short keys into symbols to avoid constantly |
2864 // reallocating them. | 2868 // reallocating them. |
2865 if (!name_raw->IsSymbol() && name_raw->length() <= 2) { | 2869 if (!name_raw->IsSymbol() && name_raw->length() <= 2) { |
2866 Object* symbol_version; | 2870 Object* symbol_version; |
2867 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name_raw); | 2871 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name_raw); |
2868 if (maybe_symbol_version->ToObject(&symbol_version)) { | 2872 if (maybe_symbol_version->ToObject(&symbol_version)) { |
2869 name_raw = String::cast(symbol_version); | 2873 name_raw = String::cast(symbol_version); |
2870 } | 2874 } |
2871 } | 2875 } |
2872 } | 2876 } |
2873 | 2877 |
2874 // Check access rights if needed. | 2878 // Check access rights if needed. |
2875 if (IsAccessCheckNeeded()) { | 2879 if (IsAccessCheckNeeded()) { |
2876 if (!heap->isolate()->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { | 2880 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
2877 return SetPropertyWithFailedAccessCheck( | 2881 return SetPropertyWithFailedAccessCheck( |
2878 lookup, name_raw, value_raw, true, strict_mode); | 2882 lookup, name_raw, value_raw, true, strict_mode); |
2879 } | 2883 } |
2880 } | 2884 } |
2881 | 2885 |
2882 if (IsJSGlobalProxy()) { | 2886 if (IsJSGlobalProxy()) { |
2883 Object* proto = GetPrototype(); | 2887 Object* proto = GetPrototype(); |
2884 if (proto->IsNull()) return value_raw; | 2888 if (proto->IsNull()) return value_raw; |
2885 ASSERT(proto->IsJSGlobalObject()); | 2889 ASSERT(proto->IsJSGlobalObject()); |
2886 return JSObject::cast(proto)->SetPropertyForResult( | 2890 return JSObject::cast(proto)->SetPropertyForResult( |
2887 lookup, name_raw, value_raw, attributes, strict_mode, store_mode); | 2891 lookup, name_raw, value_raw, attributes, strict_mode, store_mode); |
2888 } | 2892 } |
2889 | 2893 |
2890 // From this point on everything needs to be handlified, because | 2894 // From this point on everything needs to be handlified, because |
2891 // SetPropertyViaPrototypes might call back into JavaScript. | 2895 // SetPropertyViaPrototypes might call back into JavaScript. |
2892 HandleScope scope(GetIsolate()); | 2896 HandleScope scope(isolate); |
2893 Handle<JSObject> self(this); | 2897 Handle<JSObject> self(this); |
2894 Handle<String> name(name_raw); | 2898 Handle<String> name(name_raw); |
2895 Handle<Object> value(value_raw); | 2899 Handle<Object> value(value_raw, isolate); |
2896 | 2900 |
2897 if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) { | 2901 if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) { |
2898 bool done = false; | 2902 bool done = false; |
2899 MaybeObject* result_object = self->SetPropertyViaPrototypes( | 2903 MaybeObject* result_object = self->SetPropertyViaPrototypes( |
2900 *name, *value, attributes, strict_mode, &done); | 2904 *name, *value, attributes, strict_mode, &done); |
2901 if (done) return result_object; | 2905 if (done) return result_object; |
2902 } | 2906 } |
2903 | 2907 |
2904 if (!lookup->IsFound()) { | 2908 if (!lookup->IsFound()) { |
2905 // Neither properties nor transitions found. | 2909 // Neither properties nor transitions found. |
2906 return self->AddProperty( | 2910 return self->AddProperty( |
2907 *name, *value, attributes, strict_mode, store_mode); | 2911 *name, *value, attributes, strict_mode, store_mode); |
2908 } | 2912 } |
2909 | 2913 |
2910 if (lookup->IsProperty() && lookup->IsReadOnly()) { | 2914 if (lookup->IsProperty() && lookup->IsReadOnly()) { |
2911 if (strict_mode == kStrictMode) { | 2915 if (strict_mode == kStrictMode) { |
2912 Handle<Object> args[] = { name, self }; | 2916 Handle<Object> args[] = { name, self }; |
2913 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( | 2917 return isolate->Throw(*isolate->factory()->NewTypeError( |
2914 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); | 2918 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); |
2915 } else { | 2919 } else { |
2916 return *value; | 2920 return *value; |
2917 } | 2921 } |
2918 } | 2922 } |
2919 | 2923 |
2920 Handle<Object> old_value(heap->the_hole_value()); | 2924 Handle<Object> old_value(heap->the_hole_value(), isolate); |
2921 if (FLAG_harmony_observation && map()->is_observed()) { | 2925 if (FLAG_harmony_observation && map()->is_observed()) { |
2922 old_value = handle(lookup->GetLazyValue()); | 2926 old_value = handle(lookup->GetLazyValue(), isolate); |
2923 } | 2927 } |
2924 | 2928 |
2925 // This is a real property that is not read-only, or it is a | 2929 // This is a real property that is not read-only, or it is a |
2926 // transition or null descriptor and there are no setters in the prototypes. | 2930 // transition or null descriptor and there are no setters in the prototypes. |
2927 MaybeObject* result = *value; | 2931 MaybeObject* result = *value; |
2928 switch (lookup->type()) { | 2932 switch (lookup->type()) { |
2929 case NORMAL: | 2933 case NORMAL: |
2930 result = self->SetNormalizedProperty(lookup, *value); | 2934 result = self->SetNormalizedProperty(lookup, *value); |
2931 break; | 2935 break; |
2932 case FIELD: | 2936 case FIELD: |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2990 } | 2994 } |
2991 } | 2995 } |
2992 break; | 2996 break; |
2993 } | 2997 } |
2994 case HANDLER: | 2998 case HANDLER: |
2995 case NONEXISTENT: | 2999 case NONEXISTENT: |
2996 UNREACHABLE(); | 3000 UNREACHABLE(); |
2997 } | 3001 } |
2998 | 3002 |
2999 Handle<Object> hresult; | 3003 Handle<Object> hresult; |
3000 if (!result->ToHandle(&hresult)) return result; | 3004 if (!result->ToHandle(&hresult, isolate)) return result; |
3001 | 3005 |
3002 if (FLAG_harmony_observation && map()->is_observed()) { | 3006 if (FLAG_harmony_observation && map()->is_observed()) { |
3003 if (lookup->IsTransition()) { | 3007 if (lookup->IsTransition()) { |
3004 EnqueueChangeRecord(self, "new", name, old_value); | 3008 EnqueueChangeRecord(self, "new", name, old_value); |
3005 } else { | 3009 } else { |
3006 LookupResult new_lookup(self->GetIsolate()); | 3010 LookupResult new_lookup(isolate); |
3007 self->LocalLookup(*name, &new_lookup); | 3011 self->LocalLookup(*name, &new_lookup); |
3008 ASSERT(!new_lookup.GetLazyValue()->IsTheHole()); | 3012 ASSERT(!new_lookup.GetLazyValue()->IsTheHole()); |
3009 if (!new_lookup.GetLazyValue()->SameValue(*old_value)) { | 3013 if (!new_lookup.GetLazyValue()->SameValue(*old_value)) { |
3010 EnqueueChangeRecord(self, "updated", name, old_value); | 3014 EnqueueChangeRecord(self, "updated", name, old_value); |
3011 } | 3015 } |
3012 } | 3016 } |
3013 } | 3017 } |
3014 | 3018 |
3015 return *hresult; | 3019 return *hresult; |
3016 } | 3020 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3069 attributes); | 3073 attributes); |
3070 } | 3074 } |
3071 | 3075 |
3072 // Check for accessor in prototype chain removed here in clone. | 3076 // Check for accessor in prototype chain removed here in clone. |
3073 if (!lookup.IsFound()) { | 3077 if (!lookup.IsFound()) { |
3074 // Neither properties nor transitions found. | 3078 // Neither properties nor transitions found. |
3075 return AddProperty(name_raw, value_raw, attributes, kNonStrictMode); | 3079 return AddProperty(name_raw, value_raw, attributes, kNonStrictMode); |
3076 } | 3080 } |
3077 | 3081 |
3078 // From this point on everything needs to be handlified. | 3082 // From this point on everything needs to be handlified. |
3079 HandleScope scope(GetIsolate()); | 3083 HandleScope scope(isolate); |
3080 Handle<JSObject> self(this); | 3084 Handle<JSObject> self(this); |
3081 Handle<String> name(name_raw); | 3085 Handle<String> name(name_raw); |
3082 Handle<Object> value(value_raw); | 3086 Handle<Object> value(value_raw, isolate); |
3083 | 3087 |
3084 Handle<Object> old_value(isolate->heap()->the_hole_value()); | 3088 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); |
3085 PropertyAttributes old_attributes = ABSENT; | 3089 PropertyAttributes old_attributes = ABSENT; |
3086 if (FLAG_harmony_observation && map()->is_observed()) { | 3090 if (FLAG_harmony_observation && map()->is_observed()) { |
3087 old_value = handle(lookup.GetLazyValue()); | 3091 old_value = handle(lookup.GetLazyValue(), isolate); |
3088 old_attributes = lookup.GetAttributes(); | 3092 old_attributes = lookup.GetAttributes(); |
3089 } | 3093 } |
3090 | 3094 |
3091 // Check of IsReadOnly removed from here in clone. | 3095 // Check of IsReadOnly removed from here in clone. |
3092 MaybeObject* result = *value; | 3096 MaybeObject* result = *value; |
3093 switch (lookup.type()) { | 3097 switch (lookup.type()) { |
3094 case NORMAL: { | 3098 case NORMAL: { |
3095 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 3099 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
3096 result = self->SetNormalizedProperty(*name, *value, details); | 3100 result = self->SetNormalizedProperty(*name, *value, details); |
3097 break; | 3101 break; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3139 lookup.GetTransitionIndex(), *name, *value, attributes); | 3143 lookup.GetTransitionIndex(), *name, *value, attributes); |
3140 } | 3144 } |
3141 break; | 3145 break; |
3142 } | 3146 } |
3143 case HANDLER: | 3147 case HANDLER: |
3144 case NONEXISTENT: | 3148 case NONEXISTENT: |
3145 UNREACHABLE(); | 3149 UNREACHABLE(); |
3146 } | 3150 } |
3147 | 3151 |
3148 Handle<Object> hresult; | 3152 Handle<Object> hresult; |
3149 if (!result->ToHandle(&hresult)) return result; | 3153 if (!result->ToHandle(&hresult, isolate)) return result; |
3150 | 3154 |
3151 if (FLAG_harmony_observation && map()->is_observed()) { | 3155 if (FLAG_harmony_observation && map()->is_observed()) { |
3152 if (lookup.IsTransition()) { | 3156 if (lookup.IsTransition()) { |
3153 EnqueueChangeRecord(self, "new", name, old_value); | 3157 EnqueueChangeRecord(self, "new", name, old_value); |
3154 } else { | 3158 } else { |
3155 LookupResult new_lookup(isolate); | 3159 LookupResult new_lookup(isolate); |
3156 self->LocalLookup(*name, &new_lookup); | 3160 self->LocalLookup(*name, &new_lookup); |
3157 ASSERT(!new_lookup.GetLazyValue()->IsTheHole()); | 3161 ASSERT(!new_lookup.GetLazyValue()->IsTheHole()); |
3158 if (old_value->IsTheHole() || | 3162 if (old_value->IsTheHole() || |
3159 new_lookup.GetAttributes() != old_attributes) { | 3163 new_lookup.GetAttributes() != old_attributes) { |
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4146 | 4150 |
4147 MaybeObject* result; | 4151 MaybeObject* result; |
4148 // Skip interceptor if forcing deletion. | 4152 // Skip interceptor if forcing deletion. |
4149 if (self->HasIndexedInterceptor() && mode != FORCE_DELETION) { | 4153 if (self->HasIndexedInterceptor() && mode != FORCE_DELETION) { |
4150 result = self->DeleteElementWithInterceptor(index); | 4154 result = self->DeleteElementWithInterceptor(index); |
4151 } else { | 4155 } else { |
4152 result = self->GetElementsAccessor()->Delete(*self, index, mode); | 4156 result = self->GetElementsAccessor()->Delete(*self, index, mode); |
4153 } | 4157 } |
4154 | 4158 |
4155 Handle<Object> hresult; | 4159 Handle<Object> hresult; |
4156 if (!result->ToHandle(&hresult)) return result; | 4160 if (!result->ToHandle(&hresult, isolate)) return result; |
4157 | 4161 |
4158 if (FLAG_harmony_observation && map()->is_observed()) { | 4162 if (FLAG_harmony_observation && map()->is_observed()) { |
4159 if (preexists && !self->HasLocalElement(index)) | 4163 if (preexists && !self->HasLocalElement(index)) |
4160 EnqueueChangeRecord(self, "deleted", name, old_value); | 4164 EnqueueChangeRecord(self, "deleted", name, old_value); |
4161 } | 4165 } |
4162 | 4166 |
4163 return *hresult; | 4167 return *hresult; |
4164 } | 4168 } |
4165 | 4169 |
4166 | 4170 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4211 return isolate->heap()->false_value(); | 4215 return isolate->heap()->false_value(); |
4212 } | 4216 } |
4213 | 4217 |
4214 // From this point on everything needs to be handlified. | 4218 // From this point on everything needs to be handlified. |
4215 HandleScope scope(isolate); | 4219 HandleScope scope(isolate); |
4216 Handle<JSObject> self(this); | 4220 Handle<JSObject> self(this); |
4217 Handle<String> hname(name); | 4221 Handle<String> hname(name); |
4218 | 4222 |
4219 Handle<Object> old_value(isolate->heap()->the_hole_value()); | 4223 Handle<Object> old_value(isolate->heap()->the_hole_value()); |
4220 if (FLAG_harmony_observation && map()->is_observed()) { | 4224 if (FLAG_harmony_observation && map()->is_observed()) { |
4221 old_value = handle(lookup.GetLazyValue()); | 4225 old_value = handle(lookup.GetLazyValue(), isolate); |
4222 } | 4226 } |
4223 MaybeObject* result; | 4227 MaybeObject* result; |
4224 | 4228 |
4225 // Check for interceptor. | 4229 // Check for interceptor. |
4226 if (lookup.IsInterceptor()) { | 4230 if (lookup.IsInterceptor()) { |
4227 // Skip interceptor if forcing a deletion. | 4231 // Skip interceptor if forcing a deletion. |
4228 if (mode == FORCE_DELETION) { | 4232 if (mode == FORCE_DELETION) { |
4229 result = self->DeletePropertyPostInterceptor(*hname, mode); | 4233 result = self->DeletePropertyPostInterceptor(*hname, mode); |
4230 } else { | 4234 } else { |
4231 result = self->DeletePropertyWithInterceptor(*hname); | 4235 result = self->DeletePropertyWithInterceptor(*hname); |
4232 } | 4236 } |
4233 } else { | 4237 } else { |
4234 // Normalize object if needed. | 4238 // Normalize object if needed. |
4235 Object* obj; | 4239 Object* obj; |
4236 result = self->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 4240 result = self->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
4237 if (!result->To(&obj)) return result; | 4241 if (!result->To(&obj)) return result; |
4238 // Make sure the properties are normalized before removing the entry. | 4242 // Make sure the properties are normalized before removing the entry. |
4239 result = self->DeleteNormalizedProperty(*hname, mode); | 4243 result = self->DeleteNormalizedProperty(*hname, mode); |
4240 } | 4244 } |
4241 | 4245 |
4242 Handle<Object> hresult; | 4246 Handle<Object> hresult; |
4243 if (!result->ToHandle(&hresult)) return result; | 4247 if (!result->ToHandle(&hresult, isolate)) return result; |
4244 | 4248 |
4245 if (FLAG_harmony_observation && map()->is_observed()) { | 4249 if (FLAG_harmony_observation && map()->is_observed()) { |
4246 if (!self->HasLocalProperty(*hname)) | 4250 if (!self->HasLocalProperty(*hname)) |
4247 EnqueueChangeRecord(self, "deleted", hname, old_value); | 4251 EnqueueChangeRecord(self, "deleted", hname, old_value); |
4248 } | 4252 } |
4249 | 4253 |
4250 return *hresult; | 4254 return *hresult; |
4251 } | 4255 } |
4252 | 4256 |
4253 | 4257 |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4871 // Make sure that the top context does not change when doing callbacks or | 4875 // Make sure that the top context does not change when doing callbacks or |
4872 // interceptor calls. | 4876 // interceptor calls. |
4873 AssertNoContextChange ncc; | 4877 AssertNoContextChange ncc; |
4874 | 4878 |
4875 // Try to flatten before operating on the string. | 4879 // Try to flatten before operating on the string. |
4876 name_raw->TryFlatten(); | 4880 name_raw->TryFlatten(); |
4877 | 4881 |
4878 if (!CanSetCallback(name_raw)) return isolate->heap()->undefined_value(); | 4882 if (!CanSetCallback(name_raw)) return isolate->heap()->undefined_value(); |
4879 | 4883 |
4880 // From this point on everything needs to be handlified. | 4884 // From this point on everything needs to be handlified. |
4881 HandleScope scope(GetIsolate()); | 4885 HandleScope scope(isolate); |
4882 Handle<JSObject> self(this); | 4886 Handle<JSObject> self(this); |
4883 Handle<String> name(name_raw); | 4887 Handle<String> name(name_raw); |
4884 Handle<Object> getter(getter_raw); | 4888 Handle<Object> getter(getter_raw); |
4885 Handle<Object> setter(setter_raw); | 4889 Handle<Object> setter(setter_raw); |
4886 | 4890 |
4887 uint32_t index = 0; | 4891 uint32_t index = 0; |
4888 bool is_element = name->AsArrayIndex(&index); | 4892 bool is_element = name->AsArrayIndex(&index); |
4889 | 4893 |
4890 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4894 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
4891 bool preexists = false; | 4895 bool preexists = false; |
4892 if (FLAG_harmony_observation && map()->is_observed()) { | 4896 if (FLAG_harmony_observation && map()->is_observed()) { |
4893 if (is_element) { | 4897 if (is_element) { |
4894 preexists = HasLocalElement(index); | 4898 preexists = HasLocalElement(index); |
4895 if (preexists && GetLocalElementAccessorPair(index) == NULL) { | 4899 if (preexists && GetLocalElementAccessorPair(index) == NULL) { |
4896 old_value = Object::GetElement(self, index); | 4900 old_value = Object::GetElement(self, index); |
4897 } | 4901 } |
4898 } else { | 4902 } else { |
4899 LookupResult lookup(isolate); | 4903 LookupResult lookup(isolate); |
4900 LocalLookup(*name, &lookup); | 4904 LocalLookup(*name, &lookup); |
4901 preexists = lookup.IsProperty(); | 4905 preexists = lookup.IsProperty(); |
4902 if (preexists) old_value = handle(lookup.GetLazyValue()); | 4906 if (preexists) old_value = handle(lookup.GetLazyValue(), isolate); |
4903 } | 4907 } |
4904 } | 4908 } |
4905 | 4909 |
4906 MaybeObject* result = is_element ? | 4910 MaybeObject* result = is_element ? |
4907 self->DefineElementAccessor(index, *getter, *setter, attributes) : | 4911 self->DefineElementAccessor(index, *getter, *setter, attributes) : |
4908 self->DefinePropertyAccessor(*name, *getter, *setter, attributes); | 4912 self->DefinePropertyAccessor(*name, *getter, *setter, attributes); |
4909 | 4913 |
4910 Handle<Object> hresult; | 4914 Handle<Object> hresult; |
4911 if (!result->ToHandle(&hresult)) return result; | 4915 if (!result->ToHandle(&hresult, isolate)) return result; |
4912 | 4916 |
4913 if (FLAG_harmony_observation && map()->is_observed()) { | 4917 if (FLAG_harmony_observation && map()->is_observed()) { |
4914 const char* type = preexists ? "reconfigured" : "new"; | 4918 const char* type = preexists ? "reconfigured" : "new"; |
4915 EnqueueChangeRecord(self, type, name, old_value); | 4919 EnqueueChangeRecord(self, type, name, old_value); |
4916 } | 4920 } |
4917 | 4921 |
4918 return *hresult; | 4922 return *hresult; |
4919 } | 4923 } |
4920 | 4924 |
4921 | 4925 |
(...skipping 4485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9407 // stop at this index. | 9411 // stop at this index. |
9408 if (attributes == DONT_DELETE) break; | 9412 if (attributes == DONT_DELETE) break; |
9409 // TODO(adamk): Don't fetch the old value if it's an accessor. | 9413 // TODO(adamk): Don't fetch the old value if it's an accessor. |
9410 old_values.Add(Object::GetElement(self, i)); | 9414 old_values.Add(Object::GetElement(self, i)); |
9411 indices.Add(isolate->factory()->Uint32ToString(i)); | 9415 indices.Add(isolate->factory()->Uint32ToString(i)); |
9412 } | 9416 } |
9413 | 9417 |
9414 MaybeObject* result = | 9418 MaybeObject* result = |
9415 self->GetElementsAccessor()->SetLength(*self, *new_length_handle); | 9419 self->GetElementsAccessor()->SetLength(*self, *new_length_handle); |
9416 Handle<Object> hresult; | 9420 Handle<Object> hresult; |
9417 if (!result->ToHandle(&hresult)) return result; | 9421 if (!result->ToHandle(&hresult, isolate)) return result; |
9418 | 9422 |
9419 CHECK(self->length()->ToArrayIndex(&new_length)); | 9423 CHECK(self->length()->ToArrayIndex(&new_length)); |
9420 if (old_length != new_length) { | 9424 if (old_length != new_length) { |
9421 for (int i = 0; i < indices.length(); ++i) { | 9425 for (int i = 0; i < indices.length(); ++i) { |
9422 JSObject::EnqueueChangeRecord( | 9426 JSObject::EnqueueChangeRecord( |
9423 self, "deleted", indices[i], old_values[i]); | 9427 self, "deleted", indices[i], old_values[i]); |
9424 } | 9428 } |
9425 JSObject::EnqueueChangeRecord( | 9429 JSObject::EnqueueChangeRecord( |
9426 self, "updated", isolate->factory()->length_symbol(), | 9430 self, "updated", isolate->factory()->length_symbol(), |
9427 old_length_handle); | 9431 old_length_handle); |
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10368 value_raw, | 10372 value_raw, |
10369 attributes, | 10373 attributes, |
10370 strict_mode, | 10374 strict_mode, |
10371 check_prototype, | 10375 check_prototype, |
10372 set_mode); | 10376 set_mode); |
10373 } | 10377 } |
10374 | 10378 |
10375 // Don't allow element properties to be redefined for external arrays. | 10379 // Don't allow element properties to be redefined for external arrays. |
10376 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { | 10380 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { |
10377 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 10381 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
10378 Handle<Object> args[] = { handle(this), number }; | 10382 Handle<Object> args[] = { handle(this, isolate), number }; |
10379 Handle<Object> error = isolate->factory()->NewTypeError( | 10383 Handle<Object> error = isolate->factory()->NewTypeError( |
10380 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 10384 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
10381 return isolate->Throw(*error); | 10385 return isolate->Throw(*error); |
10382 } | 10386 } |
10383 | 10387 |
10384 // Normalize the elements to enable attributes on the property. | 10388 // Normalize the elements to enable attributes on the property. |
10385 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 10389 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
10386 SeededNumberDictionary* dictionary; | 10390 SeededNumberDictionary* dictionary; |
10387 MaybeObject* maybe_object = NormalizeElements(); | 10391 MaybeObject* maybe_object = NormalizeElements(); |
10388 if (!maybe_object->To(&dictionary)) return maybe_object; | 10392 if (!maybe_object->To(&dictionary)) return maybe_object; |
(...skipping 14 matching lines...) Expand all Loading... |
10403 Handle<Object> value(value_raw); | 10407 Handle<Object> value(value_raw); |
10404 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index); | 10408 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index); |
10405 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 10409 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
10406 Handle<Object> old_length; | 10410 Handle<Object> old_length; |
10407 | 10411 |
10408 if (old_attributes != ABSENT) { | 10412 if (old_attributes != ABSENT) { |
10409 if (GetLocalElementAccessorPair(index) == NULL) | 10413 if (GetLocalElementAccessorPair(index) == NULL) |
10410 old_value = Object::GetElement(self, index); | 10414 old_value = Object::GetElement(self, index); |
10411 } else if (self->IsJSArray()) { | 10415 } else if (self->IsJSArray()) { |
10412 // Store old array length in case adding an element grows the array. | 10416 // Store old array length in case adding an element grows the array. |
10413 old_length = handle(Handle<JSArray>::cast(self)->length()); | 10417 old_length = handle(Handle<JSArray>::cast(self)->length(), isolate); |
10414 } | 10418 } |
10415 | 10419 |
10416 // Check for lookup interceptor | 10420 // Check for lookup interceptor |
10417 MaybeObject* result = self->HasIndexedInterceptor() | 10421 MaybeObject* result = self->HasIndexedInterceptor() |
10418 ? self->SetElementWithInterceptor( | 10422 ? self->SetElementWithInterceptor( |
10419 index, *value, attributes, strict_mode, check_prototype, set_mode) | 10423 index, *value, attributes, strict_mode, check_prototype, set_mode) |
10420 : self->SetElementWithoutInterceptor( | 10424 : self->SetElementWithoutInterceptor( |
10421 index, *value, attributes, strict_mode, check_prototype, set_mode); | 10425 index, *value, attributes, strict_mode, check_prototype, set_mode); |
10422 | 10426 |
10423 Handle<Object> hresult; | 10427 Handle<Object> hresult; |
10424 if (!result->ToHandle(&hresult)) return result; | 10428 if (!result->ToHandle(&hresult, isolate)) return result; |
10425 | 10429 |
10426 Handle<String> name = isolate->factory()->Uint32ToString(index); | 10430 Handle<String> name = isolate->factory()->Uint32ToString(index); |
10427 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index); | 10431 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index); |
10428 if (old_attributes == ABSENT) { | 10432 if (old_attributes == ABSENT) { |
10429 EnqueueChangeRecord(self, "new", name, old_value); | 10433 EnqueueChangeRecord(self, "new", name, old_value); |
10430 if (self->IsJSArray() && | 10434 if (self->IsJSArray() && |
10431 !old_length->SameValue(Handle<JSArray>::cast(self)->length())) { | 10435 !old_length->SameValue(Handle<JSArray>::cast(self)->length())) { |
10432 EnqueueChangeRecord( | 10436 EnqueueChangeRecord( |
10433 self, "updated", isolate->factory()->length_symbol(), old_length); | 10437 self, "updated", isolate->factory()->length_symbol(), old_length); |
10434 } | 10438 } |
(...skipping 3509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13944 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13948 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13945 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13949 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13946 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13950 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13947 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13951 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13948 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13952 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13949 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13953 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13950 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13954 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13951 } | 13955 } |
13952 | 13956 |
13953 } } // namespace v8::internal | 13957 } } // namespace v8::internal |
OLD | NEW |