Bug 698420 - Make nsScriptObjectHolder typesafe; r=bz
authorMs2ger <ms2ger@gmail.com>
Sun, 18 Dec 2011 11:05:12 +0100
changeset 82898 c3525cd1ce442bf0a965c7cd08d181e963eefda6
parent 82897 82bc89d8e3c35a181e3ac218f71376f441699749
child 82899 f9f6f9ed788a73e0660b0e2d1eeb4ce960b5715a
push id4169
push usermbrubeck@mozilla.com
push dateSun, 18 Dec 2011 16:56:55 +0000
treeherdermozilla-inbound@bf93caeef44e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs698420
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 698420 - Make nsScriptObjectHolder typesafe; r=bz
content/events/src/nsEventListenerManager.cpp
content/xbl/src/nsXBLPrototypeHandler.cpp
content/xbl/src/nsXBLPrototypeHandler.h
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
dom/base/nsDOMScriptObjectHolder.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsIScriptContext.h
dom/base/nsIScriptObjectOwner.h
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/base/nsPIDOMWindow.h
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -574,17 +574,17 @@ nsEventListenerManager::CompileEventHand
   nsresult result = NS_OK;
 
   nsIJSEventListener *listener = aListenerStruct->GetJSListener();
   NS_ASSERTION(!listener->GetHandler(), "What is there to compile?");
 
   nsIScriptContext *context = listener->GetEventContext();
   nsCOMPtr<nsIScriptEventHandlerOwner> handlerOwner =
     do_QueryInterface(mTarget);
-  nsScriptObjectHolder handler(context);
+  nsScriptObjectHolder<JSObject> handler(context);
 
   if (handlerOwner) {
     result = handlerOwner->GetCompiledEventHandler(aListenerStruct->mTypeAtom,
                                                    handler);
     if (NS_SUCCEEDED(result) && handler) {
       aListenerStruct->mHandlerIsString = false;
     } else {
       // Make sure there's nothing in the holder in the failure case
@@ -694,20 +694,20 @@ nsEventListenerManager::CompileEventHand
         return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA;
       }
       NS_ENSURE_SUCCESS(result, result);
     }
   }
 
   if (handler) {
     // Bind it
-    nsScriptObjectHolder boundHandler(context);
+    nsScriptObjectHolder<JSObject> boundHandler(context);
     context->BindCompiledEventHandler(mTarget, listener->GetEventScope(),
-                                      handler.getObject(), boundHandler);
-    listener->SetHandler(boundHandler.getObject());
+                                      handler.get(), boundHandler);
+    listener->SetHandler(boundHandler.get());
   }
 
   return result;
 }
 
 nsresult
 nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
                                            nsIDOMEventListener* aListener,
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -302,61 +302,61 @@ nsXBLPrototypeHandler::ExecuteHandler(ns
   if (!boundGlobal)
     return NS_OK;
 
   nsIScriptContext *boundContext =
     boundGlobal->GetScriptContext(nsIProgrammingLanguage::JAVASCRIPT);
   if (!boundContext)
     return NS_OK;
 
-  nsScriptObjectHolder handler(boundContext);
+  nsScriptObjectHolder<JSObject> handler(boundContext);
   nsISupports *scriptTarget;
 
   if (winRoot) {
     scriptTarget = boundGlobal;
   } else {
     scriptTarget = aTarget;
   }
 
   rv = EnsureEventHandler(boundGlobal, boundContext, onEventAtom, handler);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Bind it to the bound element
   JSObject* scope = boundGlobal->GetGlobalJSObject();
-  nsScriptObjectHolder boundHandler(boundContext);
+  nsScriptObjectHolder<JSObject> boundHandler(boundContext);
   rv = boundContext->BindCompiledEventHandler(scriptTarget, scope,
-                                              handler.getObject(), boundHandler);
+                                              handler.get(), boundHandler);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Execute it.
   nsCOMPtr<nsIJSEventListener> eventListener;
   rv = NS_NewJSEventListener(boundContext, scope,
                              scriptTarget, onEventAtom,
-                             boundHandler.getObject(),
+                             boundHandler.get(),
                              getter_AddRefs(eventListener));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Handle the event.
   eventListener->HandleEvent(aEvent);
   eventListener->Disconnect();
   return NS_OK;
 }
 
 nsresult
 nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
                                           nsIScriptContext *aBoundContext,
                                           nsIAtom *aName,
