Bug 1200484 (part 11) - Set source location when initializing an nsJSScriptTimeoutHandler from a Function. r=peterv.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 03 Sep 2015 16:03:19 -0700
changeset 260757 09a4daca37279afece667a2754a9b5f16a3eb0db
parent 260756 6cb2ada75b2dc89e008cdb3327a0f6a1467c111d
child 260758 b4883fe60278dd4ea35d2a45da15627f1835d29b
push id64583
push usernnethercote@mozilla.com
push dateFri, 04 Sep 2015 03:09:30 +0000
treeherdermozilla-inbound@b4883fe60278 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1200484
milestone43.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 1200484 (part 11) - Set source location when initializing an nsJSScriptTimeoutHandler from a Function. r=peterv. Because we currently set the source location of a nsJSScriptTimeoutHandler when initializing from an expression, but not when initializing from a function, which is an undesirable inconsistency. This requires plumbing through the JSContext in a few places.
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsJSTimeoutHandler.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -12364,17 +12364,18 @@ nsGlobalWindow::InnerForSetTimeoutOrInte
 }
 
 int32_t
 nsGlobalWindow::SetTimeout(JSContext* aCx, Function& aFunction,
                            int32_t aTimeout,
                            const Sequence<JS::Value>& aArguments,
                            ErrorResult& aError)
 {
-  return SetTimeoutOrInterval(aFunction, aTimeout, aArguments, false, aError);
+  return SetTimeoutOrInterval(aCx, aFunction, aTimeout, aArguments, false,
+                              aError);
 }
 
 int32_t
 nsGlobalWindow::SetTimeout(JSContext* aCx, const nsAString& aHandler,
                            int32_t aTimeout,
                            const Sequence<JS::Value>& /* unused */,
                            ErrorResult& aError)
 {
@@ -12398,17 +12399,17 @@ IsInterval(const Optional<int32_t>& aTim
 int32_t
 nsGlobalWindow::SetInterval(JSContext* aCx, Function& aFunction,
                             const Optional<int32_t>& aTimeout,
                             const Sequence<JS::Value>& aArguments,
                             ErrorResult& aError)
 {
   int32_t timeout;
   bool isInterval = IsInterval(aTimeout, timeout);
-  return SetTimeoutOrInterval(aFunction, timeout, aArguments, isInterval,
+  return SetTimeoutOrInterval(aCx, aFunction, timeout, aArguments, isInterval,
                               aError);
 }
 
 int32_t
 nsGlobalWindow::SetInterval(JSContext* aCx, const nsAString& aHandler,
                             const Optional<int32_t>& aTimeout,
                             const Sequence<JS::Value>& /* unused */,
                             ErrorResult& aError)
@@ -12540,32 +12541,33 @@ nsGlobalWindow::SetTimeoutOrInterval(nsI
   timeout->mPublicId = ++mTimeoutPublicIdCounter;
   *aReturn = timeout->mPublicId;
 
   return NS_OK;
 
 }
 
 int32_t
-nsGlobalWindow::SetTimeoutOrInterval(Function& aFunction, int32_t aTimeout,
+nsGlobalWindow::SetTimeoutOrInterval(JSContext *aCx, Function& aFunction,
+                                     int32_t aTimeout,
                                      const Sequence<JS::Value>& aArguments,
                                      bool aIsInterval, ErrorResult& aError)
 {
   nsGlobalWindow* inner = InnerForSetTimeoutOrInterval(aError);
   if (!inner) {
     return -1;
   }
 
   if (inner != this) {
-    return inner->SetTimeoutOrInterval(aFunction, aTimeout, aArguments,
+    return inner->SetTimeoutOrInterval(aCx, aFunction, aTimeout, aArguments,
                                        aIsInterval, aError);
   }
 
   nsCOMPtr<nsIScriptTimeoutHandler> handler =
-    NS_CreateJSTimeoutHandler(this, aFunction, aArguments, aError);
+    NS_CreateJSTimeoutHandler(aCx, this, aFunction, aArguments, aError);
   if (!handler) {
     return 0;
   }
 
   int32_t result;
   aError = SetTimeoutOrInterval(handler, aTimeout, aIsInterval, &result);
   return result;
 }
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -125,17 +125,17 @@ class IDBFactory;
 } // namespace indexedDB
 } // namespace dom
 namespace gfx {
 class VRHMDInfo;
 } // namespace gfx
 } // namespace mozilla
 
 extern already_AddRefed<nsIScriptTimeoutHandler>
-NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
+NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
                           mozilla::dom::Function& aFunction,
                           const mozilla::dom::Sequence<JS::Value>& aArguments,
                           mozilla::ErrorResult& aError);
 
 extern already_AddRefed<nsIScriptTimeoutHandler>
 NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
                           const nsAString& aExpression,
                           mozilla::ErrorResult& aError);
