Back out revision 5985a4717758 (bug 1215559) because the Linux compiler is not happy with the template using bits
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 16 Oct 2015 16:16:36 -0400
changeset 268120 7f2e5ec068f70139a0534d8d5113454d4f001a83
parent 268119 dba4e2f06001d4ecae3a44d3676eaacb33fcbf8e
child 268121 09e059daabae5ad4df486a1ce2bf8e83c22188d2
push id66704
push userbzbarsky@mozilla.com
push dateFri, 16 Oct 2015 20:16:44 +0000
treeherdermozilla-inbound@7f2e5ec068f7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1215559
milestone44.0a1
backs out5985a47177581ad830879c9eb2b7908900130c51
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out revision 5985a4717758 (bug 1215559) because the Linux compiler is not happy with the template using bits
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/IterableIterator.h
dom/bindings/test/TestInterfaceIterableSingle.cpp
dom/bindings/test/TestInterfaceIterableSingle.h
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -7,17 +7,17 @@
 import os
 import re
 import string
 import math
 import textwrap
 import functools
 
 from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLInterfaceMember, IDLUndefinedValue, IDLEmptySequenceValue, IDLDictionary
-from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, getAllTypes, Descriptor, MemberIsUnforgeable, iteratorNativeType
+from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, getAllTypes, Descriptor, MemberIsUnforgeable
 
 AUTOGENERATED_WARNING_COMMENT = \
     "/* THIS FILE IS AUTOGENERATED BY Codegen.py - DO NOT EDIT */\n\n"
 AUTOGENERATED_WITH_SOURCE_WARNING_COMMENT = \
     "/* THIS FILE IS AUTOGENERATED FROM %s BY Codegen.py - DO NOT EDIT */\n\n"
 ADDPROPERTY_HOOK_NAME = '_addProperty'
 FINALIZE_HOOK_NAME = '_finalize'
 OBJECT_MOVED_HOOK_NAME = '_objectMoved'