-                                          nsScriptObjectHolder &aHandler)
+                                          nsScriptObjectHolder<JSObject>& aHandler)
 {
   // Check to see if we've already compiled this
   nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(aGlobal);
   if (pWindow) {
     JSObject* cachedHandler = pWindow->GetCachedXBLPrototypeHandler(this);
     if (cachedHandler) {
-      aHandler.setObject(cachedHandler);
+      aHandler.set(cachedHandler);
       return aHandler ? NS_OK : NS_ERROR_FAILURE;
     }
   }
 
   // Ensure that we have something to compile
   nsDependentString handlerText(mHandlerText);
   if (handlerText.IsEmpty())
     return NS_ERROR_FAILURE;
--- a/content/xbl/src/nsXBLPrototypeHandler.h
+++ b/content/xbl/src/nsXBLPrototypeHandler.h
@@ -189,17 +189,17 @@ protected:
   void ReportKeyConflict(const PRUnichar* aKey, const PRUnichar* aModifiers, nsIContent* aElement, const char *aMessageName);
   void GetEventType(nsAString& type);
   bool ModifiersMatchMask(nsIDOMUIEvent* aEvent,
                             bool aIgnoreShiftKey = false);
   nsresult DispatchXBLCommand(nsIDOMEventTarget* aTarget, nsIDOMEvent* aEvent);
   nsresult DispatchXULKeyCommand(nsIDOMEvent* aEvent);
   nsresult EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
                               nsIScriptContext *aBoundContext, nsIAtom *aName,
-                              nsScriptObjectHolder &aHandler);
+                              nsScriptObjectHolder<JSObject>& aHandler);
   static PRInt32 KeyToMask(PRInt32 key);
   
   static PRInt32 kAccelKey;
   static PRInt32 kMenuAccessKey;
   static void InitAccessKeys();
 
   static const PRInt32 cShift;
   static const PRInt32 cAlt;
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -158,19 +158,19 @@ public:
     NS_DECL_CYCLE_COLLECTION_CLASS(nsScriptEventHandlerOwnerTearoff)
 
     // nsIScriptEventHandlerOwner
     virtual nsresult CompileEventHandler(nsIScriptContext* aContext,
                                          nsIAtom *aName,
                                          const nsAString& aBody,
                                          const char* aURL,
                                          PRUint32 aLineNo,
-                                         nsScriptObjectHolder &aHandler);
+                                         nsScriptObjectHolder<JSObject>& aHandler);
     virtual nsresult GetCompiledEventHandler(nsIAtom *aName,
-                                             nsScriptObjectHolder &aHandler);
+                                             nsScriptObjectHolder<JSObject>& aHandler);
 
 private:
     nsRefPtr<nsXULElement> mElement;
 };
 
 //----------------------------------------------------------------------
 
 static NS_DEFINE_CID(kXULPopupListenerCID,        NS_XULPOPUPLISTENER_CID);
@@ -713,39 +713,39 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END_AGGREGATED(mElement)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsScriptEventHandlerOwnerTearoff)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsScriptEventHandlerOwnerTearoff)
 
 nsresult
 nsScriptEventHandlerOwnerTearoff::GetCompiledEventHandler(
                                                 nsIAtom *aName,
-                                                nsScriptObjectHolder &aHandler)
+                                                nsScriptObjectHolder<JSObject>& aHandler)
 {
     XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheTests);
     aHandler.drop();
 
     nsXULPrototypeAttribute *attr =
         mElement->FindPrototypeAttribute(kNameSpaceID_None, aName);
     if (attr) {
         XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheHits);
-        aHandler.setObject(attr->mEventHandler);
+        aHandler.set(attr->mEventHandler);
     }
 
     return NS_OK;
 }
 
 nsresult
 nsScriptEventHandlerOwnerTearoff::CompileEventHandler(
                                                 nsIScriptContext* aContext,
                                                 nsIAtom *aName,
                                                 const nsAString& aBody,
                                                 const char* aURL,
                                                 PRUint32 aLineNo,
-                                                nsScriptObjectHolder &aHandler)
+                                                nsScriptObjectHolder<JSObject>& aHandler)
 {
     nsresult rv;
 
     XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheSets);
 
     // XXX sXBL/XBL2 issue! Owner or current document?
     nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mElement->OwnerDoc());
 
