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 89249 9bbda25076bfb635ec9afcf7b7fb2234cf45a4d3
parent 89248 7869ec49aba802d50b555f01fe39ea9df392021e
child 89250 37ce3408d81372781f7644514fcd9844f34ab48b
push idunknown
push userunknown
push dateunknown
reviewersjst
bugs394769
milestone13.0a1
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>