Bug 394769. Remove the additional lateness argument for timeouts and intervals. r=jst
authorSaint Wesonga <wesongathedeveloper@yahoo.com>
Tue, 07 Feb 2012 15:28:08 -0500
changeset 86370 9bbda25076bfb635ec9afcf7b7fb2234cf45a4d3
parent 86369 7869ec49aba802d50b555f01fe39ea9df392021e
child 86371 37ce3408d81372781f7644514fcd9844f34ab48b
push id22015
push userbmo@edmorley.co.uk
push dateWed, 08 Feb 2012 12:23:25 +0000
treeherdermozilla-central@06b063c001b6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs394769
milestone13.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 394769. Remove the additional lateness argument for timeouts and intervals. r=jst
dom/base/nsGlobalWindow.cpp
dom/base/nsIScriptTimeoutHandler.h
dom/base/nsJSEnvironment.cpp
dom/base/nsJSTimeoutHandler.cpp
dom/tests/mochitest/bugs/Makefile.in
dom/tests/mochitest/bugs/test_bug394769.html
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9355,22 +9355,16 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
 
       bool is_undefined;
       scx->EvaluateString(nsDependentString(script), FastGetGlobalJSObject(),
                           timeout->mPrincipal, timeout->mPrincipal,
                           filename, lineNo,
                           handler->GetScriptVersion(), nsnull,
                           &is_undefined);
     } else {
-      // Let the script handler know about the "secret" final argument that
-      // indicates timeout lateness in milliseconds
-      TimeDuration lateness = now - timeout->mWhen;
-
-      handler->SetLateness(lateness.ToMilliseconds());
-
       nsCOMPtr<nsIVariant> dummy;
       nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
       scx->CallEventHandler(me, FastGetGlobalJSObject(),
                             scriptObject, handler->GetArgv(),
                             // XXXmarkh - consider allowing CallEventHandler to
                             // accept nsnull?
                             getter_AddRefs(dummy));
 
--- a/dom/base/nsIScriptTimeoutHandler.h
+++ b/dom/base/nsIScriptTimeoutHandler.h
@@ -37,19 +37,19 @@
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef nsIScriptTimeoutHandler_h___
 #define nsIScriptTimeoutHandler_h___
 
 class nsIArray;
 
 #define NS_ISCRIPTTIMEOUTHANDLER_IID \
-{ /* {21ba4f96-30b8-4215-a75d-d438eb16a50c} */ \
-  0x21ba4f96, 0x30b8, 0x4215, \
-  { 0xa7, 0x5d, 0xd4, 0x38, 0xeb, 0x16, 0xa5, 0x0c } }
+{ /* {17a9ce1a-d73b-45d1-8145-a0ae57bcc76e} */ \
+  0x17a9ce1a, 0xd73b, 0x45d1, \
+ { 0x81, 0x45, 0xa0, 0xae, 0x57, 0xbc, 0xc7, 0x6e } }
 
 /**
  * Abstraction of the script objects etc required to do timeouts in a
  * language agnostic way.
  */
 
 class nsIScriptTimeoutHandler : public nsISupports
 {
@@ -73,18 +73,14 @@ public:
   virtual void GetLocation(const char **aFileName, PRUint32 *aLineNo) = 0;
 
   // If a script object, get the argv suitable for passing back to the
   // script context.
   virtual nsIArray *GetArgv() = 0;
 
   // Get the language version for this timeout.
   virtual PRUint32 GetScriptVersion() = 0;
-
-  // Set the "secret" final lateness arg.  This will be called before
-  // GetArgv(), which should reflect this lateness value.
-  virtual void SetLateness(PRIntervalTime aHowLate) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptTimeoutHandler,
                               NS_ISCRIPTTIMEOUTHANDLER_IID)
 
 #endif // nsIScriptTimeoutHandler_h___
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -4112,20 +4112,16 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSArgArray)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSArgArray)
 
 nsresult
 nsJSArgArray::GetArgs(PRUint32 *argc, void **argv)
 {
-  if (!mArgv) {
-    NS_WARNING("nsJSArgArray has no argv!");
-    return NS_ERROR_UNEXPECTED;
-  }
   *argv = (void *)mArgv;
   *argc = mArgc;
   return NS_OK;
 }
 
 // nsIArray impl
 NS_IMETHODIMP nsJSArgArray::GetLength(PRUint32 *aLength)
 {
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -46,16 +46,17 @@
 #include "nsJSUtils.h"
 #include "nsDOMJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsJSEnvironment.h"
 #include "nsServiceManagerUtils.h"
 #include "nsDOMError.h"
 #include "nsGlobalWindow.h"
 #include "nsIContentSecurityPolicy.h"
+#include "nsAlgorithm.h"
 
 static const char kSetIntervalStr[] = "setInterval";
 static const char kSetTimeoutStr[] = "setTimeout";
 
 // Our JS nsIScriptTimeoutHandler implementation.
 class nsJSScriptTimeoutHandler: public nsIScriptTimeoutHandler
 {
 public:
@@ -80,19 +81,16 @@ public:
   }
   virtual PRUint32 GetScriptVersion() {
         return mVersion;
   }
 
   virtual nsIArray *GetArgv() {
     return mArgv;
   }
-  // Called by the timeout mechanism so the secret 'lateness' arg can be
-  // added.
-  virtual void SetLateness(PRIntervalTime aHowLate);
 
   nsresult Init(nsGlobalWindow *aWindow, bool *aIsInterval,
                 PRInt32 *aInterval);
 
   void ReleaseJSObjects();
 
 private:
 
@@ -319,59 +317,49 @@ nsJSScriptTimeoutHandler::Init(nsGlobalW
       mFileName.Assign(filename);
     }
   } else if (funobj) {
     rv = NS_HOLD_JS_OBJECTS(this, nsJSScriptTimeoutHandler);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mFunObj = funobj;
 
-    // Create our arg array - leave an extra slot for a secret final argument
-    // that indicates to the called function how "late" the timeout is.  We
-    // will fill that in when SetLateness is called.
+    // Create our arg array.  argc is the number of arguments passed
+    // to setTimeout or setInterval; the first two are our callback
+    // and the delay, so only arguments after that need to go in our
+    // array.
     nsCOMPtr<nsIArray> array;
-    rv = NS_CreateJSArgv(cx, (argc > 1) ? argc - 1 : argc, nsnull,
+    // NS_MAX(argc - 2, 0) wouldn't work right because argc is unsigned.
+    rv = NS_CreateJSArgv(cx, NS_MAX(argc, 2u) - 2, nsnull,
                          getter_AddRefs(array));
     if (NS_FAILED(rv)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     PRUint32 dummy;
     jsval *jsargv = nsnull;
     nsCOMPtr<nsIJSArgArray> jsarray(do_QueryInterface(array));
     jsarray->GetArgs(&dummy, reinterpret_cast<void **>(&jsargv));
 
-    // must have worked - we own the impl! :)
-    NS_ASSERTION(jsargv, "No argv!");
-    for (PRInt32 i = 2; (PRUint32)i < argc; ++i) {
-      jsargv[i - 2] = argv[i];
+    // jsargv might be null if we have argc <= 2
+    if (jsargv) {
+      for (PRInt32 i = 2; (PRUint32)i < argc; ++i) {
+        jsargv[i - 2] = argv[i];
+      }
+    } else {
+      NS_ASSERTION(argc <= 2, "Why do we have no jsargv when we have arguments?");
     }
-    // final arg slot remains null, array has rooted vals.
     mArgv = array;
   } else {
     NS_WARNING("No func and no expr - why are we here?");
   }
   *aInterval = interval;
   return NS_OK;
 }
 
-void nsJSScriptTimeoutHandler::SetLateness(PRIntervalTime aHowLate)
-{
-  nsCOMPtr<nsIJSArgArray> jsarray(do_QueryInterface(mArgv));
-  if (jsarray) {
-    PRUint32 argc;
-    jsval *jsargv;
-    nsresult rv = jsarray->GetArgs(&argc, reinterpret_cast<void **>(&jsargv));
-    if (NS_SUCCEEDED(rv) && jsargv && argc)
-      jsargv[argc-1] = INT_TO_JSVAL((jsint) aHowLate);
-  } else {
-    NS_ERROR("How can our argv not handle this?");
-  }
-}
-
 const PRUnichar *
 nsJSScriptTimeoutHandler::GetHandlerText()
 {
   NS_ASSERTION(mExpr, "No expression, so no handler text!");
   return ::JS_GetFlatStringChars(mExpr);
 }
 
 nsresult NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
--- a/dom/tests/mochitest/bugs/Makefile.in
+++ b/dom/tests/mochitest/bugs/Makefile.in
@@ -68,16 +68,17 @@ include $(topsrcdir)/config/rules.mk
 		bug346659-opener.html \
 		bug346659-opener-echoer.html \
 		test_bug351601.html \
 		test_bug370098.html \
 		test_bug377539.html \
 		test_bug384122.html \
 		test_bug389366.html \
 		test_bug393974.html \
+		test_bug394769.html \
 		test_bug396843.html \
 		test_bug397571.html \
 		test_bug400204.html \
 		test_bug404748.html \
 		test_bug407839.html \
 		iframe_bug407839-1.html \
 		iframe_bug407839-2.html \
 		test_bug424093.html \
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/test_bug394769.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=394769
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 394769</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=394769">Mozilla Bug 394769</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 394769 **/
+SimpleTest.waitForExplicitFinish();
+function h() {
+  is(arguments.length, 1, "Should only have one argument");
+  SimpleTest.finish();
+}
+
+function g() {
+  is(arguments.length, 0, "Should not have lateness argument for function with delay");
+  setTimeout(h, 0, "arg");
+}
+
+function f() {
+  is(arguments.length, 0, "Should not have lateness argument for function with no delay");
+  setTimeout(g, 0);
+}
+
+setTimeout(f);
+</script>
+</pre>
+</body>
+</html>