| 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 "src/objects.h" | 5 #include "src/objects.h" | 
| 6 | 6 | 
| 7 #include <iomanip> | 7 #include <iomanip> | 
| 8 #include <sstream> | 8 #include <sstream> | 
| 9 | 9 | 
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" | 
| (...skipping 5058 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5069 | 5069 | 
| 5070 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 5070 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 
| 5071   DisallowHeapAllocation no_gc; | 5071   DisallowHeapAllocation no_gc; | 
| 5072   DCHECK(key->IsUniqueName()); | 5072   DCHECK(key->IsUniqueName()); | 
| 5073   if (IsJSGlobalProxy()) { | 5073   if (IsJSGlobalProxy()) { | 
| 5074     // For a proxy, use the prototype as target object. | 5074     // For a proxy, use the prototype as target object. | 
| 5075     PrototypeIterator iter(GetIsolate(), this); | 5075     PrototypeIterator iter(GetIsolate(), this); | 
| 5076     // If the proxy is detached, return undefined. | 5076     // If the proxy is detached, return undefined. | 
| 5077     if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); | 5077     if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); | 
| 5078     DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 5078     DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 
| 5079     return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key); | 5079     return iter.GetCurrent<JSObject>()->GetHiddenProperty(key); | 
| 5080   } | 5080   } | 
| 5081   DCHECK(!IsJSGlobalProxy()); | 5081   DCHECK(!IsJSGlobalProxy()); | 
| 5082   Object* inline_value = GetHiddenPropertiesHashTable(); | 5082   Object* inline_value = GetHiddenPropertiesHashTable(); | 
| 5083 | 5083 | 
| 5084   if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); | 5084   if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); | 
| 5085 | 5085 | 
| 5086   ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 5086   ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 
| 5087   Object* entry = hashtable->Lookup(key); | 5087   Object* entry = hashtable->Lookup(key); | 
| 5088   return entry; | 5088   return entry; | 
| 5089 } | 5089 } | 
| 5090 | 5090 | 
| 5091 | 5091 | 
| 5092 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 5092 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 
| 5093                                            Handle<Name> key, | 5093                                            Handle<Name> key, | 
| 5094                                            Handle<Object> value) { | 5094                                            Handle<Object> value) { | 
| 5095   Isolate* isolate = object->GetIsolate(); | 5095   Isolate* isolate = object->GetIsolate(); | 
| 5096 | 5096 | 
| 5097   DCHECK(key->IsUniqueName()); | 5097   DCHECK(key->IsUniqueName()); | 
| 5098   if (object->IsJSGlobalProxy()) { | 5098   if (object->IsJSGlobalProxy()) { | 
| 5099     // For a proxy, use the prototype as target object. | 5099     // For a proxy, use the prototype as target object. | 
| 5100     PrototypeIterator iter(isolate, object); | 5100     PrototypeIterator iter(isolate, object); | 
| 5101     // If the proxy is detached, return undefined. | 5101     // If the proxy is detached, return undefined. | 
| 5102     if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); | 5102     if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); | 
| 5103     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5103     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 
| 5104     return SetHiddenProperty( | 5104     return SetHiddenProperty(PrototypeIterator::GetCurrent<JSObject>(iter), key, | 
| 5105         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key, | 5105                              value); | 
| 5106         value); |  | 
| 5107   } | 5106   } | 
| 5108   DCHECK(!object->IsJSGlobalProxy()); | 5107   DCHECK(!object->IsJSGlobalProxy()); | 
| 5109 | 5108 | 
| 5110   Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 5109   Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 
| 5111 | 5110 | 
| 5112   Handle<ObjectHashTable> hashtable = | 5111   Handle<ObjectHashTable> hashtable = | 
| 5113       GetOrCreateHiddenPropertiesHashtable(object); | 5112       GetOrCreateHiddenPropertiesHashtable(object); | 
| 5114 | 5113 | 
| 5115   // If it was found, check if the key is already in the dictionary. | 5114   // If it was found, check if the key is already in the dictionary. | 
| 5116   Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, | 5115   Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 5127 | 5126 | 
| 5128 | 5127 | 
| 5129 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { | 5128 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { | 
| 5130   Isolate* isolate = object->GetIsolate(); | 5129   Isolate* isolate = object->GetIsolate(); | 
| 5131   DCHECK(key->IsUniqueName()); | 5130   DCHECK(key->IsUniqueName()); | 
| 5132 | 5131 | 
| 5133   if (object->IsJSGlobalProxy()) { | 5132   if (object->IsJSGlobalProxy()) { | 
| 5134     PrototypeIterator iter(isolate, object); | 5133     PrototypeIterator iter(isolate, object); | 
| 5135     if (iter.IsAtEnd()) return; | 5134     if (iter.IsAtEnd()) return; | 
| 5136     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5135     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 
| 5137     return DeleteHiddenProperty( | 5136     return DeleteHiddenProperty(PrototypeIterator::GetCurrent<JSObject>(iter), | 
| 5138         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); | 5137                                 key); | 
| 5139   } | 5138   } | 
| 5140 | 5139 | 
| 5141   Object* inline_value = object->GetHiddenPropertiesHashTable(); | 5140   Object* inline_value = object->GetHiddenPropertiesHashTable(); | 
| 5142 | 5141 | 
| 5143   if (inline_value->IsUndefined()) return; | 5142   if (inline_value->IsUndefined()) return; | 
| 5144 | 5143 | 
| 5145   Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 5144   Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 
| 5146   bool was_present = false; | 5145   bool was_present = false; | 
| 5147   ObjectHashTable::Remove(hashtable, key, &was_present); | 5146   ObjectHashTable::Remove(hashtable, key, &was_present); | 
| 5148 } | 5147 } | 
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5541   if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { | 5540   if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { | 
| 5542     isolate->ReportFailedAccessCheck(object); | 5541     isolate->ReportFailedAccessCheck(object); | 
| 5543     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5542     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 
| 5544     return isolate->factory()->false_value(); | 5543     return isolate->factory()->false_value(); | 
| 5545   } | 5544   } | 
| 5546 | 5545 | 
| 5547   if (object->IsJSGlobalProxy()) { | 5546   if (object->IsJSGlobalProxy()) { | 
| 5548     PrototypeIterator iter(isolate, object); | 5547     PrototypeIterator iter(isolate, object); | 
| 5549     if (iter.IsAtEnd()) return object; | 5548     if (iter.IsAtEnd()) return object; | 
| 5550     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5549     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 
| 5551     return PreventExtensions( | 5550     return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter)); | 
| 5552         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); |  | 
| 5553   } | 5551   } | 
| 5554 | 5552 | 
| 5555   // It's not possible to seal objects with external array elements | 5553   // It's not possible to seal objects with external array elements | 
| 5556   if (object->HasFixedTypedArrayElements()) { | 5554   if (object->HasFixedTypedArrayElements()) { | 
| 5557     THROW_NEW_ERROR( | 5555     THROW_NEW_ERROR( | 
| 5558         isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 5556         isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 
| 5559         Object); | 5557         Object); | 
| 5560   } | 5558   } | 
| 5561 | 5559 | 
| 5562   // If there are fast elements we normalize. | 5560   // If there are fast elements we normalize. | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 5584   } | 5582   } | 
| 5585   return object; | 5583   return object; | 
| 5586 } | 5584 } | 
| 5587 | 5585 | 
| 5588 | 5586 | 
| 5589 bool JSObject::IsExtensible() { | 5587 bool JSObject::IsExtensible() { | 
| 5590   if (IsJSGlobalProxy()) { | 5588   if (IsJSGlobalProxy()) { | 
| 5591     PrototypeIterator iter(GetIsolate(), this); | 5589     PrototypeIterator iter(GetIsolate(), this); | 
| 5592     if (iter.IsAtEnd()) return false; | 5590     if (iter.IsAtEnd()) return false; | 
| 5593     DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 5591     DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 
| 5594     return JSObject::cast(iter.GetCurrent())->map()->is_extensible(); | 5592     return iter.GetCurrent<JSObject>()->map()->is_extensible(); | 
| 5595   } | 5593   } | 
| 5596   return map()->is_extensible(); | 5594   return map()->is_extensible(); | 
| 5597 } | 5595 } | 
| 5598 | 5596 | 
| 5599 | 5597 | 
| 5600 template <typename Dictionary> | 5598 template <typename Dictionary> | 
| 5601 static void ApplyAttributesToDictionary(Dictionary* dictionary, | 5599 static void ApplyAttributesToDictionary(Dictionary* dictionary, | 
| 5602                                         const PropertyAttributes attributes) { | 5600                                         const PropertyAttributes attributes) { | 
| 5603   int capacity = dictionary->Capacity(); | 5601   int capacity = dictionary->Capacity(); | 
| 5604   for (int i = 0; i < capacity; i++) { | 5602   for (int i = 0; i < capacity; i++) { | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 5635     isolate->ReportFailedAccessCheck(object); | 5633     isolate->ReportFailedAccessCheck(object); | 
| 5636     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5634     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 
| 5637     return isolate->factory()->false_value(); | 5635     return isolate->factory()->false_value(); | 
| 5638   } | 5636   } | 
| 5639 | 5637 | 
| 5640   if (object->IsJSGlobalProxy()) { | 5638   if (object->IsJSGlobalProxy()) { | 
| 5641     PrototypeIterator iter(isolate, object); | 5639     PrototypeIterator iter(isolate, object); | 
| 5642     if (iter.IsAtEnd()) return object; | 5640     if (iter.IsAtEnd()) return object; | 
| 5643     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5641     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 
| 5644     return PreventExtensionsWithTransition<attrs>( | 5642     return PreventExtensionsWithTransition<attrs>( | 
| 5645         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); | 5643         PrototypeIterator::GetCurrent<JSObject>(iter)); | 
| 5646   } | 5644   } | 
| 5647 | 5645 | 
| 5648   // It's not possible to seal or freeze objects with external array elements | 5646   // It's not possible to seal or freeze objects with external array elements | 
| 5649   if (object->HasFixedTypedArrayElements()) { | 5647   if (object->HasFixedTypedArrayElements()) { | 
| 5650     THROW_NEW_ERROR( | 5648     THROW_NEW_ERROR( | 
| 5651         isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 5649         isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 
| 5652         Object); | 5650         Object); | 
| 5653   } | 5651   } | 
| 5654 | 5652 | 
| 5655   Handle<SeededNumberDictionary> new_element_dictionary; | 5653   Handle<SeededNumberDictionary> new_element_dictionary; | 
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6090 // Tests for the fast common case for property enumeration: | 6088 // Tests for the fast common case for property enumeration: | 
| 6091 // - This object and all prototypes has an enum cache (which means that | 6089 // - This object and all prototypes has an enum cache (which means that | 
| 6092 //   it is no proxy, has no interceptors and needs no access checks). | 6090 //   it is no proxy, has no interceptors and needs no access checks). | 
| 6093 // - This object has no elements. | 6091 // - This object has no elements. | 
| 6094 // - No prototype has enumerable properties/elements. | 6092 // - No prototype has enumerable properties/elements. | 
| 6095 bool JSReceiver::IsSimpleEnum() { | 6093 bool JSReceiver::IsSimpleEnum() { | 
| 6096   for (PrototypeIterator iter(GetIsolate(), this, | 6094   for (PrototypeIterator iter(GetIsolate(), this, | 
| 6097                               PrototypeIterator::START_AT_RECEIVER); | 6095                               PrototypeIterator::START_AT_RECEIVER); | 
| 6098        !iter.IsAtEnd(); iter.Advance()) { | 6096        !iter.IsAtEnd(); iter.Advance()) { | 
| 6099     if (!iter.GetCurrent()->IsJSObject()) return false; | 6097     if (!iter.GetCurrent()->IsJSObject()) return false; | 
| 6100     JSObject* curr = JSObject::cast(iter.GetCurrent()); | 6098     JSObject* current = iter.GetCurrent<JSObject>(); | 
| 6101     int enum_length = curr->map()->EnumLength(); | 6099     int enum_length = current->map()->EnumLength(); | 
| 6102     if (enum_length == kInvalidEnumCacheSentinel) return false; | 6100     if (enum_length == kInvalidEnumCacheSentinel) return false; | 
| 6103     if (curr->IsAccessCheckNeeded()) return false; | 6101     if (current->IsAccessCheckNeeded()) return false; | 
| 6104     DCHECK(!curr->HasNamedInterceptor()); | 6102     DCHECK(!current->HasNamedInterceptor()); | 
| 6105     DCHECK(!curr->HasIndexedInterceptor()); | 6103     DCHECK(!current->HasIndexedInterceptor()); | 
| 6106     if (curr->NumberOfEnumElements() > 0) return false; | 6104     if (current->NumberOfEnumElements() > 0) return false; | 
| 6107     if (curr != this && enum_length != 0) return false; | 6105     if (current != this && enum_length != 0) return false; | 
| 6108   } | 6106   } | 
| 6109   return true; | 6107   return true; | 
| 6110 } | 6108 } | 
| 6111 | 6109 | 
| 6112 | 6110 | 
| 6113 static bool FilterKey(Object* key, PropertyAttributes filter) { | 6111 static bool FilterKey(Object* key, PropertyAttributes filter) { | 
| 6114   if ((filter & SYMBOLIC) && key->IsSymbol()) { | 6112   if ((filter & SYMBOLIC) && key->IsSymbol()) { | 
| 6115     return true; | 6113     return true; | 
| 6116   } | 6114   } | 
| 6117 | 6115 | 
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6298       JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 6296       JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 
| 6299 | 6297 | 
| 6300   PrototypeIterator::WhereToEnd end = type == OWN_ONLY | 6298   PrototypeIterator::WhereToEnd end = type == OWN_ONLY | 
| 6301                                           ? PrototypeIterator::END_AT_NON_HIDDEN | 6299                                           ? PrototypeIterator::END_AT_NON_HIDDEN | 
| 6302                                           : PrototypeIterator::END_AT_NULL; | 6300                                           : PrototypeIterator::END_AT_NULL; | 
| 6303   // Only collect keys if access is permitted. | 6301   // Only collect keys if access is permitted. | 
| 6304   for (PrototypeIterator iter(isolate, object, | 6302   for (PrototypeIterator iter(isolate, object, | 
| 6305                               PrototypeIterator::START_AT_RECEIVER); | 6303                               PrototypeIterator::START_AT_RECEIVER); | 
| 6306        !iter.IsAtEnd(end); iter.Advance()) { | 6304        !iter.IsAtEnd(end); iter.Advance()) { | 
| 6307     if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 6305     if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 
| 6308       Handle<JSProxy> proxy(JSProxy::cast(*PrototypeIterator::GetCurrent(iter)), | 6306       Handle<JSProxy> proxy = PrototypeIterator::GetCurrent<JSProxy>(iter); | 
| 6309                             isolate); |  | 
| 6310       Handle<Object> args[] = { proxy }; | 6307       Handle<Object> args[] = { proxy }; | 
| 6311       Handle<Object> names; | 6308       Handle<Object> names; | 
| 6312       ASSIGN_RETURN_ON_EXCEPTION( | 6309       ASSIGN_RETURN_ON_EXCEPTION( | 
| 6313           isolate, names, | 6310           isolate, names, | 
| 6314           Execution::Call(isolate, | 6311           Execution::Call(isolate, | 
| 6315                           isolate->proxy_enumerate(), | 6312                           isolate->proxy_enumerate(), | 
| 6316                           object, | 6313                           object, | 
| 6317                           arraysize(args), | 6314                           arraysize(args), | 
| 6318                           args), | 6315                           args), | 
| 6319           FixedArray); | 6316           FixedArray); | 
| 6320       ASSIGN_RETURN_ON_EXCEPTION( | 6317       ASSIGN_RETURN_ON_EXCEPTION( | 
| 6321           isolate, content, | 6318           isolate, content, | 
| 6322           FixedArray::AddKeysFromArrayLike( | 6319           FixedArray::AddKeysFromArrayLike( | 
| 6323               content, Handle<JSObject>::cast(names)), | 6320               content, Handle<JSObject>::cast(names)), | 
| 6324           FixedArray); | 6321           FixedArray); | 
| 6325       break; | 6322       break; | 
| 6326     } | 6323     } | 
| 6327 | 6324 | 
| 6328     Handle<JSObject> current = | 6325     Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); | 
| 6329         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |  | 
| 6330 | 6326 | 
| 6331     // Check access rights if required. | 6327     // Check access rights if required. | 
| 6332     if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) { | 6328     if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) { | 
| 6333       if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { | 6329       if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { | 
| 6334         isolate->ReportFailedAccessCheck(current); | 6330         isolate->ReportFailedAccessCheck(current); | 
| 6335         RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); | 6331         RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); | 
| 6336       } | 6332       } | 
| 6337       break; | 6333       break; | 
| 6338     } | 6334     } | 
| 6339 | 6335 | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6402 bool Map::DictionaryElementsInPrototypeChainOnly() { | 6398 bool Map::DictionaryElementsInPrototypeChainOnly() { | 
| 6403   if (IsDictionaryElementsKind(elements_kind())) { | 6399   if (IsDictionaryElementsKind(elements_kind())) { | 
| 6404     return false; | 6400     return false; | 
| 6405   } | 6401   } | 
| 6406 | 6402 | 
| 6407   for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) { | 6403   for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) { | 
| 6408     // Be conservative, don't walk into proxies. | 6404     // Be conservative, don't walk into proxies. | 
| 6409     if (iter.GetCurrent()->IsJSProxy()) return true; | 6405     if (iter.GetCurrent()->IsJSProxy()) return true; | 
| 6410     // String wrappers have non-configurable, non-writable elements. | 6406     // String wrappers have non-configurable, non-writable elements. | 
| 6411     if (iter.GetCurrent()->IsStringWrapper()) return true; | 6407     if (iter.GetCurrent()->IsStringWrapper()) return true; | 
| 6412     JSObject* current = JSObject::cast(iter.GetCurrent()); | 6408     JSObject* current = iter.GetCurrent<JSObject>(); | 
| 6413 | 6409 | 
| 6414     if (current->HasDictionaryElements() && | 6410     if (current->HasDictionaryElements() && | 
| 6415         current->element_dictionary()->requires_slow_elements()) { | 6411         current->element_dictionary()->requires_slow_elements()) { | 
| 6416       return true; | 6412       return true; | 
| 6417     } | 6413     } | 
| 6418 | 6414 | 
| 6419     if (current->HasSlowArgumentsElements()) { | 6415     if (current->HasSlowArgumentsElements()) { | 
| 6420       FixedArray* parameter_map = FixedArray::cast(current->elements()); | 6416       FixedArray* parameter_map = FixedArray::cast(current->elements()); | 
| 6421       Object* arguments = parameter_map->get(1); | 6417       Object* arguments = parameter_map->get(1); | 
| 6422       if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) { | 6418       if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) { | 
| (...skipping 3538 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 9961   if (!user->prototype_info()->IsPrototypeInfo()) return false; | 9957   if (!user->prototype_info()->IsPrototypeInfo()) return false; | 
| 9962   // If it doesn't have a prototype, it can't be registered. | 9958   // If it doesn't have a prototype, it can't be registered. | 
| 9963   if (!user->prototype()->IsJSObject()) return false; | 9959   if (!user->prototype()->IsJSObject()) return false; | 
| 9964   Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate); | 9960   Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate); | 
| 9965   Handle<PrototypeInfo> user_info = | 9961   Handle<PrototypeInfo> user_info = | 
| 9966       Map::GetOrCreatePrototypeInfo(user, isolate); | 9962       Map::GetOrCreatePrototypeInfo(user, isolate); | 
| 9967   int slot = user_info->registry_slot(); | 9963   int slot = user_info->registry_slot(); | 
| 9968   if (slot == PrototypeInfo::UNREGISTERED) return false; | 9964   if (slot == PrototypeInfo::UNREGISTERED) return false; | 
| 9969   if (prototype->IsJSGlobalProxy()) { | 9965   if (prototype->IsJSGlobalProxy()) { | 
| 9970     PrototypeIterator iter(isolate, prototype); | 9966     PrototypeIterator iter(isolate, prototype); | 
| 9971     prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 9967     prototype = PrototypeIterator::GetCurrent<JSObject>(iter); | 
| 9972   } | 9968   } | 
| 9973   DCHECK(prototype->map()->is_prototype_map()); | 9969   DCHECK(prototype->map()->is_prototype_map()); | 
| 9974   Object* maybe_proto_info = prototype->map()->prototype_info(); | 9970   Object* maybe_proto_info = prototype->map()->prototype_info(); | 
| 9975   // User knows its registry slot, prototype info and user registry must exist. | 9971   // User knows its registry slot, prototype info and user registry must exist. | 
| 9976   DCHECK(maybe_proto_info->IsPrototypeInfo()); | 9972   DCHECK(maybe_proto_info->IsPrototypeInfo()); | 
| 9977   Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), | 9973   Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), | 
| 9978                                    isolate); | 9974                                    isolate); | 
| 9979   Object* maybe_registry = proto_info->prototype_users(); | 9975   Object* maybe_registry = proto_info->prototype_users(); | 
| 9980   DCHECK(maybe_registry->IsWeakFixedArray()); | 9976   DCHECK(maybe_registry->IsWeakFixedArray()); | 
| 9981   DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user); | 9977   DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user); | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 10013   } | 10009   } | 
| 10014 } | 10010 } | 
| 10015 | 10011 | 
| 10016 | 10012 | 
| 10017 // static | 10013 // static | 
| 10018 void JSObject::InvalidatePrototypeChains(Map* map) { | 10014 void JSObject::InvalidatePrototypeChains(Map* map) { | 
| 10019   if (!FLAG_eliminate_prototype_chain_checks) return; | 10015   if (!FLAG_eliminate_prototype_chain_checks) return; | 
| 10020   DisallowHeapAllocation no_gc; | 10016   DisallowHeapAllocation no_gc; | 
| 10021   if (map->IsJSGlobalProxyMap()) { | 10017   if (map->IsJSGlobalProxyMap()) { | 
| 10022     PrototypeIterator iter(map); | 10018     PrototypeIterator iter(map); | 
| 10023     map = JSObject::cast(iter.GetCurrent())->map(); | 10019     map = iter.GetCurrent<JSObject>()->map(); | 
| 10024   } | 10020   } | 
| 10025   InvalidatePrototypeChainsInternal(map); | 10021   InvalidatePrototypeChainsInternal(map); | 
| 10026 } | 10022 } | 
| 10027 | 10023 | 
| 10028 | 10024 | 
| 10029 // static | 10025 // static | 
| 10030 Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<JSObject> prototype, | 10026 Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<JSObject> prototype, | 
| 10031                                                     Isolate* isolate) { | 10027                                                     Isolate* isolate) { | 
| 10032   Object* maybe_proto_info = prototype->map()->prototype_info(); | 10028   Object* maybe_proto_info = prototype->map()->prototype_info(); | 
| 10033   if (maybe_proto_info->IsPrototypeInfo()) { | 10029   if (maybe_proto_info->IsPrototypeInfo()) { | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 10053 | 10049 | 
| 10054 | 10050 | 
| 10055 // static | 10051 // static | 
| 10056 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, | 10052 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, | 
| 10057                                                         Isolate* isolate) { | 10053                                                         Isolate* isolate) { | 
| 10058   Handle<Object> maybe_prototype(map->prototype(), isolate); | 10054   Handle<Object> maybe_prototype(map->prototype(), isolate); | 
| 10059   if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); | 10055   if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); | 
| 10060   Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); | 10056   Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); | 
| 10061   if (prototype->IsJSGlobalProxy()) { | 10057   if (prototype->IsJSGlobalProxy()) { | 
| 10062     PrototypeIterator iter(isolate, prototype); | 10058     PrototypeIterator iter(isolate, prototype); | 
| 10063     prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 10059     prototype = PrototypeIterator::GetCurrent<JSObject>(iter); | 
| 10064   } | 10060   } | 
| 10065   // Ensure the prototype is registered with its own prototypes so its cell | 10061   // Ensure the prototype is registered with its own prototypes so its cell | 
| 10066   // will be invalidated when necessary. | 10062   // will be invalidated when necessary. | 
| 10067   JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate), | 10063   JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate), | 
| 10068                                       isolate); | 10064                                       isolate); | 
| 10069   Handle<PrototypeInfo> proto_info = | 10065   Handle<PrototypeInfo> proto_info = | 
| 10070       GetOrCreatePrototypeInfo(prototype, isolate); | 10066       GetOrCreatePrototypeInfo(prototype, isolate); | 
| 10071   Object* maybe_cell = proto_info->validity_cell(); | 10067   Object* maybe_cell = proto_info->validity_cell(); | 
| 10072   // Return existing cell if it's still valid. | 10068   // Return existing cell if it's still valid. | 
| 10073   if (maybe_cell->IsCell()) { | 10069   if (maybe_cell->IsCell()) { | 
| (...skipping 2310 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 12384                     Object); | 12380                     Object); | 
| 12385   } | 12381   } | 
| 12386 | 12382 | 
| 12387   // Before we can set the prototype we need to be sure | 12383   // Before we can set the prototype we need to be sure | 
| 12388   // prototype cycles are prevented. | 12384   // prototype cycles are prevented. | 
| 12389   // It is sufficient to validate that the receiver is not in the new prototype | 12385   // It is sufficient to validate that the receiver is not in the new prototype | 
| 12390   // chain. | 12386   // chain. | 
| 12391   for (PrototypeIterator iter(isolate, *value, | 12387   for (PrototypeIterator iter(isolate, *value, | 
| 12392                               PrototypeIterator::START_AT_RECEIVER); | 12388                               PrototypeIterator::START_AT_RECEIVER); | 
| 12393        !iter.IsAtEnd(); iter.Advance()) { | 12389        !iter.IsAtEnd(); iter.Advance()) { | 
| 12394     if (JSReceiver::cast(iter.GetCurrent()) == *object) { | 12390     if (iter.GetCurrent<JSReceiver>() == *object) { | 
| 12395       // Cycle detected. | 12391       // Cycle detected. | 
| 12396       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kCyclicProto), | 12392       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kCyclicProto), | 
| 12397                       Object); | 12393                       Object); | 
| 12398     } | 12394     } | 
| 12399   } | 12395   } | 
| 12400 | 12396 | 
| 12401   bool dictionary_elements_in_chain = | 12397   bool dictionary_elements_in_chain = | 
| 12402       object->map()->DictionaryElementsInPrototypeChainOnly(); | 12398       object->map()->DictionaryElementsInPrototypeChainOnly(); | 
| 12403   Handle<JSObject> real_receiver = object; | 12399   Handle<JSObject> real_receiver = object; | 
| 12404 | 12400 | 
| 12405   if (from_javascript) { | 12401   if (from_javascript) { | 
| 12406     // Find the first object in the chain whose prototype object is not | 12402     // Find the first object in the chain whose prototype object is not | 
| 12407     // hidden and set the new prototype on that object. | 12403     // hidden and set the new prototype on that object. | 
| 12408     PrototypeIterator iter(isolate, real_receiver); | 12404     PrototypeIterator iter(isolate, real_receiver); | 
| 12409     while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { | 12405     while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { | 
| 12410       real_receiver = | 12406       real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter); | 
| 12411           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |  | 
| 12412       iter.Advance(); | 12407       iter.Advance(); | 
| 12413       if (!real_receiver->map()->is_extensible()) { | 12408       if (!real_receiver->map()->is_extensible()) { | 
| 12414         THROW_NEW_ERROR( | 12409         THROW_NEW_ERROR( | 
| 12415             isolate, NewTypeError(MessageTemplate::kNonExtensibleProto, object), | 12410             isolate, NewTypeError(MessageTemplate::kNonExtensibleProto, object), | 
| 12416             Object); | 12411             Object); | 
| 12417       } | 12412       } | 
| 12418     } | 12413     } | 
| 12419   } | 12414   } | 
| 12420 | 12415 | 
| 12421   // Set the new prototype of the object. | 12416   // Set the new prototype of the object. | 
| (...skipping 3742 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 16164   if (cell->value() != *new_value) { | 16159   if (cell->value() != *new_value) { | 
| 16165     cell->set_value(*new_value); | 16160     cell->set_value(*new_value); | 
| 16166     Isolate* isolate = cell->GetIsolate(); | 16161     Isolate* isolate = cell->GetIsolate(); | 
| 16167     cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16162     cell->dependent_code()->DeoptimizeDependentCodeGroup( | 
| 16168         isolate, DependentCode::kPropertyCellChangedGroup); | 16163         isolate, DependentCode::kPropertyCellChangedGroup); | 
| 16169   } | 16164   } | 
| 16170 } | 16165 } | 
| 16171 | 16166 | 
| 16172 }  // namespace internal | 16167 }  // namespace internal | 
| 16173 }  // namespace v8 | 16168 }  // namespace v8 | 
| OLD | NEW | 
|---|