Bug 1096328 - Remove nativeOwnership from Bindings.conf, add template to detect refcounted classes. r=bz.
☠☠ backed out by a7f64e53893e ☠ ☠
authorPeter Van der Beken <peterv@propagandism.org>
Sat, 01 Nov 2014 14:10:59 +0100
changeset 249150 0f330a5dd34661249917e477977cc2b67c48c440
parent 249149 c37e10cff7654d9a8b0f8af8571c3f40bcef72b3
child 249151 6005fd357342edf5f5282e584fbe5655c4fee340
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1096328
milestone37.0a1
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
Bug 1096328 - Remove nativeOwnership from Bindings.conf, add template to detect refcounted classes. r=bz.
dom/base/DOMMatrix.cpp
dom/base/DOMMatrix.h
dom/base/DOMPoint.cpp
dom/base/DOMPoint.h
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -18,16 +18,21 @@
 #include "nsAutoPtr.h"
 #include <math.h>
 
 namespace mozilla {
 namespace dom {
 
 static const double radPerDegree = 2.0 * M_PI / 360.0;
 
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMMatrixReadOnly, mParent)
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMatrixReadOnly, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMatrixReadOnly, Release)
+
 already_AddRefed<DOMMatrix>
 DOMMatrixReadOnly::Translate(double aTx,
                              double aTy,
                              double aTz) const
 {
   nsRefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
   retval->TranslateSelf(aTx, aTy, aTz);
 
@@ -298,21 +303,16 @@ DOMMatrixReadOnly::Stringify(nsAString& 
       M41(), M42(), M43(), M44());
   } else {
     matrixStr.AppendPrintf("matrix(%g, %g, %g, %g, %g, %g)", A(), B(), C(), D(), E(), F());
   }
 
   aResult = matrixStr;
 }
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMMatrix, mParent)
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMatrix, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMatrix, Release)
-
 already_AddRefed<DOMMatrix>
 DOMMatrix::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
   return obj.forget();
 }
 
 already_AddRefed<DOMMatrix>
--- a/dom/base/DOMMatrix.h
+++ b/dom/base/DOMMatrix.h
@@ -35,16 +35,19 @@ public:
   {
     if (other.mMatrix2D) {
       mMatrix2D = new gfx::Matrix(*other.mMatrix2D);
     } else {
       mMatrix3D = new gfx::Matrix4x4(*other.mMatrix3D);
     }
   }
 
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrixReadOnly)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMMatrixReadOnly)
+
 #define GetMatrixMember(entry2D, entry3D, default) \
 { \
   if (mMatrix3D) { \
     return mMatrix3D->entry3D; \
   } \
   return mMatrix2D->entry2D; \
 }
 
@@ -125,19 +128,18 @@ public:
                                              JS::MutableHandle<JSObject*> aResult,
                                              ErrorResult& aRv) const;
   void                        Stringify(nsAString& aResult);
 protected:
   nsCOMPtr<nsISupports>     mParent;
   nsAutoPtr<gfx::Matrix>    mMatrix2D;
   nsAutoPtr<gfx::Matrix4x4> mMatrix3D;
 
-  ~DOMMatrixReadOnly()
-  {
-  }
+  virtual ~DOMMatrixReadOnly() {}
+
 private:
   DOMMatrixReadOnly() = delete;
   DOMMatrixReadOnly(const DOMMatrixReadOnly&) = delete;
   DOMMatrixReadOnly& operator=(const DOMMatrixReadOnly&) = delete;
 };
 
 class DOMMatrix MOZ_FINAL : public DOMMatrixReadOnly
 {
@@ -145,19 +147,16 @@ public:
   explicit DOMMatrix(nsISupports* aParent)
     : DOMMatrixReadOnly(aParent)
   {}
 
   DOMMatrix(nsISupports* aParent, const DOMMatrixReadOnly& other)
     : DOMMatrixReadOnly(aParent, other)
   {}
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrix)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMMatrix)
-
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const nsAString& aTransformList, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const DOMMatrixReadOnly& aOther, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv);
@@ -241,16 +240,14 @@ public:
                                  double aZ,
                                  double aAngle);
   DOMMatrix* SkewXSelf(double aSx);
   DOMMatrix* SkewYSelf(double aSy);
   DOMMatrix* InvertSelf();
   DOMMatrix* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv);
 private:
   void Ensure3DMatrix();
-
-  ~DOMMatrix() {}
 };
 
 }
 }
 
 #endif /*MOZILLA_DOM_DOMMATRIX_H_*/