@@ -804,23 +804,23 @@ nsScriptEventHandlerOwnerTearoff::Compil
         XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheFills);
         // take a copy of the event handler, and tell the language about it.
         if (aHandler) {
             NS_ASSERTION(!attr->mEventHandler, "Leaking handler.");
 
             rv = nsContentUtils::HoldScriptObject(aContext->GetScriptTypeID(),
                                                   elem,
                                                   &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode),
-                                                  aHandler,
+                                                  aHandler.get(),
                                                   elem->mHoldsScriptObject);
             if (NS_FAILED(rv)) return rv;
 
             elem->mHoldsScriptObject = true;
         }
-        attr->mEventHandler = aHandler.getObject();
+        attr->mEventHandler = aHandler.get();
     }
 
     return NS_OK;
 }
 
 void
 nsXULElement::AddListenerFor(const nsAttrName& aName,
                              bool aCompileEventHandlers)
@@ -2997,17 +2997,17 @@ nsXULPrototypeScript::Deserialize(nsIObj
     // Read basic prototype data
     aStream->Read32(&mLineNo);
     aStream->Read32(&mLangVersion);
 
     nsIScriptContext *context = aGlobal->GetScriptContext(
                                             mScriptObject.mLangID);
     NS_ASSERTION(context != nsnull, "Have no context for deserialization");
     NS_ENSURE_TRUE(context, NS_ERROR_UNEXPECTED);
-    nsScriptObjectHolder newScriptObject(context);
+    nsScriptObjectHolder<JSScript> newScriptObject(context);
     rv = context->Deserialize(aStream, newScriptObject);
     if (NS_FAILED(rv)) {
         NS_WARNING("Language deseralization failed");
         return rv;
     }
     Set(newScriptObject);
     return NS_OK;
 }
@@ -3133,17 +3133,17 @@ nsXULPrototypeScript::Compile(const PRUn
             return NS_ERROR_UNEXPECTED;
     }
 
     nsCAutoString urlspec;
     nsContentUtils::GetWrapperSafeScriptFilename(aDocument, aURI, urlspec);
 
     // Ok, compile it to create a prototype script object!
 
