| 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 |