Bug 975246 - Part2- Test Invoking via operator->*. r=nfroyd
authorJames Cheng <jacheng@mozilla.com>
Wed, 29 Jul 2015 02:52:00 +0200
changeset 287094 c016da5a123d5f7246901196a085f079d96ac06e
parent 287093 c9d25e716d31e97d801451d8eeedaac3b7664664
child 287095 4075070296955acf65f29edf2097c56e782db305
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnfroyd
bugs975246
milestone42.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 975246 - Part2- Test Invoking via operator->*. r=nfroyd
xpcom/tests/TestNsRefPtr.cpp
--- a/xpcom/tests/TestNsRefPtr.cpp
+++ b/xpcom/tests/TestNsRefPtr.cpp
@@ -22,17 +22,19 @@ class Foo : public nsISupports
 		public:
       Foo();
       // virtual dtor because Bar uses our Release()
       virtual ~Foo();
 
       NS_IMETHOD_(MozExternalRefCountType) AddRef();
       NS_IMETHOD_(MozExternalRefCountType) Release();
       NS_IMETHOD QueryInterface( const nsIID&, void** );
-
+      void MemberFunction( int, int*, int& );
+      virtual void VirtualMemberFunction( int, int*, int& );
+      virtual void VirtualConstMemberFunction( int, int*, int& ) const;
       static void print_totals();
 
     private:
       unsigned int refcount_;
 
       static unsigned int total_constructions_;
       static unsigned int total_destructions_;
   };
@@ -151,16 +153,33 @@ Foo::QueryInterface( const nsIID& aIID, 
 			}
 
 		NS_IF_ADDREF(rawPtr);
 		*aResult = rawPtr;
 
 		return status;
 	}
 
+void
+Foo::MemberFunction( int aArg1, int* aArgPtr, int& aArgRef )
+  {
+    printf("member function is invoked.\n");
+  }
+
+void
+Foo::VirtualMemberFunction( int aArg1, int* aArgPtr, int& aArgRef )
+  {
+    printf("virtual member function is invoked.\n");
+  }
+void
+Foo::VirtualConstMemberFunction( int aArg1, int* aArgPtr, int& aArgRef ) const
+  {
+    printf("virtual const member function is invoked.\n");
+  }
+
 nsresult
 CreateFoo( void** result )
     // a typical factory function (that calls AddRef)
   {
     printf(">>CreateFoo() --> ");
     Foo* foop = new Foo;
     printf("Foo@%p\n", static_cast<void*>(foop));
 
@@ -202,17 +221,20 @@ class Bar : public Foo
   {
   	public:
 		NS_DECLARE_STATIC_IID_ACCESSOR(NS_BAR_IID)
 
     public:
       Bar();
       virtual ~Bar();
 
-      NS_IMETHOD QueryInterface( const nsIID&, void** );
+      NS_IMETHOD QueryInterface( const nsIID&, void** ) override;
+
+      virtual void VirtualMemberFunction( int, int*, int& ) override;
+      virtual void VirtualConstMemberFunction( int, int*, int& ) const override;
   };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(Bar, NS_BAR_IID)
 
 Bar::Bar()
   {
     printf("  new Bar@%p\n", static_cast<void*>(this));
   }
@@ -243,17 +265,26 @@ Bar::QueryInterface( const nsID& aIID, v
 			}
 
 		NS_IF_ADDREF(rawPtr);
 		*aResult = rawPtr;
 
 		return status;
 	}
 
-
+void
+Bar::VirtualMemberFunction( int aArg1, int* aArgPtr, int& aArgRef )
+  {
+    printf("override virtual member function is invoked.\n");
+  }
+void
+Bar::VirtualConstMemberFunction( int aArg1, int* aArgPtr, int& aArgRef ) const
+  {
+    printf("override virtual const member function is invoked.\n");
+  }
 
 nsresult
 CreateBar( void** result )
     // a typical factory function (that calls AddRef)
   {
     printf(">>CreateBar() --> ");
     Bar* barp = new Bar;
     printf("Bar@%p\n", static_cast<void*>(barp));
@@ -312,17 +343,53 @@ TestBloat_Smart()
 		nsRefPtr<Foo> fooP( do_QueryObject(barP, &result) );
 
 		if ( fooP )
 			fooP->print_totals();
 
 		return result;
 	}
 
