xpcom/reflect/xptinfo/src/xptiprivate.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /* Library-private header for Interface Info system. */
     8 #ifndef xptiprivate_h___
     9 #define xptiprivate_h___
    11 #include "nscore.h"
    12 #include <new>
    13 #include "nsISupports.h"
    15 // this after nsISupports, to pick up IID
    16 // so that xpt stuff doesn't try to define it itself...
    17 #include "xpt_struct.h"
    18 #include "xpt_xdr.h"
    20 #include "nsIInterfaceInfo.h"
    21 #include "nsIInterfaceInfoManager.h"
    22 #include "xptinfo.h"
    24 #include "nsIServiceManager.h"
    25 #include "nsIFile.h"
    26 #include "nsIDirectoryService.h"
    27 #include "nsDirectoryServiceDefs.h"
    28 #include "nsAppDirectoryServiceDefs.h"
    29 #include "nsIWeakReference.h"
    31 #include "mozilla/ReentrantMonitor.h"
    32 #include "mozilla/Mutex.h"
    33 #include "mozilla/Attributes.h"
    35 #include "nsCRT.h"
    36 #include "nsMemory.h"
    38 #include "nsCOMArray.h"
    39 #include "nsQuickSort.h"
    41 #include "nsXPIDLString.h"
    43 #include "nsIInputStream.h"
    45 #include "nsHashKeys.h"
    46 #include "nsDataHashtable.h"
    47 #include "plstr.h"
    48 #include "prprf.h"
    49 #include "prio.h"
    50 #include "prtime.h"
    51 #include "prenv.h"
    53 #include <stdio.h>
    54 #include <stdarg.h>
    56 /***************************************************************************/
    58 #if 0 && defined(DEBUG_jband)
    59 #define LOG_RESOLVE(x) printf x
    60 #define LOG_LOAD(x)    printf x
    61 #define LOG_AUTOREG(x) do{printf x; xptiInterfaceInfoManager::WriteToLog x;}while(0)
    62 #else
    63 #define LOG_RESOLVE(x) ((void)0)
    64 #define LOG_LOAD(x)    ((void)0)
    65 #define LOG_AUTOREG(x) ((void)0)
    66 #endif
    68 #if 1 && defined(DEBUG_jband)
    69 #define SHOW_INFO_COUNT_STATS
    70 #endif
    72 /***************************************************************************/
    74 class xptiInterfaceInfo;
    75 class xptiInterfaceEntry;
    76 class xptiTypelibGuts;
    78 extern XPTArena* gXPTIStructArena;
    80 /***************************************************************************/
    82 /***************************************************************************/
    84 // No virtuals.
    85 // These are always constructed in the struct arena using placement new.
    86 // dtor need not be called.
    88 class xptiTypelibGuts
    89 {
    90 public:
    91     static xptiTypelibGuts* Create(XPTHeader* aHeader);
    93     XPTHeader*          GetHeader()           {return mHeader;}
    94     uint16_t            GetEntryCount() const {return mHeader->num_interfaces;}
    96     void                SetEntryAt(uint16_t i, xptiInterfaceEntry* ptr)
    97     {
    98         NS_ASSERTION(mHeader,"bad state!");
    99         NS_ASSERTION(i < GetEntryCount(),"bad param!");
   100         mEntryArray[i] = ptr;
   101     }        
   103     xptiInterfaceEntry* GetEntryAt(uint16_t i);
   105 private:
   106     xptiTypelibGuts(XPTHeader* aHeader)
   107         : mHeader(aHeader)
   108     { }
   109     ~xptiTypelibGuts();
   111 private:
   112     XPTHeader*           mHeader;        // hold pointer into arena
   113     xptiInterfaceEntry*  mEntryArray[1]; // Always last. Sized to fit.
   114 };
   116 /***************************************************************************/
   118 /***************************************************************************/
   120 // This class exists to help xptiInterfaceInfo store a 4-state (2 bit) value 
   121 // and a set of bitflags in one 8bit value. See below.
   123 class xptiInfoFlags
   124 {
   125     enum {STATE_MASK = 3};
   126 public:
   127     xptiInfoFlags(uint8_t n) : mData(n) {}
   128     xptiInfoFlags(const xptiInfoFlags& r) : mData(r.mData) {}
   130     static uint8_t GetStateMask()
   131         {return uint8_t(STATE_MASK);}
   133     void Clear()
   134         {mData = 0;}
   136     uint8_t GetData() const
   137         {return mData;}
   139     uint8_t GetState() const 
   140         {return mData & GetStateMask();}
   142     void SetState(uint8_t state) 
   143         {mData &= ~GetStateMask(); mData |= state;}                                   
   145     void SetFlagBit(uint8_t flag, bool on) 
   146         {if(on)
   147             mData |= ~GetStateMask() & flag;
   148          else
   149             mData &= GetStateMask() | ~flag;}
   151     bool GetFlagBit(uint8_t flag) const 
   152         {return (mData & flag) ? true : false;}
   154 private:
   155     uint8_t mData;    
   156 };
   158 /****************************************************/
   160 // No virtual methods.
   161 // We always create in the struct arena and construct using "placement new".
   162 // No members need dtor calls.
   164 class xptiInterfaceEntry
   165 {
   166 public:
   167     static xptiInterfaceEntry* Create(const char* name,
   168                                       const nsID& iid,
   169                                       XPTInterfaceDescriptor* aDescriptor,
   170                                       xptiTypelibGuts* aTypelib);
   172     enum {
   173         PARTIALLY_RESOLVED    = 1,
   174         FULLY_RESOLVED        = 2,
   175         RESOLVE_FAILED        = 3
   176     };
   178     // Additional bit flags...
   179     enum {SCRIPTABLE = 4, BUILTINCLASS = 8};
   181     uint8_t GetResolveState() const {return mFlags.GetState();}
   183     bool IsFullyResolved() const 
   184         {return GetResolveState() == (uint8_t) FULLY_RESOLVED;}
   186     void   SetScriptableFlag(bool on)
   187                 {mFlags.SetFlagBit(uint8_t(SCRIPTABLE),on);}
   188     bool GetScriptableFlag() const
   189                 {return mFlags.GetFlagBit(uint8_t(SCRIPTABLE));}
   190     void   SetBuiltinClassFlag(bool on)
   191                 {mFlags.SetFlagBit(uint8_t(BUILTINCLASS),on);}
   192     bool GetBuiltinClassFlag() const
   193                 {return mFlags.GetFlagBit(uint8_t(BUILTINCLASS));}
   195     const nsID* GetTheIID()  const {return &mIID;}
   196     const char* GetTheName() const {return mName;}
   198     bool EnsureResolved()
   199         {return IsFullyResolved() ? true : Resolve();}
   201     already_AddRefed<xptiInterfaceInfo> InterfaceInfo();
   202     bool     InterfaceInfoEquals(const xptiInterfaceInfo* info) const 
   203         {return info == mInfo;}
   205     void     LockedInvalidateInterfaceInfo();
   206     void     LockedInterfaceInfoDeathNotification() {mInfo = nullptr;}
   208     xptiInterfaceEntry* Parent() const {
   209         NS_ASSERTION(IsFullyResolved(), "Parent() called while not resolved?");
   210         return mParent;
   211     }
   213     const nsID& IID() const { return mIID; }
   215     //////////////////////
   216     // These non-virtual methods handle the delegated nsIInterfaceInfo methods.
   218     nsresult GetName(char * *aName);
   219     nsresult GetIID(nsIID * *aIID);
   220     nsresult IsScriptable(bool *_retval);
   221     nsresult IsBuiltinClass(bool *_retval) {
   222         *_retval = GetBuiltinClassFlag();
   223         return NS_OK;
   224     }
   225     // Except this one.
   226     //nsresult GetParent(nsIInterfaceInfo * *aParent);
   227     nsresult GetMethodCount(uint16_t *aMethodCount);
   228     nsresult GetConstantCount(uint16_t *aConstantCount);
   229     nsresult GetMethodInfo(uint16_t index, const nsXPTMethodInfo * *info);
   230     nsresult GetMethodInfoForName(const char *methodName, uint16_t *index, const nsXPTMethodInfo * *info);
   231     nsresult GetConstant(uint16_t index, const nsXPTConstant * *constant);
   232     nsresult GetInfoForParam(uint16_t methodIndex, const nsXPTParamInfo * param, nsIInterfaceInfo **_retval);
   233     nsresult GetIIDForParam(uint16_t methodIndex, const nsXPTParamInfo * param, nsIID * *_retval);
   234     nsresult GetTypeForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint16_t dimension, nsXPTType *_retval);
   235     nsresult GetSizeIsArgNumberForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint16_t dimension, uint8_t *_retval);
   236     nsresult GetInterfaceIsArgNumberForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint8_t *_retval);
   237     nsresult IsIID(const nsIID * IID, bool *_retval);
   238     nsresult GetNameShared(const char **name);
   239     nsresult GetIIDShared(const nsIID * *iid);
   240     nsresult IsFunction(bool *_retval);
   241     nsresult HasAncestor(const nsIID * iid, bool *_retval);
   242     nsresult GetIIDForParamNoAlloc(uint16_t methodIndex, const nsXPTParamInfo * param, nsIID *iid);
   244 private:
   245     xptiInterfaceEntry(const char* name,
   246                        size_t nameLength,
   247                        const nsID& iid,
   248                        XPTInterfaceDescriptor* aDescriptor,
   249                        xptiTypelibGuts* aTypelib);
   250     ~xptiInterfaceEntry();
   252     void SetResolvedState(int state) 
   253         {mFlags.SetState(uint8_t(state));}
   255     bool Resolve();
   257     // We only call these "*Locked" variants after locking. This is done to 
   258     // allow reentrace as files are loaded and various interfaces resolved 
   259     // without having to worry about the locked state.
   261     bool EnsureResolvedLocked()
   262         {return IsFullyResolved() ? true : ResolveLocked();}
   263     bool ResolveLocked();
   265     // private helpers
   267     nsresult GetEntryForParam(uint16_t methodIndex, 
   268                               const nsXPTParamInfo * param,
   269                               xptiInterfaceEntry** entry);
   271     nsresult GetTypeInArray(const nsXPTParamInfo* param,
   272                             uint16_t dimension,
   273                             const XPTTypeDescriptor** type);
   275 private:
   276     nsID                    mIID;
   277     XPTInterfaceDescriptor* mDescriptor;
   279     uint16_t mMethodBaseIndex;
   280     uint16_t mConstantBaseIndex;
   281     xptiTypelibGuts* mTypelib;
   283     xptiInterfaceEntry*     mParent;      // Valid only when fully resolved
   285     xptiInterfaceInfo*      mInfo;        // May come and go.
   286     xptiInfoFlags           mFlags;
   287     char                    mName[1];     // Always last. Sized to fit.
   288 };
   290 class xptiInterfaceInfo MOZ_FINAL : public nsIInterfaceInfo
   291 {
   292 public:
   293     NS_DECL_THREADSAFE_ISUPPORTS
   295     // Use delegation to implement (most!) of nsIInterfaceInfo.
   296     NS_IMETHOD GetName(char * *aName) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetName(aName); }
   297     NS_IMETHOD GetInterfaceIID(nsIID * *aIID) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIID(aIID); }
   298     NS_IMETHOD IsScriptable(bool *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsScriptable(_retval); }
   299     NS_IMETHOD IsBuiltinClass(bool *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsBuiltinClass(_retval); }
   300     // Except this one.
   301     NS_IMETHOD GetParent(nsIInterfaceInfo * *aParent) 
   302     {
   303         if(!EnsureResolved() || !EnsureParent())
   304             return NS_ERROR_UNEXPECTED;
   305         NS_IF_ADDREF(*aParent = mParent);
   306         return NS_OK;
   307     }
   308     NS_IMETHOD GetMethodCount(uint16_t *aMethodCount) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetMethodCount(aMethodCount); }
   309     NS_IMETHOD GetConstantCount(uint16_t *aConstantCount) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetConstantCount(aConstantCount); }
   310     NS_IMETHOD GetMethodInfo(uint16_t index, const nsXPTMethodInfo * *info) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetMethodInfo(index, info); }
   311     NS_IMETHOD GetMethodInfoForName(const char *methodName, uint16_t *index, const nsXPTMethodInfo * *info) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetMethodInfoForName(methodName, index, info); }
   312     NS_IMETHOD GetConstant(uint16_t index, const nsXPTConstant * *constant) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetConstant(index, constant); }
   313     NS_IMETHOD GetInfoForParam(uint16_t methodIndex, const nsXPTParamInfo * param, nsIInterfaceInfo **_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetInfoForParam(methodIndex, param, _retval); }
   314     NS_IMETHOD GetIIDForParam(uint16_t methodIndex, const nsXPTParamInfo * param, nsIID * *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIIDForParam(methodIndex, param, _retval); }
   315     NS_IMETHOD GetTypeForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint16_t dimension, nsXPTType *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetTypeForParam(methodIndex, param, dimension, _retval); }
   316     NS_IMETHOD GetSizeIsArgNumberForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint16_t dimension, uint8_t *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetSizeIsArgNumberForParam(methodIndex, param, dimension, _retval); }
   317     NS_IMETHOD GetInterfaceIsArgNumberForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint8_t *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetInterfaceIsArgNumberForParam(methodIndex, param, _retval); }
   318     NS_IMETHOD IsIID(const nsIID * IID, bool *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsIID(IID, _retval); }
   319     NS_IMETHOD GetNameShared(const char **name) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetNameShared(name); }
   320     NS_IMETHOD GetIIDShared(const nsIID * *iid) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIIDShared(iid); }
   321     NS_IMETHOD IsFunction(bool *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsFunction(_retval); }
   322     NS_IMETHOD HasAncestor(const nsIID * iid, bool *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->HasAncestor(iid, _retval); }
   323     NS_IMETHOD GetIIDForParamNoAlloc(uint16_t methodIndex, const nsXPTParamInfo * param, nsIID *iid) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIIDForParamNoAlloc(methodIndex, param, iid); }
   325 public:
   326     xptiInterfaceInfo(xptiInterfaceEntry* entry);
   328     void Invalidate() 
   329         {NS_IF_RELEASE(mParent); mEntry = nullptr;}
   331 private:
   333     ~xptiInterfaceInfo();
   335     // Note that mParent might still end up as nullptr if we don't have one.
   336     bool EnsureParent()
   337     {
   338         NS_ASSERTION(mEntry && mEntry->IsFullyResolved(), "bad EnsureParent call");
   339         return mParent || !mEntry->Parent() || BuildParent();
   340     }
   342     bool EnsureResolved()
   343     {
   344         return mEntry && mEntry->EnsureResolved();
   345     }
   347     bool BuildParent();
   349     xptiInterfaceInfo();  // not implemented
   351 private:
   352     xptiInterfaceEntry* mEntry;
   353     xptiInterfaceInfo*  mParent;
   354 };
   356 /***************************************************************************/
   358 #endif /* xptiprivate_h___ */

mercurial