js/xpconnect/src/xpcprivate.h

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* vim: set ts=8 sts=4 et sw=4 tw=99: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /*
     8  * XPConnect allows JS code to manipulate C++ object and C++ code to manipulate
     9  * JS objects. JS manipulation of C++ objects tends to be significantly more
    10  * complex. This comment explains how it is orchestrated by XPConnect.
    11  *
    12  * For each C++ object to be manipulated in JS, there is a corresponding JS
    13  * object. This is called the "flattened JS object". By default, there is an
    14  * additional C++ object involved of type XPCWrappedNative. The XPCWrappedNative
    15  * holds pointers to the C++ object and the flat JS object.
    16  *
    17  * All XPCWrappedNative objects belong to an XPCWrappedNativeScope. These scopes
    18  * are essentially in 1:1 correspondence with JS global objects. The
    19  * XPCWrappedNativeScope has a pointer to the JS global object. The parent of a
    20  * flattened JS object is, by default, the global JS object corresponding to the
    21  * wrapper's XPCWrappedNativeScope (the exception to this rule is when a
    22  * PreCreate hook asks for a different parent; see nsIXPCScriptable below).
    23  *
    24  * Some C++ objects (notably DOM objects) have information associated with them
    25  * that lists the interfaces implemented by these objects. A C++ object exposes
    26  * this information by implementing nsIClassInfo. If a C++ object implements
    27  * nsIClassInfo, then JS code can call its methods without needing to use
    28  * QueryInterface first. Typically, all instances of a C++ class share the same
    29  * nsIClassInfo instance. (That is, obj->QueryInterface(nsIClassInfo) returns
    30  * the same result for every obj of a given class.)
    31  *
    32  * XPConnect tracks nsIClassInfo information in an XPCWrappedNativeProto object.
    33  * A given XPCWrappedNativeScope will have one XPCWrappedNativeProto for each
    34  * nsIClassInfo instance being used. The XPCWrappedNativeProto has an associated
    35  * JS object, which is used as the prototype of all flattened JS objects created
    36  * for C++ objects with the given nsIClassInfo.
    37  *
    38  * Each XPCWrappedNativeProto has a pointer to its XPCWrappedNativeScope. If an
    39  * XPCWrappedNative wraps a C++ object with class info, then it points to its
    40  * XPCWrappedNativeProto. Otherwise it points to its XPCWrappedNativeScope. (The
    41  * pointers are smooshed together in a tagged union.) Either way it can reach
    42  * its scope.
    43  *
    44  * An XPCWrappedNativeProto keeps track of the set of interfaces implemented by
    45  * the C++ object in an XPCNativeSet. (The list of interfaces is obtained by
    46  * calling a method on the nsIClassInfo.) An XPCNativeSet is a collection of
    47  * XPCNativeInterfaces. Each interface stores the list of members, which can be
    48  * methods, constants, getters, or setters.
    49  *
    50  * An XPCWrappedNative also points to an XPCNativeSet. Initially this starts out
    51  * the same as the XPCWrappedNativeProto's set. If there is no proto, it starts
    52  * out as a singleton set containing nsISupports. If JS code QI's new interfaces
    53  * outside of the existing set, the set will grow. All QueryInterface results
    54  * are cached in XPCWrappedNativeTearOff objects, which are linked off of the
    55  * XPCWrappedNative.
    56  *
    57  * Besides having class info, a C++ object may be "scriptable" (i.e., implement
    58  * nsIXPCScriptable). This allows it to implement a more DOM-like interface,
    59  * besides just exposing XPCOM methods and constants. An nsIXPCScriptable
    60  * instance has hooks that correspond to all the normal JSClass hooks. Each
    61  * nsIXPCScriptable instance is mirrored by an XPCNativeScriptableInfo in
    62  * XPConnect. These can have pointers from XPCWrappedNativeProto and
    63  * XPCWrappedNative (since C++ objects can have scriptable info without having
    64  * class info).
    65  *
    66  * Most data in an XPCNativeScriptableInfo is shared between instances. The
    67  * shared data is stored in an XPCNativeScriptableShared object. This type is
    68  * important because it holds the JSClass of the flattened JS objects with the
    69  * given scriptable info.
    70  */
    72 /* All the XPConnect private declarations - only include locally. */
    74 #ifndef xpcprivate_h___
    75 #define xpcprivate_h___
    77 #include "mozilla/Alignment.h"
    78 #include "mozilla/Assertions.h"
    79 #include "mozilla/Attributes.h"
    80 #include "mozilla/CycleCollectedJSRuntime.h"
    81 #include "mozilla/GuardObjects.h"
    82 #include "mozilla/Maybe.h"
    83 #include "mozilla/MemoryReporting.h"
    84 #include "mozilla/TimeStamp.h"
    86 #include <math.h>
    87 #include <stdint.h>
    88 #include <stdlib.h>
    89 #include <string.h>
    91 #include "xpcpublic.h"
    92 #include "js/TracingAPI.h"
    93 #include "js/WeakMapPtr.h"
    94 #include "pldhash.h"
    95 #include "nscore.h"
    96 #include "nsXPCOM.h"
    97 #include "nsAutoPtr.h"
    98 #include "nsCycleCollectionParticipant.h"
    99 #include "nsDebug.h"
   100 #include "nsISupports.h"
   101 #include "nsIServiceManager.h"
   102 #include "nsIClassInfoImpl.h"
   103 #include "nsIComponentManager.h"
   104 #include "nsIComponentRegistrar.h"
   105 #include "nsISupportsPrimitives.h"
   106 #include "nsMemory.h"
   107 #include "nsIXPConnect.h"
   108 #include "nsIInterfaceInfo.h"
   109 #include "nsIXPCScriptable.h"
   110 #include "nsIXPCSecurityManager.h"
   111 #include "nsIJSRuntimeService.h"
   112 #include "nsWeakReference.h"
   113 #include "nsCOMPtr.h"
   114 #include "nsXPTCUtils.h"
   115 #include "xptinfo.h"
   116 #include "XPCForwards.h"
   117 #include "XPCLog.h"
   118 #include "xpccomponents.h"
   119 #include "xpcexception.h"
   120 #include "xpcjsid.h"
   121 #include "prenv.h"
   122 #include "prclist.h"
   123 #include "prcvar.h"
   124 #include "nsString.h"
   125 #include "nsReadableUtils.h"
   126 #include "nsXPIDLString.h"
   127 #include "nsAutoJSValHolder.h"
   129 #include "MainThreadUtils.h"
   131 #include "nsIConsoleService.h"
   132 #include "nsIScriptError.h"
   133 #include "nsIException.h"
   135 #include "nsVariant.h"
   136 #include "nsIPropertyBag.h"
   137 #include "nsIProperty.h"
   138 #include "nsCOMArray.h"
   139 #include "nsTArray.h"
   140 #include "nsBaseHashtable.h"
   141 #include "nsHashKeys.h"
   142 #include "nsWrapperCache.h"
   143 #include "nsStringBuffer.h"
   144 #include "nsDataHashtable.h"
   145 #include "nsDeque.h"
   147 #include "nsIScriptSecurityManager.h"
   148 #include "nsNetUtil.h"
   150 #include "nsIPrincipal.h"
   151 #include "nsJSPrincipals.h"
   152 #include "nsIScriptObjectPrincipal.h"
   153 #include "xpcObjectHelper.h"
   154 #include "nsIThreadInternal.h"
   156 #include "SandboxPrivate.h"
   157 #include "BackstagePass.h"
   158 #include "nsCxPusher.h"
   159 #include "nsAXPCNativeCallContext.h"
   161 #ifdef XP_WIN
   162 // Nasty MS defines
   163 #ifdef GetClassInfo
   164 #undef GetClassInfo
   165 #endif
   166 #ifdef GetClassName
   167 #undef GetClassName
   168 #endif
   169 #endif /* XP_WIN */
   171 #include "nsINode.h"
   173 /***************************************************************************/
   174 // default initial sizes for maps (hashtables)
   176 #define XPC_CONTEXT_MAP_SIZE                16
   177 #define XPC_JS_MAP_SIZE                     64
   178 #define XPC_JS_CLASS_MAP_SIZE               64
   180 #define XPC_NATIVE_MAP_SIZE                 64
   181 #define XPC_NATIVE_PROTO_MAP_SIZE           16
   182 #define XPC_DYING_NATIVE_PROTO_MAP_SIZE     16
   183 #define XPC_DETACHED_NATIVE_PROTO_MAP_SIZE  32
   184 #define XPC_NATIVE_INTERFACE_MAP_SIZE       64
   185 #define XPC_NATIVE_SET_MAP_SIZE             64
   186 #define XPC_NATIVE_JSCLASS_MAP_SIZE         32
   187 #define XPC_THIS_TRANSLATOR_MAP_SIZE         8
   188 #define XPC_NATIVE_WRAPPER_MAP_SIZE         16
   189 #define XPC_WRAPPER_MAP_SIZE                16
   191 /***************************************************************************/
   192 // data declarations...
   193 extern const char XPC_CONTEXT_STACK_CONTRACTID[];
   194 extern const char XPC_RUNTIME_CONTRACTID[];
   195 extern const char XPC_EXCEPTION_CONTRACTID[];
   196 extern const char XPC_CONSOLE_CONTRACTID[];
   197 extern const char XPC_SCRIPT_ERROR_CONTRACTID[];
   198 extern const char XPC_ID_CONTRACTID[];
   199 extern const char XPC_XPCONNECT_CONTRACTID[];
   201 /***************************************************************************/
   202 // Useful macros...
   204 #define XPC_STRING_GETTER_BODY(dest, src)                                     \
   205     NS_ENSURE_ARG_POINTER(dest);                                              \
   206     char* result;                                                             \
   207     if (src)                                                                  \
   208         result = (char*) nsMemory::Clone(src,                                 \
   209                                          sizeof(char)*(strlen(src)+1));       \
   210     else                                                                      \
   211         result = nullptr;                                                      \
   212     *dest = result;                                                           \
   213     return (result || !src) ? NS_OK : NS_ERROR_OUT_OF_MEMORY
   216 #define WRAPPER_SLOTS (JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS )
   218 #define INVALID_OBJECT ((JSObject *)1)
   220 // If IS_WN_CLASS for the JSClass of an object is true, the object is a
   221 // wrappednative wrapper, holding the XPCWrappedNative in its private slot.
   222 static inline bool IS_WN_CLASS(const js::Class* clazz)
   223 {
   224     return clazz->ext.isWrappedNative;
   225 }
   227 static inline bool IS_WN_REFLECTOR(JSObject *obj)
   228 {
   229     return IS_WN_CLASS(js::GetObjectClass(obj));
   230 }
   232 /***************************************************************************
   233 ****************************************************************************
   234 *
   235 * Core runtime and context classes...
   236 *
   237 ****************************************************************************
   238 ***************************************************************************/
   240 // We have a general rule internally that getters that return addref'd interface
   241 // pointer generally do so using an 'out' parm. When interface pointers are
   242 // returned as function call result values they are not addref'd. Exceptions
   243 // to this rule are noted explicitly.
   245 inline bool
   246 AddToCCKind(JSGCTraceKind kind)
   247 {
   248     return kind == JSTRACE_OBJECT || kind == JSTRACE_SCRIPT;
   249 }
   251 class nsXPConnect : public nsIXPConnect,
   252                     public nsIThreadObserver,
   253                     public nsSupportsWeakReference,
   254                     public nsIJSRuntimeService
   255 {
   256 public:
   257     // all the interface method declarations...
   258     NS_DECL_ISUPPORTS
   259     NS_DECL_NSIXPCONNECT
   260     NS_DECL_NSITHREADOBSERVER
   261     NS_DECL_NSIJSRUNTIMESERVICE
   263     // non-interface implementation
   264 public:
   265     // These get non-addref'd pointers
   266     static nsXPConnect*  XPConnect()
   267     {
   268         // Do a release-mode assert that we're not doing anything significant in
   269         // XPConnect off the main thread. If you're an extension developer hitting
   270         // this, you need to change your code. See bug 716167.
   271         if (!MOZ_LIKELY(NS_IsMainThread()))
   272             MOZ_CRASH();
   274         return gSelf;
   275     }
   277     static XPCJSRuntime* GetRuntimeInstance();
   278     XPCJSRuntime* GetRuntime() {return mRuntime;}
   280     static bool IsISupportsDescendant(nsIInterfaceInfo* info);
   282     nsIXPCSecurityManager* GetDefaultSecurityManager() const
   283     {
   284         // mDefaultSecurityManager is main-thread only.
   285         if (!NS_IsMainThread()) {
   286             return nullptr;
   287         }
   288         return mDefaultSecurityManager;
   289     }
   291     // This returns an AddRef'd pointer. It does not do this with an 'out' param
   292     // only because this form is required by the generic module macro:
   293     // NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
   294     static nsXPConnect* GetSingleton();
   296     // Called by module code in dll startup
   297     static void InitStatics();
   298     // Called by module code on dll shutdown.
   299     static void ReleaseXPConnectSingleton();
   301     virtual ~nsXPConnect();
   303     bool IsShuttingDown() const {return mShuttingDown;}
   305     nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info);
   306     nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info);
   308     virtual nsIPrincipal* GetPrincipal(JSObject* obj,
   309                                        bool allowShortCircuit) const;
   311     void RecordTraversal(void *p, nsISupports *s);
   312     virtual char* DebugPrintJSStack(bool showArgs,
   313                                     bool showLocals,
   314                                     bool showThisProps);
   317     static bool ReportAllJSExceptions()
   318     {
   319       return gReportAllJSExceptions > 0;
   320     }
   322     static void CheckForDebugMode(JSRuntime *rt);
   324 protected:
   325     nsXPConnect();
   327 private:
   328     // Singleton instance
   329     static nsXPConnect*             gSelf;
   330     static bool                     gOnceAliveNowDead;
   332     XPCJSRuntime*                   mRuntime;
   333     nsRefPtr<nsIXPCSecurityManager> mDefaultSecurityManager;
   334     bool                            mShuttingDown;
   336     // nsIThreadInternal doesn't remember which observers it called
   337     // OnProcessNextEvent on when it gets around to calling AfterProcessNextEvent.
   338     // So if XPConnect gets initialized mid-event (which can happen), we'll get
   339     // an 'after' notification without getting an 'on' notification. If we don't
   340     // watch out for this, we'll do an unmatched |pop| on the context stack.
   341     uint16_t                 mEventDepth;
   343     static uint32_t gReportAllJSExceptions;
   345 public:
   346     static nsIScriptSecurityManager *gScriptSecurityManager;
   347 };
   349 /***************************************************************************/
   351 class XPCRootSetElem
   352 {
   353 public:
   354     XPCRootSetElem()
   355     {
   356 #ifdef DEBUG
   357         mNext = nullptr;
   358         mSelfp = nullptr;
   359 #endif
   360     }
   362     ~XPCRootSetElem()
   363     {
   364         MOZ_ASSERT(!mNext, "Must be unlinked");
   365         MOZ_ASSERT(!mSelfp, "Must be unlinked");
   366     }
   368     inline XPCRootSetElem* GetNextRoot() { return mNext; }
   369     void AddToRootSet(XPCRootSetElem **listHead);
   370     void RemoveFromRootSet();
   372 private:
   373     XPCRootSetElem *mNext;
   374     XPCRootSetElem **mSelfp;
   375 };
   377 /***************************************************************************/
   379 // In the current xpconnect system there can only be one XPCJSRuntime.
   380 // So, xpconnect can only be used on one JSRuntime within the process.
   382 class XPCJSContextStack;
   383 class WatchdogManager;
   385 enum WatchdogTimestampCategory
   386 {
   387     TimestampRuntimeStateChange = 0,
   388     TimestampWatchdogWakeup,
   389     TimestampWatchdogHibernateStart,
   390     TimestampWatchdogHibernateStop,
   391     TimestampCount
   392 };
   394 class AsyncFreeSnowWhite;
   396 class XPCJSRuntime : public mozilla::CycleCollectedJSRuntime
   397 {
   398 public:
   399     static XPCJSRuntime* newXPCJSRuntime(nsXPConnect* aXPConnect);
   400     static XPCJSRuntime* Get() { return nsXPConnect::XPConnect()->GetRuntime(); }
   402     XPCJSContextStack* GetJSContextStack() {return mJSContextStack;}
   403     void DestroyJSContextStack();
   405     XPCCallContext*  GetCallContext() const {return mCallContext;}
   406     XPCCallContext*  SetCallContext(XPCCallContext* ccx)
   407         {XPCCallContext* old = mCallContext; mCallContext = ccx; return old;}
   409     jsid GetResolveName() const {return mResolveName;}
   410     jsid SetResolveName(jsid name)
   411         {jsid old = mResolveName; mResolveName = name; return old;}
   413     XPCWrappedNative* GetResolvingWrapper() const {return mResolvingWrapper;}
   414     XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w)
   415         {XPCWrappedNative* old = mResolvingWrapper;
   416          mResolvingWrapper = w; return old;}
   418     JSObject2WrappedJSMap*     GetWrappedJSMap()        const
   419         {return mWrappedJSMap;}
   421     IID2WrappedJSClassMap*     GetWrappedJSClassMap()   const
   422         {return mWrappedJSClassMap;}
   424     IID2NativeInterfaceMap* GetIID2NativeInterfaceMap() const
   425         {return mIID2NativeInterfaceMap;}
   427     ClassInfo2NativeSetMap* GetClassInfo2NativeSetMap() const
   428         {return mClassInfo2NativeSetMap;}
   430     NativeSetMap* GetNativeSetMap() const
   431         {return mNativeSetMap;}
   433     IID2ThisTranslatorMap* GetThisTranslatorMap() const
   434         {return mThisTranslatorMap;}
   436     XPCNativeScriptableSharedMap* GetNativeScriptableSharedMap() const
   437         {return mNativeScriptableSharedMap;}
   439     XPCWrappedNativeProtoMap* GetDyingWrappedNativeProtoMap() const
   440         {return mDyingWrappedNativeProtoMap;}
   442     XPCWrappedNativeProtoMap* GetDetachedWrappedNativeProtoMap() const
   443         {return mDetachedWrappedNativeProtoMap;}
   445     bool OnJSContextNew(JSContext* cx);
   447     virtual bool
   448     DescribeCustomObjects(JSObject* aObject, const js::Class* aClasp,
   449                           char (&aName)[72]) const MOZ_OVERRIDE;
   450     virtual bool
   451     NoteCustomGCThingXPCOMChildren(const js::Class* aClasp, JSObject* aObj,
   452                                    nsCycleCollectionTraversalCallback& aCb) const MOZ_OVERRIDE;
   454     /**
   455      * Infrastructure for classes that need to defer part of the finalization
   456      * until after the GC has run, for example for objects that we don't want to
   457      * destroy during the GC.
   458      */
   460 public:
   461     bool GetDoingFinalization() const {return mDoingFinalization;}
   463     // Mapping of often used strings to jsid atoms that live 'forever'.
   464     //
   465     // To add a new string: add to this list and to XPCJSRuntime::mStrings
   466     // at the top of xpcjsruntime.cpp
   467     enum {
   468         IDX_CONSTRUCTOR             = 0 ,
   469         IDX_TO_STRING               ,
   470         IDX_TO_SOURCE               ,
   471         IDX_LAST_RESULT             ,
   472         IDX_RETURN_CODE             ,
   473         IDX_VALUE                   ,
   474         IDX_QUERY_INTERFACE         ,
   475         IDX_COMPONENTS              ,
   476         IDX_WRAPPED_JSOBJECT        ,
   477         IDX_OBJECT                  ,
   478         IDX_FUNCTION                ,
   479         IDX_PROTOTYPE               ,
   480         IDX_CREATE_INSTANCE         ,
   481         IDX_ITEM                    ,
   482         IDX_PROTO                   ,
   483         IDX_ITERATOR                ,
   484         IDX_EXPOSEDPROPS            ,
   485         IDX_EVAL                    ,
   486         IDX_CONTROLLERS             ,
   487         IDX_TOTAL_COUNT // just a count of the above
   488     };
   490     JS::HandleId GetStringID(unsigned index) const
   491     {
   492         MOZ_ASSERT(index < IDX_TOTAL_COUNT, "index out of range");
   493         // fromMarkedLocation() is safe because the string is interned.
   494         return JS::HandleId::fromMarkedLocation(&mStrIDs[index]);
   495     }
   496     JS::HandleValue GetStringJSVal(unsigned index) const
   497     {
   498         MOZ_ASSERT(index < IDX_TOTAL_COUNT, "index out of range");
   499         // fromMarkedLocation() is safe because the string is interned.
   500         return JS::HandleValue::fromMarkedLocation(&mStrJSVals[index]);
   501     }
   502     const char* GetStringName(unsigned index) const
   503     {
   504         MOZ_ASSERT(index < IDX_TOTAL_COUNT, "index out of range");
   505         return mStrings[index];
   506     }
   508     void TraceNativeBlackRoots(JSTracer* trc) MOZ_OVERRIDE;
   509     void TraceAdditionalNativeGrayRoots(JSTracer* aTracer) MOZ_OVERRIDE;
   510     void TraverseAdditionalNativeRoots(nsCycleCollectionNoteRootCallback& cb) MOZ_OVERRIDE;
   511     void UnmarkSkippableJSHolders();
   512     void PrepareForForgetSkippable() MOZ_OVERRIDE;
   513     void BeginCycleCollectionCallback() MOZ_OVERRIDE;
   514     void EndCycleCollectionCallback(mozilla::CycleCollectorResults &aResults) MOZ_OVERRIDE;
   515     void DispatchDeferredDeletion(bool continuation) MOZ_OVERRIDE;
   517     void CustomGCCallback(JSGCStatus status) MOZ_OVERRIDE;
   518     bool CustomContextCallback(JSContext *cx, unsigned operation) MOZ_OVERRIDE;
   519     static void GCSliceCallback(JSRuntime *rt,
   520                                 JS::GCProgress progress,
   521                                 const JS::GCDescription &desc);
   522     static void FinalizeCallback(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartmentGC);
   524     inline void AddVariantRoot(XPCTraceableVariant* variant);
   525     inline void AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS);
   526     inline void AddObjectHolderRoot(XPCJSObjectHolder* holder);
   528     static void SuspectWrappedNative(XPCWrappedNative *wrapper,
   529                                      nsCycleCollectionNoteRootCallback &cb);
   531     void DebugDump(int16_t depth);
   533     void SystemIsBeingShutDown();
   535     bool GCIsRunning() const {return mGCIsRunning;}
   537     ~XPCJSRuntime();
   539     nsString* NewShortLivedString();
   540     void DeleteShortLivedString(nsString *string);
   542     void AddGCCallback(xpcGCCallback cb);
   543     void RemoveGCCallback(xpcGCCallback cb);
   544     void AddContextCallback(xpcContextCallback cb);
   545     void RemoveContextCallback(xpcContextCallback cb);
   547     static JSContext* DefaultJSContextCallback(JSRuntime *rt);
   548     static void ActivityCallback(void *arg, bool active);
   549     static void CTypesActivityCallback(JSContext *cx,
   550                                        js::CTypesActivityType type);
   551     static bool InterruptCallback(JSContext *cx);
   552     static void OutOfMemoryCallback(JSContext *cx);
   554     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
   556     AutoMarkingPtr**  GetAutoRootsAdr() {return &mAutoRoots;}
   558     JSObject* GetJunkScope();
   559     JSObject* GetCompilationScope();
   560     void DeleteSingletonScopes();
   562     PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory);
   563     void OnAfterProcessNextEvent() { mSlowScriptCheckpoint = mozilla::TimeStamp(); }
   565 private:
   566     XPCJSRuntime(); // no implementation
   567     XPCJSRuntime(nsXPConnect* aXPConnect);
   569     void ReleaseIncrementally(nsTArray<nsISupports *> &array);
   571     static const char* const mStrings[IDX_TOTAL_COUNT];
   572     jsid mStrIDs[IDX_TOTAL_COUNT];
   573     jsval mStrJSVals[IDX_TOTAL_COUNT];
   575     XPCJSContextStack*       mJSContextStack;
   576     XPCCallContext*          mCallContext;
   577     AutoMarkingPtr*          mAutoRoots;
   578     jsid                     mResolveName;
   579     XPCWrappedNative*        mResolvingWrapper;
   580     JSObject2WrappedJSMap*   mWrappedJSMap;
   581     IID2WrappedJSClassMap*   mWrappedJSClassMap;
   582     IID2NativeInterfaceMap*  mIID2NativeInterfaceMap;
   583     ClassInfo2NativeSetMap*  mClassInfo2NativeSetMap;
   584     NativeSetMap*            mNativeSetMap;
   585     IID2ThisTranslatorMap*   mThisTranslatorMap;
   586     XPCNativeScriptableSharedMap* mNativeScriptableSharedMap;
   587     XPCWrappedNativeProtoMap* mDyingWrappedNativeProtoMap;
   588     XPCWrappedNativeProtoMap* mDetachedWrappedNativeProtoMap;
   589     bool mGCIsRunning;
   590     nsTArray<nsXPCWrappedJS*> mWrappedJSToReleaseArray;
   591     nsTArray<nsISupports*> mNativesToReleaseArray;
   592     bool mDoingFinalization;
   593     XPCRootSetElem *mVariantRoots;
   594     XPCRootSetElem *mWrappedJSRoots;
   595     XPCRootSetElem *mObjectHolderRoots;
   596     nsTArray<xpcGCCallback> extraGCCallbacks;
   597     nsTArray<xpcContextCallback> extraContextCallbacks;
   598     nsRefPtr<WatchdogManager> mWatchdogManager;
   599     JS::GCSliceCallback mPrevGCSliceCallback;
   600     JS::PersistentRootedObject mJunkScope;
   601     JS::PersistentRootedObject mCompilationScope;
   602     nsRefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer;
   604     mozilla::TimeStamp mSlowScriptCheckpoint;
   606 #define XPCCCX_STRING_CACHE_SIZE 2
   608     mozilla::Maybe<nsString> mScratchStrings[XPCCCX_STRING_CACHE_SIZE];
   610     friend class Watchdog;
   611     friend class AutoLockWatchdog;
   612     friend class XPCIncrementalReleaseRunnable;
   613 };
   615 /***************************************************************************/
   616 /***************************************************************************/
   617 // XPCContext is mostly a dumb class to hold JSContext specific data and
   618 // maps that let us find wrappers created for the given JSContext.
   620 // no virtuals
   621 class XPCContext
   622 {
   623     friend class XPCJSRuntime;
   624 public:
   625     static XPCContext* GetXPCContext(JSContext* aJSContext)
   626         {
   627             MOZ_ASSERT(JS_GetSecondContextPrivate(aJSContext), "should already have XPCContext");
   628             return static_cast<XPCContext *>(JS_GetSecondContextPrivate(aJSContext));
   629         }
   631     XPCJSRuntime* GetRuntime() const {return mRuntime;}
   632     JSContext* GetJSContext() const {return mJSContext;}
   634     enum LangType {LANG_UNKNOWN, LANG_JS, LANG_NATIVE};
   636     LangType GetCallingLangType() const
   637         {
   638             return mCallingLangType;
   639         }
   640     LangType SetCallingLangType(LangType lt)
   641         {
   642             LangType tmp = mCallingLangType;
   643             mCallingLangType = lt;
   644             return tmp;
   645         }
   646     bool CallerTypeIsJavaScript() const
   647         {
   648             return LANG_JS == mCallingLangType;
   649         }
   650     bool CallerTypeIsNative() const
   651         {
   652             return LANG_NATIVE == mCallingLangType;
   653         }
   654     bool CallerTypeIsKnown() const
   655         {
   656             return LANG_UNKNOWN != mCallingLangType;
   657         }
   659     nsresult GetException(nsIException** e)
   660         {
   661             nsCOMPtr<nsIException> rval = mException;
   662             rval.forget(e);
   663             return NS_OK;
   664         }
   665     void SetException(nsIException* e)
   666         {
   667             mException = e;
   668         }
   670     nsresult GetLastResult() {return mLastResult;}
   671     void SetLastResult(nsresult rc) {mLastResult = rc;}
   673     nsresult GetPendingResult() {return mPendingResult;}
   674     void SetPendingResult(nsresult rc) {mPendingResult = rc;}
   676     void DebugDump(int16_t depth);
   677     void AddScope(PRCList *scope) { PR_INSERT_AFTER(scope, &mScopes); }
   678     void RemoveScope(PRCList *scope) { PR_REMOVE_LINK(scope); }
   680     void MarkErrorUnreported() { mErrorUnreported = true; }
   681     void ClearUnreportedError() { mErrorUnreported = false; }
   682     bool WasErrorReported() { return !mErrorUnreported; }
   684     ~XPCContext();
   686 private:
   687     XPCContext();    // no implementation
   688     XPCContext(XPCJSRuntime* aRuntime, JSContext* aJSContext);
   690     static XPCContext* newXPCContext(XPCJSRuntime* aRuntime,
   691                                      JSContext* aJSContext);
   692 private:
   693     XPCJSRuntime* mRuntime;
   694     JSContext*  mJSContext;
   695     nsresult mLastResult;
   696     nsresult mPendingResult;
   697     nsCOMPtr<nsIException> mException;
   698     LangType mCallingLangType;
   699     bool mErrorUnreported;
   701     // A linked list of scopes to notify when we are destroyed.
   702     PRCList mScopes;
   703 };
   705 /***************************************************************************/
   707 #define NATIVE_CALLER  XPCContext::LANG_NATIVE
   708 #define JS_CALLER      XPCContext::LANG_JS
   710 // No virtuals
   711 // XPCCallContext is ALWAYS declared as a local variable in some function;
   712 // i.e. instance lifetime is always controled by some C++ function returning.
   713 //
   714 // These things are created frequently in many places. We *intentionally* do
   715 // not inialialize all members in order to save on construction overhead.
   716 // Some constructor pass more valid params than others. We init what must be
   717 // init'd and leave other members undefined. In debug builds the accessors
   718 // use a CHECK_STATE macro to track whether or not the object is in a valid
   719 // state to answer the question a caller might be asking. As long as this
   720 // class is maintained correctly it can do its job without a bunch of added
   721 // overhead from useless initializations and non-DEBUG error checking.
   722 //
   723 // Note that most accessors are inlined.
   725 class MOZ_STACK_CLASS XPCCallContext : public nsAXPCNativeCallContext
   726 {
   727 public:
   728     NS_IMETHOD GetCallee(nsISupports **aResult);
   729     NS_IMETHOD GetCalleeMethodIndex(uint16_t *aResult);
   730     NS_IMETHOD GetCalleeWrapper(nsIXPConnectWrappedNative **aResult);
   731     NS_IMETHOD GetJSContext(JSContext **aResult);
   732     NS_IMETHOD GetArgc(uint32_t *aResult);
   733     NS_IMETHOD GetArgvPtr(jsval **aResult);
   734     NS_IMETHOD GetCalleeInterface(nsIInterfaceInfo **aResult);
   735     NS_IMETHOD GetCalleeClassInfo(nsIClassInfo **aResult);
   736     NS_IMETHOD GetPreviousCallContext(nsAXPCNativeCallContext **aResult);
   737     NS_IMETHOD GetLanguage(uint16_t *aResult);
   739     enum {NO_ARGS = (unsigned) -1};
   741     static JSContext* GetDefaultJSContext();
   743     XPCCallContext(XPCContext::LangType callerLanguage,
   744                    JSContext* cx,
   745                    JS::HandleObject obj    = JS::NullPtr(),
   746                    JS::HandleObject funobj = JS::NullPtr(),
   747                    JS::HandleId id         = JSID_VOIDHANDLE,
   748                    unsigned argc           = NO_ARGS,
   749                    jsval *argv             = nullptr,
   750                    jsval *rval             = nullptr);
   752     virtual ~XPCCallContext();
   754     inline bool                         IsValid() const ;
   756     inline XPCJSRuntime*                GetRuntime() const ;
   757     inline XPCContext*                  GetXPCContext() const ;
   758     inline JSContext*                   GetJSContext() const ;
   759     inline bool                         GetContextPopRequired() const ;
   760     inline XPCContext::LangType         GetCallerLanguage() const ;
   761     inline XPCContext::LangType         GetPrevCallerLanguage() const ;
   762     inline XPCCallContext*              GetPrevCallContext() const ;
   764     inline JSObject*                    GetFlattenedJSObject() const ;
   765     inline nsISupports*                 GetIdentityObject() const ;
   766     inline XPCWrappedNative*            GetWrapper() const ;
   767     inline XPCWrappedNativeProto*       GetProto() const ;
   769     inline bool                         CanGetTearOff() const ;
   770     inline XPCWrappedNativeTearOff*     GetTearOff() const ;
   772     inline XPCNativeScriptableInfo*     GetScriptableInfo() const ;
   773     inline bool                         CanGetSet() const ;
   774     inline XPCNativeSet*                GetSet() const ;
   775     inline bool                         CanGetInterface() const ;
   776     inline XPCNativeInterface*          GetInterface() const ;
   777     inline XPCNativeMember*             GetMember() const ;
   778     inline bool                         HasInterfaceAndMember() const ;
   779     inline jsid                         GetName() const ;
   780     inline bool                         GetStaticMemberIsLocal() const ;
   781     inline unsigned                     GetArgc() const ;
   782     inline jsval*                       GetArgv() const ;
   783     inline jsval*                       GetRetVal() const ;
   785     inline uint16_t                     GetMethodIndex() const ;
   786     inline void                         SetMethodIndex(uint16_t index) ;
   788     inline jsid GetResolveName() const;
   789     inline jsid SetResolveName(JS::HandleId name);
   791     inline XPCWrappedNative* GetResolvingWrapper() const;
   792     inline XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w);
   794     inline void SetRetVal(jsval val);
   796     void SetName(jsid name);
   797     void SetArgsAndResultPtr(unsigned argc, jsval *argv, jsval *rval);
   798     void SetCallInfo(XPCNativeInterface* iface, XPCNativeMember* member,
   799                      bool isSetter);
   801     nsresult  CanCallNow();
   803     void SystemIsBeingShutDown();
   805     operator JSContext*() const {return GetJSContext();}
   807 private:
   809     // no copy ctor or assignment allowed
   810     XPCCallContext(const XPCCallContext& r); // not implemented
   811     XPCCallContext& operator= (const XPCCallContext& r); // not implemented
   813     XPCWrappedNative* UnwrapThisIfAllowed(JS::HandleObject obj, JS::HandleObject fun,
   814                                           unsigned argc);
   816 private:
   817     // posible values for mState
   818     enum State {
   819         INIT_FAILED,
   820         SYSTEM_SHUTDOWN,
   821         HAVE_CONTEXT,
   822         HAVE_OBJECT,
   823         HAVE_NAME,
   824         HAVE_ARGS,
   825         READY_TO_CALL,
   826         CALL_DONE
   827     };
   829 #ifdef DEBUG
   830 inline void CHECK_STATE(int s) const {MOZ_ASSERT(mState >= s, "bad state");}
   831 #else
   832 #define CHECK_STATE(s) ((void)0)
   833 #endif
   835 private:
   836     JSAutoRequest                   mAr;
   837     State                           mState;
   839     nsRefPtr<nsXPConnect>           mXPC;
   841     XPCContext*                     mXPCContext;
   842     JSContext*                      mJSContext;
   844     XPCContext::LangType            mCallerLanguage;
   846     // ctor does not necessarily init the following. BEWARE!
   848     XPCContext::LangType            mPrevCallerLanguage;
   850     XPCCallContext*                 mPrevCallContext;
   852     JS::RootedObject                mFlattenedJSObject;
   853     XPCWrappedNative*               mWrapper;
   854     XPCWrappedNativeTearOff*        mTearOff;
   856     XPCNativeScriptableInfo*        mScriptableInfo;
   858     XPCNativeSet*                   mSet;
   859     XPCNativeInterface*             mInterface;
   860     XPCNativeMember*                mMember;
   862     JS::RootedId                    mName;
   863     bool                            mStaticMemberIsLocal;
   865     unsigned                        mArgc;
   866     jsval*                          mArgv;
   867     jsval*                          mRetVal;
   869     uint16_t                        mMethodIndex;
   870 };
   872 /***************************************************************************
   873 ****************************************************************************
   874 *
   875 * Core classes for wrapped native objects for use from JavaScript...
   876 *
   877 ****************************************************************************
   878 ***************************************************************************/
   880 // These are the various JSClasses and callbacks whose use that required
   881 // visibility from more than one .cpp file.
   883 struct XPCWrappedNativeJSClass;
   884 extern const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass;
   885 extern const js::Class XPC_WN_NoMods_WithCall_Proto_JSClass;
   886 extern const js::Class XPC_WN_NoMods_NoCall_Proto_JSClass;
   887 extern const js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass;
   888 extern const js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
   889 extern const js::Class XPC_WN_Tearoff_JSClass;
   890 extern const js::Class XPC_WN_NoHelper_Proto_JSClass;
   892 extern bool
   893 XPC_WN_CallMethod(JSContext *cx, unsigned argc, jsval *vp);
   895 extern bool
   896 XPC_WN_GetterSetter(JSContext *cx, unsigned argc, jsval *vp);
   898 extern bool
   899 XPC_WN_JSOp_Enumerate(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op,
   900                       JS::MutableHandleValue statep, JS::MutableHandleId idp);
   902 extern JSObject*
   903 XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
   905 // Macros to initialize Object or Function like XPC_WN classes
   906 #define XPC_WN_WithCall_ObjectOps                                             \
   907     {                                                                         \
   908         nullptr, /* lookupGeneric */                                          \
   909         nullptr, /* lookupProperty */                                         \
   910         nullptr, /* lookupElement */                                          \
   911         nullptr, /* defineGeneric */                                          \
   912         nullptr, /* defineProperty */                                         \
   913         nullptr, /* defineElement */                                          \
   914         nullptr, /* getGeneric    */                                          \
   915         nullptr, /* getProperty    */                                         \
   916         nullptr, /* getElement    */                                          \
   917         nullptr, /* setGeneric    */                                          \
   918         nullptr, /* setProperty    */                                         \
   919         nullptr, /* setElement    */                                          \
   920         nullptr, /* getGenericAttributes  */                                  \
   921         nullptr, /* setGenericAttributes  */                                  \
   922         nullptr, /* deleteProperty */                                         \
   923         nullptr, /* deleteElement */                                          \
   924         nullptr, nullptr, /* watch/unwatch */                                 \
   925         nullptr, /* slice */                                                  \
   926         XPC_WN_JSOp_Enumerate,                                                \
   927         XPC_WN_JSOp_ThisObject,                                               \
   928     }
   930 #define XPC_WN_NoCall_ObjectOps                                               \
   931     {                                                                         \
   932         nullptr, /* lookupGeneric */                                          \
   933         nullptr, /* lookupProperty */                                         \
   934         nullptr, /* lookupElement */                                          \
   935         nullptr, /* defineGeneric */                                          \
   936         nullptr, /* defineProperty */                                         \
   937         nullptr, /* defineElement */                                          \
   938         nullptr, /* getGeneric    */                                          \
   939         nullptr, /* getProperty    */                                         \
   940         nullptr, /* getElement    */                                          \
   941         nullptr, /* setGeneric    */                                          \
   942         nullptr, /* setProperty    */                                         \
   943         nullptr, /* setElement    */                                          \
   944         nullptr, /* getGenericAttributes  */                                  \
   945         nullptr, /* setGenericAttributes  */                                  \
   946         nullptr, /* deleteProperty */                                         \
   947         nullptr, /* deleteElement */                                          \
   948         nullptr, nullptr, /* watch/unwatch */                                 \
   949         nullptr, /* slice */                                                  \
   950         XPC_WN_JSOp_Enumerate,                                                \
   951         XPC_WN_JSOp_ThisObject,                                               \
   952     }
   954 // Maybe this macro should check for class->enumerate ==
   955 // XPC_WN_Shared_Proto_Enumerate or something rather than checking for
   956 // 4 classes?
   957 static inline bool IS_PROTO_CLASS(const js::Class *clazz)
   958 {
   959     return clazz == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
   960            clazz == &XPC_WN_NoMods_NoCall_Proto_JSClass ||
   961            clazz == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
   962            clazz == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
   963 }
   965 /***************************************************************************/
   966 // XPCWrappedNativeScope is one-to-one with a JS global object.
   968 class nsXPCComponentsBase;
   969 class XPCWrappedNativeScope : public PRCList
   970 {
   971 public:
   973     static XPCWrappedNativeScope*
   974     GetNewOrUsed(JSContext *cx, JS::HandleObject aGlobal);
   976     XPCJSRuntime*
   977     GetRuntime() const {return XPCJSRuntime::Get();}
   979     Native2WrappedNativeMap*
   980     GetWrappedNativeMap() const {return mWrappedNativeMap;}
   982     ClassInfo2WrappedNativeProtoMap*
   983     GetWrappedNativeProtoMap() const {return mWrappedNativeProtoMap;}
   985     nsXPCComponentsBase*
   986     GetComponents() const {return mComponents;}
   988     // Forces the creation of a privileged |Components| object, even in
   989     // content scopes. This will crash if used outside of automation.
   990     void
   991     ForcePrivilegedComponents();
   993     bool AttachComponentsObject(JSContext *aCx);
   995     // Returns the JS object reflection of the Components object.
   996     bool
   997     GetComponentsJSObject(JS::MutableHandleObject obj);
   999     JSObject*
  1000     GetGlobalJSObject() const {
  1001         JS::ExposeObjectToActiveJS(mGlobalJSObject);
  1002         return mGlobalJSObject;
  1005     JSObject*
  1006     GetGlobalJSObjectPreserveColor() const {return mGlobalJSObject;}
  1008     nsIPrincipal*
  1009     GetPrincipal() const {
  1010         JSCompartment *c = js::GetObjectCompartment(mGlobalJSObject);
  1011         return nsJSPrincipals::get(JS_GetCompartmentPrincipals(c));
  1014     JSObject*
  1015     GetExpandoChain(JS::HandleObject target);
  1017     bool
  1018     SetExpandoChain(JSContext *cx, JS::HandleObject target, JS::HandleObject chain);
  1020     void RemoveWrappedNativeProtos();
  1022     static void
  1023     SystemIsBeingShutDown();
  1025     static void
  1026     TraceWrappedNativesInAllScopes(JSTracer* trc, XPCJSRuntime* rt);
  1028     void TraceInside(JSTracer *trc) {
  1029         MOZ_ASSERT(mGlobalJSObject);
  1030         mGlobalJSObject.trace(trc, "XPCWrappedNativeScope::mGlobalJSObject");
  1031         if (mXBLScope)
  1032             mXBLScope.trace(trc, "XPCWrappedNativeScope::mXBLScope");
  1033         if (mXrayExpandos.initialized())
  1034             mXrayExpandos.trace(trc);
  1037     static void
  1038     SuspectAllWrappers(XPCJSRuntime* rt, nsCycleCollectionNoteRootCallback &cb);
  1040     static void
  1041     StartFinalizationPhaseOfGC(JSFreeOp *fop, XPCJSRuntime* rt);
  1043     static void
  1044     FinishedFinalizationPhaseOfGC();
  1046     static void
  1047     MarkAllWrappedNativesAndProtos();
  1049 #ifdef DEBUG
  1050     static void
  1051     ASSERT_NoInterfaceSetsAreMarked();
  1052 #endif
  1054     static void
  1055     SweepAllWrappedNativeTearOffs();
  1057     static void
  1058     DebugDumpAllScopes(int16_t depth);
  1060     void
  1061     DebugDump(int16_t depth);
  1063     struct ScopeSizeInfo {
  1064         ScopeSizeInfo(mozilla::MallocSizeOf mallocSizeOf)
  1065             : mMallocSizeOf(mallocSizeOf),
  1066               mScopeAndMapSize(0),
  1067               mProtoAndIfaceCacheSize(0)
  1068         {}
  1070         mozilla::MallocSizeOf mMallocSizeOf;
  1071         size_t mScopeAndMapSize;
  1072         size_t mProtoAndIfaceCacheSize;
  1073     };
  1075     static void
  1076     AddSizeOfAllScopesIncludingThis(ScopeSizeInfo* scopeSizeInfo);
  1078     void
  1079     AddSizeOfIncludingThis(ScopeSizeInfo* scopeSizeInfo);
  1081     bool
  1082     IsValid() const {return mRuntime != nullptr;}
  1084     static bool
  1085     IsDyingScope(XPCWrappedNativeScope *scope);
  1087     static void InitStatics() { gScopes = nullptr; gDyingScopes = nullptr; }
  1089     XPCContext *GetContext() { return mContext; }
  1090     void ClearContext() { mContext = nullptr; }
  1092     typedef js::HashSet<JSObject *,
  1093                         js::PointerHasher<JSObject *, 3>,
  1094                         js::SystemAllocPolicy> DOMExpandoSet;
  1096     bool RegisterDOMExpandoObject(JSObject *expando) {
  1097         // Expandos are proxy objects, and proxies are always tenured.
  1098         JS::AssertGCThingMustBeTenured(expando);
  1099         if (!mDOMExpandoSet) {
  1100             mDOMExpandoSet = new DOMExpandoSet();
  1101             mDOMExpandoSet->init(8);
  1103         return mDOMExpandoSet->put(expando);
  1105     void RemoveDOMExpandoObject(JSObject *expando) {
  1106         if (mDOMExpandoSet)
  1107             mDOMExpandoSet->remove(expando);
  1110     // Gets the appropriate scope object for XBL in this scope. The context
  1111     // must be same-compartment with the global upon entering, and the scope
  1112     // object is wrapped into the compartment of the global.
  1113     JSObject *EnsureXBLScope(JSContext *cx);
  1115     XPCWrappedNativeScope(JSContext *cx, JS::HandleObject aGlobal);
  1117     nsAutoPtr<JSObject2JSObjectMap> mWaiverWrapperMap;
  1119     bool IsXBLScope() { return mIsXBLScope; }
  1120     bool AllowXBLScope();
  1121     bool UseXBLScope() { return mUseXBLScope; }
  1123 protected:
  1124     virtual ~XPCWrappedNativeScope();
  1126     static void KillDyingScopes();
  1128     XPCWrappedNativeScope(); // not implemented
  1130 private:
  1131     static XPCWrappedNativeScope* gScopes;
  1132     static XPCWrappedNativeScope* gDyingScopes;
  1134     XPCJSRuntime*                    mRuntime;
  1135     Native2WrappedNativeMap*         mWrappedNativeMap;
  1136     ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
  1137     nsRefPtr<nsXPCComponentsBase>    mComponents;
  1138     XPCWrappedNativeScope*           mNext;
  1139     // The JS global object for this scope.  If non-null, this will be the
  1140     // default parent for the XPCWrappedNatives that have us as the scope,
  1141     // unless a PreCreate hook overrides it.  Note that this _may_ be null (see
  1142     // constructor).
  1143     JS::ObjectPtr                    mGlobalJSObject;
  1145     // XBL Scope. This is is a lazily-created sandbox for non-system scopes.
  1146     // EnsureXBLScope() decides whether it needs to be created or not.
  1147     // This reference is wrapped into the compartment of mGlobalJSObject.
  1148     JS::ObjectPtr                    mXBLScope;
  1150     XPCContext*                      mContext;
  1152     nsAutoPtr<DOMExpandoSet> mDOMExpandoSet;
  1154     JS::WeakMapPtr<JSObject*, JSObject*> mXrayExpandos;
  1156     bool mIsXBLScope;
  1158     // For remote XUL domains, we run all XBL in the content scope for compat
  1159     // reasons (though we sometimes pref this off for automation). We separately
  1160     // track the result of this decision (mAllowXBLScope), from the decision
  1161     // of whether to actually _use_ an XBL scope (mUseXBLScope), which depends
  1162     // on the type of global and whether the compartment is system principal
  1163     // or not.
  1164     //
  1165     // This distinction is useful primarily because, if true, we know that we
  1166     // have no way of distinguishing XBL script from content script for the
  1167     // given scope. In these (unsupported) situations, we just always claim to
  1168     // be XBL.
  1169     bool mAllowXBLScope;
  1170     bool mUseXBLScope;
  1171 };
  1173 /***************************************************************************/
  1174 // XPCNativeMember represents a single idl declared method, attribute or
  1175 // constant.
  1177 // Tight. No virtual methods. Can be bitwise copied (until any resolution done).
  1179 class XPCNativeMember
  1181 public:
  1182     static bool GetCallInfo(JSObject* funobj,
  1183                             XPCNativeInterface** pInterface,
  1184                             XPCNativeMember**    pMember);
  1186     jsid   GetName() const {return mName;}
  1188     uint16_t GetIndex() const {return mIndex;}
  1190     bool GetConstantValue(XPCCallContext& ccx, XPCNativeInterface* iface,
  1191                           jsval* pval)
  1192         {MOZ_ASSERT(IsConstant(),
  1193                     "Only call this if you're sure this is a constant!");
  1194          return Resolve(ccx, iface, JS::NullPtr(), pval);}
  1196     bool NewFunctionObject(XPCCallContext& ccx, XPCNativeInterface* iface,
  1197                            JS::HandleObject parent, jsval* pval);
  1199     bool IsMethod() const
  1200         {return 0 != (mFlags & METHOD);}
  1202     bool IsConstant() const
  1203         {return 0 != (mFlags & CONSTANT);}
  1205     bool IsAttribute() const
  1206         {return 0 != (mFlags & GETTER);}
  1208     bool IsWritableAttribute() const
  1209         {return 0 != (mFlags & SETTER_TOO);}
  1211     bool IsReadOnlyAttribute() const
  1212         {return IsAttribute() && !IsWritableAttribute();}
  1215     void SetName(jsid a) {mName = a;}
  1217     void SetMethod(uint16_t index)
  1218         {mFlags = METHOD; mIndex = index;}
  1220     void SetConstant(uint16_t index)
  1221         {mFlags = CONSTANT; mIndex = index;}
  1223     void SetReadOnlyAttribute(uint16_t index)
  1224         {mFlags = GETTER; mIndex = index;}
  1226     void SetWritableAttribute()
  1227         {MOZ_ASSERT(mFlags == GETTER,"bad"); mFlags = GETTER | SETTER_TOO;}
  1229     /* default ctor - leave random contents */
  1230     XPCNativeMember()  {MOZ_COUNT_CTOR(XPCNativeMember);}
  1231     ~XPCNativeMember() {MOZ_COUNT_DTOR(XPCNativeMember);}
  1233 private:
  1234     bool Resolve(XPCCallContext& ccx, XPCNativeInterface* iface,
  1235                  JS::HandleObject parent, jsval *vp);
  1237     enum {
  1238         METHOD      = 0x01,
  1239         CONSTANT    = 0x02,
  1240         GETTER      = 0x04,
  1241         SETTER_TOO  = 0x08
  1242     };
  1244 private:
  1245     // our only data...
  1246     jsid     mName;
  1247     uint16_t mIndex;
  1248     uint16_t mFlags;
  1249 };
  1251 /***************************************************************************/
  1252 // XPCNativeInterface represents a single idl declared interface. This is
  1253 // primarily the set of XPCNativeMembers.
  1255 // Tight. No virtual methods.
  1257 class XPCNativeInterface
  1259   public:
  1260     static XPCNativeInterface* GetNewOrUsed(const nsIID* iid);
  1261     static XPCNativeInterface* GetNewOrUsed(nsIInterfaceInfo* info);
  1262     static XPCNativeInterface* GetNewOrUsed(const char* name);
  1263     static XPCNativeInterface* GetISupports();
  1265     inline nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo.get();}
  1266     inline jsid              GetName()          const {return mName;}
  1268     inline const nsIID* GetIID() const;
  1269     inline const char*  GetNameString() const;
  1270     inline XPCNativeMember* FindMember(jsid name) const;
  1272     inline bool HasAncestor(const nsIID* iid) const;
  1274     uint16_t GetMemberCount() const {
  1275         return mMemberCount;
  1277     XPCNativeMember* GetMemberAt(uint16_t i) {
  1278         MOZ_ASSERT(i < mMemberCount, "bad index");
  1279         return &mMembers[i];
  1282     void DebugDump(int16_t depth);
  1284 #define XPC_NATIVE_IFACE_MARK_FLAG ((uint16_t)JS_BIT(15)) // only high bit of 16 is set
  1286     void Mark() {
  1287         mMarked = 1;
  1290     void Unmark() {
  1291         mMarked = 0;
  1294     bool IsMarked() const {
  1295         return mMarked != 0;
  1298     // NOP. This is just here to make the AutoMarkingPtr code compile.
  1299     inline void TraceJS(JSTracer* trc) {}
  1300     inline void AutoTrace(JSTracer* trc) {}
  1302     static void DestroyInstance(XPCNativeInterface* inst);
  1304     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
  1306   protected:
  1307     static XPCNativeInterface* NewInstance(nsIInterfaceInfo* aInfo);
  1309     XPCNativeInterface();   // not implemented
  1310     XPCNativeInterface(nsIInterfaceInfo* aInfo, jsid aName)
  1311       : mInfo(aInfo), mName(aName), mMemberCount(0), mMarked(0)
  1313         MOZ_COUNT_CTOR(XPCNativeInterface);
  1315     ~XPCNativeInterface() {
  1316         MOZ_COUNT_DTOR(XPCNativeInterface);
  1319     void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
  1321     XPCNativeInterface(const XPCNativeInterface& r); // not implemented
  1322     XPCNativeInterface& operator= (const XPCNativeInterface& r); // not implemented
  1324 private:
  1325     nsCOMPtr<nsIInterfaceInfo> mInfo;
  1326     jsid                       mName;
  1327     uint16_t                   mMemberCount : 15;
  1328     uint16_t                   mMarked : 1;
  1329     XPCNativeMember            mMembers[1]; // always last - object sized for array
  1330 };
  1332 /***************************************************************************/
  1333 // XPCNativeSetKey is used to key a XPCNativeSet in a NativeSetMap.
  1335 class XPCNativeSetKey
  1337 public:
  1338     XPCNativeSetKey(XPCNativeSet*       BaseSet  = nullptr,
  1339                     XPCNativeInterface* Addition = nullptr,
  1340                     uint16_t            Position = 0)
  1341         : mIsAKey(IS_A_KEY), mPosition(Position), mBaseSet(BaseSet),
  1342           mAddition(Addition) {}
  1343     ~XPCNativeSetKey() {}
  1345     XPCNativeSet*           GetBaseSet()  const {return mBaseSet;}
  1346     XPCNativeInterface*     GetAddition() const {return mAddition;}
  1347     uint16_t                GetPosition() const {return mPosition;}
  1349     // This is a fun little hack...
  1350     // We build these keys only on the stack. We use them for lookup in
  1351     // NativeSetMap. Becasue we don't want to pay the cost of cloning a key and
  1352     // sticking it into the hashtable, when the XPCNativeSet actually
  1353     // gets added to the table the 'key' in the table is a pointer to the
  1354     // set itself and not this key. Our key compare function expects to get
  1355     // a key and a set. When we do external lookups in the map we pass in one
  1356     // of these keys and our compare function gets passed a key and a set.
  1357     // (see compare_NativeKeyToSet in xpcmaps.cpp). This is all well and good.
  1358     // Except, when the table decides to resize itself. Then it tries to use
  1359     // our compare function with the 'keys' that are in the hashtable (which are
  1360     // really XPCNativeSet objects and not XPCNativeSetKey objects!
  1361     //
  1362     // So, the hack is to have the compare function assume it is getting a
  1363     // XPCNativeSetKey pointer and call this IsAKey method. If that fails then
  1364     // it realises that it really has a XPCNativeSet pointer and deals with that
  1365     // fact. This is safe because we know that both of these classes have no
  1366     // virtual methods and their first data member is a uint16_t. We are
  1367     // confident that XPCNativeSet->mMemberCount will never be 0xffff.
  1369     bool                    IsAKey() const {return mIsAKey == IS_A_KEY;}
  1371     enum {IS_A_KEY = 0xffff};
  1373     // Allow shallow copy
  1375 private:
  1376     uint16_t                mIsAKey;    // must be first data member
  1377     uint16_t                mPosition;
  1378     XPCNativeSet*           mBaseSet;
  1379     XPCNativeInterface*     mAddition;
  1380 };
  1382 /***************************************************************************/
  1383 // XPCNativeSet represents an ordered collection of XPCNativeInterface pointers.
  1385 class XPCNativeSet
  1387   public:
  1388     static XPCNativeSet* GetNewOrUsed(const nsIID* iid);
  1389     static XPCNativeSet* GetNewOrUsed(nsIClassInfo* classInfo);
  1390     static XPCNativeSet* GetNewOrUsed(XPCNativeSet* otherSet,
  1391                                       XPCNativeInterface* newInterface,
  1392                                       uint16_t position);
  1394     // This generates a union set.
  1395     //
  1396     // If preserveFirstSetOrder is true, the elements from |firstSet| come first,
  1397     // followed by any non-duplicate items from |secondSet|. If false, the same
  1398     // algorithm is applied; but if we detect that |secondSet| is a superset of
  1399     // |firstSet|, we return |secondSet| without worrying about whether the
  1400     // ordering might differ from |firstSet|.
  1401     static XPCNativeSet* GetNewOrUsed(XPCNativeSet* firstSet,
  1402                                       XPCNativeSet* secondSet,
  1403                                       bool preserveFirstSetOrder);
  1405     static void ClearCacheEntryForClassInfo(nsIClassInfo* classInfo);
  1407     inline bool FindMember(jsid name, XPCNativeMember** pMember,
  1408                              uint16_t* pInterfaceIndex) const;
  1410     inline bool FindMember(jsid name, XPCNativeMember** pMember,
  1411                              XPCNativeInterface** pInterface) const;
  1413     inline bool FindMember(jsid name,
  1414                              XPCNativeMember** pMember,
  1415                              XPCNativeInterface** pInterface,
  1416                              XPCNativeSet* protoSet,
  1417                              bool* pIsLocal) const;
  1419     inline bool HasInterface(XPCNativeInterface* aInterface) const;
  1420     inline bool HasInterfaceWithAncestor(XPCNativeInterface* aInterface) const;
  1421     inline bool HasInterfaceWithAncestor(const nsIID* iid) const;
  1423     inline XPCNativeInterface* FindInterfaceWithIID(const nsIID& iid) const;
  1425     inline XPCNativeInterface* FindNamedInterface(jsid name) const;
  1427     uint16_t GetMemberCount() const {
  1428         return mMemberCount;
  1430     uint16_t GetInterfaceCount() const {
  1431         return mInterfaceCount;
  1433     XPCNativeInterface **GetInterfaceArray() {
  1434         return mInterfaces;
  1437     XPCNativeInterface* GetInterfaceAt(uint16_t i)
  1438         {MOZ_ASSERT(i < mInterfaceCount, "bad index"); return mInterfaces[i];}
  1440     inline bool MatchesSetUpToInterface(const XPCNativeSet* other,
  1441                                           XPCNativeInterface* iface) const;
  1443 #define XPC_NATIVE_SET_MARK_FLAG ((uint16_t)JS_BIT(15)) // only high bit of 16 is set
  1445     inline void Mark();
  1447     // NOP. This is just here to make the AutoMarkingPtr code compile.
  1448     inline void TraceJS(JSTracer* trc) {}
  1449     inline void AutoTrace(JSTracer* trc) {}
  1451   private:
  1452     void MarkSelfOnly() {
  1453         mMarked = 1;
  1456   public:
  1457     void Unmark() {
  1458         mMarked = 0;
  1460     bool IsMarked() const {
  1461         return !!mMarked;
  1464 #ifdef DEBUG
  1465     inline void ASSERT_NotMarked();
  1466 #endif
  1468     void DebugDump(int16_t depth);
  1470     static void DestroyInstance(XPCNativeSet* inst);
  1472     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
  1474   protected:
  1475     static XPCNativeSet* NewInstance(XPCNativeInterface** array,
  1476                                      uint16_t count);
  1477     static XPCNativeSet* NewInstanceMutate(XPCNativeSet*       otherSet,
  1478                                            XPCNativeInterface* newInterface,
  1479                                            uint16_t            position);
  1480     XPCNativeSet()
  1481       : mMemberCount(0), mInterfaceCount(0), mMarked(0)
  1483         MOZ_COUNT_CTOR(XPCNativeSet);
  1485     ~XPCNativeSet() {
  1486         MOZ_COUNT_DTOR(XPCNativeSet);
  1488     void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
  1490   private:
  1491     uint16_t                mMemberCount;
  1492     uint16_t                mInterfaceCount : 15;
  1493     uint16_t                mMarked : 1;
  1494     XPCNativeInterface*     mInterfaces[1];  // always last - object sized for array
  1495 };
  1497 /***************************************************************************/
  1498 // XPCNativeScriptableFlags is a wrapper class that holds the flags returned
  1499 // from calls to nsIXPCScriptable::GetScriptableFlags(). It has convenience
  1500 // methods to check for particular bitflags. Since we also use this class as
  1501 // a member of the gc'd class XPCNativeScriptableShared, this class holds the
  1502 // bit and exposes the inlined methods to support marking.
  1504 #define XPC_WN_SJSFLAGS_MARK_FLAG JS_BIT(31) // only high bit of 32 is set
  1506 class XPCNativeScriptableFlags
  1508 private:
  1509     uint32_t mFlags;
  1511 public:
  1513     XPCNativeScriptableFlags(uint32_t flags = 0) : mFlags(flags) {}
  1515     uint32_t GetFlags() const {return mFlags & ~XPC_WN_SJSFLAGS_MARK_FLAG;}
  1516     void     SetFlags(uint32_t flags) {mFlags = flags;}
  1518     operator uint32_t() const {return GetFlags();}
  1520     XPCNativeScriptableFlags(const XPCNativeScriptableFlags& r)
  1521         {mFlags = r.GetFlags();}
  1523     XPCNativeScriptableFlags& operator= (const XPCNativeScriptableFlags& r)
  1524         {mFlags = r.GetFlags(); return *this;}
  1526     void Mark()       {mFlags |= XPC_WN_SJSFLAGS_MARK_FLAG;}
  1527     void Unmark()     {mFlags &= ~XPC_WN_SJSFLAGS_MARK_FLAG;}
  1528     bool IsMarked() const {return 0 != (mFlags & XPC_WN_SJSFLAGS_MARK_FLAG);}
  1530 #ifdef GET_IT
  1531 #undef GET_IT
  1532 #endif
  1533 #define GET_IT(f_) const {return 0 != (mFlags & nsIXPCScriptable:: f_ );}
  1535     bool WantPreCreate()                GET_IT(WANT_PRECREATE)
  1536     bool WantCreate()                   GET_IT(WANT_CREATE)
  1537     bool WantPostCreate()               GET_IT(WANT_POSTCREATE)
  1538     bool WantAddProperty()              GET_IT(WANT_ADDPROPERTY)
  1539     bool WantDelProperty()              GET_IT(WANT_DELPROPERTY)
  1540     bool WantGetProperty()              GET_IT(WANT_GETPROPERTY)
  1541     bool WantSetProperty()              GET_IT(WANT_SETPROPERTY)
  1542     bool WantEnumerate()                GET_IT(WANT_ENUMERATE)
  1543     bool WantNewEnumerate()             GET_IT(WANT_NEWENUMERATE)
  1544     bool WantNewResolve()               GET_IT(WANT_NEWRESOLVE)
  1545     bool WantConvert()                  GET_IT(WANT_CONVERT)
  1546     bool WantFinalize()                 GET_IT(WANT_FINALIZE)
  1547     bool WantCall()                     GET_IT(WANT_CALL)
  1548     bool WantConstruct()                GET_IT(WANT_CONSTRUCT)
  1549     bool WantHasInstance()              GET_IT(WANT_HASINSTANCE)
  1550     bool WantOuterObject()              GET_IT(WANT_OUTER_OBJECT)
  1551     bool UseJSStubForAddProperty()      GET_IT(USE_JSSTUB_FOR_ADDPROPERTY)
  1552     bool UseJSStubForDelProperty()      GET_IT(USE_JSSTUB_FOR_DELPROPERTY)
  1553     bool UseJSStubForSetProperty()      GET_IT(USE_JSSTUB_FOR_SETPROPERTY)
  1554     bool DontEnumStaticProps()          GET_IT(DONT_ENUM_STATIC_PROPS)
  1555     bool DontEnumQueryInterface()       GET_IT(DONT_ENUM_QUERY_INTERFACE)
  1556     bool DontAskInstanceForScriptable() GET_IT(DONT_ASK_INSTANCE_FOR_SCRIPTABLE)
  1557     bool ClassInfoInterfacesOnly()      GET_IT(CLASSINFO_INTERFACES_ONLY)
  1558     bool AllowPropModsDuringResolve()   GET_IT(ALLOW_PROP_MODS_DURING_RESOLVE)
  1559     bool AllowPropModsToPrototype()     GET_IT(ALLOW_PROP_MODS_TO_PROTOTYPE)
  1560     bool IsGlobalObject()               GET_IT(IS_GLOBAL_OBJECT)
  1561     bool DontReflectInterfaceNames()    GET_IT(DONT_REFLECT_INTERFACE_NAMES)
  1563 #undef GET_IT
  1564 };
  1566 /***************************************************************************/
  1568 // XPCNativeScriptableShared is used to hold the JSClass and the
  1569 // associated scriptable flags for XPCWrappedNatives. These are shared across
  1570 // the runtime and are garbage collected by xpconnect. We *used* to just store
  1571 // this inside the XPCNativeScriptableInfo (usually owned by instances of
  1572 // XPCWrappedNativeProto. This had two problems... It was wasteful, and it
  1573 // was a big problem when wrappers are reparented to different scopes (and
  1574 // thus different protos (the DOM does this).
  1576 // We maintain the invariant that every JSClass for which ext.isWrappedNative
  1577 // is true is a contained in an instance of this struct, and can thus be cast
  1578 // to it.
  1579 struct XPCWrappedNativeJSClass
  1581     js::Class base;
  1582     uint32_t interfacesBitmap;
  1583 };
  1585 class XPCNativeScriptableShared
  1587 public:
  1588     const XPCNativeScriptableFlags& GetFlags() const {return mFlags;}
  1589     uint32_t                        GetInterfacesBitmap() const
  1590         {return mJSClass.interfacesBitmap;}
  1591     const JSClass*                  GetJSClass()
  1592         {return Jsvalify(&mJSClass.base);}
  1594     XPCNativeScriptableShared(uint32_t aFlags, char* aName,
  1595                               uint32_t interfacesBitmap)
  1596         : mFlags(aFlags)
  1597         {memset(&mJSClass, 0, sizeof(mJSClass));
  1598          mJSClass.base.name = aName;  // take ownership
  1599          mJSClass.interfacesBitmap = interfacesBitmap;
  1600          MOZ_COUNT_CTOR(XPCNativeScriptableShared);}
  1602     ~XPCNativeScriptableShared()
  1603         {if (mJSClass.base.name)nsMemory::Free((void*)mJSClass.base.name);
  1604          MOZ_COUNT_DTOR(XPCNativeScriptableShared);}
  1606     char* TransferNameOwnership()
  1607         {char* name=(char*)mJSClass.base.name; mJSClass.base.name = nullptr;
  1608         return name;}
  1610     void PopulateJSClass();
  1612     void Mark()       {mFlags.Mark();}
  1613     void Unmark()     {mFlags.Unmark();}
  1614     bool IsMarked() const {return mFlags.IsMarked();}
  1616 private:
  1617     XPCNativeScriptableFlags mFlags;
  1618     XPCWrappedNativeJSClass  mJSClass;
  1619 };
  1621 /***************************************************************************/
  1622 // XPCNativeScriptableInfo is used to hold the nsIXPCScriptable state for a
  1623 // given class or instance.
  1625 class XPCNativeScriptableInfo
  1627 public:
  1628     static XPCNativeScriptableInfo*
  1629     Construct(const XPCNativeScriptableCreateInfo* sci);
  1631     nsIXPCScriptable*
  1632     GetCallback() const {return mCallback;}
  1634     const XPCNativeScriptableFlags&
  1635     GetFlags() const      {return mShared->GetFlags();}
  1637     uint32_t
  1638     GetInterfacesBitmap() const {return mShared->GetInterfacesBitmap();}
  1640     const JSClass*
  1641     GetJSClass()          {return mShared->GetJSClass();}
  1643     XPCNativeScriptableShared*
  1644     GetScriptableShared() {return mShared;}
  1646     void
  1647     SetCallback(nsIXPCScriptable* s) {mCallback = s;}
  1648     void
  1649     SetCallback(already_AddRefed<nsIXPCScriptable>&& s) {mCallback = s;}
  1651     void
  1652     SetScriptableShared(XPCNativeScriptableShared* shared) {mShared = shared;}
  1654     void Mark() {
  1655         if (mShared)
  1656             mShared->Mark();
  1659     void TraceJS(JSTracer *trc) {}
  1660     void AutoTrace(JSTracer *trc) {}
  1662 protected:
  1663     XPCNativeScriptableInfo(nsIXPCScriptable* scriptable = nullptr,
  1664                             XPCNativeScriptableShared* shared = nullptr)
  1665         : mCallback(scriptable), mShared(shared)
  1666                                {MOZ_COUNT_CTOR(XPCNativeScriptableInfo);}
  1667 public:
  1668     ~XPCNativeScriptableInfo() {MOZ_COUNT_DTOR(XPCNativeScriptableInfo);}
  1669 private:
  1671     // disable copy ctor and assignment
  1672     XPCNativeScriptableInfo(const XPCNativeScriptableInfo& r); // not implemented
  1673     XPCNativeScriptableInfo& operator= (const XPCNativeScriptableInfo& r); // not implemented
  1675 private:
  1676     nsCOMPtr<nsIXPCScriptable>  mCallback;
  1677     XPCNativeScriptableShared*  mShared;
  1678 };
  1680 /***************************************************************************/
  1681 // XPCNativeScriptableCreateInfo is used in creating new wrapper and protos.
  1682 // it abstracts out the scriptable interface pointer and the flags. After
  1683 // creation these are factored differently using XPCNativeScriptableInfo.
  1685 class MOZ_STACK_CLASS XPCNativeScriptableCreateInfo
  1687 public:
  1689     XPCNativeScriptableCreateInfo(const XPCNativeScriptableInfo& si)
  1690         : mCallback(si.GetCallback()), mFlags(si.GetFlags()),
  1691           mInterfacesBitmap(si.GetInterfacesBitmap()) {}
  1693     XPCNativeScriptableCreateInfo(already_AddRefed<nsIXPCScriptable>&& callback,
  1694                                   XPCNativeScriptableFlags flags,
  1695                                   uint32_t interfacesBitmap)
  1696         : mCallback(callback), mFlags(flags),
  1697           mInterfacesBitmap(interfacesBitmap) {}
  1699     XPCNativeScriptableCreateInfo()
  1700         : mFlags(0), mInterfacesBitmap(0) {}
  1703     nsIXPCScriptable*
  1704     GetCallback() const {return mCallback;}
  1706     const XPCNativeScriptableFlags&
  1707     GetFlags() const      {return mFlags;}
  1709     uint32_t
  1710     GetInterfacesBitmap() const     {return mInterfacesBitmap;}
  1712     void
  1713     SetCallback(already_AddRefed<nsIXPCScriptable>&& callback)
  1714         {mCallback = callback;}
  1716     void
  1717     SetFlags(const XPCNativeScriptableFlags& flags)  {mFlags = flags;}
  1719     void
  1720     SetInterfacesBitmap(uint32_t interfacesBitmap)
  1721         {mInterfacesBitmap = interfacesBitmap;}
  1723 private:
  1724     nsCOMPtr<nsIXPCScriptable>  mCallback;
  1725     XPCNativeScriptableFlags    mFlags;
  1726     uint32_t                    mInterfacesBitmap;
  1727 };
  1729 /***********************************************/
  1730 // XPCWrappedNativeProto hold the additional shared wrapper data
  1731 // for XPCWrappedNative whose native objects expose nsIClassInfo.
  1733 class XPCWrappedNativeProto
  1735 public:
  1736     static XPCWrappedNativeProto*
  1737     GetNewOrUsed(XPCWrappedNativeScope* scope,
  1738                  nsIClassInfo* classInfo,
  1739                  const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
  1740                  bool callPostCreatePrototype = true);
  1742     XPCWrappedNativeScope*
  1743     GetScope()   const {return mScope;}
  1745     XPCJSRuntime*
  1746     GetRuntime() const {return mScope->GetRuntime();}
  1748     JSObject*
  1749     GetJSProtoObject() const {
  1750         JS::ExposeObjectToActiveJS(mJSProtoObject);
  1751         return mJSProtoObject;
  1754     nsIClassInfo*
  1755     GetClassInfo()     const {return mClassInfo;}
  1757     XPCNativeSet*
  1758     GetSet()           const {return mSet;}
  1760     XPCNativeScriptableInfo*
  1761     GetScriptableInfo()   {return mScriptableInfo;}
  1763     uint32_t
  1764     GetClassInfoFlags() const {return mClassInfoFlags;}
  1766 #ifdef GET_IT
  1767 #undef GET_IT
  1768 #endif
  1769 #define GET_IT(f_) const {return !!(mClassInfoFlags & nsIClassInfo:: f_ );}
  1771     bool ClassIsSingleton()           GET_IT(SINGLETON)
  1772     bool ClassIsDOMObject()           GET_IT(DOM_OBJECT)
  1773     bool ClassIsPluginObject()        GET_IT(PLUGIN_OBJECT)
  1775 #undef GET_IT
  1777     void SetScriptableInfo(XPCNativeScriptableInfo* si)
  1778         {MOZ_ASSERT(!mScriptableInfo, "leak here!"); mScriptableInfo = si;}
  1780     bool CallPostCreatePrototype();
  1781     void JSProtoObjectFinalized(js::FreeOp *fop, JSObject *obj);
  1783     void SystemIsBeingShutDown();
  1785     void DebugDump(int16_t depth);
  1787     void TraceSelf(JSTracer *trc) {
  1788         if (mJSProtoObject)
  1789             mJSProtoObject.trace(trc, "XPCWrappedNativeProto::mJSProtoObject");
  1792     void TraceInside(JSTracer *trc) {
  1793         if (JS_IsGCMarkingTracer(trc)) {
  1794             mSet->Mark();
  1795             if (mScriptableInfo)
  1796                 mScriptableInfo->Mark();
  1799         GetScope()->TraceInside(trc);
  1802     void TraceJS(JSTracer *trc) {
  1803         TraceSelf(trc);
  1804         TraceInside(trc);
  1807     void WriteBarrierPre(JSRuntime* rt)
  1809         if (JS::IsIncrementalBarrierNeeded(rt) && mJSProtoObject)
  1810             mJSProtoObject.writeBarrierPre(rt);
  1813     // NOP. This is just here to make the AutoMarkingPtr code compile.
  1814     inline void AutoTrace(JSTracer* trc) {}
  1816     // Yes, we *do* need to mark the mScriptableInfo in both cases.
  1817     void Mark() const
  1818         {mSet->Mark();
  1819          if (mScriptableInfo) mScriptableInfo->Mark();}
  1821 #ifdef DEBUG
  1822     void ASSERT_SetNotMarked() const {mSet->ASSERT_NotMarked();}
  1823 #endif
  1825     ~XPCWrappedNativeProto();
  1827 protected:
  1828     // disable copy ctor and assignment
  1829     XPCWrappedNativeProto(const XPCWrappedNativeProto& r); // not implemented
  1830     XPCWrappedNativeProto& operator= (const XPCWrappedNativeProto& r); // not implemented
  1832     // hide ctor
  1833     XPCWrappedNativeProto(XPCWrappedNativeScope* Scope,
  1834                           nsIClassInfo* ClassInfo,
  1835                           uint32_t ClassInfoFlags,
  1836                           XPCNativeSet* Set);
  1838     bool Init(const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
  1839               bool callPostCreatePrototype);
  1841 private:
  1842 #ifdef DEBUG
  1843     static int32_t gDEBUG_LiveProtoCount;
  1844 #endif
  1846 private:
  1847     XPCWrappedNativeScope*   mScope;
  1848     JS::ObjectPtr            mJSProtoObject;
  1849     nsCOMPtr<nsIClassInfo>   mClassInfo;
  1850     uint32_t                 mClassInfoFlags;
  1851     XPCNativeSet*            mSet;
  1852     XPCNativeScriptableInfo* mScriptableInfo;
  1853 };
  1855 /***********************************************/
  1856 // XPCWrappedNativeTearOff represents the info needed to make calls to one
  1857 // interface on the underlying native object of a XPCWrappedNative.
  1859 class XPCWrappedNativeTearOff
  1861 public:
  1862     bool IsAvailable() const {return mInterface == nullptr;}
  1863     bool IsReserved()  const {return mInterface == (XPCNativeInterface*)1;}
  1864     bool IsValid()     const {return !IsAvailable() && !IsReserved();}
  1865     void   SetReserved()       {mInterface = (XPCNativeInterface*)1;}
  1867     XPCNativeInterface* GetInterface() const {return mInterface;}
  1868     nsISupports*        GetNative()    const {return mNative;}
  1869     JSObject*           GetJSObject();
  1870     JSObject*           GetJSObjectPreserveColor() const;
  1871     void SetInterface(XPCNativeInterface*  Interface) {mInterface = Interface;}
  1872     void SetNative(nsISupports*  Native)              {mNative = Native;}
  1873     void SetJSObject(JSObject*  JSObj);
  1875     void JSObjectFinalized() {SetJSObject(nullptr);}
  1877     XPCWrappedNativeTearOff()
  1878         : mInterface(nullptr), mNative(nullptr), mJSObject(nullptr) {}
  1879     ~XPCWrappedNativeTearOff();
  1881     // NOP. This is just here to make the AutoMarkingPtr code compile.
  1882     inline void TraceJS(JSTracer* trc) {}
  1883     inline void AutoTrace(JSTracer* trc) {}
  1885     void Mark()       {mJSObject = (JSObject*)(intptr_t(mJSObject) | 1);}
  1886     void Unmark()     {mJSObject = (JSObject*)(intptr_t(mJSObject) & ~1);}
  1887     bool IsMarked() const {return !!(intptr_t(mJSObject) & 1);}
  1889 private:
  1890     XPCWrappedNativeTearOff(const XPCWrappedNativeTearOff& r) MOZ_DELETE;
  1891     XPCWrappedNativeTearOff& operator= (const XPCWrappedNativeTearOff& r) MOZ_DELETE;
  1893 private:
  1894     XPCNativeInterface* mInterface;
  1895     nsISupports*        mNative;
  1896     JSObject*           mJSObject;
  1897 };
  1899 /***********************************************/
  1900 // XPCWrappedNativeTearOffChunk is a collections of XPCWrappedNativeTearOff
  1901 // objects. It lets us allocate a set of XPCWrappedNativeTearOff objects and
  1902 // link the sets - rather than only having the option of linking single
  1903 // XPCWrappedNativeTearOff objects.
  1904 //
  1905 // The value of XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK can be tuned at buildtime
  1906 // to balance between the code of allocations of additional chunks and the waste
  1907 // of space for ununsed XPCWrappedNativeTearOff objects.
  1909 #define XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK 1
  1911 class XPCWrappedNativeTearOffChunk
  1913 friend class XPCWrappedNative;
  1914 private:
  1915     XPCWrappedNativeTearOffChunk() : mNextChunk(nullptr) {}
  1916     ~XPCWrappedNativeTearOffChunk() {delete mNextChunk;}
  1918 private:
  1919     XPCWrappedNativeTearOff mTearOffs[XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK];
  1920     XPCWrappedNativeTearOffChunk* mNextChunk;
  1921 };
  1923 void *xpc_GetJSPrivate(JSObject *obj);
  1925 /***************************************************************************/
  1926 // XPCWrappedNative the wrapper around one instance of a native xpcom object
  1927 // to be used from JavaScript.
  1929 class XPCWrappedNative : public nsIXPConnectWrappedNative
  1931 public:
  1932     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  1933     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
  1934     NS_DECL_NSIXPCONNECTWRAPPEDNATIVE
  1936     NS_DECL_CYCLE_COLLECTION_CLASS(XPCWrappedNative)
  1938     nsIPrincipal* GetObjectPrincipal() const;
  1940     bool
  1941     IsValid() const { return mFlatJSObject.hasFlag(FLAT_JS_OBJECT_VALID); }
  1943 #define XPC_SCOPE_WORD(s)   (intptr_t(s))
  1944 #define XPC_SCOPE_MASK      (intptr_t(0x3))
  1945 #define XPC_SCOPE_TAG       (intptr_t(0x1))
  1946 #define XPC_WRAPPER_EXPIRED (intptr_t(0x2))
  1948     static inline bool
  1949     IsTaggedScope(XPCWrappedNativeScope* s)
  1950         {return XPC_SCOPE_WORD(s) & XPC_SCOPE_TAG;}
  1952     static inline XPCWrappedNativeScope*
  1953     TagScope(XPCWrappedNativeScope* s)
  1954         {MOZ_ASSERT(!IsTaggedScope(s), "bad pointer!");
  1955          return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) | XPC_SCOPE_TAG);}
  1957     static inline XPCWrappedNativeScope*
  1958     UnTagScope(XPCWrappedNativeScope* s)
  1959         {return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) & ~XPC_SCOPE_TAG);}
  1961     inline bool
  1962     IsWrapperExpired() const
  1963         {return XPC_SCOPE_WORD(mMaybeScope) & XPC_WRAPPER_EXPIRED;}
  1965     bool
  1966     HasProto() const {return !IsTaggedScope(mMaybeScope);}
  1968     XPCWrappedNativeProto*
  1969     GetProto() const
  1970         {return HasProto() ?
  1971          (XPCWrappedNativeProto*)
  1972          (XPC_SCOPE_WORD(mMaybeProto) & ~XPC_SCOPE_MASK) : nullptr;}
  1974     void SetProto(XPCWrappedNativeProto* p);
  1976     XPCWrappedNativeScope*
  1977     GetScope() const
  1978         {return GetProto() ? GetProto()->GetScope() :
  1979          (XPCWrappedNativeScope*)
  1980          (XPC_SCOPE_WORD(mMaybeScope) & ~XPC_SCOPE_MASK);}
  1982     nsISupports*
  1983     GetIdentityObject() const {return mIdentity;}
  1985     /**
  1986      * This getter clears the gray bit before handing out the JSObject which
  1987      * means that the object is guaranteed to be kept alive past the next CC.
  1988      */
  1989     JSObject*
  1990     GetFlatJSObject() const
  1992         JS::ExposeObjectToActiveJS(mFlatJSObject);
  1993         return mFlatJSObject;
  1996     /**
  1997      * This getter does not change the color of the JSObject meaning that the
  1998      * object returned is not guaranteed to be kept alive past the next CC.
  2000      * This should only be called if you are certain that the return value won't
  2001      * be passed into a JS API function and that it won't be stored without
  2002      * being rooted (or otherwise signaling the stored value to the CC).
  2003      */
  2004     JSObject*
  2005     GetFlatJSObjectPreserveColor() const {return mFlatJSObject;}
  2007     XPCNativeSet*
  2008     GetSet() const {return mSet;}
  2010     void
  2011     SetSet(XPCNativeSet* set) {mSet = set;}
  2013     static XPCWrappedNative* Get(JSObject *obj) {
  2014         MOZ_ASSERT(IS_WN_REFLECTOR(obj));
  2015         return (XPCWrappedNative*)js::GetObjectPrivate(obj);
  2018 private:
  2019     inline void
  2020     ExpireWrapper()
  2021         {mMaybeScope = (XPCWrappedNativeScope*)
  2022                        (XPC_SCOPE_WORD(mMaybeScope) | XPC_WRAPPER_EXPIRED);}
  2024 public:
  2026     XPCNativeScriptableInfo*
  2027     GetScriptableInfo() const {return mScriptableInfo;}
  2029     nsIXPCScriptable*      // call this wrong and you deserve to crash
  2030     GetScriptableCallback() const  {return mScriptableInfo->GetCallback();}
  2032     nsIClassInfo*
  2033     GetClassInfo() const {return IsValid() && HasProto() ?
  2034                             GetProto()->GetClassInfo() : nullptr;}
  2036     bool
  2037     HasMutatedSet() const {return IsValid() &&
  2038                                   (!HasProto() ||
  2039                                    GetSet() != GetProto()->GetSet());}
  2041     XPCJSRuntime*
  2042     GetRuntime() const {XPCWrappedNativeScope* scope = GetScope();
  2043                         return scope ? scope->GetRuntime() : nullptr;}
  2045     static nsresult
  2046     WrapNewGlobal(xpcObjectHelper &nativeHelper,
  2047                   nsIPrincipal *principal, bool initStandardClasses,
  2048                   JS::CompartmentOptions& aOptions,
  2049                   XPCWrappedNative **wrappedGlobal);
  2051     static nsresult
  2052     GetNewOrUsed(xpcObjectHelper& helper,
  2053                  XPCWrappedNativeScope* Scope,
  2054                  XPCNativeInterface* Interface,
  2055                  XPCWrappedNative** wrapper);
  2057 public:
  2058     static nsresult
  2059     GetUsedOnly(nsISupports* Object,
  2060                 XPCWrappedNativeScope* Scope,
  2061                 XPCNativeInterface* Interface,
  2062                 XPCWrappedNative** wrapper);
  2064     static nsresult
  2065     ReparentWrapperIfFound(XPCWrappedNativeScope* aOldScope,
  2066                            XPCWrappedNativeScope* aNewScope,
  2067                            JS::HandleObject aNewParent,
  2068                            nsISupports* aCOMObj);
  2070     nsresult RescueOrphans();
  2072     void FlatJSObjectFinalized();
  2074     void SystemIsBeingShutDown();
  2076     enum CallMode {CALL_METHOD, CALL_GETTER, CALL_SETTER};
  2078     static bool CallMethod(XPCCallContext& ccx,
  2079                            CallMode mode = CALL_METHOD);
  2081     static bool GetAttribute(XPCCallContext& ccx)
  2082         {return CallMethod(ccx, CALL_GETTER);}
  2084     static bool SetAttribute(XPCCallContext& ccx)
  2085         {return CallMethod(ccx, CALL_SETTER);}
  2087     inline bool HasInterfaceNoQI(const nsIID& iid);
  2089     XPCWrappedNativeTearOff* LocateTearOff(XPCNativeInterface* aInterface);
  2090     XPCWrappedNativeTearOff* FindTearOff(XPCNativeInterface* aInterface,
  2091                                          bool needJSObject = false,
  2092                                          nsresult* pError = nullptr);
  2093     void Mark() const
  2095         mSet->Mark();
  2096         if (mScriptableInfo) mScriptableInfo->Mark();
  2097         if (HasProto()) GetProto()->Mark();
  2100     // Yes, we *do* need to mark the mScriptableInfo in both cases.
  2101     inline void TraceInside(JSTracer *trc) {
  2102         if (JS_IsGCMarkingTracer(trc)) {
  2103             mSet->Mark();
  2104             if (mScriptableInfo)
  2105                 mScriptableInfo->Mark();
  2107         if (HasProto())
  2108             GetProto()->TraceSelf(trc);
  2109         else
  2110             GetScope()->TraceInside(trc);
  2111         if (mFlatJSObject && JS_IsGlobalObject(mFlatJSObject))
  2113             xpc::TraceXPCGlobal(trc, mFlatJSObject);
  2117     void TraceJS(JSTracer *trc) {
  2118         TraceInside(trc);
  2121     void TraceSelf(JSTracer *trc) {
  2122         // If this got called, we're being kept alive by someone who really
  2123         // needs us alive and whole.  Do not let our mFlatJSObject go away.
  2124         // This is the only time we should be tracing our mFlatJSObject,
  2125         // normally somebody else is doing that. Be careful not to trace the
  2126         // bogus INVALID_OBJECT value we can have during init, though.
  2127         if (mFlatJSObject) {
  2128             JS_CallTenuredObjectTracer(trc, &mFlatJSObject,
  2129                                        "XPCWrappedNative::mFlatJSObject");
  2133     static void Trace(JSTracer *trc, JSObject *obj);
  2135     void AutoTrace(JSTracer *trc) {
  2136         TraceSelf(trc);
  2139 #ifdef DEBUG
  2140     void ASSERT_SetsNotMarked() const
  2141         {mSet->ASSERT_NotMarked();
  2142          if (HasProto()){GetProto()->ASSERT_SetNotMarked();}}
  2143 #endif
  2145     inline void SweepTearOffs();
  2147     // Returns a string that shuld be free'd using JS_smprintf_free (or null).
  2148     char* ToString(XPCWrappedNativeTearOff* to = nullptr) const;
  2150     static void GatherProtoScriptableCreateInfo(nsIClassInfo* classInfo,
  2151                                                 XPCNativeScriptableCreateInfo& sciProto);
  2153     bool HasExternalReference() const {return mRefCnt > 1;}
  2155     void NoteTearoffs(nsCycleCollectionTraversalCallback& cb);
  2157     // Make ctor and dtor protected (rather than private) to placate nsCOMPtr.
  2158 protected:
  2159     XPCWrappedNative(); // not implemented
  2161     // This ctor is used if this object will have a proto.
  2162     XPCWrappedNative(already_AddRefed<nsISupports>&& aIdentity,
  2163                      XPCWrappedNativeProto* aProto);
  2165     // This ctor is used if this object will NOT have a proto.
  2166     XPCWrappedNative(already_AddRefed<nsISupports>&& aIdentity,
  2167                      XPCWrappedNativeScope* aScope,
  2168                      XPCNativeSet* aSet);
  2170     virtual ~XPCWrappedNative();
  2171     void Destroy();
  2173     void UpdateScriptableInfo(XPCNativeScriptableInfo *si);
  2175 private:
  2176     enum {
  2177         // Flags bits for mFlatJSObject:
  2178         FLAT_JS_OBJECT_VALID = JS_BIT(0)
  2179     };
  2181 private:
  2183     bool Init(JS::HandleObject parent, const XPCNativeScriptableCreateInfo* sci);
  2184     bool FinishInit();
  2186     bool ExtendSet(XPCNativeInterface* aInterface);
  2188     nsresult InitTearOff(XPCWrappedNativeTearOff* aTearOff,
  2189                          XPCNativeInterface* aInterface,
  2190                          bool needJSObject);
  2192     bool InitTearOffJSObject(XPCWrappedNativeTearOff* to);
  2194 public:
  2195     static const XPCNativeScriptableCreateInfo& GatherScriptableCreateInfo(nsISupports* obj,
  2196                                                                            nsIClassInfo* classInfo,
  2197                                                                            XPCNativeScriptableCreateInfo& sciProto,
  2198                                                                            XPCNativeScriptableCreateInfo& sciWrapper);
  2200 private:
  2201     union
  2203         XPCWrappedNativeScope*   mMaybeScope;
  2204         XPCWrappedNativeProto*   mMaybeProto;
  2205     };
  2206     XPCNativeSet*                mSet;
  2207     JS::TenuredHeap<JSObject*>   mFlatJSObject;
  2208     XPCNativeScriptableInfo*     mScriptableInfo;
  2209     XPCWrappedNativeTearOffChunk mFirstChunk;
  2210 };
  2212 /***************************************************************************
  2213 ****************************************************************************
  2215 * Core classes for wrapped JSObject for use from native code...
  2217 ****************************************************************************
  2218 ***************************************************************************/
  2220 // this interfaces exists so we can refcount nsXPCWrappedJSClass
  2221 // {2453EBA0-A9B8-11d2-BA64-00805F8A5DD7}
  2222 #define NS_IXPCONNECT_WRAPPED_JS_CLASS_IID                                    \
  2223 { 0x2453eba0, 0xa9b8, 0x11d2,                                                 \
  2224   { 0xba, 0x64, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
  2226 class nsIXPCWrappedJSClass : public nsISupports
  2228 public:
  2229     NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXPCONNECT_WRAPPED_JS_CLASS_IID)
  2230     NS_IMETHOD DebugDump(int16_t depth) = 0;
  2231 };
  2233 NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPCWrappedJSClass,
  2234                               NS_IXPCONNECT_WRAPPED_JS_CLASS_IID)
  2236 /*************************/
  2237 // nsXPCWrappedJSClass represents the sharable factored out common code and
  2238 // data for nsXPCWrappedJS instances for the same interface type.
  2240 class nsXPCWrappedJSClass : public nsIXPCWrappedJSClass
  2242     // all the interface method declarations...
  2243     NS_DECL_ISUPPORTS
  2244     NS_IMETHOD DebugDump(int16_t depth);
  2245 public:
  2247     static already_AddRefed<nsXPCWrappedJSClass>
  2248     GetNewOrUsed(JSContext* cx,
  2249                  REFNSIID aIID);
  2251     REFNSIID GetIID() const {return mIID;}
  2252     XPCJSRuntime* GetRuntime() const {return mRuntime;}
  2253     nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;}
  2254     const char* GetInterfaceName();
  2256     static bool IsWrappedJS(nsISupports* aPtr);
  2258     NS_IMETHOD DelegatedQueryInterface(nsXPCWrappedJS* self, REFNSIID aIID,
  2259                                        void** aInstancePtr);
  2261     JSObject* GetRootJSObject(JSContext* cx, JSObject* aJSObj);
  2263     NS_IMETHOD CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
  2264                           const XPTMethodDescriptor* info,
  2265                           nsXPTCMiniVariant* params);
  2267     JSObject*  CallQueryInterfaceOnJSObject(JSContext* cx,
  2268                                             JSObject* jsobj, REFNSIID aIID);
  2270     static nsresult BuildPropertyEnumerator(XPCCallContext& ccx,
  2271                                             JSObject* aJSObj,
  2272                                             nsISimpleEnumerator** aEnumerate);
  2274     static nsresult GetNamedPropertyAsVariant(XPCCallContext& ccx,
  2275                                               JSObject* aJSObj,
  2276                                               const nsAString& aName,
  2277                                               nsIVariant** aResult);
  2279     virtual ~nsXPCWrappedJSClass();
  2281     static nsresult CheckForException(XPCCallContext & ccx,
  2282                                       const char * aPropertyName,
  2283                                       const char * anInterfaceName,
  2284                                       bool aForceReport);
  2285 private:
  2286     nsXPCWrappedJSClass();   // not implemented
  2287     nsXPCWrappedJSClass(JSContext* cx, REFNSIID aIID,
  2288                         nsIInterfaceInfo* aInfo);
  2290     bool IsReflectable(uint16_t i) const
  2291         {return (bool)(mDescriptors[i/32] & (1 << (i%32)));}
  2292     void SetReflectable(uint16_t i, bool b)
  2293         {if (b) mDescriptors[i/32] |= (1 << (i%32));
  2294          else mDescriptors[i/32] &= ~(1 << (i%32));}
  2296     bool GetArraySizeFromParam(JSContext* cx,
  2297                                const XPTMethodDescriptor* method,
  2298                                const nsXPTParamInfo& param,
  2299                                uint16_t methodIndex,
  2300                                uint8_t paramIndex,
  2301                                nsXPTCMiniVariant* params,
  2302                                uint32_t* result);
  2304     bool GetInterfaceTypeFromParam(JSContext* cx,
  2305                                    const XPTMethodDescriptor* method,
  2306                                    const nsXPTParamInfo& param,
  2307                                    uint16_t methodIndex,
  2308                                    const nsXPTType& type,
  2309                                    nsXPTCMiniVariant* params,
  2310                                    nsID* result);
  2312     void CleanupPointerArray(const nsXPTType& datum_type,
  2313                              uint32_t array_count,
  2314                              void** arrayp);
  2316     void CleanupPointerTypeObject(const nsXPTType& type,
  2317                                   void** pp);
  2319 private:
  2320     XPCJSRuntime* mRuntime;
  2321     nsCOMPtr<nsIInterfaceInfo> mInfo;
  2322     char* mName;
  2323     nsIID mIID;
  2324     uint32_t* mDescriptors;
  2325 };
  2327 /*************************/
  2328 // nsXPCWrappedJS is a wrapper for a single JSObject for use from native code.
  2329 // nsXPCWrappedJS objects are chained together to represent the various
  2330 // interface on the single underlying (possibly aggregate) JSObject.
  2332 class nsXPCWrappedJS : protected nsAutoXPTCStub,
  2333                        public nsIXPConnectWrappedJS,
  2334                        public nsSupportsWeakReference,
  2335                        public nsIPropertyBag,
  2336                        public XPCRootSetElem
  2338 public:
  2339     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  2340     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
  2341     NS_DECL_NSIXPCONNECTWRAPPEDJS
  2342     NS_DECL_NSISUPPORTSWEAKREFERENCE
  2343     NS_DECL_NSIPROPERTYBAG
  2345     NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(nsXPCWrappedJS, nsIXPConnectWrappedJS)
  2347     NS_IMETHOD CallMethod(uint16_t methodIndex,
  2348                           const XPTMethodDescriptor *info,
  2349                           nsXPTCMiniVariant* params);
  2351     /*
  2352     * This is rarely called directly. Instead one usually calls
  2353     * XPCConvert::JSObject2NativeInterface which will handles cases where the
  2354     * JS object is already a wrapped native or a DOM object.
  2355     */
  2357     static nsresult
  2358     GetNewOrUsed(JS::HandleObject aJSObj,
  2359                  REFNSIID aIID,
  2360                  nsXPCWrappedJS** wrapper);
  2362     nsISomeInterface* GetXPTCStub() { return mXPTCStub; }
  2364     /**
  2365      * This getter does not change the color of the JSObject meaning that the
  2366      * object returned is not guaranteed to be kept alive past the next CC.
  2368      * This should only be called if you are certain that the return value won't
  2369      * be passed into a JS API function and that it won't be stored without
  2370      * being rooted (or otherwise signaling the stored value to the CC).
  2371      */
  2372     JSObject* GetJSObjectPreserveColor() const {return mJSObj;}
  2374     nsXPCWrappedJSClass*  GetClass() const {return mClass;}
  2375     REFNSIID GetIID() const {return GetClass()->GetIID();}
  2376     nsXPCWrappedJS* GetRootWrapper() const {return mRoot;}
  2377     nsXPCWrappedJS* GetNextWrapper() const {return mNext;}
  2379     nsXPCWrappedJS* Find(REFNSIID aIID);
  2380     nsXPCWrappedJS* FindInherited(REFNSIID aIID);
  2381     nsXPCWrappedJS* FindOrFindInherited(REFNSIID aIID) {
  2382         nsXPCWrappedJS* wrapper = Find(aIID);
  2383         if (wrapper)
  2384             return wrapper;
  2385         return FindInherited(aIID);
  2388     bool IsRootWrapper() const {return mRoot == this;}
  2389     bool IsValid() const {return mJSObj != nullptr;}
  2390     void SystemIsBeingShutDown();
  2392     // These two methods are used by JSObject2WrappedJSMap::FindDyingJSObjects
  2393     // to find non-rooting wrappers for dying JS objects. See the top of
  2394     // XPCWrappedJS.cpp for more details.
  2395     bool IsSubjectToFinalization() const {return IsValid() && mRefCnt == 1;}
  2396     bool IsObjectAboutToBeFinalized() {return JS_IsAboutToBeFinalized(&mJSObj);}
  2398     bool IsAggregatedToNative() const {return mRoot->mOuter != nullptr;}
  2399     nsISupports* GetAggregatedNativeObject() const {return mRoot->mOuter;}
  2400     void SetAggregatedNativeObject(nsISupports *aNative) {
  2401         MOZ_ASSERT(aNative);
  2402         if (mRoot->mOuter) {
  2403             MOZ_ASSERT(mRoot->mOuter == aNative,
  2404                        "Only one aggregated native can be set");
  2405             return;
  2407         mRoot->mOuter = aNative;
  2410     void TraceJS(JSTracer* trc);
  2411     static void GetTraceName(JSTracer* trc, char *buf, size_t bufsize);
  2413     virtual ~nsXPCWrappedJS();
  2414 protected:
  2415     nsXPCWrappedJS();   // not implemented
  2416     nsXPCWrappedJS(JSContext* cx,
  2417                    JSObject* aJSObj,
  2418                    nsXPCWrappedJSClass* aClass,
  2419                    nsXPCWrappedJS* root);
  2421     bool CanSkip();
  2422     void Destroy();
  2423     void Unlink();
  2425 private:
  2426     JS::Heap<JSObject*> mJSObj;
  2427     nsRefPtr<nsXPCWrappedJSClass> mClass;
  2428     nsXPCWrappedJS* mRoot;    // If mRoot != this, it is an owning pointer.
  2429     nsXPCWrappedJS* mNext;
  2430     nsCOMPtr<nsISupports> mOuter;    // only set in root
  2431 };
  2433 /***************************************************************************/
  2435 class XPCJSObjectHolder : public nsIXPConnectJSObjectHolder,
  2436                           public XPCRootSetElem
  2438 public:
  2439     // all the interface method declarations...
  2440     NS_DECL_ISUPPORTS
  2441     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
  2443     // non-interface implementation
  2445 public:
  2446     static XPCJSObjectHolder* newHolder(JSObject* obj);
  2448     virtual ~XPCJSObjectHolder();
  2450     void TraceJS(JSTracer *trc);
  2451     static void GetTraceName(JSTracer* trc, char *buf, size_t bufsize);
  2453 private:
  2454     XPCJSObjectHolder(JSObject* obj);
  2455     XPCJSObjectHolder(); // not implemented
  2457     JS::Heap<JSObject*> mJSObj;
  2458 };
  2460 /***************************************************************************
  2461 ****************************************************************************
  2463 * All manner of utility classes follow...
  2465 ****************************************************************************
  2466 ***************************************************************************/
  2468 class xpcProperty : public nsIProperty
  2470 public:
  2471   NS_DECL_ISUPPORTS
  2472   NS_DECL_NSIPROPERTY
  2474   xpcProperty(const char16_t* aName, uint32_t aNameLen, nsIVariant* aValue);
  2475   virtual ~xpcProperty() {}
  2477 private:
  2478     nsString             mName;
  2479     nsCOMPtr<nsIVariant> mValue;
  2480 };
  2482 /***************************************************************************/
  2483 // class here just for static methods
  2484 class XPCConvert
  2486 public:
  2487     static bool IsMethodReflectable(const XPTMethodDescriptor& info);
  2489     /**
  2490      * Convert a native object into a jsval.
  2492      * @param d [out] the resulting jsval
  2493      * @param s the native object we're working with
  2494      * @param type the type of object that s is
  2495      * @param iid the interface of s that we want
  2496      * @param scope the default scope to put on the new JSObject's parent
  2497      *        chain
  2498      * @param pErr [out] relevant error code, if any.
  2499      */
  2501     static bool NativeData2JS(JS::MutableHandleValue d,
  2502                               const void* s, const nsXPTType& type,
  2503                               const nsID* iid, nsresult* pErr);
  2505     static bool JSData2Native(void* d, JS::HandleValue s,
  2506                               const nsXPTType& type,
  2507                               bool useAllocator, const nsID* iid,
  2508                               nsresult* pErr);
  2510     /**
  2511      * Convert a native nsISupports into a JSObject.
  2513      * @param dest [out] the resulting JSObject
  2514      * @param src the native object we're working with
  2515      * @param iid the interface of src that we want (may be null)
  2516      * @param Interface the interface of src that we want
  2517      * @param cache the wrapper cache for src (may be null, in which case src
  2518      *              will be QI'ed to get the cache)
  2519      * @param allowNativeWrapper if true, this method may wrap the resulting
  2520      *        JSObject in an XPCNativeWrapper and return that, as needed.
  2521      * @param pErr [out] relevant error code, if any.
  2522      * @param src_is_identity optional performance hint. Set to true only
  2523      *                        if src is the identity pointer.
  2524      */
  2525     static bool NativeInterface2JSObject(JS::MutableHandleValue d,
  2526                                          nsIXPConnectJSObjectHolder** dest,
  2527                                          xpcObjectHelper& aHelper,
  2528                                          const nsID* iid,
  2529                                          XPCNativeInterface** Interface,
  2530                                          bool allowNativeWrapper,
  2531                                          nsresult* pErr);
  2533     static bool GetNativeInterfaceFromJSObject(void** dest, JSObject* src,
  2534                                                const nsID* iid,
  2535                                                nsresult* pErr);
  2536     static bool JSObject2NativeInterface(void** dest, JS::HandleObject src,
  2537                                          const nsID* iid,
  2538                                          nsISupports* aOuter,
  2539                                          nsresult* pErr);
  2540     static bool GetISupportsFromJSObject(JSObject* obj, nsISupports** iface);
  2542     /**
  2543      * Convert a native array into a jsval.
  2545      * @param d [out] the resulting jsval
  2546      * @param s the native array we're working with
  2547      * @param type the type of objects in the array
  2548      * @param iid the interface of each object in the array that we want
  2549      * @param count the number of items in the array
  2550      * @param scope the default scope to put on the new JSObjects' parent chain
  2551      * @param pErr [out] relevant error code, if any.
  2552      */
  2553     static bool NativeArray2JS(JS::MutableHandleValue d, const void** s,
  2554                                const nsXPTType& type, const nsID* iid,
  2555                                uint32_t count, nsresult* pErr);
  2557     static bool JSArray2Native(void** d, JS::HandleValue s,
  2558                                uint32_t count, const nsXPTType& type,
  2559                                const nsID* iid, nsresult* pErr);
  2561     static bool JSTypedArray2Native(void** d,
  2562                                     JSObject* jsarray,
  2563                                     uint32_t count,
  2564                                     const nsXPTType& type,
  2565                                     nsresult* pErr);
  2567     static bool NativeStringWithSize2JS(JS::MutableHandleValue d, const void* s,
  2568                                         const nsXPTType& type,
  2569                                         uint32_t count,
  2570                                         nsresult* pErr);
  2572     static bool JSStringWithSize2Native(void* d, JS::HandleValue s,
  2573                                         uint32_t count, const nsXPTType& type,
  2574                                         nsresult* pErr);
  2576     static nsresult JSValToXPCException(JS::MutableHandleValue s,
  2577                                         const char* ifaceName,
  2578                                         const char* methodName,
  2579                                         nsIException** exception);
  2581     static nsresult JSErrorToXPCException(const char* message,
  2582                                           const char* ifaceName,
  2583                                           const char* methodName,
  2584                                           const JSErrorReport* report,
  2585                                           nsIException** exception);
  2587     static nsresult ConstructException(nsresult rv, const char* message,
  2588                                        const char* ifaceName,
  2589                                        const char* methodName,
  2590                                        nsISupports* data,
  2591                                        nsIException** exception,
  2592                                        JSContext* cx,
  2593                                        jsval *jsExceptionPtr);
  2595 private:
  2596     XPCConvert(); // not implemented
  2598 };
  2600 /***************************************************************************/
  2601 // code for throwing exceptions into JS
  2603 class nsXPCException;
  2605 class XPCThrower
  2607 public:
  2608     static void Throw(nsresult rv, JSContext* cx);
  2609     static void Throw(nsresult rv, XPCCallContext& ccx);
  2610     static void ThrowBadResult(nsresult rv, nsresult result, XPCCallContext& ccx);
  2611     static void ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx);
  2612     static bool SetVerbosity(bool state)
  2613         {bool old = sVerbose; sVerbose = state; return old;}
  2615     static bool CheckForPendingException(nsresult result, JSContext *cx);
  2617 private:
  2618     static void Verbosify(XPCCallContext& ccx,
  2619                           char** psz, bool own);
  2621 private:
  2622     static bool sVerbose;
  2623 };
  2625 /***************************************************************************/
  2627 class nsXPCException
  2629 public:
  2630     static bool NameAndFormatForNSResult(nsresult rv,
  2631                                          const char** name,
  2632                                          const char** format);
  2634     static const void* IterateNSResults(nsresult* rv,
  2635                                         const char** name,
  2636                                         const char** format,
  2637                                         const void** iterp);
  2639     static uint32_t GetNSResultCount();
  2640 };
  2642 /***************************************************************************/
  2643 /*
  2644 * nsJSID implements nsIJSID. It is also used by nsJSIID and nsJSCID as a
  2645 * member (as a hidden implementaion detail) to which they delegate many calls.
  2646 */
  2648 // Initialization is done on demand, and calling the destructor below is always
  2649 // safe.
  2650 extern void xpc_DestroyJSxIDClassObjects();
  2652 class nsJSID : public nsIJSID
  2654 public:
  2655     NS_DEFINE_STATIC_CID_ACCESSOR(NS_JS_ID_CID)
  2657     NS_DECL_ISUPPORTS
  2658     NS_DECL_NSIJSID
  2660     bool InitWithName(const nsID& id, const char *nameString);
  2661     bool SetName(const char* name);
  2662     void   SetNameToNoString()
  2663         {MOZ_ASSERT(!mName, "name already set"); mName = gNoString;}
  2664     bool NameIsSet() const {return nullptr != mName;}
  2665     const nsID& ID() const {return mID;}
  2666     bool IsValid() const {return !mID.Equals(GetInvalidIID());}
  2668     static already_AddRefed<nsJSID> NewID(const char* str);
  2669     static already_AddRefed<nsJSID> NewID(const nsID& id);
  2671     nsJSID();
  2672     virtual ~nsJSID();
  2673 protected:
  2675     void Reset();
  2676     const nsID& GetInvalidIID() const;
  2678 protected:
  2679     static char gNoString[];
  2680     nsID    mID;
  2681     char*   mNumber;
  2682     char*   mName;
  2683 };
  2685 // nsJSIID
  2687 class nsJSIID : public nsIJSIID,
  2688                 public nsIXPCScriptable
  2690 public:
  2691     NS_DECL_ISUPPORTS
  2693     // we manually delagate these to nsJSID
  2694     NS_DECL_NSIJSID
  2696     // we implement the rest...
  2697     NS_DECL_NSIJSIID
  2698     NS_DECL_NSIXPCSCRIPTABLE
  2700     static already_AddRefed<nsJSIID> NewID(nsIInterfaceInfo* aInfo);
  2702     nsJSIID(nsIInterfaceInfo* aInfo);
  2703     nsJSIID(); // not implemented
  2704     virtual ~nsJSIID();
  2706 private:
  2707     nsCOMPtr<nsIInterfaceInfo> mInfo;
  2708 };
  2710 // nsJSCID
  2712 class nsJSCID : public nsIJSCID, public nsIXPCScriptable
  2714 public:
  2715     NS_DECL_ISUPPORTS
  2717     // we manually delagate these to nsJSID
  2718     NS_DECL_NSIJSID
  2720     // we implement the rest...
  2721     NS_DECL_NSIJSCID
  2722     NS_DECL_NSIXPCSCRIPTABLE
  2724     static already_AddRefed<nsJSCID> NewID(const char* str);
  2726     nsJSCID();
  2727     virtual ~nsJSCID();
  2729 private:
  2730     void ResolveName();
  2732 private:
  2733     nsJSID mDetails;
  2734 };
  2737 /***************************************************************************/
  2738 // XPCJSContextStack is not actually an xpcom object, but xpcom calls are
  2739 // delegated to it as an implementation detail.
  2740 struct XPCJSContextInfo {
  2741     XPCJSContextInfo(JSContext* aCx) :
  2742         cx(aCx),
  2743         savedFrameChain(false)
  2744     {}
  2745     JSContext* cx;
  2747     // Whether the frame chain was saved
  2748     bool savedFrameChain;
  2749 };
  2751 namespace xpc {
  2753 // These functions are used in a few places where a callback model makes it
  2754 // impossible to push a JSContext using one of our stack-scoped classes. We
  2755 // depend on those stack-scoped classes to maintain nsIScriptContext
  2756 // invariants, so these functions may only be used of the context is not
  2757 // associated with an nsJSContext/nsIScriptContext.
  2758 bool PushJSContextNoScriptContext(JSContext *aCx);
  2759 void PopJSContextNoScriptContext();
  2761 } /* namespace xpc */
  2763 class XPCJSContextStack
  2765 public:
  2766     XPCJSContextStack(XPCJSRuntime *aRuntime)
  2767       : mRuntime(aRuntime)
  2768       , mSafeJSContext(nullptr)
  2769       , mSafeJSContextGlobal(aRuntime->Runtime(), nullptr)
  2770     { }
  2772     virtual ~XPCJSContextStack();
  2774     uint32_t Count()
  2776         return mStack.Length();
  2779     JSContext *Peek()
  2781         return mStack.IsEmpty() ? nullptr : mStack[mStack.Length() - 1].cx;
  2784     JSContext *InitSafeJSContext();
  2785     JSContext *GetSafeJSContext();
  2786     JSObject *GetSafeJSContextGlobal();
  2787     bool HasJSContext(JSContext *cx);
  2789     const InfallibleTArray<XPCJSContextInfo>* GetStack()
  2790     { return &mStack; }
  2792 private:
  2793     friend class mozilla::AutoCxPusher;
  2794     friend bool xpc::PushJSContextNoScriptContext(JSContext *aCx);;
  2795     friend void xpc::PopJSContextNoScriptContext();
  2797     // We make these private so that stack manipulation can only happen
  2798     // through one of the above friends.
  2799     JSContext *Pop();
  2800     bool Push(JSContext *cx);
  2802     AutoInfallibleTArray<XPCJSContextInfo, 16> mStack;
  2803     XPCJSRuntime* mRuntime;
  2804     JSContext*  mSafeJSContext;
  2805     JS::PersistentRootedObject mSafeJSContextGlobal;
  2806 };
  2808 /***************************************************************************/
  2809 // 'Components' object implementations. nsXPCComponentsBase has the
  2810 // less-privileged stuff that we're willing to expose to XBL.
  2812 class nsXPCComponentsBase : public nsIXPCComponentsBase
  2814 public:
  2815     NS_DECL_ISUPPORTS
  2816     NS_DECL_NSIXPCCOMPONENTSBASE
  2818 public:
  2819     void SystemIsBeingShutDown() { ClearMembers(); }
  2820     virtual ~nsXPCComponentsBase();
  2822     XPCWrappedNativeScope *GetScope() { return mScope; }
  2824 protected:
  2825     nsXPCComponentsBase(XPCWrappedNativeScope* aScope);
  2826     virtual void ClearMembers();
  2828     XPCWrappedNativeScope*                   mScope;
  2830     // Unprivileged members from nsIXPCComponentsBase.
  2831     nsRefPtr<nsXPCComponents_Interfaces>     mInterfaces;
  2832     nsRefPtr<nsXPCComponents_InterfacesByID> mInterfacesByID;
  2833     nsRefPtr<nsXPCComponents_Results>        mResults;
  2835     friend class XPCWrappedNativeScope;
  2836 };
  2838 class nsXPCComponents : public nsXPCComponentsBase,
  2839                         public nsIXPCComponents
  2841 public:
  2842     NS_DECL_ISUPPORTS
  2843     NS_FORWARD_NSIXPCCOMPONENTSBASE(nsXPCComponentsBase::)
  2844     NS_DECL_NSIXPCCOMPONENTS
  2846 protected:
  2847     nsXPCComponents(XPCWrappedNativeScope* aScope);
  2848     virtual ~nsXPCComponents();
  2849     virtual void ClearMembers() MOZ_OVERRIDE;
  2851     // Privileged members added by nsIXPCComponents.
  2852     nsRefPtr<nsXPCComponents_Classes>     mClasses;
  2853     nsRefPtr<nsXPCComponents_ClassesByID> mClassesByID;
  2854     nsRefPtr<nsXPCComponents_ID>          mID;
  2855     nsRefPtr<nsXPCComponents_Exception>   mException;
  2856     nsRefPtr<nsXPCComponents_Constructor> mConstructor;
  2857     nsRefPtr<nsXPCComponents_Utils>       mUtils;
  2859     friend class XPCWrappedNativeScope;
  2860 };
  2863 /***************************************************************************/
  2865 extern JSObject*
  2866 xpc_NewIDObject(JSContext *cx, JS::HandleObject jsobj, const nsID& aID);
  2868 extern const nsID*
  2869 xpc_JSObjectToID(JSContext *cx, JSObject* obj);
  2871 extern bool
  2872 xpc_JSObjectIsID(JSContext *cx, JSObject* obj);
  2874 /***************************************************************************/
  2875 // in XPCDebug.cpp
  2877 extern bool
  2878 xpc_DumpJSStack(JSContext* cx, bool showArgs, bool showLocals,
  2879                 bool showThisProps);
  2881 // Return a newly-allocated string containing a representation of the
  2882 // current JS stack.  It is the *caller's* responsibility to free this
  2883 // string with JS_smprintf_free().
  2884 extern char*
  2885 xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals,
  2886                  bool showThisProps);
  2888 extern bool
  2889 xpc_DumpEvalInJSStackFrame(JSContext* cx, uint32_t frameno, const char* text);
  2891 extern bool
  2892 xpc_InstallJSDebuggerKeywordHandler(JSRuntime* rt);
  2894 /***************************************************************************/
  2896 // Definition of nsScriptError, defined here because we lack a place to put
  2897 // XPCOM objects associated with the JavaScript engine.
  2898 class nsScriptError : public nsIScriptError {
  2899 public:
  2900     nsScriptError();
  2902     virtual ~nsScriptError();
  2904   // TODO - do something reasonable on getting null from these babies.
  2906     NS_DECL_THREADSAFE_ISUPPORTS
  2907     NS_DECL_NSICONSOLEMESSAGE
  2908     NS_DECL_NSISCRIPTERROR
  2910 private:
  2911     nsString mMessage;
  2912     nsString mSourceName;
  2913     uint32_t mLineNumber;
  2914     nsString mSourceLine;
  2915     uint32_t mColumnNumber;
  2916     uint32_t mFlags;
  2917     nsCString mCategory;
  2918     uint64_t mOuterWindowID;
  2919     uint64_t mInnerWindowID;
  2920     int64_t mTimeStamp;
  2921     bool mIsFromPrivateWindow;
  2922 };
  2924 /******************************************************************************
  2925  * Handles pre/post script processing and the setting/resetting the error
  2926  * reporter
  2927  */
  2928 class MOZ_STACK_CLASS AutoScriptEvaluate
  2930 public:
  2931     /**
  2932      * Saves the JSContext as well as initializing our state
  2933      * @param cx The JSContext, this can be null, we don't do anything then
  2934      */
  2935     AutoScriptEvaluate(JSContext * cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  2936          : mJSContext(cx), mErrorReporterSet(false), mEvaluated(false) {
  2937         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  2940     /**
  2941      * Does the pre script evaluation and sets the error reporter if given
  2942      * This function should only be called once, and will assert if called
  2943      * more than once
  2944      * @param errorReporter the error reporter callback function to set
  2945      */
  2947     bool StartEvaluating(JS::HandleObject scope, JSErrorReporter errorReporter = nullptr);
  2949     /**
  2950      * Does the post script evaluation and resets the error reporter
  2951      */
  2952     ~AutoScriptEvaluate();
  2953 private:
  2954     JSContext* mJSContext;
  2955     mozilla::Maybe<JS::AutoSaveExceptionState> mState;
  2956     bool mErrorReporterSet;
  2957     bool mEvaluated;
  2958     mozilla::Maybe<JSAutoCompartment> mAutoCompartment;
  2959     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  2961     // No copying or assignment allowed
  2962     AutoScriptEvaluate(const AutoScriptEvaluate &) MOZ_DELETE;
  2963     AutoScriptEvaluate & operator =(const AutoScriptEvaluate &) MOZ_DELETE;
  2964 };
  2966 /***************************************************************************/
  2967 class MOZ_STACK_CLASS AutoResolveName
  2969 public:
  2970     AutoResolveName(XPCCallContext& ccx, JS::HandleId name
  2971                     MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
  2972           mOld(ccx, XPCJSRuntime::Get()->SetResolveName(name))
  2973 #ifdef DEBUG
  2974           ,mCheck(ccx, name)
  2975 #endif
  2977         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  2979     ~AutoResolveName()
  2981 #ifdef DEBUG
  2982             jsid old =
  2983 #endif
  2984             XPCJSRuntime::Get()->SetResolveName(mOld);
  2985             MOZ_ASSERT(old == mCheck, "Bad Nesting!");
  2988 private:
  2989     JS::RootedId mOld;
  2990 #ifdef DEBUG
  2991     JS::RootedId mCheck;
  2992 #endif
  2993     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  2994 };
  2996 /***************************************************************************/
  2997 // AutoMarkingPtr is the base class for the various AutoMarking pointer types
  2998 // below. This system allows us to temporarily protect instances of our garbage
  2999 // collected types after they are constructed but before they are safely
  3000 // attached to other rooted objects.
  3001 // This base class has pure virtual support for marking.
  3003 class AutoMarkingPtr
  3005   public:
  3006     AutoMarkingPtr(JSContext* cx) {
  3007         mRoot = XPCJSRuntime::Get()->GetAutoRootsAdr();
  3008         mNext = *mRoot;
  3009         *mRoot = this;
  3012     virtual ~AutoMarkingPtr() {
  3013         if (mRoot) {
  3014             MOZ_ASSERT(*mRoot == this);
  3015             *mRoot = mNext;
  3019     void TraceJSAll(JSTracer* trc) {
  3020         for (AutoMarkingPtr *cur = this; cur; cur = cur->mNext)
  3021             cur->TraceJS(trc);
  3024     void MarkAfterJSFinalizeAll() {
  3025         for (AutoMarkingPtr *cur = this; cur; cur = cur->mNext)
  3026             cur->MarkAfterJSFinalize();
  3029   protected:
  3030     virtual void TraceJS(JSTracer* trc) = 0;
  3031     virtual void MarkAfterJSFinalize() = 0;
  3033   private:
  3034     AutoMarkingPtr** mRoot;
  3035     AutoMarkingPtr* mNext;
  3036 };
  3038 template<class T>
  3039 class TypedAutoMarkingPtr : public AutoMarkingPtr
  3041   public:
  3042     TypedAutoMarkingPtr(JSContext* cx) : AutoMarkingPtr(cx), mPtr(nullptr) {}
  3043     TypedAutoMarkingPtr(JSContext* cx, T* ptr) : AutoMarkingPtr(cx), mPtr(ptr) {}
  3045     T* get() const { return mPtr; }
  3046     operator T *() const { return mPtr; }
  3047     T* operator->() const { return mPtr; }
  3049     TypedAutoMarkingPtr<T>& operator =(T* ptr) { mPtr = ptr; return *this; }
  3051   protected:
  3052     virtual void TraceJS(JSTracer* trc)
  3054         if (mPtr) {
  3055             mPtr->TraceJS(trc);
  3056             mPtr->AutoTrace(trc);
  3060     virtual void MarkAfterJSFinalize()
  3062         if (mPtr)
  3063             mPtr->Mark();
  3066   private:
  3067     T* mPtr;
  3068 };
  3070 typedef TypedAutoMarkingPtr<XPCNativeInterface> AutoMarkingNativeInterfacePtr;
  3071 typedef TypedAutoMarkingPtr<XPCNativeSet> AutoMarkingNativeSetPtr;
  3072 typedef TypedAutoMarkingPtr<XPCWrappedNative> AutoMarkingWrappedNativePtr;
  3073 typedef TypedAutoMarkingPtr<XPCWrappedNativeTearOff> AutoMarkingWrappedNativeTearOffPtr;
  3074 typedef TypedAutoMarkingPtr<XPCWrappedNativeProto> AutoMarkingWrappedNativeProtoPtr;
  3075 typedef TypedAutoMarkingPtr<XPCNativeScriptableInfo> AutoMarkingNativeScriptableInfoPtr;
  3077 template<class T>
  3078 class ArrayAutoMarkingPtr : public AutoMarkingPtr
  3080   public:
  3081     ArrayAutoMarkingPtr(JSContext* cx)
  3082       : AutoMarkingPtr(cx), mPtr(nullptr), mCount(0) {}
  3083     ArrayAutoMarkingPtr(JSContext* cx, T** ptr, uint32_t count, bool clear)
  3084       : AutoMarkingPtr(cx), mPtr(ptr), mCount(count)
  3086         if (!mPtr) mCount = 0;
  3087         else if (clear) memset(mPtr, 0, mCount*sizeof(T*));
  3090     T** get() const { return mPtr; }
  3091     operator T **() const { return mPtr; }
  3092     T** operator->() const { return mPtr; }
  3094     ArrayAutoMarkingPtr<T>& operator =(const ArrayAutoMarkingPtr<T> &other)
  3096         mPtr = other.mPtr;
  3097         mCount = other.mCount;
  3098         return *this;
  3101   protected:
  3102     virtual void TraceJS(JSTracer* trc)
  3104         for (uint32_t i = 0; i < mCount; i++) {
  3105             if (mPtr[i]) {
  3106                 mPtr[i]->TraceJS(trc);
  3107                 mPtr[i]->AutoTrace(trc);
  3112     virtual void MarkAfterJSFinalize()
  3114         for (uint32_t i = 0; i < mCount; i++) {
  3115             if (mPtr[i])
  3116                 mPtr[i]->Mark();
  3120   private:
  3121     T** mPtr;
  3122     uint32_t mCount;
  3123 };
  3125 typedef ArrayAutoMarkingPtr<XPCNativeInterface> AutoMarkingNativeInterfacePtrArrayPtr;
  3127 /***************************************************************************/
  3128 namespace xpc {
  3129 // Allocates a string that grants all access ("AllAccess")
  3130 char *
  3131 CloneAllAccess();
  3133 // Returns access if wideName is in list
  3134 char *
  3135 CheckAccessList(const char16_t *wideName, const char *const list[]);
  3136 } /* namespace xpc */
  3138 /***************************************************************************/
  3139 // in xpcvariant.cpp...
  3141 // {1809FD50-91E8-11d5-90F9-0010A4E73D9A}
  3142 #define XPCVARIANT_IID                                                        \
  3143     {0x1809fd50, 0x91e8, 0x11d5,                                              \
  3144       { 0x90, 0xf9, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
  3146 // {DC524540-487E-4501-9AC7-AAA784B17C1C}
  3147 #define XPCVARIANT_CID                                                        \
  3148     {0xdc524540, 0x487e, 0x4501,                                              \
  3149       { 0x9a, 0xc7, 0xaa, 0xa7, 0x84, 0xb1, 0x7c, 0x1c } }
  3151 class XPCVariant : public nsIVariant
  3153 public:
  3154     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  3155     NS_DECL_NSIVARIANT
  3156     NS_DECL_CYCLE_COLLECTION_CLASS(XPCVariant)
  3158     // If this class ever implements nsIWritableVariant, take special care with
  3159     // the case when mJSVal is JSVAL_STRING, since we don't own the data in
  3160     // that case.
  3162     // We #define and iid so that out module local code can use QI to detect
  3163     // if a given nsIVariant is in fact an XPCVariant.
  3164     NS_DECLARE_STATIC_IID_ACCESSOR(XPCVARIANT_IID)
  3166     static already_AddRefed<XPCVariant> newVariant(JSContext* cx, jsval aJSVal);
  3168     /**
  3169      * This getter clears the gray bit before handing out the jsval if the jsval
  3170      * represents a JSObject. That means that the object is guaranteed to be
  3171      * kept alive past the next CC.
  3172      */
  3173     jsval GetJSVal() const {
  3174         if (!JSVAL_IS_PRIMITIVE(mJSVal))
  3175             JS::ExposeObjectToActiveJS(&mJSVal.toObject());
  3176         return mJSVal;
  3179     /**
  3180      * This getter does not change the color of the jsval (if it represents a
  3181      * JSObject) meaning that the value returned is not guaranteed to be kept
  3182      * alive past the next CC.
  3184      * This should only be called if you are certain that the return value won't
  3185      * be passed into a JS API function and that it won't be stored without
  3186      * being rooted (or otherwise signaling the stored value to the CC).
  3187      */
  3188     jsval GetJSValPreserveColor() const {return mJSVal;}
  3190     XPCVariant(JSContext* cx, jsval aJSVal);
  3192     /**
  3193      * Convert a variant into a jsval.
  3195      * @param ccx the context for the whole procedure
  3196      * @param variant the variant to convert
  3197      * @param scope the default scope to put on the new JSObject's parent chain
  3198      * @param pErr [out] relevant error code, if any.
  3199      * @param pJSVal [out] the resulting jsval.
  3200      */
  3201     static bool VariantDataToJS(nsIVariant* variant,
  3202                                 nsresult* pErr, JS::MutableHandleValue pJSVal);
  3204     bool IsPurple()
  3206         return mRefCnt.IsPurple();
  3209     void RemovePurple()
  3211         mRefCnt.RemovePurple();
  3214     void SetCCGeneration(uint32_t aGen)
  3216         mCCGeneration = aGen;
  3219     uint32_t CCGeneration() { return mCCGeneration; }
  3220 protected:
  3221     virtual ~XPCVariant() { }
  3223     bool InitializeData(JSContext* cx);
  3225 protected:
  3226     nsDiscriminatedUnion mData;
  3227     JS::Heap<JS::Value>  mJSVal;
  3228     bool                 mReturnRawObject : 1;
  3229     uint32_t             mCCGeneration : 31;
  3230 };
  3232 NS_DEFINE_STATIC_IID_ACCESSOR(XPCVariant, XPCVARIANT_IID)
  3234 class XPCTraceableVariant: public XPCVariant,
  3235                            public XPCRootSetElem
  3237 public:
  3238     XPCTraceableVariant(JSContext* cx, jsval aJSVal)
  3239         : XPCVariant(cx, aJSVal)
  3241          nsXPConnect::GetRuntimeInstance()->AddVariantRoot(this);
  3244     virtual ~XPCTraceableVariant();
  3246     void TraceJS(JSTracer* trc);
  3247     static void GetTraceName(JSTracer* trc, char *buf, size_t bufsize);
  3248 };
  3250 /***************************************************************************/
  3251 // Utilities
  3253 inline void *
  3254 xpc_GetJSPrivate(JSObject *obj)
  3256     return js::GetObjectPrivate(obj);
  3259 inline JSContext *
  3260 xpc_GetSafeJSContext()
  3262     return XPCJSRuntime::Get()->GetJSContextStack()->GetSafeJSContext();
  3265 namespace xpc {
  3267 // JSNatives to expose atob and btoa in various non-DOM XPConnect scopes.
  3268 bool
  3269 Atob(JSContext *cx, unsigned argc, jsval *vp);
  3271 bool
  3272 Btoa(JSContext *cx, unsigned argc, jsval *vp);
  3275 // Helper function that creates a JSFunction that wraps a native function that
  3276 // forwards the call to the original 'callable'. If the 'doclone' argument is
  3277 // set, it also structure clones non-native arguments for extra security.
  3278 bool
  3279 NewFunctionForwarder(JSContext *cx, JS::HandleId id, JS::HandleObject callable,
  3280                      bool doclone, JS::MutableHandleValue vp);
  3282 bool
  3283 NewFunctionForwarder(JSContext *cx, JS::HandleObject callable,
  3284                      bool doclone, JS::MutableHandleValue vp);
  3286 // Old fashioned xpc error reporter. Try to use JS_ReportError instead.
  3287 nsresult
  3288 ThrowAndFail(nsresult errNum, JSContext *cx, bool *retval);
  3290 struct GlobalProperties {
  3291     GlobalProperties(bool aPromise) {
  3292       mozilla::PodZero(this);
  3293       Promise = true;
  3295     bool Parse(JSContext *cx, JS::HandleObject obj);
  3296     bool Define(JSContext *cx, JS::HandleObject obj);
  3297     bool Promise : 1;
  3298     bool indexedDB : 1;
  3299     bool XMLHttpRequest : 1;
  3300     bool TextDecoder : 1;
  3301     bool TextEncoder : 1;
  3302     bool URL : 1;
  3303     bool atob : 1;
  3304     bool btoa : 1;
  3305 };
  3307 // Infallible.
  3308 already_AddRefed<nsIXPCComponents_utils_Sandbox>
  3309 NewSandboxConstructor();
  3311 // Returns true if class of 'obj' is SandboxClass.
  3312 bool
  3313 IsSandbox(JSObject *obj);
  3315 class MOZ_STACK_CLASS OptionsBase {
  3316 public:
  3317     OptionsBase(JSContext *cx = xpc_GetSafeJSContext(),
  3318                 JSObject *options = nullptr)
  3319         : mCx(cx)
  3320         , mObject(cx, options)
  3321     { }
  3323     virtual bool Parse() = 0;
  3325 protected:
  3326     bool ParseValue(const char *name, JS::MutableHandleValue prop, bool *found = nullptr);
  3327     bool ParseBoolean(const char *name, bool *prop);
  3328     bool ParseObject(const char *name, JS::MutableHandleObject prop);
  3329     bool ParseString(const char *name, nsCString &prop);
  3330     bool ParseString(const char *name, nsString &prop);
  3331     bool ParseId(const char* name, JS::MutableHandleId id);
  3333     JSContext *mCx;
  3334     JS::RootedObject mObject;
  3335 };
  3337 class MOZ_STACK_CLASS SandboxOptions : public OptionsBase {
  3338 public:
  3339     SandboxOptions(JSContext *cx = xpc_GetSafeJSContext(),
  3340                    JSObject *options = nullptr)
  3341         : OptionsBase(cx, options)
  3342         , wantXrays(true)
  3343         , wantComponents(true)
  3344         , wantExportHelpers(false)
  3345         , proto(cx)
  3346         , sameZoneAs(cx)
  3347         , invisibleToDebugger(false)
  3348         , discardSource(false)
  3349         , globalProperties(true)
  3350         , metadata(cx)
  3351     { }
  3353     virtual bool Parse();
  3355     bool wantXrays;
  3356     bool wantComponents;
  3357     bool wantExportHelpers;
  3358     JS::RootedObject proto;
  3359     nsCString sandboxName;
  3360     JS::RootedObject sameZoneAs;
  3361     bool invisibleToDebugger;
  3362     bool discardSource;
  3363     GlobalProperties globalProperties;
  3364     JS::RootedValue metadata;
  3366 protected:
  3367     bool ParseGlobalProperties();
  3368 };
  3370 class MOZ_STACK_CLASS CreateObjectInOptions : public OptionsBase {
  3371 public:
  3372     CreateObjectInOptions(JSContext *cx = xpc_GetSafeJSContext(),
  3373                           JSObject* options = nullptr)
  3374         : OptionsBase(cx, options)
  3375         , defineAs(cx, JSID_VOID)
  3376     { }
  3378     virtual bool Parse() { return ParseId("defineAs", &defineAs); };
  3380     JS::RootedId defineAs;
  3381 };
  3383 class MOZ_STACK_CLASS ExportOptions : public OptionsBase {
  3384 public:
  3385     ExportOptions(JSContext *cx = xpc_GetSafeJSContext(),
  3386                   JSObject* options = nullptr)
  3387         : OptionsBase(cx, options)
  3388         , defineAs(cx, JSID_VOID)
  3389     { }
  3391     virtual bool Parse() { return ParseId("defineAs", &defineAs); };
  3393     JS::RootedId defineAs;
  3394 };
  3396 JSObject *
  3397 CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal,
  3398                    JS::CompartmentOptions& aOptions);
  3400 bool
  3401 InitGlobalObject(JSContext* aJSContext, JS::Handle<JSObject*> aGlobal,
  3402                  uint32_t aFlags);
  3404 // Helper for creating a sandbox object to use for evaluating
  3405 // untrusted code completely separated from all other code in the
  3406 // system using EvalInSandbox(). Takes the JSContext on which to
  3407 // do setup etc on, puts the sandbox object in *vp (which must be
  3408 // rooted by the caller), and uses the principal that's either
  3409 // directly passed in prinOrSop or indirectly as an
  3410 // nsIScriptObjectPrincipal holding the principal. If no principal is
  3411 // reachable through prinOrSop, a new null principal will be created
  3412 // and used.
  3413 nsresult
  3414 CreateSandboxObject(JSContext *cx, JS::MutableHandleValue vp, nsISupports *prinOrSop,
  3415                     xpc::SandboxOptions& options);
  3416 // Helper for evaluating scripts in a sandbox object created with
  3417 // CreateSandboxObject(). The caller is responsible of ensuring
  3418 // that *rval doesn't get collected during the call or usage after the
  3419 // call. This helper will use filename and lineNo for error reporting,
  3420 // and if no filename is provided it will use the codebase from the
  3421 // principal and line number 1 as a fallback. if returnStringOnly is
  3422 // true, then the result in *rval, or the exception in cx->exception
  3423 // will be coerced into strings. If an exception is thrown converting
  3424 // an exception to a string, evalInSandbox will return an NS_ERROR_*
  3425 // result, and cx->exception will be empty.
  3426 nsresult
  3427 EvalInSandbox(JSContext *cx, JS::HandleObject sandbox, const nsAString& source,
  3428               const nsACString& filename, int32_t lineNo,
  3429               JSVersion jsVersion, bool returnStringOnly,
  3430               JS::MutableHandleValue rval);
  3432 // Helper for retrieving metadata stored in a reserved slot. The metadata
  3433 // is set during the sandbox creation using the "metadata" option.
  3434 nsresult
  3435 GetSandboxMetadata(JSContext *cx, JS::HandleObject sandboxArg,
  3436                    JS::MutableHandleValue rval);
  3438 nsresult
  3439 SetSandboxMetadata(JSContext *cx, JS::HandleObject sandboxArg,
  3440                    JS::HandleValue metadata);
  3442 bool
  3443 CreateObjectIn(JSContext *cx, JS::HandleValue vobj, CreateObjectInOptions &options,
  3444                JS::MutableHandleValue rval);
  3446 bool
  3447 EvalInWindow(JSContext *cx, const nsAString &source, JS::HandleObject scope,
  3448              JS::MutableHandleValue rval);
  3450 bool
  3451 ExportFunction(JSContext *cx, JS::HandleValue vscope, JS::HandleValue vfunction,
  3452                JS::HandleValue voptions, JS::MutableHandleValue rval);
  3454 bool
  3455 CloneInto(JSContext *cx, JS::HandleValue vobj, JS::HandleValue vscope,
  3456           JS::HandleValue voptions, JS::MutableHandleValue rval);
  3458 } /* namespace xpc */
  3461 /***************************************************************************/
  3462 // Inlined utilities.
  3464 inline bool
  3465 xpc_ForcePropertyResolve(JSContext* cx, JS::HandleObject obj, jsid id);
  3467 inline jsid
  3468 GetRTIdByIndex(JSContext *cx, unsigned index);
  3470 namespace xpc {
  3472 class CompartmentPrivate
  3474 public:
  3475     enum LocationHint {
  3476         LocationHintRegular,
  3477         LocationHintAddon
  3478     };
  3480     CompartmentPrivate(JSCompartment *c)
  3481         : wantXrays(false)
  3482         , universalXPConnectEnabled(false)
  3483         , adoptedNode(false)
  3484         , donatedNode(false)
  3485         , scriptability(c)
  3486         , scope(nullptr)
  3488         MOZ_COUNT_CTOR(xpc::CompartmentPrivate);
  3491     ~CompartmentPrivate();
  3493     bool wantXrays;
  3495     // This is only ever set during mochitest runs when enablePrivilege is called.
  3496     // It's intended as a temporary stopgap measure until we can finish ripping out
  3497     // enablePrivilege. Once set, this value is never unset (i.e., it doesn't follow
  3498     // the old scoping rules of enablePrivilege). Using it is inherently unsafe.
  3499     bool universalXPConnectEnabled;
  3501     // for telemetry. See bug 928476.
  3502     bool adoptedNode;
  3503     bool donatedNode;
  3505     // The scriptability of this compartment.
  3506     Scriptability scriptability;
  3508     // Our XPCWrappedNativeScope. This is non-null if and only if this is an
  3509     // XPConnect compartment.
  3510     XPCWrappedNativeScope *scope;
  3512     const nsACString& GetLocation() {
  3513         if (location.IsEmpty() && locationURI) {
  3514             if (NS_FAILED(locationURI->GetSpec(location)))
  3515                 location = NS_LITERAL_CSTRING("<unknown location>");
  3517         return location;
  3519     bool GetLocationURI(nsIURI **aURI) {
  3520         return GetLocationURI(LocationHintRegular, aURI);
  3522     bool GetLocationURI(LocationHint aLocationHint, nsIURI **aURI) {
  3523         if (locationURI) {
  3524             nsCOMPtr<nsIURI> rval = locationURI;
  3525             rval.forget(aURI);
  3526             return true;
  3528         return TryParseLocationURI(aLocationHint, aURI);
  3530     void SetLocation(const nsACString& aLocation) {
  3531         if (aLocation.IsEmpty())
  3532             return;
  3533         if (!location.IsEmpty() || locationURI)
  3534             return;
  3535         location = aLocation;
  3537     void SetLocationURI(nsIURI *aLocationURI) {
  3538         if (!aLocationURI)
  3539             return;
  3540         if (locationURI)
  3541             return;
  3542         locationURI = aLocationURI;
  3545 private:
  3546     nsCString location;
  3547     nsCOMPtr<nsIURI> locationURI;
  3549     bool TryParseLocationURI(LocationHint aType, nsIURI** aURI);
  3550 };
  3552 CompartmentPrivate*
  3553 EnsureCompartmentPrivate(JSObject *obj);
  3555 CompartmentPrivate*
  3556 EnsureCompartmentPrivate(JSCompartment *c);
  3558 inline CompartmentPrivate*
  3559 GetCompartmentPrivate(JSCompartment *compartment)
  3561     MOZ_ASSERT(compartment);
  3562     void *priv = JS_GetCompartmentPrivate(compartment);
  3563     return static_cast<CompartmentPrivate*>(priv);
  3566 inline CompartmentPrivate*
  3567 GetCompartmentPrivate(JSObject *object)
  3569     MOZ_ASSERT(object);
  3570     JSCompartment *compartment = js::GetObjectCompartment(object);
  3572     MOZ_ASSERT(compartment);
  3573     return GetCompartmentPrivate(compartment);
  3576 bool IsUniversalXPConnectEnabled(JSCompartment *compartment);
  3577 bool IsUniversalXPConnectEnabled(JSContext *cx);
  3578 bool EnableUniversalXPConnect(JSContext *cx);
  3580 // This returns null if and only if it is called on an object in a non-XPConnect
  3581 // compartment.
  3582 inline XPCWrappedNativeScope*
  3583 GetObjectScope(JSObject *obj)
  3585     return EnsureCompartmentPrivate(obj)->scope;
  3588 // This returns null if a scope doesn't already exist.
  3589 XPCWrappedNativeScope* MaybeGetObjectScope(JSObject *obj);
  3591 extern bool gDebugMode;
  3592 extern bool gDesiredDebugMode;
  3594 extern const JSClass SafeJSContextGlobalClass;
  3596 JSObject* NewOutObject(JSContext* cx, JSObject* scope);
  3597 bool IsOutObject(JSContext* cx, JSObject* obj);
  3599 nsresult HasInstance(JSContext *cx, JS::HandleObject objArg, const nsID *iid, bool *bp);
  3601 /**
  3602  * Define quick stubs on the given object, @a proto.
  3604  * @param cx
  3605  *     A context.  Requires request.
  3606  * @param proto
  3607  *     The (newly created) prototype object for a DOM class.  The JS half
  3608  *     of an XPCWrappedNativeProto.
  3609  * @param flags
  3610  *     Property flags for the quick stub properties--should be either
  3611  *     JSPROP_ENUMERATE or 0.
  3612  * @param interfaceCount
  3613  *     The number of interfaces the class implements.
  3614  * @param interfaceArray
  3615  *     The interfaces the class implements; interfaceArray and
  3616  *     interfaceCount are like what nsIClassInfo.getInterfaces returns.
  3617  */
  3618 bool
  3619 DOM_DefineQuickStubs(JSContext *cx, JSObject *proto, uint32_t flags,
  3620                      uint32_t interfaceCount, const nsIID **interfaceArray);
  3622 nsIPrincipal *GetObjectPrincipal(JSObject *obj);
  3624 } // namespace xpc
  3626 namespace mozilla {
  3627 namespace dom {
  3628 extern bool
  3629 DefineStaticJSVals(JSContext *cx);
  3630 } // namespace dom
  3631 } // namespace mozilla
  3633 bool
  3634 xpc_LocalizeRuntime(JSRuntime *rt);
  3635 void
  3636 xpc_DelocalizeRuntime(JSRuntime *rt);
  3638 /***************************************************************************/
  3639 // Inlines use the above - include last.
  3641 #include "XPCInlines.h"
  3643 /***************************************************************************/
  3644 // Maps have inlines that use the above - include last.
  3646 #include "XPCMaps.h"
  3648 /***************************************************************************/
  3650 #endif /* xpcprivate_h___ */

mercurial