-    nsScriptObjectHolder newScriptObject(context);
+    nsScriptObjectHolder<JSScript> newScriptObject(context);
     rv = context->CompileScript(aText,
                                 aTextLength,
                                 // Use the enclosing document's principal
                                 // XXX is this right? or should we use the
                                 // protodoc's?
                                 // If we start using the protodoc's, make sure
                                 // the DowngradePrincipalIfNeeded stuff in
                                 // nsXULDocument::OnStreamComplete still works!
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -331,23 +331,23 @@ public:
 
     nsresult Compile(const PRUnichar* aText, PRInt32 aTextLength,
                      nsIURI* aURI, PRUint32 aLineNo,
                      nsIDocument* aDocument,
                      nsIScriptGlobalObjectOwner* aGlobalOwner);
 
     void UnlinkJSObjects();
 
-    void Set(nsScriptObjectHolder &aHolder)
+    void Set(nsScriptObjectHolder<JSScript>& aHolder)
     {
         NS_ASSERTION(mScriptObject.mLangID == aHolder.getScriptTypeID(),
                      "Wrong language, this will leak the previous object.");
 
         mScriptObject.mLangID = aHolder.getScriptTypeID();
-        Set(aHolder.getScript());
+        Set(aHolder.get());
     }
     void Set(JSScript* aObject);
 
     struct ScriptObjectHolder
     {
         ScriptObjectHolder(PRUint32 aLangID) : mLangID(aLangID),
                                                mObject(nsnull)
         {
--- a/dom/base/nsDOMScriptObjectHolder.h
+++ b/dom/base/nsDOMScriptObjectHolder.h
@@ -43,99 +43,91 @@
 #include "nsIDOMScriptObjectFactory.h"
 
 #include "jspubtd.h"
 
 // A thin class used to help with script object memory management.  No virtual
 // functions and a fully inline implementation should keep the cost down.
 // [Note that a fully inline implementation is necessary for use by other
 // languages, which do not link against the layout component module]
+template<class T>
 class NS_STACK_CLASS nsScriptObjectHolder {
 public:
   // A constructor that will cause a reference to |ctx| to be stored in
   // the object.  Only use for short-lived object holders.
-  nsScriptObjectHolder(nsIScriptContext *ctx, void *aObject = nsnull) :
+  nsScriptObjectHolder<T>(nsIScriptContext *ctx, T* aObject = nsnull) :
       mObject(aObject), mContext(ctx) {
     NS_ASSERTION(ctx, "Must provide a valid context");
   }
 
   // copy constructor
-  nsScriptObjectHolder(const nsScriptObjectHolder& other) :
+  nsScriptObjectHolder<T>(const nsScriptObjectHolder<T>& other) :
       mObject(other.mObject),
       mContext(other.mContext)
   {
     // New hold the script object and new reference on the script context.
     if (mObject)
       mContext->HoldScriptObject(mObject);
   }
 
-  ~nsScriptObjectHolder() {
+  ~nsScriptObjectHolder<T>() {
     if (mObject)
       mContext->DropScriptObject(mObject);
   }
 
   // misc operators
-  nsScriptObjectHolder &operator=(const nsScriptObjectHolder &other) {
+  nsScriptObjectHolder<T> &operator=(const nsScriptObjectHolder<T> &other) {
     set(other);
     return *this;
   }
   bool operator!() const {
     return !mObject;
   }
-  operator void *() const {
-    return mObject;
+  operator bool() const {
+    return !!mObject;
   }
-  JSScript* getScript() const {
-    return static_cast<JSScript*>(mObject);
-  }
-  JSObject* getObject() const {
-    return static_cast<JSObject*>(mObject);
+  T* get() const {
+    return mObject;
   }
 
   // Drop the script object - but *not* the nsIScriptContext.
   nsresult drop() {
     nsresult rv = NS_OK;
     if (mObject) {
       rv = mContext->DropScriptObject(mObject);
       mObject = nsnull;
     }
     return rv;
   }
 
-  nsresult setScript(JSScript* aScript) {
-    return set(aScript);
-  }
-  nsresult setObject(JSObject* aObject) {
-    return set(aObject);
-  }
-  nsresult set(void *object) {
+  nsresult set(T* object) {
     NS_ASSERTION(getScriptTypeID() != nsIProgrammingLanguage::UNKNOWN,
                  "Must know the language!");
     nsresult rv = drop();
     if (NS_FAILED(rv))
       return rv;
     if (object) {
       rv = mContext->HoldScriptObject(object);
       // don't store the pointer if we failed to lock it.
       if (NS_SUCCEEDED(rv)) {
         mObject = object;
       }
     }
     return rv;
   }
-  nsresult set(const nsScriptObjectHolder &other) {
+  nsresult set(const nsScriptObjectHolder<T> &other) {
     NS_ASSERTION(getScriptTypeID() == other.getScriptTypeID(),
                  "Must have identical languages!");
     nsresult rv = drop();
     if (NS_FAILED(rv))
       return rv;
     return set(other.mObject);
   }
   // Get the language ID.
   PRUint32 getScriptTypeID() const {
     return mContext->GetScriptTypeID();
   }
 protected:
-  void *mObject;
+  T* mObject;
   nsCOMPtr<nsIScriptContext> mContext;
 };
 
 #endif // nsDOMScriptObjectHolder_h__
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -6879,17 +6879,17 @@ nsGlobalWindow::GetCachedXBLPrototypeHan
   if (mCachedXBLPrototypeHandlers.IsInitialized()) {
     mCachedXBLPrototypeHandlers.Get(aKey, &handler);
   }
   return handler;
 }
 
 void
 nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
-                                         nsScriptObjectHolder& aHandler)
+                                         nsScriptObjectHolder<JSObject>& aHandler)
 {
   if (!mCachedXBLPrototypeHandlers.IsInitialized() &&
       !mCachedXBLPrototypeHandlers.Init()) {
     NS_ERROR("Failed to initiailize hashtable!");
     return;
   }
 
   if (!mCachedXBLPrototypeHandlers.Count()) {
@@ -6907,17 +6907,17 @@ nsGlobalWindow::CacheXBLPrototypeHandler
 
     nsresult rv = nsContentUtils::HoldJSObjects(thisSupports, participant);
     if (NS_FAILED(rv)) {
       NS_ERROR("nsContentUtils::HoldJSObjects failed!");
       return;
     }
   }
 
-  mCachedXBLPrototypeHandlers.Put(aKey, aHandler.getObject());
+  mCachedXBLPrototypeHandlers.Put(aKey, aHandler.get());
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetFrameElement(nsIDOMElement** aFrameElement)
 {
   FORWARD_TO_OUTER(GetFrameElement, (aFrameElement), NS_ERROR_NOT_INITIALIZED);
 
   *aFrameElement = nsnull;
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -513,17 +513,17 @@ public:
 
   void InitJavaProperties();
 
   virtual NS_HIDDEN_(JSObject*)
     GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey);
 
   virtual NS_HIDDEN_(void)
     CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
-                             nsScriptObjectHolder& aHandler);
+                             nsScriptObjectHolder<JSObject>& aHandler);
 
   virtual bool TakeFocus(bool aFocus, PRUint32 aFocusMethod);
   virtual void SetReadyForFocus();
   virtual void PageHidden();
   virtual nsresult DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI);
   virtual nsresult DispatchSyncPopState();
 
   virtual nsresult SetArguments(nsIArray *aArguments, nsIPrincipal *aOrigin);
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -48,17 +48,17 @@
 class nsIScriptGlobalObject;
 class nsIScriptSecurityManager;
 class nsIPrincipal;
 class nsIAtom;
 class nsIArray;
 class nsIVariant;
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
-class nsScriptObjectHolder;
+template<class> class nsScriptObjectHolder;
 class nsIScriptObjectPrincipal;
 
 typedef void (*nsScriptTerminationFunc)(nsISupports* aRef);
 
 #define NS_ISCRIPTCONTEXTPRINCIPAL_IID \
   { 0xd012cdb3, 0x8f1e, 0x4440, \
     { 0x8c, 0xbd, 0x32, 0x7f, 0x98, 0x1d, 0x37, 0xb4 } }
 
@@ -69,18 +69,18 @@ public:
 
   virtual nsIScriptObjectPrincipal* GetObjectPrincipal() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
                               NS_ISCRIPTCONTEXTPRINCIPAL_IID)
 
 #define NS_ISCRIPTCONTEXT_IID \
-{ 0x39b3ea7c, 0xdc26, 0x4756, \
-  { 0xa0, 0x3c, 0x13, 0xa0, 0x42, 0x03, 0x07, 0x6a } }
+{ 0xe22f85d1, 0xae90, 0x418a, \
+  { 0x83, 0xf0, 0xaf, 0x0d, 0xa3, 0x04, 0x92, 0x6a } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
 /**
  * It is used by the application to initialize a runtime and run scripts.
  * A script runtime would implement this interface.
@@ -146,17 +146,17 @@ public:
    *
    **/
   virtual nsresult CompileScript(const PRUnichar* aText,
                                  PRInt32 aTextLength,
                                  nsIPrincipal* aPrincipal,
                                  const char* aURL,
                                  PRUint32 aLineNo,
                                  PRUint32 aVersion,
-                                 nsScriptObjectHolder &aScriptObject) = 0;
+                                 nsScriptObjectHolder<JSScript>& aScriptObject) = 0;
 
   /**
    * Execute a precompiled script object.
    *
    * @param aScriptObject an object representing the script to be executed
    * @param aScopeObject an object telling the scope in which to execute,
    *                     or nsnull to use a default scope
    * @param aRetValue the result of executing the script, may be null in
@@ -201,17 +201,17 @@ public:
    */
   virtual nsresult CompileEventHandler(nsIAtom* aName,
                                        PRUint32 aArgCount,
                                        const char** aArgNames,
                                        const nsAString& aBody,
                                        const char* aURL,
                                        PRUint32 aLineNo,
                                        PRUint32 aVersion,
-                                       nsScriptObjectHolder &aHandler) = 0;
+                                       nsScriptObjectHolder<JSObject>& aHandler) = 0;
 
   /**
    * Call the function object with given args and return its boolean result,
    * or true if the result isn't boolean.
    *
    * @param aTarget the event target
    * @param aScript an object telling the scope in which to call the compiled
    *        event handler function.
@@ -243,17 +243,17 @@ public:
    * @param aHandler the function object to bind, created by an earlier call to
    *        CompileEventHandler
    * @param aBoundHandler [out] the result of the bind operation.
    * @return NS_OK if the function was successfully bound
    */
   virtual nsresult BindCompiledEventHandler(nsISupports* aTarget,
                                             JSObject* aScope,
                                             JSObject* aHandler,
-                                            nsScriptObjectHolder& aBoundHandler) = 0;
+                                            nsScriptObjectHolder<JSObject>& aBoundHandler) = 0;
 
   /**
    * Compile a function that isn't used as an event handler.
    *
    * NOTE: Not yet language agnostic (main problem is XBL - not yet agnostic)
    * Caller must make sure aFunctionObject is a JS GC root.
    *
    **/
@@ -375,17 +375,17 @@ public:
   virtual void ScriptEvaluated(bool aTerminated) = 0;
 
   virtual nsresult Serialize(nsIObjectOutputStream* aStream,
                              JSScript* aScriptObject) = 0;
   
   /* Deserialize a script from a stream.
    */
   virtual nsresult Deserialize(nsIObjectInputStream* aStream,
-                               nsScriptObjectHolder &aResult) = 0;
+                               nsScriptObjectHolder<JSScript>& aResult) = 0;
 
   /**
    * JS only - this function need not be implemented by languages other
    * than JS (ie, this should be moved to a private interface!)
    * Called to specify a function that should be called when the current
    * script (if there is one) terminates. Generally used if breakdown
    * of script state needs to happen, but should be deferred till
    * the end of script evaluation.
--- a/dom/base/nsIScriptObjectOwner.h
+++ b/dom/base/nsIScriptObjectOwner.h
@@ -37,17 +37,17 @@
 
 #ifndef nsIScriptObjectOwner_h__
 #define nsIScriptObjectOwner_h__
 
 #include "nsISupports.h"
 #include "nsIScriptContext.h"
 #include "nsAString.h"
 
-class nsScriptObjectHolder;
+template<class> class nsScriptObjectHolder;
 
 #define NS_ISCRIPTOBJECTOWNER_IID \
 { /* 8f6bca7e-ce42-11d1-b724-00600891d8c9 */ \
 0x8f6bca7e, 0xce42, 0x11d1, \
   {0xb7, 0x24, 0x00, 0x60, 0x08, 0x91, 0xd8, 0xc9} } \
 
 /**
  * Creates a link between the script object and its native implementation
@@ -89,18 +89,18 @@ public:
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptObjectOwner,
                               NS_ISCRIPTOBJECTOWNER_IID)
 
 class nsIAtom;
 
 #define NS_ISCRIPTEVENTHANDLEROWNER_IID \
-{ 0x1e2be5d2, 0x381a, 0x46dc, \
- { 0xae, 0x97, 0xa5, 0x5f, 0x45, 0xfd, 0x36, 0x63 } }
+{ 0xc8f35f71, 0x07d1, 0x4ff3, \
+  { 0xa3, 0x2f, 0x65, 0xcb, 0x35, 0x64, 0xac, 0xe0 } }
 
 /**
  * Associate a compiled event handler with its target object, which owns it
  * This is an adjunct to nsIScriptObjectOwner that nsEventListenerManager's
  * implementation queries for, in order to avoid recompiling a recurrent or
  * prototype-inherited event handler.
  */
 class nsIScriptEventHandlerOwner : public nsISupports
