Adding template parameter to PrototypeIterator GetCurrent
authorcbruni <cbruni@chromium.org>
Thu, 10 Sep 2015 10:56:06 +0000 (03:56 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 10 Sep 2015 10:56:18 +0000 (10:56 +0000)
BUG=

Review URL: https://codereview.chromium.org/1330153003

Cr-Commit-Position: refs/heads/master@{#30676}

12 files changed:
src/api.cc
src/builtins.cc
src/debug/debug-evaluate.cc
src/hydrogen.cc
src/ic/handler-compiler.cc
src/isolate.cc
src/lookup.cc
src/objects.cc
src/prototype.h
src/runtime/runtime-array.cc
src/runtime/runtime-object.cc
src/string-stream.cc

index 1cf5d52..4833c31 100644 (file)
@@ -3702,8 +3702,7 @@ Local<Object> v8::Object::FindInstanceInPrototypeChain(
       return Local<Object>();
     }
   }
-  return Utils::ToLocal(
-      i::handle(i::JSObject::cast(iter.GetCurrent()), isolate));
+  return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
 }
 
 
index f777f14..4ad6c21 100644 (file)
@@ -215,7 +215,7 @@ inline bool PrototypeHasNoElements(PrototypeIterator* iter) {
   DisallowHeapAllocation no_gc;
   for (; !iter->IsAtEnd(); iter->Advance()) {
     if (iter->GetCurrent()->IsJSProxy()) return false;
-    JSObject* current = JSObject::cast(iter->GetCurrent());
+    JSObject* current = iter->GetCurrent<JSObject>();
     if (current->IsAccessCheckNeeded()) return false;
     if (current->HasIndexedInterceptor()) return false;
     if (current->elements()->length() != 0) return false;
@@ -953,9 +953,8 @@ void CollectElementIndices(Handle<JSObject> object, uint32_t range,
   if (!iter.IsAtEnd()) {
     // The prototype will usually have no inherited element indices,
     // but we have to check.
-    CollectElementIndices(
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range,
-        indices);
+    CollectElementIndices(PrototypeIterator::GetCurrent<JSObject>(iter), range,
+                          indices);
   }
 }
 
index 10bc754..8d7635c 100644 (file)
@@ -106,7 +106,7 @@ MaybeHandle<Object> DebugEvaluate::Evaluate(
   if (result->IsJSGlobalProxy()) {
     PrototypeIterator iter(isolate, result);
     // TODO(verwaest): This will crash when the global proxy is detached.
-    result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+    result = PrototypeIterator::GetCurrent<JSObject>(iter);
   }
 
   return result;
index 337c35b..4d88303 100644 (file)
@@ -7368,7 +7368,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
     PrototypeIterator iter(map);
     JSObject* holder = NULL;
     while (!iter.IsAtEnd()) {
-      holder = JSObject::cast(*PrototypeIterator::GetCurrent(iter));
+      holder = *PrototypeIterator::GetCurrent<JSObject>(iter);
       iter.Advance();
     }
     DCHECK(holder && holder->IsJSObject());
@@ -7932,15 +7932,13 @@ HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
                          PrototypeIterator::START_AT_RECEIVER);
   while (holder.is_null() ||
          !PrototypeIterator::GetCurrent(iter).is_identical_to(holder)) {
-    BuildConstantMapCheck(
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
+    BuildConstantMapCheck(PrototypeIterator::GetCurrent<JSObject>(iter));
     iter.Advance();
     if (iter.IsAtEnd()) {
       return NULL;
     }
   }
-  return BuildConstantMapCheck(
-      Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
+  return BuildConstantMapCheck(PrototypeIterator::GetCurrent<JSObject>(iter));
 }
 
 
index a42fc69..c7f1f24 100644 (file)
@@ -330,7 +330,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
     PrototypeIterator iter(isolate(), last);
     while (!iter.IsAtEnd()) {
       lost_holder_register = true;
-      last = JSObject::cast(iter.GetCurrent());
+      last = iter.GetCurrent<JSObject>();
       iter.Advance();
     }
     auto last_handle = handle(last);
@@ -436,7 +436,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
                           : PrototypeIterator::END_AT_NULL;
     PrototypeIterator iter(isolate(), holder());
     while (!iter.IsAtEnd(end)) {
-      last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+      last = PrototypeIterator::GetCurrent<JSObject>(iter);
       iter.Advance();
     }
     if (!last.is_null()) set_holder(last);
index 80024ca..b8b3c26 100644 (file)
@@ -1348,7 +1348,7 @@ bool Isolate::IsErrorObject(Handle<Object> obj) {
   for (PrototypeIterator iter(this, *obj, PrototypeIterator::START_AT_RECEIVER);
        !iter.IsAtEnd(); iter.Advance()) {
     if (iter.GetCurrent()->IsJSProxy()) return false;
-    if (JSObject::cast(iter.GetCurrent())->map()->GetConstructor() ==
+    if (iter.GetCurrent<JSObject>()->map()->GetConstructor() ==
         *error_constructor) {
       return true;
     }
index e9dc3d3..69b733e 100644 (file)
@@ -94,7 +94,7 @@ Handle<JSObject> LookupIterator::GetStoreTarget() const {
   if (receiver_->IsJSGlobalProxy()) {
     PrototypeIterator iter(isolate(), receiver_);
     if (iter.IsAtEnd()) return Handle<JSGlobalProxy>::cast(receiver_);
-    return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
+    return PrototypeIterator::GetCurrent<JSGlobalObject>(iter);
   }
   return Handle<JSObject>::cast(receiver_);
 }
@@ -359,7 +359,7 @@ bool LookupIterator::InternalHolderIsReceiverOrHiddenPrototype() const {
   PrototypeIterator iter(isolate(), current,
                          PrototypeIterator::START_AT_RECEIVER);
   do {
-    if (JSReceiver::cast(iter.GetCurrent()) == holder) return true;
+    if (iter.GetCurrent<JSReceiver>() == holder) return true;
     DCHECK(!current->IsJSProxy());
     iter.Advance();
   } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
index c91ed7c..2287dd9 100644 (file)
@@ -5076,7 +5076,7 @@ Object* JSObject::GetHiddenProperty(Handle<Name> key) {
     // If the proxy is detached, return undefined.
     if (iter.IsAtEnd()) return GetHeap()->the_hole_value();
     DCHECK(iter.GetCurrent()->IsJSGlobalObject());
-    return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key);
+    return iter.GetCurrent<JSObject>()->GetHiddenProperty(key);
   }
   DCHECK(!IsJSGlobalProxy());
   Object* inline_value = GetHiddenPropertiesHashTable();
@@ -5101,9 +5101,8 @@ Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object,
     // If the proxy is detached, return undefined.
     if (iter.IsAtEnd()) return isolate->factory()->undefined_value();
     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
-    return SetHiddenProperty(
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key,
-        value);
+    return SetHiddenProperty(PrototypeIterator::GetCurrent<JSObject>(iter), key,
+                             value);
   }
   DCHECK(!object->IsJSGlobalProxy());
 
@@ -5134,8 +5133,8 @@ void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) {
     PrototypeIterator iter(isolate, object);
     if (iter.IsAtEnd()) return;
     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
-    return DeleteHiddenProperty(
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key);
+    return DeleteHiddenProperty(PrototypeIterator::GetCurrent<JSObject>(iter),
+                                key);
   }
 
   Object* inline_value = object->GetHiddenPropertiesHashTable();
@@ -5548,8 +5547,7 @@ MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
     PrototypeIterator iter(isolate, object);
     if (iter.IsAtEnd()) return object;
     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
-    return PreventExtensions(
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
+    return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter));
   }
 
   // It's not possible to seal objects with external array elements
@@ -5591,7 +5589,7 @@ bool JSObject::IsExtensible() {
     PrototypeIterator iter(GetIsolate(), this);
     if (iter.IsAtEnd()) return false;
     DCHECK(iter.GetCurrent()->IsJSGlobalObject());
-    return JSObject::cast(iter.GetCurrent())->map()->is_extensible();
+    return iter.GetCurrent<JSObject>()->map()->is_extensible();
   }
   return map()->is_extensible();
 }
@@ -5642,7 +5640,7 @@ MaybeHandle<Object> JSObject::PreventExtensionsWithTransition(
     if (iter.IsAtEnd()) return object;
     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
     return PreventExtensionsWithTransition<attrs>(
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
+        PrototypeIterator::GetCurrent<JSObject>(iter));
   }
 
   // It's not possible to seal or freeze objects with external array elements
@@ -6097,14 +6095,14 @@ bool JSReceiver::IsSimpleEnum() {
                               PrototypeIterator::START_AT_RECEIVER);
        !iter.IsAtEnd(); iter.Advance()) {
     if (!iter.GetCurrent()->IsJSObject()) return false;
-    JSObject* curr = JSObject::cast(iter.GetCurrent());
-    int enum_length = curr->map()->EnumLength();
+    JSObject* current = iter.GetCurrent<JSObject>();
+    int enum_length = current->map()->EnumLength();
     if (enum_length == kInvalidEnumCacheSentinel) return false;
-    if (curr->IsAccessCheckNeeded()) return false;
-    DCHECK(!curr->HasNamedInterceptor());
-    DCHECK(!curr->HasIndexedInterceptor());
-    if (curr->NumberOfEnumElements() > 0) return false;
-    if (curr != this && enum_length != 0) return false;
+    if (current->IsAccessCheckNeeded()) return false;
+    DCHECK(!current->HasNamedInterceptor());
+    DCHECK(!current->HasIndexedInterceptor());
+    if (current->NumberOfEnumElements() > 0) return false;
+    if (current != this && enum_length != 0) return false;
   }
   return true;
 }
