Bug 841312 - Remove the termination function API. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Tue, 21 May 2013 11:45:56 -0600
changeset 132555 75abbd7e7e2450a0f595c87f549a3d4b434fdb03
parent 132554 7d3eb1cf0ac249af6cd8a7d653886a6517d6c893
child 132556 f74414ca211dd5f8a19ff683d9d81d3882eb38cd
push id24711
push userryanvm@gmail.com
push dateWed, 22 May 2013 16:29:12 +0000
treeherdermozilla-central@00b264c7cced [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs841312
milestone24.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 841312 - Remove the termination function API. r=bz \o/
dom/base/nsIScriptContext.h
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/bindings/CallbackObject.cpp
dom/bindings/CallbackObject.h
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -22,21 +22,19 @@ class nsIAtom;
 class nsIArray;
 class nsIVariant;
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 class nsIScriptObjectPrincipal;
 class nsIDOMWindow;
 class nsIURI;
 
-typedef void (*nsScriptTerminationFunc)(nsISupports* aRef);
-
 #define NS_ISCRIPTCONTEXT_IID \
-{ 0x821c5be9, 0xbf9e, 0x4041, \
-  { 0x9f, 0xf2, 0x1f, 0xca, 0x39, 0xf7, 0x89, 0xf3 } }
+{ 0xef0c91ce, 0x14f6, 0x41c9, \
+  { 0xa5, 0x77, 0xa6, 0xeb, 0xdc, 0x6d, 0x44, 0x7b } }
 
 /* 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.
@@ -174,47 +172,33 @@ public:
    */
   virtual void GC(JS::gcreason::Reason aReason) = 0;
 
   /**
    * Inform the context that a script was evaluated.
    * A GC may be done if "necessary."
    * This call is necessary if script evaluation is done
    * without using the EvaluateScript method.
-   * @param aTerminated If true then call termination function if it was 
-   *    previously set. Within DOM this will always be true, but outside 
-   *    callers (such as xpconnect) who may do script evaluations nested
-   *    inside DOM script evaluations can pass false to avoid premature
-   *    calls to the termination function.
+   * @param aTerminated If true then do script termination handling. Within DOM
+   *     this will always be true, but outside  callers (such as xpconnect) who
+   *     may do script evaluations nested inside inside DOM script evaluations
+   *     can pass false to avoid premature termination handling.
    * @return NS_OK if the method is successful
    */
   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,
                                JS::MutableHandle<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.
-   *
-   * @throws NS_ERROR_OUT_OF_MEMORY if that happens
-   */
-  virtual void SetTerminationFunction(nsScriptTerminationFunc aFunc,
-                                      nsIDOMWindow* aRef) = 0;
-
-  /**
    * Called to disable/enable script execution in this context.
    */
   virtual bool GetScriptsEnabled() = 0;
   virtual void SetScriptsEnabled(bool aEnabled, bool aFireTimeouts) = 0;
 
   // SetProperty is suspect and jst believes should not be needed.  Currenly
   // used only for "arguments".
   virtual nsresult SetProperty(JS::Handle<JSObject*> aTarget,
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1136,36 +1136,30 @@ nsJSContext::nsJSContext(JSRuntime *aRun
 
     // Watch for the JS boolean options
     Preferences::RegisterCallback(JSOptionChangedCallback,
                                   js_options_dot_str, this);
 
     ::JS_SetOperationCallback(mContext, DOMOperationCallback);
   }
   mIsInitialized = false;
-  mTerminations = nullptr;
   mScriptsEnabled = true;
   mOperationCallbackTime = 0;
   mModalStateTime = 0;
   mModalStateDepth = 0;
   mProcessingScriptTag = false;
 }
 
 nsJSContext::~nsJSContext()
 {
   *mPrev = mNext;
   if (mNext) {
     mNext->mPrev = mPrev;
   }
 
-  // We may still have pending termination functions if the context is destroyed
-  // before they could be executed. In this case, free the references to their
-  // parameters, but don't execute the functions (see bug 622326).
-  delete mTerminations;
-
   mGlobalObjectRef = nullptr;
 
   DestroyJSContext();
 
   --sContextCount;
 
   if (!sContextCount && sDidShutdown) {
     // The last context is being deleted, and we're already in the
@@ -1284,18 +1278,16 @@ nsJSContext::EvaluateString(const nsAStr
   JSPrincipals* p = JS_GetCompartmentPrincipals(js::GetObjectCompartment(aScopeObject));
   aOptions.setPrincipals(p);
 
   bool ok = false;
   nsresult rv = sSecurityManager->CanExecuteScripts(mContext, nsJSPrincipals::get(p), &ok);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(ok, NS_OK);
 
-  nsJSContext::TerminationFuncHolder holder(this);
-
   // Scope the JSAutoCompartment so that it gets destroyed before we pop the
   // cx and potentially call JS_RestoreFrameChain.
   XPCAutoRequest ar(mContext);
   {
     JSAutoCompartment ac(mContext, aScopeObject);
 
     ++mExecuteDepth;
 
@@ -1409,17 +1401,16 @@ nsJSContext::ExecuteScript(JSScript* aSc
   xpc_UnmarkGrayScript(aScriptObject);
   xpc_UnmarkGrayObject(aScopeObject);
 
   // Push our JSContext on our thread's context stack, in case native code
   // called from JS calls back into JS via XPConnect.
   nsCxPusher pusher;
   pusher.Push(mContext);
 
-  nsJSContext::TerminationFuncHolder holder(this);
   XPCAutoRequest ar(mContext);
 
   // Scope the JSAutoCompartment so that it gets destroyed before we pop the
   // cx and potentially call JS_RestoreFrameChain.
   {
     JSAutoCompartment ac(mContext, aScopeObject);
     ++mExecuteDepth;
 
@@ -2356,50 +2347,25 @@ bool
 nsJSContext::IsContextInitialized()
 {
   return mIsInitialized;
 }
 
 void
 nsJSContext::ScriptEvaluated(bool aTerminated)
 {
-  if (aTerminated && mTerminations) {
-    // Make sure to null out mTerminations before doing anything that
-    // might cause new termination funcs to be added!
-    nsJSContext::TerminationFuncClosure* start = mTerminations;
-    mTerminations = nullptr;
-
-    for (nsJSContext::TerminationFuncClosure* cur = start;
-         cur;
-         cur = cur->mNext) {
-      (*(cur->mTerminationFunc))(cur->mTerminationFuncArg);
-    }
-    delete start;
-  }
-
   JS_MaybeGC(mContext);
 
   if (aTerminated) {
     mOperationCallbackTime = 0;
     mModalStateTime = 0;
     mActive = true;
   }
 }
 
-void
-nsJSContext::SetTerminationFunction(nsScriptTerminationFunc aFunc,
-                                    nsIDOMWindow* aRef)
-{
-  NS_PRECONDITION(GetExecutingScript(), "should be executing script");
-
-  nsJSContext::TerminationFuncClosure* newClosure =
-    new nsJSContext::TerminationFuncClosure(aFunc, aRef, mTerminations);
-  mTerminations = newClosure;
-}
-
 bool
 nsJSContext::GetScriptsEnabled()
 {
   return mScriptsEnabled;
 }
 
 void
 nsJSContext::SetScriptsEnabled(bool aEnabled, bool aFireTimeouts)
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -70,18 +70,16 @@ public:
   inline nsIScriptGlobalObject *GetGlobalObjectRef() { return mGlobalObjectRef; }
 
   virtual JSContext* GetNativeContext();
   virtual JSObject* GetNativeGlobal();
   virtual nsresult InitContext();
   virtual bool IsContextInitialized();
 
   virtual void ScriptEvaluated(bool aTerminated);
-  virtual void SetTerminationFunction(nsScriptTerminationFunc aFunc,
-                                      nsIDOMWindow* aRef);
   virtual bool GetScriptsEnabled();
   virtual void SetScriptsEnabled(bool aEnabled, bool aFireTimeouts);
 
   virtual nsresult SetProperty(JS::Handle<JSObject*> aTarget, const char* aPropName, nsISupports* aVal);
 
   virtual bool GetProcessingScriptTag();
   virtual void SetProcessingScriptTag(bool aResult);
 
@@ -181,76 +179,16 @@ protected:
 private:
   void DestroyJSContext();
 
   nsrefcnt GetCCRefcnt();
 
   JSContext *mContext;
   bool mActive;
 
-  // Public so we can use it from CallbackFunction
-public:
-  struct TerminationFuncHolder;
-protected:
-  friend struct TerminationFuncHolder;
-  
-  struct TerminationFuncClosure
-  {
-    TerminationFuncClosure(nsScriptTerminationFunc aFunc,
-                           nsISupports* aArg,
-                           TerminationFuncClosure* aNext) :
-      mTerminationFunc(aFunc),
-      mTerminationFuncArg(aArg),
-      mNext(aNext)
-    {
-    }
-    ~TerminationFuncClosure()
-    {
-      delete mNext;
-    }
-    
-    nsScriptTerminationFunc mTerminationFunc;
-    nsCOMPtr<nsISupports> mTerminationFuncArg;
-    TerminationFuncClosure* mNext;
-  };
-
-  // Public so we can use it from CallbackFunction
-public:
-  struct TerminationFuncHolder
-  {
-    TerminationFuncHolder(nsJSContext* aContext)
-      : mContext(aContext),
-        mTerminations(aContext->mTerminations)
-    {
-      aContext->mTerminations = nullptr;
-    }
-    ~TerminationFuncHolder()
-    {
-      // Have to be careful here.  mContext might have picked up new
-      // termination funcs while the script was evaluating.  Prepend whatever
-      // we have to the current termination funcs on the context (since our
-      // termination funcs were posted first).
-      if (mTerminations) {
-        TerminationFuncClosure* cur = mTerminations;
-        while (cur->mNext) {
-          cur = cur->mNext;
-        }
-        cur->mNext = mContext->mTerminations;
-        mContext->mTerminations = mTerminations;
-      }
-    }
-
-    nsJSContext* mContext;
-    TerminationFuncClosure* mTerminations;
-  };
-
-protected:
-  TerminationFuncClosure* mTerminations;
-
-private:
   bool mIsInitialized;
   bool mScriptsEnabled;
   bool mGCOnDestruction;
   bool mProcessingScriptTag;
 
   uint32_t mExecuteDepth;
   uint32_t mDefaultJSOptions;
   PRTime mOperationCallbackTime;
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -104,24 +104,16 @@ CallbackObject::CallSetup::CallSetup(JS:
 
   // Check that it's ok to run this callback at all.
   // FIXME: Bug 807371: we want a less silly check here.
   // Make sure to unwrap aCallback before passing it in, because
   // getting principals from wrappers is silly.
   nsresult rv = nsContentUtils::GetSecurityManager()->
     CheckFunctionAccess(cx, js::UncheckedUnwrap(aCallback), nullptr);
 
-  // Construct a termination func holder even if we're not planning to
-  // run any script.  We need this because we're going to call
-  // ScriptEvaluated even if we don't run the script...  See XXX
-  // comment above.
-  if (ctx) {
-    mTerminationFuncHolder.construct(static_cast<nsJSContext*>(ctx));
-  }
-
   if (NS_FAILED(rv)) {
     // Security check failed.  We're done here.
     return;
   }
 
   // Enter the compartment of our callback, so we can actually work with it.
   mAc.construct(cx, aCallback);
 
--- a/dom/bindings/CallbackObject.h
+++ b/dom/bindings/CallbackObject.h
@@ -143,20 +143,16 @@ protected:
     // Put our nsAutoMicrotask first, so it gets destroyed after everything else
     // is gone
     nsAutoMicroTask mMt;
 
     // Can't construct an XPCAutoRequest until we have a JSContext, so
     // this needs to be a Maybe.
     Maybe<XPCAutoRequest> mAr;
 
-    // Can't construct a TerminationFuncHolder without an nsJSContext.  But we
-    // generally want its destructor to come after the destructor of mCxPusher.
-    Maybe<nsJSContext::TerminationFuncHolder> mTerminationFuncHolder;
-
     nsCxPusher mCxPusher;
 
     // Can't construct a JSAutoCompartment without a JSContext either.  Also,
     // Put mAc after mCxPusher so that we exit the compartment before we pop the
     // JSContext.  Though in practice we'll often manually order those two
     // things.
     Maybe<JSAutoCompartment> mAc;