@@ -1389,17 +1389,18 @@ private:
 
 public:
   // Timeout Functions
   // Language agnostic timeout function (all args passed).
   // |interval| is in milliseconds.
   nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
                                 int32_t interval,
                                 bool aIsInterval, int32_t* aReturn) override;
-  int32_t SetTimeoutOrInterval(mozilla::dom::Function& aFunction,
+  int32_t SetTimeoutOrInterval(JSContext* aCx,
+                               mozilla::dom::Function& aFunction,
                                int32_t aTimeout,
                                const mozilla::dom::Sequence<JS::Value>& aArguments,
                                bool aIsInterval, mozilla::ErrorResult& aError);
   int32_t SetTimeoutOrInterval(JSContext* aCx, const nsAString& aHandler,
                                int32_t aTimeout, bool aIsInterval,
                                mozilla::ErrorResult& aError);
   void ClearTimeoutOrInterval(int32_t aTimerID,
                                   mozilla::ErrorResult& aError);
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -30,17 +30,18 @@ class nsJSScriptTimeoutHandler final : p
 {
 public:
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsJSScriptTimeoutHandler)
 
   nsJSScriptTimeoutHandler();
   // This will call SwapElements on aArguments with an empty array.
-  nsJSScriptTimeoutHandler(nsGlobalWindow *aWindow, Function& aFunction,
+  nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
+                           Function& aFunction,
                            FallibleTArray<JS::Heap<JS::Value> >& aArguments,
                            ErrorResult& aError);
   nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
                            const nsAString& aExpression, bool* aAllowEval,
                            ErrorResult& aError);
 
   virtual const char16_t* GetHandlerText() override;
   virtual Function* GetCallback() override
@@ -183,32 +184,36 @@ CheckCSPForEval(JSContext* aCx, nsGlobal
   return allowsEval;
 }
 
 nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler() :
   mLineNo(0)
 {
 }
 
-nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(nsGlobalWindow *aWindow,
+nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
+                                                   nsGlobalWindow *aWindow,
                                                    Function& aFunction,
                                                    FallibleTArray<JS::Heap<JS::Value> >& aArguments,
                                                    ErrorResult& aError) :
   mLineNo(0),
   mFunction(&aFunction)
 {
   if (!aWindow->GetContextInternal() || !aWindow->FastGetGlobalJSObject()) {
     // This window was already closed, or never properly initialized,
     // don't let a timer be scheduled on such a window.
     aError.Throw(NS_ERROR_NOT_INITIALIZED);
     return;
   }
 
   mozilla::HoldJSObjects(this);
   mArgs.SwapElements(aArguments);
+
+  // Get the calling location.
+  nsJSUtils::GetCallingLocation(aCx, mFileName, &mLineNo);
 }
 
 nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
                                                    nsGlobalWindow *aWindow,
                                                    const nsAString& aExpression,
                                                    bool* aAllowEval,
                                                    ErrorResult& aError) :
   mLineNo(0),
@@ -248,28 +253,29 @@ nsJSScriptTimeoutHandler::ReleaseJSObjec
 const char16_t *
 nsJSScriptTimeoutHandler::GetHandlerText()
 {
   NS_ASSERTION(!mFunction, "No expression, so no handler text!");
   return mExpr.get();
 }
 
 already_AddRefed<nsIScriptTimeoutHandler>
-NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, Function& aFunction,
+NS_CreateJSTimeoutHandler(JSContext *aCx, nsGlobalWindow *aWindow,
+                          Function& aFunction,
                           const Sequence<JS::Value>& aArguments,
                           ErrorResult& aError)
 {
   FallibleTArray<JS::Heap<JS::Value> > args;
   if (!args.AppendElements(aArguments, fallible)) {
     aError.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
 
   nsRefPtr<nsJSScriptTimeoutHandler> handler =
-    new nsJSScriptTimeoutHandler(aWindow, aFunction, args, aError);
+    new nsJSScriptTimeoutHandler(aCx, aWindow, aFunction, args, aError);
   return aError.Failed() ? nullptr : handler.forget();
 }
 
 already_AddRefed<nsIScriptTimeoutHandler>
 NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
                           const nsAString& aExpression, ErrorResult& aError)
 {
   ErrorResult rv;