@@ -6305,8 +6303,7 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
                               PrototypeIterator::START_AT_RECEIVER);
        !iter.IsAtEnd(end); iter.Advance()) {
     if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
-      Handle<JSProxy> proxy(JSProxy::cast(*PrototypeIterator::GetCurrent(iter)),
-                            isolate);
+      Handle<JSProxy> proxy = PrototypeIterator::GetCurrent<JSProxy>(iter);
       Handle<Object> args[] = { proxy };
       Handle<Object> names;
       ASSIGN_RETURN_ON_EXCEPTION(
@@ -6325,8 +6322,7 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
       break;
     }
 
-    Handle<JSObject> current =
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+    Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
 
     // Check access rights if required.
     if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) {
@@ -6409,7 +6405,7 @@ bool Map::DictionaryElementsInPrototypeChainOnly() {
     if (iter.GetCurrent()->IsJSProxy()) return true;
     // String wrappers have non-configurable, non-writable elements.
     if (iter.GetCurrent()->IsStringWrapper()) return true;
-    JSObject* current = JSObject::cast(iter.GetCurrent());
+    JSObject* current = iter.GetCurrent<JSObject>();
 
     if (current->HasDictionaryElements() &&
         current->element_dictionary()->requires_slow_elements()) {
@@ -9968,7 +9964,7 @@ bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
   if (slot == PrototypeInfo::UNREGISTERED) return false;
   if (prototype->IsJSGlobalProxy()) {
     PrototypeIterator iter(isolate, prototype);
-    prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+    prototype = PrototypeIterator::GetCurrent<JSObject>(iter);
   }
   DCHECK(prototype->map()->is_prototype_map());
   Object* maybe_proto_info = prototype->map()->prototype_info();
@@ -10020,7 +10016,7 @@ void JSObject::InvalidatePrototypeChains(Map* map) {
   DisallowHeapAllocation no_gc;
   if (map->IsJSGlobalProxyMap()) {
     PrototypeIterator iter(map);
-    map = JSObject::cast(iter.GetCurrent())->map();
+    map = iter.GetCurrent<JSObject>()->map();
   }
   InvalidatePrototypeChainsInternal(map);
 }
@@ -10060,7 +10056,7 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
   Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
   if (prototype->IsJSGlobalProxy()) {
     PrototypeIterator iter(isolate, prototype);
-    prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+    prototype = PrototypeIterator::GetCurrent<JSObject>(iter);
   }
   // Ensure the prototype is registered with its own prototypes so its cell
   // will be invalidated when necessary.
@@ -12391,7 +12387,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
   for (PrototypeIterator iter(isolate, *value,
                               PrototypeIterator::START_AT_RECEIVER);
        !iter.IsAtEnd(); iter.Advance()) {
-    if (JSReceiver::cast(iter.GetCurrent()) == *object) {
+    if (iter.GetCurrent<JSReceiver>() == *object) {
       // Cycle detected.
       THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kCyclicProto),
                       Object);
@@ -12407,8 +12403,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
     // hidden and set the new prototype on that object.
     PrototypeIterator iter(isolate, real_receiver);
     while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
-      real_receiver =
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+      real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
       iter.Advance();
       if (!real_receiver->map()->is_extensible()) {
         THROW_NEW_ERROR(
index 4df1114..0727749 100644 (file)
@@ -39,6 +39,7 @@ class PrototypeIterator {
       Advance();
     }
   }
+
   PrototypeIterator(Isolate* isolate, Object* receiver,
                     WhereToStart where_to_start = START_AT_PROTOTYPE)
       : did_jump_to_prototype_chain_(false),
@@ -48,25 +49,32 @@ class PrototypeIterator {
       Advance();
     }
   }
+
   explicit PrototypeIterator(Map* receiver_map)
       : did_jump_to_prototype_chain_(true),
         object_(receiver_map->prototype()),
         isolate_(receiver_map->GetIsolate()) {}
+
   explicit PrototypeIterator(Handle<Map> receiver_map)
       : did_jump_to_prototype_chain_(true),
         object_(NULL),
         handle_(handle(receiver_map->prototype(), receiver_map->GetIsolate())),
         isolate_(receiver_map->GetIsolate()) {}
+
   ~PrototypeIterator() {}
 
-  Object* GetCurrent() const {
+  template <typename T = Object>
+  T* GetCurrent() const {
     DCHECK(handle_.is_null());
-    return object_;
+    return T::cast(object_);
   }
-  static Handle<Object> GetCurrent(const PrototypeIterator& iterator) {
+
+  template <typename T = Object>
+  static Handle<T> GetCurrent(const PrototypeIterator& iterator) {
     DCHECK(!iterator.handle_.is_null());
-    return iterator.handle_;
+    return Handle<T>::cast(iterator.handle_);
   }
+
   void Advance() {
     if (handle_.is_null() && object_->IsJSProxy()) {
       did_jump_to_prototype_chain_ = true;
@@ -79,6 +87,7 @@ class PrototypeIterator {
     }
     AdvanceIgnoringProxies();
   }
+
   void AdvanceIgnoringProxies() {
     if (!did_jump_to_prototype_chain_) {
       did_jump_to_prototype_chain_ = true;
@@ -96,6 +105,7 @@ class PrototypeIterator {
       }
     }
   }
+
   bool IsAtEnd(WhereToEnd where_to_end = END_AT_NULL) const {
     if (handle_.is_null()) {
       return object_->IsNull() ||
@@ -109,10 +119,12 @@ class PrototypeIterator {
               !Handle<HeapObject>::cast(handle_)->map()->is_hidden_prototype());
     }
   }
+
   bool IsAtEnd(Object* final_object) {
     DCHECK(handle_.is_null());
     return object_->IsNull() || object_ == final_object;
   }
+
   bool IsAtEnd(Handle<Object> final_object) {
     DCHECK(!handle_.is_null());
     return handle_->IsNull() || *handle_ == *final_object;
index 4b41bd8..721f291 100644 (file)
@@ -203,14 +203,13 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
                                 PrototypeIterator::START_AT_RECEIVER);
          !iter.IsAtEnd(); iter.Advance()) {
       if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() ||
-          JSObject::cast(*PrototypeIterator::GetCurrent(iter))
+          PrototypeIterator::GetCurrent<JSObject>(iter)
               ->HasIndexedInterceptor()) {
         // Bail out if we find a proxy or interceptor, likely not worth
         // collecting keys in that case.
         return *isolate->factory()->NewNumberFromUint(length);
       }
-      Handle<JSObject> current =
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+      Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
       Handle<FixedArray> current_keys =
           isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
       current->GetOwnElementKeys(*current_keys, NONE);
@@ -454,8 +453,7 @@ RUNTIME_FUNCTION(Runtime_HasComplexElements) {
     if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
       return isolate->heap()->true_value();
     }
-    Handle<JSObject> current =
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+    Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
     if (current->HasIndexedInterceptor()) {
       return isolate->heap()->true_value();
     }
index b475e56..9ffb250 100644 (file)
@@ -186,8 +186,7 @@ RUNTIME_FUNCTION(Runtime_GetPrototype) {
   PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
   do {
     if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
-        !isolate->MayAccess(
-            Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)))) {
+        !isolate->MayAccess(PrototypeIterator::GetCurrent<JSObject>(iter))) {
       return isolate->heap()->null_value();
     }
     iter.AdvanceIgnoringProxies();
index 92fff27..2801d23 100644 (file)
@@ -531,7 +531,7 @@ void StringStream::PrintPrototype(JSFunction* fun, Object* receiver) {
                               PrototypeIterator::START_AT_RECEIVER);
        !iter.IsAtEnd(); iter.Advance()) {
     if (iter.GetCurrent()->IsJSObject()) {
-      Object* key = JSObject::cast(iter.GetCurrent())->SlowReverseLookup(fun);
+      Object* key = iter.GetCurrent<JSObject>()->SlowReverseLookup(fun);
       if (key != isolate->heap()->undefined_value()) {
         if (!name->IsString() ||
             !key->IsString() ||