@@ -119,25 +119,25 @@ public:
    * @param aLineNo the starting line number of the script for error messages
    * @param aHandler the holder for the compiled handler object
    */
   virtual nsresult CompileEventHandler(nsIScriptContext* aContext,
                                        nsIAtom *aName,
                                        const nsAString& aBody,
                                        const char* aURL,
                                        PRUint32 aLineNo,
-                                       nsScriptObjectHolder &aHandler) = 0;
+                                       nsScriptObjectHolder<JSObject>& aHandler) = 0;
 
   /**
    * Retrieve an already-compiled event handler that can be bound to a
    * target object using a script context.
    *
    * @param aName the name of the event handler to retrieve
    * @param aHandler the holder for the compiled event handler.
    */
   virtual nsresult GetCompiledEventHandler(nsIAtom *aName,
-                                           nsScriptObjectHolder &aHandler) = 0;
+                                           nsScriptObjectHolder<JSObject>& aHandler) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptEventHandlerOwner,
                               NS_ISCRIPTEVENTHANDLEROWNER_IID)
 
 #endif // nsIScriptObjectOwner_h__
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1542,17 +1542,17 @@ nsJSContext::EvaluateString(const nsAStr
 
 nsresult
 nsJSContext::CompileScript(const PRUnichar* aText,
                            PRInt32 aTextLength,
                            nsIPrincipal *aPrincipal,
                            const char *aURL,
                            PRUint32 aLineNo,
                            PRUint32 aVersion,
-                           nsScriptObjectHolder &aScriptObject)
+                           nsScriptObjectHolder<JSScript>& aScriptObject)
 {
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   NS_ENSURE_ARG_POINTER(aPrincipal);
 
   JSObject* scopeObject = ::JS_GetGlobalObject(mContext);
 
   JSPrincipals *jsprin;
@@ -1582,17 +1582,17 @@ nsJSContext::CompileScript(const PRUnich
                                                  static_cast<const jschar*>(aText),
                                                  aTextLength,
                                                  aURL,
                                                  aLineNo,
                                                  JSVersion(aVersion));
     if (script) {
       NS_ASSERTION(aScriptObject.getScriptTypeID()==JAVASCRIPT,
                    "Expecting JS script object holder");
-      rv = aScriptObject.setScript(script);
+      rv = aScriptObject.set(script);
     } else {
       rv = NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   // Whew!  Finally done.
   JSPRINCIPALS_DROP(mContext, jsprin);
   return rv;
@@ -1740,17 +1740,17 @@ nsJSContext::JSObjectFromInterface(nsISu
 
 nsresult
 nsJSContext::CompileEventHandler(nsIAtom *aName,
                                  PRUint32 aArgCount,
                                  const char** aArgNames,
                                  const nsAString& aBody,
                                  const char *aURL, PRUint32 aLineNo,
                                  PRUint32 aVersion,
-                                 nsScriptObjectHolder &aHandler)
+                                 nsScriptObjectHolder<JSObject>& aHandler)
 {
   NS_TIME_FUNCTION_MIN_FMT(1.0, "%s (line %d) (url: %s, line: %d)", MOZ_FUNCTION_NAME,
                            __LINE__, aURL, aLineNo);
 
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   NS_PRECONDITION(AtomIsEventHandlerName(aName), "Bad event name");
   NS_PRECONDITION(!::JS_IsExceptionPending(mContext),
@@ -1790,17 +1790,17 @@ nsJSContext::CompileEventHandler(nsIAtom
   if (!fun) {
     ReportPendingException();
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   JSObject *handler = ::JS_GetFunctionObject(fun);
   NS_ASSERTION(aHandler.getScriptTypeID()==JAVASCRIPT,
                "Expecting JS script object holder");
-  return aHandler.setObject(handler);
+  return aHandler.set(handler);
 }
 
 // XXX - note that CompileFunction doesn't yet play the nsScriptObjectHolder
 // game - caller must still ensure JS GC root.
 nsresult
 nsJSContext::CompileFunction(JSObject* aTarget,
                              const nsACString& aName,
                              PRUint32 aArgCount,
@@ -1980,17 +1980,17 @@ nsJSContext::CallEventHandler(nsISupport
   ScriptEvaluated(true);
 
   return rv;
 }
 
 nsresult
 nsJSContext::BindCompiledEventHandler(nsISupports* aTarget, JSObject* aScope,
                                       JSObject* aHandler,
-                                      nsScriptObjectHolder& aBoundHandler)
+                                      nsScriptObjectHolder<JSObject>& aBoundHandler)
 {
   NS_ENSURE_ARG(aHandler);
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
   NS_PRECONDITION(!aBoundHandler, "Shouldn't already have a bound handler!");
 
   JSAutoRequest ar(mContext);
 
   // Get the jsobject associated with this target
@@ -2022,17 +2022,17 @@ nsJSContext::BindCompiledEventHandler(ns
     funobj = JS_CloneFunctionObject(mContext, aHandler, target);
     if (!funobj) {
       rv = NS_ERROR_OUT_OF_MEMORY;
     }
   } else {
     funobj = NULL;
   }
 
-  aBoundHandler.setObject(funobj);
+  aBoundHandler.set(funobj);
 
   return rv;
 }
 
 // serialization
 nsresult
 nsJSContext::Serialize(nsIObjectOutputStream* aStream, JSScript* aScriptObject)
 {
@@ -2078,17 +2078,17 @@ nsJSContext::Serialize(nsIObjectOutputSt
     ::JS_XDRDestroy(xdr);
     if (NS_FAILED(rv)) return rv;
 
     return rv;
 }
 
 nsresult
 nsJSContext::Deserialize(nsIObjectInputStream* aStream,
-                         nsScriptObjectHolder &aResult)
+                         nsScriptObjectHolder<JSScript>& aResult)
 {
     NS_TIME_FUNCTION_MIN(1.0);
 
     PRUint32 size;
     nsresult rv = aStream->Read32(&size);
     if (NS_FAILED(rv)) return rv;
 
     char* data;
@@ -2143,17 +2143,17 @@ nsJSContext::Deserialize(nsIObjectInputS
         nsMemory::Free(data);
     NS_ASSERTION(aResult.getScriptTypeID()==JAVASCRIPT,
                  "Expecting JS script object holder");
 
     // Now that we've cleaned up, handle the case when rv is a failure
     // code, which could happen for all sorts of reasons above.
     NS_ENSURE_SUCCESS(rv, rv);
 
-    return aResult.setScript(result);
+    return aResult.set(result);
 }
 
 void
 nsJSContext::SetDefaultLanguageVersion(PRUint32 aVersion)
 {
   ::JS_SetVersion(mContext, (JSVersion)aVersion);
 }
 
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -90,36 +90,36 @@ public:
                                            bool* aIsUndefined);
 
   virtual nsresult CompileScript(const PRUnichar* aText,
                                  PRInt32 aTextLength,
                                  nsIPrincipal *principal,
                                  const char *aURL,
                                  PRUint32 aLineNo,
                                  PRUint32 aVersion,
-                                 nsScriptObjectHolder &aScriptObject);
+                                 nsScriptObjectHolder<JSScript>& aScriptObject);
   virtual nsresult ExecuteScript(JSScript* aScriptObject,
                                  JSObject* aScopeObject,
                                  nsAString* aRetValue,
                                  bool* aIsUndefined);
 
   virtual nsresult CompileEventHandler(nsIAtom *aName,
                                        PRUint32 aArgCount,
                                        const char** aArgNames,
                                        const nsAString& aBody,
                                        const char *aURL, PRUint32 aLineNo,
                                        PRUint32 aVersion,
-                                       nsScriptObjectHolder &aHandler);
+                                       nsScriptObjectHolder<JSObject>& aHandler);
   virtual nsresult CallEventHandler(nsISupports* aTarget, JSObject* aScope,
                                     JSObject* aHandler,
                                     nsIArray *argv, nsIVariant **rv);
   virtual nsresult BindCompiledEventHandler(nsISupports *aTarget,
                                             JSObject *aScope,
                                             JSObject* aHandler,
-                                            nsScriptObjectHolder& aBoundHandler);
+                                            nsScriptObjectHolder<JSObject>& aBoundHandler);
   virtual nsresult CompileFunction(JSObject* aTarget,
                                    const nsACString& aName,
                                    PRUint32 aArgCount,
                                    const char** aArgArray,
                                    const nsAString& aBody,
                                    const char* aURL,
                                    PRUint32 aLineNo,
                                    PRUint32 aVersion,
@@ -164,17 +164,17 @@ public:
   virtual nsresult InitClasses(JSObject* aGlobalObj);
   virtual void ClearScope(void* aGlobalObj, bool bClearPolluters);
 
   virtual void WillInitializeContext();
   virtual void DidInitializeContext();
 
   virtual nsresult Serialize(nsIObjectOutputStream* aStream, JSScript* aScriptObject);
   virtual nsresult Deserialize(nsIObjectInputStream* aStream,
-                               nsScriptObjectHolder &aResult);
+                               nsScriptObjectHolder<JSScript>& aResult);
 
   virtual nsresult DropScriptObject(void *object);
   virtual nsresult HoldScriptObject(void *object);
 
   virtual void EnterModalState();
   virtual void LeaveModalState();
 
   NS_DECL_NSIXPCSCRIPTNOTIFY
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -69,24 +69,24 @@ enum PopupControlState {
   openOverridden    // disallow window open
 };
 
 class nsIDocShell;
 class nsIContent;
 class nsIDocument;
 class nsIScriptTimeoutHandler;
 struct nsTimeout;
-class nsScriptObjectHolder;
+template <class> class nsScriptObjectHolder;
 class nsXBLPrototypeHandler;
 class nsIArray;
 class nsPIWindowRoot;
 
 #define NS_PIDOMWINDOW_IID \
-{ 0x29e6cc54, 0x10da, 0x4a68, \
-  { 0xb7, 0x68, 0xfe, 0xa7, 0x71, 0x17, 0x93, 0x81 } }
+{ 0x1352de12, 0x7a07, 0x4610, \
+  { 0x93, 0xd5, 0xb8, 0x76, 0xfe, 0x93, 0x09, 0x50 } }
 
 class nsPIDOMWindow : public nsIDOMWindowInternal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID)
 
   virtual nsPIDOMWindow* GetPrivateRoot() = 0;
 
@@ -483,17 +483,17 @@ public:
 
   /**
    * Initialize window.java and window.Packages.
    */
   virtual void InitJavaProperties() = 0;
 
   virtual JSObject* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0;
   virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
-                                        nsScriptObjectHolder& aHandler) = 0;
+                                        nsScriptObjectHolder<JSObject>& aHandler) = 0;
 
   /*
    * Get and set the currently focused element within the document. If
    * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a
    * document focus event is needed.
    *
    * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER
    * INSTEAD.