+#define NS_INLINE_DECL_THREADSAFE_MUTABLE_REFCOUNTING(_class)                 \
+public:                                                                       \
+  NS_METHOD_(MozExternalRefCountType) AddRef(void) const {                    \
+    MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(_class)                                \
+    MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");                      \
+    nsrefcnt count = ++mRefCnt;                                               \
+    return (nsrefcnt) count;                                                  \
+  }                                                                           \
+  NS_METHOD_(MozExternalRefCountType) Release(void) const {                   \
+    MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");                          \
+    nsrefcnt count = --mRefCnt;                                               \
+    if (count == 0) {                                                         \
+      delete (this);                                                          \
+      return 0;                                                               \
+    }                                                                         \
+    return count;                                                             \
+  }                                                                           \
+protected:                                                                    \
+  mutable ::mozilla::ThreadSafeAutoRefCnt mRefCnt;                            \
+public:
 
+class ObjectForConstPtr
+{
+private:
+  // Reference-counted classes cannot have public destructors.
+  ~ObjectForConstPtr()
+  {
+    printf("ObjectForConstPtr@%p::~ObjectForConstPtr()\n", static_cast<void*>(this));
+  }
+public:
+  NS_INLINE_DECL_THREADSAFE_MUTABLE_REFCOUNTING(ObjectForConstPtr)
+  void ConstMemberFunction( int aArg1, int* aArgPtr, int& aArgRef ) const
+  {
+    printf("const member function is invoked by nsRefPtr<const T>->*.\n");
+  }
+};
+#undef NS_INLINE_DECL_THREADSAFE_MUTABLE_REFCOUNTING
 
 
 nsRefPtr<Foo> gFoop;
 
 int
 main()
   {
     printf(">>main()\n");
@@ -385,17 +452,17 @@ main()
       if ( foo1p != 0 )
       	printf("foo1p != 0\n");
       if ( 0 != foo1p )
       	printf("0 != foo1p\n");
       if ( foo1p == 0 )
       	printf("foo1p == 0\n");
       if ( 0 == foo1p )
       	printf("0 == foo1p\n");
-			
+
 
       Foo* raw_foo2p = foo2p.get();
 
       printf("\n### Test  8: can you compare a |nsCOMPtr| with a raw interface pointer [!=]?\n");
       if ( foo1p.get() != raw_foo2p )
         printf("foo1p != raw_foo2p\n");
       else
         printf("foo1p == raw_foo2p\n");
@@ -544,13 +611,39 @@ main()
 
 			AnFooPtrPtrContext( getter_AddRefs(fooP) );
 			AVoidPtrPtrContext( getter_AddRefs(fooP) );
 		}
 
 
     printf("\n### Test 25: will a static |nsCOMPtr| |Release| before program termination?\n");
     gFoop = do_QueryObject(new Foo);
-    
+
+    {
+      printf("\n### setup for Test 26, 27, 28\n");
+      nsRefPtr<Foo> foop = new Foo;
+      nsRefPtr<Foo> foop2 = new Bar;
+      nsRefPtr<const ObjectForConstPtr> foop3 = new ObjectForConstPtr;
+      int test = 1;
+      void (Foo::*fPtr)( int, int*, int& ) = &Foo::MemberFunction;
+      void (Foo::*fVPtr)( int, int*, int& ) = &Foo::VirtualMemberFunction;
+      void (Foo::*fVCPtr)( int, int*, int& ) const = &Foo::VirtualConstMemberFunction;
+      void (ObjectForConstPtr::*fCPtr2)( int, int*, int& ) const = &ObjectForConstPtr::ConstMemberFunction;
+
+      printf("### Test 26: invoke member function via operator ->*\n");
+      (foop->*fPtr)(test, &test, test);
+      printf("### End Test 26\n");
+
+      printf("### Test 27: invoke virtual / virtual const member function via operator ->*\n");
+      (foop2->*fVPtr)(test, &test, test);
+      (foop2->*fVCPtr)(test, &test, test);
+      printf("### End Test 27\n");
+
+      printf("### Test 28: invoke virtual const member function via nsRefPtr<const T> operator ->*\n");
+      (foop3->*fCPtr2)(test, &test, test);
+      printf("### End Test 28\n");
+    }
+
+
     printf("<<main()\n");
     return 0;
   }