| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2144 ASSERT(!threw); | 2144 ASSERT(!threw); |
| 2145 isolate->set_observer_delivery_pending(false); | 2145 isolate->set_observer_delivery_pending(false); |
| 2146 } | 2146 } |
| 2147 | 2147 |
| 2148 | 2148 |
| 2149 MaybeObject* JSObject::SetPropertyPostInterceptor( | 2149 MaybeObject* JSObject::SetPropertyPostInterceptor( |
| 2150 Name* name, | 2150 Name* name, |
| 2151 Object* value, | 2151 Object* value, |
| 2152 PropertyAttributes attributes, | 2152 PropertyAttributes attributes, |
| 2153 StrictModeFlag strict_mode, | 2153 StrictModeFlag strict_mode, |
| 2154 ExtensibilityCheck extensibility_check, | |
| 2155 StoreMode mode) { | 2154 StoreMode mode) { |
| 2156 // Check local property, ignore interceptor. | 2155 // Check local property, ignore interceptor. |
| 2157 LookupResult result(GetIsolate()); | 2156 LookupResult result(GetIsolate()); |
| 2158 LocalLookupRealNamedProperty(name, &result); | 2157 LocalLookupRealNamedProperty(name, &result); |
| 2159 if (!result.IsFound()) map()->LookupTransition(this, name, &result); | 2158 if (!result.IsFound()) map()->LookupTransition(this, name, &result); |
| 2160 if (result.IsFound()) { | 2159 if (result.IsFound()) { |
| 2161 // An existing property or a map transition was found. Use set property to | 2160 // An existing property or a map transition was found. Use set property to |
| 2162 // handle all these cases. | 2161 // handle all these cases. |
| 2163 return SetProperty(&result, name, value, attributes, strict_mode); | 2162 return SetProperty(&result, name, value, attributes, strict_mode); |
| 2164 } | 2163 } |
| 2165 bool done = false; | 2164 bool done = false; |
| 2166 MaybeObject* result_object; | 2165 MaybeObject* result_object = |
| 2167 result_object = | |
| 2168 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); | 2166 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); |
| 2169 if (done) return result_object; | 2167 if (done) return result_object; |
| 2170 // Add a new real property. | 2168 // Add a new real property. |
| 2171 return AddProperty(name, value, attributes, strict_mode, | 2169 return AddProperty(name, value, attributes, strict_mode, |
| 2172 MAY_BE_STORE_FROM_KEYED, extensibility_check, | 2170 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, |
| 2173 OPTIMAL_REPRESENTATION, mode); | 2171 OPTIMAL_REPRESENTATION, mode); |
| 2174 } | 2172 } |
| 2175 | 2173 |
| 2176 | 2174 |
| 2177 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, | 2175 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, |
| 2178 Object* value, | 2176 Object* value, |
| 2179 PropertyAttributes attributes) { | 2177 PropertyAttributes attributes) { |
| 2180 NameDictionary* dictionary = property_dictionary(); | 2178 NameDictionary* dictionary = property_dictionary(); |
| 2181 int old_index = dictionary->FindEntry(name); | 2179 int old_index = dictionary->FindEntry(name); |
| 2182 int new_enumeration_index = 0; // 0 means "Use the next available index." | 2180 int new_enumeration_index = 0; // 0 means "Use the next available index." |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2820 v8::Handle<v8::Value> result = args.Call(setter, | 2818 v8::Handle<v8::Value> result = args.Call(setter, |
| 2821 v8::Utils::ToLocal(name_handle), | 2819 v8::Utils::ToLocal(name_handle), |
| 2822 v8::Utils::ToLocal(value_unhole)); | 2820 v8::Utils::ToLocal(value_unhole)); |
| 2823 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 2821 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 2824 if (!result.IsEmpty()) return *value_handle; | 2822 if (!result.IsEmpty()) return *value_handle; |
| 2825 } | 2823 } |
| 2826 MaybeObject* raw_result = | 2824 MaybeObject* raw_result = |
| 2827 this_handle->SetPropertyPostInterceptor(*name_handle, | 2825 this_handle->SetPropertyPostInterceptor(*name_handle, |
| 2828 *value_handle, | 2826 *value_handle, |
| 2829 attributes, | 2827 attributes, |
| 2830 strict_mode, | 2828 strict_mode); |
| 2831 PERFORM_EXTENSIBILITY_CHECK); | |
| 2832 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 2829 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 2833 return raw_result; | 2830 return raw_result; |
| 2834 } | 2831 } |
| 2835 | 2832 |
| 2836 | 2833 |
| 2837 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 2834 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
| 2838 Handle<Name> key, | 2835 Handle<Name> key, |
| 2839 Handle<Object> value, | 2836 Handle<Object> value, |
| 2840 PropertyAttributes attributes, | 2837 PropertyAttributes attributes, |
| 2841 StrictModeFlag strict_mode) { | 2838 StrictModeFlag strict_mode) { |
| (...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4020 *key, *value, attributes, value_type, mode), | 4017 *key, *value, attributes, value_type, mode), |
| 4021 Object); | 4018 Object); |
| 4022 } | 4019 } |
| 4023 | 4020 |
| 4024 | 4021 |
| 4025 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( | 4022 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| 4026 Name* name_raw, | 4023 Name* name_raw, |
| 4027 Object* value_raw, | 4024 Object* value_raw, |
| 4028 PropertyAttributes attributes, | 4025 PropertyAttributes attributes, |
| 4029 ValueType value_type, | 4026 ValueType value_type, |
| 4030 StoreMode mode) { | 4027 StoreMode mode, |
| 4028 ExtensibilityCheck extensibility_check) { |
| 4031 // Make sure that the top context does not change when doing callbacks or | 4029 // Make sure that the top context does not change when doing callbacks or |
| 4032 // interceptor calls. | 4030 // interceptor calls. |
| 4033 AssertNoContextChange ncc; | 4031 AssertNoContextChange ncc; |
| 4034 Isolate* isolate = GetIsolate(); | 4032 Isolate* isolate = GetIsolate(); |
| 4035 LookupResult lookup(isolate); | 4033 LookupResult lookup(isolate); |
| 4036 LocalLookup(name_raw, &lookup, true); | 4034 LocalLookup(name_raw, &lookup, true); |
| 4037 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); | 4035 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); |
| 4038 // Check access rights if needed. | 4036 // Check access rights if needed. |
| 4039 if (IsAccessCheckNeeded()) { | 4037 if (IsAccessCheckNeeded()) { |
| 4040 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { | 4038 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
| 4041 return SetPropertyWithFailedAccessCheck(&lookup, | 4039 return SetPropertyWithFailedAccessCheck(&lookup, |
| 4042 name_raw, | 4040 name_raw, |
| 4043 value_raw, | 4041 value_raw, |
| 4044 false, | 4042 false, |
| 4045 kNonStrictMode); | 4043 kNonStrictMode); |
| 4046 } | 4044 } |
| 4047 } | 4045 } |
| 4048 | 4046 |
| 4049 if (IsJSGlobalProxy()) { | 4047 if (IsJSGlobalProxy()) { |
| 4050 Object* proto = GetPrototype(); | 4048 Object* proto = GetPrototype(); |
| 4051 if (proto->IsNull()) return value_raw; | 4049 if (proto->IsNull()) return value_raw; |
| 4052 ASSERT(proto->IsJSGlobalObject()); | 4050 ASSERT(proto->IsJSGlobalObject()); |
| 4053 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( | 4051 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( |
| 4054 name_raw, | 4052 name_raw, |
| 4055 value_raw, | 4053 value_raw, |
| 4056 attributes, | 4054 attributes, |
| 4057 value_type, | 4055 value_type, |
| 4058 mode); | 4056 mode, |
| 4057 extensibility_check); |
| 4059 } | 4058 } |
| 4060 | 4059 |
| 4061 // Check for accessor in prototype chain removed here in clone. | 4060 // Check for accessor in prototype chain removed here in clone. |
| 4062 if (!lookup.IsFound()) { | 4061 if (!lookup.IsFound()) { |
| 4063 // Neither properties nor transitions found. | 4062 // Neither properties nor transitions found. |
| 4064 return AddProperty( | 4063 return AddProperty( |
| 4065 name_raw, value_raw, attributes, kNonStrictMode, | 4064 name_raw, value_raw, attributes, kNonStrictMode, |
| 4066 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, value_type, mode); | 4065 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); |
| 4067 } | 4066 } |
| 4068 | 4067 |
| 4069 // From this point on everything needs to be handlified. | 4068 // From this point on everything needs to be handlified. |
| 4070 HandleScope scope(isolate); | 4069 HandleScope scope(isolate); |
| 4071 Handle<JSObject> self(this); | 4070 Handle<JSObject> self(this); |
| 4072 Handle<Name> name(name_raw); | 4071 Handle<Name> name(name_raw); |
| 4073 Handle<Object> value(value_raw, isolate); | 4072 Handle<Object> value(value_raw, isolate); |
| 4074 | 4073 |
| 4075 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); | 4074 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); |
| 4076 PropertyAttributes old_attributes = ABSENT; | 4075 PropertyAttributes old_attributes = ABSENT; |
| (...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4976 // dictionary. Put the identity hash into the new dictionary. | 4975 // dictionary. Put the identity hash into the new dictionary. |
| 4977 MaybeObject* insert_result = | 4976 MaybeObject* insert_result = |
| 4978 hashtable->Put(GetHeap()->identity_hash_string(), inline_value); | 4977 hashtable->Put(GetHeap()->identity_hash_string(), inline_value); |
| 4979 ObjectHashTable* new_table; | 4978 ObjectHashTable* new_table; |
| 4980 if (!insert_result->To(&new_table)) return insert_result; | 4979 if (!insert_result->To(&new_table)) return insert_result; |
| 4981 // We expect no resizing for the first insert. | 4980 // We expect no resizing for the first insert. |
| 4982 ASSERT_EQ(hashtable, new_table); | 4981 ASSERT_EQ(hashtable, new_table); |
| 4983 } | 4982 } |
| 4984 | 4983 |
| 4985 MaybeObject* store_result = | 4984 MaybeObject* store_result = |
| 4986 SetPropertyPostInterceptor(GetHeap()->hidden_string(), | 4985 SetLocalPropertyIgnoreAttributes(GetHeap()->hidden_string(), |
| 4987 hashtable, | 4986 hashtable, |
| 4988 DONT_ENUM, | 4987 DONT_ENUM, |
| 4989 kNonStrictMode, | 4988 OPTIMAL_REPRESENTATION, |
| 4990 OMIT_EXTENSIBILITY_CHECK, | 4989 ALLOW_AS_CONSTANT, |
| 4991 FORCE_FIELD); | 4990 OMIT_EXTENSIBILITY_CHECK); |
| 4992 if (store_result->IsFailure()) return store_result; | 4991 if (store_result->IsFailure()) return store_result; |
| 4993 return hashtable; | 4992 return hashtable; |
| 4994 } | 4993 } |
| 4995 | 4994 |
| 4996 | 4995 |
| 4997 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { | 4996 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { |
| 4998 ASSERT(!IsJSGlobalProxy()); | 4997 ASSERT(!IsJSGlobalProxy()); |
| 4999 // We can store the identity hash inline iff there is no backing store | 4998 // We can store the identity hash inline iff there is no backing store |
| 5000 // for hidden properties yet. | 4999 // for hidden properties yet. |
| 5001 ASSERT(HasHiddenProperties() != value->IsSmi()); | 5000 ASSERT(HasHiddenProperties() != value->IsSmi()); |
| 5002 if (HasFastProperties()) { | 5001 if (HasFastProperties()) { |
| 5003 // If the object has fast properties, check whether the first slot | 5002 // If the object has fast properties, check whether the first slot |
| 5004 // in the descriptor array matches the hidden string. Since the | 5003 // in the descriptor array matches the hidden string. Since the |
| 5005 // hidden strings hash code is zero (and no other name has hash | 5004 // hidden strings hash code is zero (and no other name has hash |
| 5006 // code zero) it will always occupy the first entry if present. | 5005 // code zero) it will always occupy the first entry if present. |
| 5007 DescriptorArray* descriptors = this->map()->instance_descriptors(); | 5006 DescriptorArray* descriptors = this->map()->instance_descriptors(); |
| 5008 if (descriptors->number_of_descriptors() > 0) { | 5007 if (descriptors->number_of_descriptors() > 0) { |
| 5009 int sorted_index = descriptors->GetSortedKeyIndex(0); | 5008 int sorted_index = descriptors->GetSortedKeyIndex(0); |
| 5010 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && | 5009 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && |
| 5011 sorted_index < map()->NumberOfOwnDescriptors()) { | 5010 sorted_index < map()->NumberOfOwnDescriptors()) { |
| 5012 ASSERT(descriptors->GetType(sorted_index) == FIELD); | 5011 ASSERT(descriptors->GetType(sorted_index) == FIELD); |
| 5013 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value); | 5012 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value); |
| 5014 return this; | 5013 return this; |
| 5015 } | 5014 } |
| 5016 } | 5015 } |
| 5017 } | 5016 } |
| 5018 MaybeObject* store_result = | 5017 MaybeObject* store_result = |
| 5019 SetPropertyPostInterceptor(GetHeap()->hidden_string(), | 5018 SetLocalPropertyIgnoreAttributes(GetHeap()->hidden_string(), |
| 5020 value, | 5019 value, |
| 5021 DONT_ENUM, | 5020 DONT_ENUM, |
| 5022 kNonStrictMode, | 5021 OPTIMAL_REPRESENTATION, |
| 5023 OMIT_EXTENSIBILITY_CHECK, | 5022 ALLOW_AS_CONSTANT, |
| 5024 FORCE_FIELD); | 5023 OMIT_EXTENSIBILITY_CHECK); |
| 5025 if (store_result->IsFailure()) return store_result; | 5024 if (store_result->IsFailure()) return store_result; |
| 5026 return this; | 5025 return this; |
| 5027 } | 5026 } |
| 5028 | 5027 |
| 5029 | 5028 |
| 5030 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, | 5029 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, |
| 5031 Handle<Name> name, | 5030 Handle<Name> name, |
| 5032 DeleteMode mode) { | 5031 DeleteMode mode) { |
| 5033 // Check local property, ignore interceptor. | 5032 // Check local property, ignore interceptor. |
| 5034 Isolate* isolate = object->GetIsolate(); | 5033 Isolate* isolate = object->GetIsolate(); |
| (...skipping 10321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15356 } | 15355 } |
| 15357 | 15356 |
| 15358 | 15357 |
| 15359 MaybeObject* ObjectHashSet::Add(Object* key) { | 15358 MaybeObject* ObjectHashSet::Add(Object* key) { |
| 15360 ASSERT(IsKey(key)); | 15359 ASSERT(IsKey(key)); |
| 15361 | 15360 |
| 15362 // Make sure the key object has an identity hash code. | 15361 // Make sure the key object has an identity hash code. |
| 15363 int hash; | 15362 int hash; |
| 15364 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); | 15363 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); |
| 15365 if (maybe_hash->IsFailure()) return maybe_hash; | 15364 if (maybe_hash->IsFailure()) return maybe_hash; |
| 15365 ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash); |
| 15366 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | 15366 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
| 15367 } | 15367 } |
| 15368 int entry = FindEntry(key); | 15368 int entry = FindEntry(key); |
| 15369 | 15369 |
| 15370 // Check whether key is already present. | 15370 // Check whether key is already present. |
| 15371 if (entry != kNotFound) return this; | 15371 if (entry != kNotFound) return this; |
| 15372 | 15372 |
| 15373 // Check whether the hash set should be extended and add entry. | 15373 // Check whether the hash set should be extended and add entry. |
| 15374 Object* obj; | 15374 Object* obj; |
| 15375 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15375 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15417 } | 15417 } |
| 15418 | 15418 |
| 15419 | 15419 |
| 15420 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { | 15420 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { |
| 15421 ASSERT(IsKey(key)); | 15421 ASSERT(IsKey(key)); |
| 15422 | 15422 |
| 15423 // Make sure the key object has an identity hash code. | 15423 // Make sure the key object has an identity hash code. |
| 15424 int hash; | 15424 int hash; |
| 15425 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); | 15425 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); |
| 15426 if (maybe_hash->IsFailure()) return maybe_hash; | 15426 if (maybe_hash->IsFailure()) return maybe_hash; |
| 15427 ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash); |
| 15427 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | 15428 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
| 15428 } | 15429 } |
| 15429 int entry = FindEntry(key); | 15430 int entry = FindEntry(key); |
| 15430 | 15431 |
| 15431 // Check whether to perform removal operation. | 15432 // Check whether to perform removal operation. |
| 15432 if (value->IsTheHole()) { | 15433 if (value->IsTheHole()) { |
| 15433 if (entry == kNotFound) return this; | 15434 if (entry == kNotFound) return this; |
| 15434 RemoveEntry(entry); | 15435 RemoveEntry(entry); |
| 15435 return Shrink(key); | 15436 return Shrink(key); |
| 15436 } | 15437 } |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16007 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16008 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16008 static const char* error_messages_[] = { | 16009 static const char* error_messages_[] = { |
| 16009 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16010 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16010 }; | 16011 }; |
| 16011 #undef ERROR_MESSAGES_TEXTS | 16012 #undef ERROR_MESSAGES_TEXTS |
| 16012 return error_messages_[reason]; | 16013 return error_messages_[reason]; |
| 16013 } | 16014 } |
| 16014 | 16015 |
| 16015 | 16016 |
| 16016 } } // namespace v8::internal | 16017 } } // namespace v8::internal |
| OLD | NEW |