--- a/dom/base/DOMPoint.cpp
+++ b/dom/base/DOMPoint.cpp
@@ -7,20 +7,20 @@
 
 #include "mozilla/dom/DOMPointBinding.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "nsAutoPtr.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMPoint, mParent)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMPointReadOnly, mParent)
 
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPoint, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPoint, Release)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPointReadOnly, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPointReadOnly, Release)
 
 already_AddRefed<DOMPoint>
 DOMPoint::Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
                       ErrorResult& aRV)
 {
   nsRefPtr<DOMPoint> obj =
     new DOMPoint(aGlobal.GetAsSupports(), aParams.mX, aParams.mY,
                  aParams.mZ, aParams.mW);
--- a/dom/base/DOMPoint.h
+++ b/dom/base/DOMPoint.h
@@ -28,39 +28,39 @@ public:
     : mParent(aParent)
     , mX(aX)
     , mY(aY)
     , mZ(aZ)
     , mW(aW)
   {
   }
 
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPointReadOnly)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPointReadOnly)
+
   double X() const { return mX; }
   double Y() const { return mY; }
   double Z() const { return mZ; }
   double W() const { return mW; }
 
 protected:
+  virtual ~DOMPointReadOnly() {}
+
   nsCOMPtr<nsISupports> mParent;
   double mX, mY, mZ, mW;
 };
 
 class DOMPoint MOZ_FINAL : public DOMPointReadOnly
 {
-  ~DOMPoint() {}
-
 public:
   explicit DOMPoint(nsISupports* aParent, double aX = 0.0, double aY = 0.0,
                     double aZ = 0.0, double aW = 1.0)
     : DOMPointReadOnly(aParent, aX, aY, aZ, aW)
   {}
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPoint)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPoint)
-
   static already_AddRefed<DOMPoint>
   Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
               ErrorResult& aRV);
   static already_AddRefed<DOMPoint>
   Constructor(const GlobalObject& aGlobal, double aX, double aY,
               double aZ, double aW, ErrorResult& aRV);
 
   nsISupports* GetParentObject() const { return mParent; }
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -702,16 +702,36 @@ struct NativeHasMember
 template<class T>
 struct IsSmartPtr
 {
   HAS_MEMBER_TYPEDEFS;
 
   HAS_MEMBER(get, value);
 };
 
+template<class T>
+struct IsRefcounted
+{
+  HAS_MEMBER_TYPEDEFS;
+
+  HAS_MEMBER(AddRef, HasAddref);
+  HAS_MEMBER(Release, HasRelease);
+
+public:
+  static bool const value = HasAddref && HasRelease;
+
+private:
+  // This struct only works if T is fully declared (not just forward declared).
+  // The IsBaseOf check will ensure that, we don't really need it for any other
+  // reason (the static assert will of course always be true).
+  static_assert(!IsBaseOf<nsISupports, T>::value || IsRefcounted::value,
+                "Classes derived from nsISupports are refcounted!");
+
+};
+
 #undef HAS_MEMBER
 #undef HAS_MEMBER_CHECK
 #undef HAS_MEMBER_TYPEDEFS
 
 #ifdef DEBUG
 template <class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
 struct
 CheckWrapperCacheCast
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -10989,26 +10989,27 @@ def memberProperties(m, descriptor):
     return props
 
 class CGDescriptor(CGThing):
     def __init__(self, descriptor):
         CGThing.__init__(self)
 
         assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
 
-        if descriptor.nativeOwnership == 'owned' and (
-                descriptor.interface.hasChildInterfaces() or
-                descriptor.interface.parent):
-            raise TypeError("Owned interface cannot have a parent or children")
-
         self._deps = descriptor.interface.getDeps()
 
         cgThings = []
         cgThings.append(CGGeneric(declare="typedef %s NativeType;\n" %
                                   descriptor.nativeType))
+        parent = descriptor.interface.parent
+        if parent:
+            cgThings.append(CGGeneric("static_assert(IsRefcounted<NativeType>::value == IsRefcounted<%s::NativeType>::value,\n"
+                                      "              \"Can't inherit from an interface with a different ownership model.\");\n" %
+                                      toBindingNamespace(descriptor.parentPrototypeName)))
+
         # These are set to true if at least one non-static
         # method/getter/setter or jsonifier exist on the interface.
         (hasMethod, hasGetter, hasLenientGetter, hasSetter, hasLenientSetter,
             hasPromiseReturningMethod) = False, False, False, False, False, False
         jsonifierMethod = None
         crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set()
         for n in descriptor.interface.namedConstructors:
             cgThings.append(CGClassConstructor(descriptor, n,