@@ -15467,22 +15467,22 @@ class CGIterableMethodGenerator(CGGeneri
     Creates methods for iterable interfaces. Unwrapping/wrapping
     will be taken care of by the usual method generation machinery in
     CGMethodCall/CGPerSignatureCall. Functionality is filled in here instead of
     using CGCallGenerator.
     """
     def __init__(self, descriptor, iterable, methodName):
         CGGeneric.__init__(self, fill(
             """
-            typedef ${iterClass} itrType;
+            typedef IterableIterator<${nativeType}> itrType;
             nsRefPtr<itrType> result(new itrType(self,
                                                  itrType::IterableIteratorType::${itrMethod},
                                                  &${ifaceName}IteratorBinding::Wrap));
             """,
-            iterClass=iteratorNativeType(descriptor),
+            nativeType=descriptor.nativeType,
             ifaceName=descriptor.interface.identifier.name,
             itrMethod=methodName.title()))
 
 
 class GlobalGenRoots():
     """
     Roots for global codegen.
 
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -355,17 +355,18 @@ class Descriptor(DescriptorProvider):
         # For generated iterator interfaces for other iterable interfaces, we
         # just use IterableIterator as the native type, templated on the
         # nativeType of the iterable interface. That way we can have a
         # templated implementation for all the duplicated iterator
         # functionality.
         if self.interface.isIteratorInterface():
             itrName = self.interface.iterableInterface.identifier.name
             itrDesc = self.getDescriptor(itrName)
-            nativeTypeDefault = iteratorNativeType(itrDesc)
+            nativeTypeDefault = ("mozilla::dom::IterableIterator<%s>"
+                                 % itrDesc.nativeType)
 
         elif self.interface.isExternal():
             assert not self.workers
             nativeTypeDefault = "nsIDOM" + ifaceName
         elif self.interface.isCallback():
             nativeTypeDefault = "mozilla::dom::" + ifaceName
         else:
             if self.workers:
@@ -884,17 +885,8 @@ def getAllTypes(descriptors, dictionarie
         for t in getTypesFromDescriptor(d):
             yield (t, d, None)
     for dictionary in dictionaries:
         for t in getTypesFromDictionary(dictionary):
             yield (t, None, dictionary)
     for callback in callbacks:
         for t in getTypesFromCallback(callback):
             yield (t, None, None)
-
-def iteratorNativeType(descriptor):
-    assert descriptor.interface.isIterable()
-    iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable
-    if iterableDecl.valueType is None:
-        iterClass = "OneTypeIterableIterator"
-    else:
-        iterClass = "TwoTypeIterableIterator"
-    return "mozilla::dom::%s<%s>" % (iterClass, descriptor.nativeType)
--- a/dom/bindings/IterableIterator.h
+++ b/dom/bindings/IterableIterator.h
@@ -4,28 +4,26 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * The IterableIterator class is used for WebIDL interfaces that have a
  * iterable<> member defined. It handles the ES6 Iterator-like functions that
  * are generated for the iterable interface.
  *
- * For iterable interfaces, the implementation class will need to
- * implement these two functions:
+ * For iterable interfaces, the implementation class will need to contain three
+ * functions:
  *
  * - size_t GetIterableLength()
  *   - Returns the number of elements available to iterate over
- * - [type] GetValueAtIndex(size_t index)
- *   - Returns the value at the requested index.
- *
- * If this is a two-type iterator, then the implementation class will also need to implement:
- *
  * - [type] GetKeyAtIndex(size_t index)
  *   - Returns the key at the requested index
+ * - [type] GetValueAtIndex(size_t index)
+ *   - Returns the value at the requested index, or the key again if this is
+ *     a single type iterator.
  *
  * Examples of iterable interface implementations can be found in the bindings
  * test directory.
  */
 
 #ifndef mozilla_dom_IterableIterator_h
 #define mozilla_dom_IterableIterator_h
 
@@ -55,243 +53,140 @@ public:
   
 protected:
   virtual ~IterableIteratorBase() {}
   virtual void UnlinkHelper() = 0;
   virtual void TraverseHelper(nsCycleCollectionTraversalCallback& cb) = 0;
 };
 
 template <typename T>
-class IterableIterator : public IterableIteratorBase
+class IterableIterator final : public IterableIteratorBase
 {
 public:
-  IterableIterator(T* aIterableObj)
-    : mIterableObj(aIterableObj)
+
+  typedef bool (*WrapFunc)(JSContext* aCx,
+                           mozilla::dom::IterableIterator<T>* aObject,
+                           JS::Handle<JSObject*> aGivenProto,
+                           JS::MutableHandle<JSObject*> aReflector);
+  IterableIterator(T* aIterableObj, IterableIteratorType aIteratorType, WrapFunc aWrapFunc)
+    : mIteratorType(aIteratorType)
+    , mIterableObj(aIterableObj)
+    , mIndex(0)
+    , mWrapFunc(aWrapFunc)
   {
     MOZ_ASSERT(mIterableObj);
+    MOZ_ASSERT(mWrapFunc);
   }
 
-protected:
-  static void
+  void
   DictReturn(JSContext* aCx, JS::MutableHandle<JSObject*> aResult,
              bool aDone, JS::Handle<JS::Value> aValue, ErrorResult& aRv)
   {
     RootedDictionary<IterableKeyOrValueResult> dict(aCx);
     dict.mDone = aDone;
     dict.mValue = aValue;
     JS::Rooted<JS::Value> dictValue(aCx);
     if (!ToJSValue(aCx, dict, &dictValue)) {
       aRv.Throw(NS_ERROR_FAILURE);
       return;
     }
     aResult.set(&dictValue.toObject());
   }
 
-  static void
-  KeyAndValueReturn(JSContext* aCx, JS::Handle<JS::Value> aKey,
-                    JS::Handle<JS::Value> aValue,
-                    JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
+  void
+  Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
   {
-    RootedDictionary<IterableKeyAndValueResult> dict(aCx);
-    dict.mDone = false;
-    // Dictionary values are a Sequence, which is a FallibleTArray, so we need
-    // to check returns when appending.
-    if (!dict.mValue.AppendElement(aKey, mozilla::fallible)) {
-      aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+    JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
+    if (mIndex >= mIterableObj->GetIterableLength()) {
+      DictReturn(aCx, aResult, true, value, aRv);
       return;
     }
-    if (!dict.mValue.AppendElement(aValue, mozilla::fallible)) {
-      aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
-      return;
+    switch (mIteratorType) {
+    case IterableIteratorType::Keys:
+    {
+      if (!ToJSValue(aCx, mIterableObj->GetKeyAtIndex(mIndex), &value)) {
+        aRv.Throw(NS_ERROR_FAILURE);
+        return;
+      }
+      DictReturn(aCx, aResult, false, value, aRv);
+      break;
+    }
+    case IterableIteratorType::Values:
+    {
+      if (!ToJSValue(aCx, mIterableObj->GetValueAtIndex(mIndex), &value)) {
+        aRv.Throw(NS_ERROR_FAILURE);
+        return;
+      }
+      DictReturn(aCx, aResult, false, value, aRv);
+      break;
     }
-    JS::Rooted<JS::Value> dictValue(aCx);
-    if (!ToJSValue(aCx, dict, &dictValue)) {
-      aRv.Throw(NS_ERROR_FAILURE);
-      return;
+    case IterableIteratorType::Entries:
+    {
+      JS::Rooted<JS::Value> key(aCx);
+      if (!ToJSValue(aCx, mIterableObj->GetKeyAtIndex(mIndex), &key)) {
+        aRv.Throw(NS_ERROR_FAILURE);
+        return;
+      }
+      if (!ToJSValue(aCx, mIterableObj->GetValueAtIndex(mIndex), &value)) {
+        aRv.Throw(NS_ERROR_FAILURE);
+        return;
+      }
+      RootedDictionary<IterableKeyAndValueResult> dict(aCx);
+      dict.mDone = false;
+      // Dictionary values are a Sequence, which is a FallibleTArray, so we need
+      // to check returns when appending.
+      if (!dict.mValue.AppendElement(key, mozilla::fallible)) {
+        aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+        return;
+      }
+      if (!dict.mValue.AppendElement(value, mozilla::fallible)) {
+        aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+        return;
+      }
+      JS::Rooted<JS::Value> dictValue(aCx);
+      if (!ToJSValue(aCx, dict, &dictValue)) {
+        aRv.Throw(NS_ERROR_FAILURE);
+        return;
+      }
+      aResult.set(&dictValue.toObject());
+      break;
     }
-    aResult.set(&dictValue.toObject());
+    default:
+      MOZ_CRASH("Invalid iterator type!");
+    }
+    ++mIndex;
+  }
+  virtual ~IterableIterator() {}
+
+  bool
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
+  {
+    return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
   }
 
 protected:
-  virtual ~IterableIterator() {}
+  // Tells whether this is a key, value, or entries iterator.
+  IterableIteratorType mIteratorType;
+  // Binding Implementation Object that we're iterating over.
+  nsRefPtr<T> mIterableObj;
+  // Current index of iteration.
+  uint32_t mIndex;
+  // Function pointer to binding-type-specific Wrap() call for this iterator.
+  WrapFunc mWrapFunc;
 
   // Since we're templated on a binding, we need to possibly CC it, but can't do
   // that through macros. So it happens here.
   virtual void UnlinkHelper() final
   {
     mIterableObj = nullptr;
   }
 
   virtual void TraverseHelper(nsCycleCollectionTraversalCallback& cb) override
   {
     IterableIterator<T>* tmp = this;
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIterableObj);
   }
-
-  // Binding Implementation object that we're iterating over.
-  nsRefPtr<T> mIterableObj;
-};
-
-template<typename T>
-class OneTypeIterableIterator final : public IterableIterator<T>
-{
-public:
-  using typename IterableIterator<T>::IterableIteratorType;
-  using IterableIterator<T>::DictReturn;
-  using IterableIterator<T>::KeyAndValueReturn;
-  typedef bool (*WrapFunc)(JSContext* aCx,
-                           OneTypeIterableIterator<T>* aObject,
-                           JS::Handle<JSObject*> aGivenProto,
-                           JS::MutableHandle<JSObject*> aReflector);
-
-  OneTypeIterableIterator(T* aIterableObj,
-                          IterableIteratorType aIteratorType,
-                          WrapFunc aWrapFunc)
-    : IterableIterator<T>(aIterableObj)
-    , mIteratorType(aIteratorType)
-    , mWrapFunc(aWrapFunc)
-    , mIndex(0)
-  {
-    MOZ_ASSERT(mWrapFunc);
-  }
-
-  void
-  Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
-  {
-    JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
-    if (mIndex >= this->mIterableObj->GetIterableLength()) {
-      DictReturn(aCx, aResult, true, value, aRv);
-      return;
-    }
-
-    switch (mIteratorType) {
-    case IterableIteratorType::Keys:
-    case IterableIteratorType::Values:
-    {
-      if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
-        aRv.Throw(NS_ERROR_FAILURE);
-        return;
-      }
-      DictReturn(aCx, aResult, false, value, aRv);
-      break;
-    }
-    case IterableIteratorType::Entries:
-    {
-      if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
-        aRv.Throw(NS_ERROR_FAILURE);
-        return;
-      }
-      KeyAndValueReturn(aCx, value, value, aResult, aRv);
-      break;
-    }
-    default:
-      MOZ_CRASH("Invalid iterator type!");
-    }
-    ++mIndex;
-  }
-
-  bool
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
-  {
-    return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
-  }
-
-protected:
-  virtual ~OneTypeIterableIterator() {}
-
-  // Tells whether this is a key, value, or entries iterator.
-  IterableIteratorType mIteratorType;
-  // Function pointer to binding-type-specific Wrap() call for this iterator.
-  WrapFunc mWrapFunc;
-  // Current index of iteration.
-  uint32_t mIndex;
-};
-
-template<typename T>
-class TwoTypeIterableIterator final : public IterableIterator<T>
-{
-public:
-  using typename IterableIterator<T>::IterableIteratorType;
-  using IterableIterator<T>::DictReturn;
-  using IterableIterator<T>::KeyAndValueReturn;
-  typedef bool (*WrapFunc)(JSContext* aCx,
-                           TwoTypeIterableIterator<T>* aObject,
-                           JS::Handle<JSObject*> aGivenProto,
-                           JS::MutableHandle<JSObject*> aReflector);
-
-  TwoTypeIterableIterator(T* aIterableObj, IterableIteratorType aIteratorType,
-                          WrapFunc aWrapFunc)
-    : IterableIterator<T>(aIterableObj)
-    , mIteratorType(aIteratorType)
-    , mWrapFunc(aWrapFunc)
-    , mIndex(0)
-  {
-    MOZ_ASSERT(mWrapFunc);
-  }
-
-  void
-  Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
-  {
-    JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
-    if (mIndex >= this->mIterableObj->GetIterableLength()) {
-      DictReturn(aCx, aResult, true, value, aRv);
-      return;
-    }
-    switch (mIteratorType) {
-    case IterableIteratorType::Keys:
-    {
-      if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &value)) {
-        aRv.Throw(NS_ERROR_FAILURE);
-        return;
-      }
-      DictReturn(aCx, aResult, false, value, aRv);
-      break;
-    }
-    case IterableIteratorType::Values:
-    {
-      if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
-        aRv.Throw(NS_ERROR_FAILURE);
-        return;
-      }
-      DictReturn(aCx, aResult, false, value, aRv);
-      break;
-    }
-    case IterableIteratorType::Entries:
-    {
-      JS::Rooted<JS::Value> key(aCx);
-      if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &key)) {
-        aRv.Throw(NS_ERROR_FAILURE);
-        return;
-      }
-      if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
-        aRv.Throw(NS_ERROR_FAILURE);
-        return;
-      }
-      KeyAndValueReturn(aCx, key, value, aResult, aRv);
-      break;
-    }
-    default:
-      MOZ_CRASH("Invalid iterator type!");
-    }
-    ++mIndex;
-  }
-
-  bool
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
-  {
-    return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
-  }
-
-protected:
-  virtual ~TwoTypeIterableIterator() {}
-
-  // Tells whether this is a key, value, or entries iterator.
-  IterableIteratorType mIteratorType;
-  // Function pointer to binding-type-specific Wrap() call for this iterator.
-  WrapFunc mWrapFunc;
-  // Current index of iteration.
-  uint32_t mIndex;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_IterableIterator_h
--- a/dom/bindings/test/TestInterfaceIterableSingle.cpp
+++ b/dom/bindings/test/TestInterfaceIterableSingle.cpp
@@ -57,16 +57,22 @@ TestInterfaceIterableSingle::GetParentOb
 
 size_t
 TestInterfaceIterableSingle::GetIterableLength() const
 {
   return mValues.Length();
 }
 
 uint32_t
-TestInterfaceIterableSingle::GetValueAtIndex(uint32_t index) const
+TestInterfaceIterableSingle::GetKeyAtIndex(uint32_t index) const
 {
   MOZ_ASSERT(index < mValues.Length());
   return mValues.ElementAt(index);
 }
 
+uint32_t
+TestInterfaceIterableSingle::GetValueAtIndex(uint32_t index) const
+{
+  return GetKeyAtIndex(index);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/bindings/test/TestInterfaceIterableSingle.h
+++ b/dom/bindings/test/TestInterfaceIterableSingle.h
@@ -32,16 +32,17 @@ public:
   explicit TestInterfaceIterableSingle(nsPIDOMWindow* aParent);
   nsPIDOMWindow* GetParentObject() const;
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) override;
   static already_AddRefed<TestInterfaceIterableSingle>
     Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
 
   size_t GetIterableLength() const;
+  uint32_t GetKeyAtIndex(uint32_t aIndex) const;
   uint32_t GetValueAtIndex(uint32_t aIndex) const;
 private:
   virtual ~TestInterfaceIterableSingle() {}
   nsCOMPtr<nsPIDOMWindow> mParent;
   nsTArray<uint32_t> mValues;
 };
 
 } // namespace dom