Merge inbound to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 16 Jun 2015 14:38:49 -0400
changeset 249138 27caa5299f9f1bacf8a92b898837edf360b3b212
parent 249100 02f2b34ed5e40c7888eb5a0c207bc885f0aa1000 (current diff)
parent 249137 6579ed36ffa737904810bd1948b2d34457056151 (diff)
child 249139 7f8d6477291eb0545afe4a36d2f4884daae10920
child 249154 4f381552336d56fd7befc57dc9bfd08a1f2650bf
child 249157 3ce5e13f9693af700be0eda6a04b286718b3e50c
push id28918
push userryanvm@gmail.com
push dateTue, 16 Jun 2015 18:38:57 +0000
treeherdermozilla-central@27caa5299f9f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone41.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
Merge inbound to m-c. a=merge
media/mtransport/runnable_utils.py
media/mtransport/runnable_utils_generated.h
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -323,16 +323,28 @@ var shell = {
     this.contentBrowser = container.appendChild(systemAppFrame);
 
     systemAppFrame.contentWindow
                   .QueryInterface(Ci.nsIInterfaceRequestor)
                   .getInterface(Ci.nsIWebNavigation)
                   .sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
                                       .createInstance(Ci.nsISHistory);
 
+    this.allowedAudioChannels = new Map();
+    let audioChannels = systemAppFrame.allowedAudioChannels;
+    audioChannels && audioChannels.forEach(function(audioChannel) {
+      this.allowedAudioChannels.set(audioChannel.name, audioChannel);
+      audioChannel.addEventListener('activestatechanged', this);
+      // Set all audio channels as unmuted by default
+      // because some audio in System app will be played
+      // before AudioChannelService[1] is Gaia is loaded.
+      // [1]: https://github.com/mozilla-b2g/gaia/blob/master/apps/system/js/audio_channel_service.js
+      audioChannel.setMuted(false);
+    }.bind(this));
+
     // On firefox mulet, shell.html is loaded in a tab
     // and we have to listen on the chrome event handler
     // to catch key events
     let chromeEventHandler = window.QueryInterface(Ci.nsIInterfaceRequestor)
                                    .getInterface(Ci.nsIWebNavigation)
                                    .QueryInterface(Ci.nsIDocShell)
                                    .chromeEventHandler || window;
     // Capture all key events so we can filter out hardware buttons
@@ -556,16 +568,28 @@ var shell = {
         window.removeEventListener('MozAfterPaint', this);
         this.sendChromeEvent({
           type: 'system-first-paint'
         });
         break;
       case 'unload':
         this.stop();
         break;
+      case 'activestatechanged':
+        var channel = evt.target;
+        // TODO: We should get the `isActive` state from evt.isActive.
+        // Then we don't need to do `channel.isActive()` here.
+        channel.isActive().onsuccess = function(evt) {
+          this.sendChromeEvent({
+            type: 'system-audiochannel-state-changed',
+            name: channel.name,
+            isActive: evt.target.result
+          });
+        }.bind(this);
+        break;
     }
   },
 
   // Send an event to a specific window, document or element.
   sendEvent: function shell_sendEvent(target, type, details) {
     let doc = target.document || target.ownerDocument || target;
     let event = doc.createEvent('CustomEvent');
     event.initCustomEvent(type, true, true, details ? details : {});
@@ -734,16 +758,21 @@ var CustomEventManager = {
       case 'captive-portal-login-cancel':
         CaptivePortalLoginHelper.handleEvent(detail);
         break;
       case 'inputmethod-update-layouts':
       case 'inputregistry-add':
       case 'inputregistry-remove':
         KeyboardHelper.handleEvent(detail);
         break;
+      case 'system-audiochannel-list':
+      case 'system-audiochannel-mute':
+      case 'system-audiochannel-volume':
+        SystemAppMozBrowserHelper.handleEvent(detail);
+        break;
       case 'do-command':
         DoCommandHelper.handleEvent(detail.cmd);
         break;
       case 'copypaste-do-command':
         Services.obs.notifyObservers({ wrappedJSObject: shell.contentBrowser },
                                      'ask-children-to-execute-copypaste-command', detail.cmd);
         break;
     }
@@ -862,16 +891,73 @@ let KeyboardHelper = {
       case 'inputregistry-remove':
         Keyboard.inputRegistryGlue.returnMessage(detail);
 
         break;
     }
   }
 };
 
+let SystemAppMozBrowserHelper = {
+  handleEvent: function systemAppMozBrowser_handleEvent(detail) {
+    let request;
+    let name;
+    switch (detail.type) {
+      case 'system-audiochannel-list':
+        let audioChannels = [];
+        shell.allowedAudioChannels.forEach(function(value, name) {
+          audioChannels.push(name);
+        });
+        SystemAppProxy._sendCustomEvent('mozSystemWindowChromeEvent', {
+          type: 'system-audiochannel-list',
+          audioChannels: audioChannels
+        });
+        break;
+      case 'system-audiochannel-mute':
+        name = detail.name;
+        let isMuted = detail.isMuted;
+        request = shell.allowedAudioChannels.get(name).setMuted(isMuted);
+        request.onsuccess = function() {
+          SystemAppProxy._sendCustomEvent('mozSystemWindowChromeEvent', {
+            type: 'system-audiochannel-mute-onsuccess',
+            name: name,
+            isMuted: isMuted
+          });
+        };
+        request.onerror = function() {
+          SystemAppProxy._sendCustomEvent('mozSystemWindowChromeEvent', {
+            type: 'system-audiochannel-mute-onerror',
+            name: name,
+            isMuted: isMuted
+          });
+        };
+        break;
+      case 'system-audiochannel-volume':
+        name = detail.name;
+        let volume = detail.volume;
+        request = shell.allowedAudioChannels.get(name).setVolume(volume);
+        request.onsuccess = function() {
+          sSystemAppProxy._sendCustomEvent('mozSystemWindowChromeEvent', {
+            type: 'system-audiochannel-volume-onsuccess',
+            name: name,
+            volume: volume
+          });
+        };
+        request.onerror = function() {
+          SystemAppProxy._sendCustomEvent('mozSystemWindowChromeEvent', {
+            type: 'system-audiochannel-volume-onerror',
+            name: name,
+            volume: volume
+          });
+        };
+        break;
+    }
+  }
+};
+
 // This is the backend for Gaia's screenshot feature.  Gaia requests a
 // screenshot by sending a mozContentEvent with detail.type set to
 // 'take-screenshot'.  Then we take a screenshot and send a
 // mozChromeEvent with detail.type set to 'take-screenshot-success'
 // and detail.file set to the an image/png blob
 window.addEventListener('ContentStart', function ss_onContentStart() {
   let content = shell.contentBrowser.contentWindow;
   content.addEventListener('mozContentEvent', function ss_onMozContentEvent(e) {
--- a/dom/base/nsIContentPolicyBase.idl
+++ b/dom/base/nsIContentPolicyBase.idl
@@ -254,18 +254,19 @@ interface nsIContentPolicyBase : nsISupp
    * Indicates an internal constant for content loaded from track elements.
    *
    * This will be mapped to TYPE_MEDIA.
    */
   const nsContentPolicyType TYPE_INTERNAL_TRACK = 32;
 
   /* When adding new content types, please update nsContentBlocker,
    * NS_CP_ContentTypeName, nsCSPContext, all nsIContentPolicy
-   * implementations, and other things that are not listed here that are
-   * related to nsIContentPolicy. */
+   * implementations, the static_assert in dom/cache/DBSchema.cpp,
+   * and other things that are not listed here that are related to
+   * nsIContentPolicy. */
 
   //////////////////////////////////////////////////////////////////////
 
   /**
    * Returned from shouldLoad or shouldProcess if the load or process request
    * is rejected based on details of the request.
    */
   const short REJECT_REQUEST = -1;
--- a/dom/base/nsNoDataProtocolContentPolicy.cpp
+++ b/dom/base/nsNoDataProtocolContentPolicy.cpp
@@ -25,16 +25,19 @@ nsNoDataProtocolContentPolicy::ShouldLoa
                                           nsIURI *aContentLocation,
                                           nsIURI *aRequestingLocation,
                                           nsISupports *aRequestingContext,
                                           const nsACString &aMimeGuess,
                                           nsISupports *aExtra,
                                           nsIPrincipal *aRequestPrincipal,
                                           int16_t *aDecision)
 {
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   *aDecision = nsIContentPolicy::ACCEPT;
 
   // Don't block for TYPE_OBJECT since such URIs are sometimes loaded by the
   // plugin, so they don't necessarily open external apps
   // TYPE_WEBSOCKET loads can only go to ws:// or wss://, so we don't need to
   // concern ourselves with them.
   if (aContentType != TYPE_DOCUMENT &&
       aContentType != TYPE_SUBDOCUMENT &&
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -123,17 +123,28 @@ static_assert(nsIContentPolicy::TYPE_INV
               nsIContentPolicy::TYPE_DTD == 13 &&
               nsIContentPolicy::TYPE_FONT == 14 &&
               nsIContentPolicy::TYPE_MEDIA == 15 &&
               nsIContentPolicy::TYPE_WEBSOCKET == 16 &&
               nsIContentPolicy::TYPE_CSP_REPORT == 17 &&
               nsIContentPolicy::TYPE_XSLT == 18 &&
               nsIContentPolicy::TYPE_BEACON == 19 &&
               nsIContentPolicy::TYPE_FETCH == 20 &&
-              nsIContentPolicy::TYPE_IMAGESET == 21,
+              nsIContentPolicy::TYPE_IMAGESET == 21 &&
+              nsIContentPolicy::TYPE_WEB_MANIFEST == 22 &&
+              nsIContentPolicy::TYPE_INTERNAL_SCRIPT == 23 &&
+              nsIContentPolicy::TYPE_INTERNAL_WORKER == 24 &&
+              nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER == 25 &&
+              nsIContentPolicy::TYPE_INTERNAL_EMBED == 26 &&
+              nsIContentPolicy::TYPE_INTERNAL_OBJECT == 27 &&
+              nsIContentPolicy::TYPE_INTERNAL_FRAME == 28 &&
+              nsIContentPolicy::TYPE_INTERNAL_IFRAME == 29 &&
+              nsIContentPolicy::TYPE_INTERNAL_AUDIO == 30 &&
+              nsIContentPolicy::TYPE_INTERNAL_VIDEO == 31 &&
+              nsIContentPolicy::TYPE_INTERNAL_TRACK == 32,
               "nsContentPolicytType values are as expected");
 
 namespace {
 
 typedef int32_t EntryId;
 
 struct IdCount
 {
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -323,177 +323,16 @@ UploadLastDir::ContentPrefCallback::Hand
   // HandleCompletion is always called (even with HandleError was called),
   // so we don't need to do anything special here.
   return NS_OK;
 }
 
 namespace {
 
 /**
- * This enumerator returns File objects after wrapping a single
- * nsIFile representing a directory. It enumerates the files under that
- * directory and its subdirectories as a flat list of files, ignoring/skipping
- * over symbolic links.
- *
- * The enumeration involves I/O, so this class must NOT be used on the main
- * thread or else the main thread could be blocked for a very long time.
- *
- * This enumerator does not walk the directory tree breadth-first, but it also
- * is not guaranteed to walk it depth-first either (since it uses
- * nsIFile::GetDirectoryEntries, which is not guaranteed to group a directory's
- * subdirectories at the beginning of the list that it returns).
- */
-class DirPickerRecursiveFileEnumerator final
-  : public nsISimpleEnumerator
-{
-  ~DirPickerRecursiveFileEnumerator() {}
-
-public:
-  NS_DECL_ISUPPORTS
-
-  explicit DirPickerRecursiveFileEnumerator(nsIFile* aTopDir)
-    : mTopDir(aTopDir)
-  {
-    MOZ_ASSERT(!NS_IsMainThread(), "This class blocks on I/O!");
-
-#ifdef DEBUG
-    {
-      bool isDir;
-      aTopDir->IsDirectory(&isDir);
-      MOZ_ASSERT(isDir);
-    }
-#endif
-
-    if (NS_FAILED(aTopDir->GetParent(getter_AddRefs(mTopDirsParent)))) {
-      // This just means that the name of the picked directory won't be
-      // included in the File.path string.
-      mTopDirsParent = aTopDir;
-    }
-
-    nsCOMPtr<nsISimpleEnumerator> entries;
-    if (NS_SUCCEEDED(mTopDir->GetDirectoryEntries(getter_AddRefs(entries))) &&
-        entries) {
-      mDirEnumeratorStack.AppendElement(entries);
-      LookupAndCacheNext();
-    }
-  }
-
-  NS_IMETHOD
-  GetNext(nsISupports** aResult) override
-  {
-    MOZ_ASSERT(!NS_IsMainThread(),
-               "Walking the directory tree involves I/O, so using this "
-               "enumerator can block a thread for a long time!");
-
-    if (!mNextFile) {
-      return NS_ERROR_FAILURE;
-    }
-
-    // The parent for this object will be set on the main thread.
-    nsRefPtr<File> domFile = File::CreateFromFile(nullptr, mNextFile);
-    nsCString relDescriptor;
-    nsresult rv =
-      mNextFile->GetRelativeDescriptor(mTopDirsParent, relDescriptor);
-    NS_ENSURE_SUCCESS(rv, rv);
-    NS_ConvertUTF8toUTF16 path(relDescriptor);
-    nsAutoString leafName;
-    mNextFile->GetLeafName(leafName);
-    MOZ_ASSERT(leafName.Length() <= path.Length());
-    int32_t length = path.Length() - leafName.Length();
-    MOZ_ASSERT(length >= 0);
-    if (length > 0) {
-      // Note that we leave the trailing "/" on the path.
-      BlobImplFile* blobImpl = static_cast<BlobImplFile*>(domFile->Impl());
-      MOZ_ASSERT(blobImpl);
-      blobImpl->SetPath(Substring(path, 0, uint32_t(length)));
-    }
-
-    nsCOMPtr<nsIDOMBlob> blob = domFile.get();
-    blob.forget(aResult);
-    LookupAndCacheNext();
-    return NS_OK;
-  }
-
-  NS_IMETHOD
-  HasMoreElements(bool* aResult) override
-  {
-    *aResult = !!mNextFile;
-    return NS_OK;
-  }
-
-private:
-
-  void
-  LookupAndCacheNext()
-  {
-    for (;;) {
-      if (mDirEnumeratorStack.IsEmpty()) {
-        mNextFile = nullptr;
-        break;
-      }
-
-      nsISimpleEnumerator* currentDirEntries =
-        mDirEnumeratorStack.LastElement();
-
-      bool hasMore;
-      DebugOnly<nsresult> rv = currentDirEntries->HasMoreElements(&hasMore);
-      MOZ_ASSERT(NS_SUCCEEDED(rv));
-
-      if (!hasMore) {
-        mDirEnumeratorStack.RemoveElementAt(mDirEnumeratorStack.Length() - 1);
-        continue;
-      }
-
-      nsCOMPtr<nsISupports> entry;
-      rv = currentDirEntries->GetNext(getter_AddRefs(entry));
-      MOZ_ASSERT(NS_SUCCEEDED(rv));
-
-      nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
-      MOZ_ASSERT(file);
-
-      bool isLink, isSpecial;
-      file->IsSymlink(&isLink);
-      file->IsSpecial(&isSpecial);
-      if (isLink || isSpecial) {
-        continue;
-      }
-
-      bool isDir;
-      file->IsDirectory(&isDir);
-      if (isDir) {
-        nsCOMPtr<nsISimpleEnumerator> subDirEntries;
-        rv = file->GetDirectoryEntries(getter_AddRefs(subDirEntries));
-        MOZ_ASSERT(NS_SUCCEEDED(rv) && subDirEntries);
-        mDirEnumeratorStack.AppendElement(subDirEntries);
-        continue;
-      }
-
-#ifdef DEBUG
-      {
-        bool isFile;
-        file->IsFile(&isFile);
-        MOZ_ASSERT(isFile);
-      }
-#endif
-
-      mNextFile.swap(file);
-      return;
-    }
-  }
-
-private:
-  nsCOMPtr<nsIFile> mTopDir;
-  nsCOMPtr<nsIFile> mTopDirsParent; // May be mTopDir if no parent
-  nsCOMPtr<nsIFile> mNextFile;
-  nsTArray<nsCOMPtr<nsISimpleEnumerator> > mDirEnumeratorStack;
-};
-
-NS_IMPL_ISUPPORTS(DirPickerRecursiveFileEnumerator, nsISimpleEnumerator)
-
-/**
  * This may return nullptr if aDomFile's implementation of
  * File::mozFullPathInternal does not successfully return a non-empty
  * string that is a valid path. This can happen on Firefox OS, for example,
  * where the file picker can create Blobs.
  */
 static already_AddRefed<nsIFile>
 DOMFileToLocalFile(File* aDomFile)
 {
@@ -513,180 +352,29 @@ DOMFileToLocalFile(File* aDomFile)
     return nullptr;
   }
 
   return localFile.forget();
 }
 
 } // anonymous namespace
 
-class DirPickerFileListBuilderTask final
-  : public nsRunnable
-{
-public:
-  DirPickerFileListBuilderTask(HTMLInputElement* aInput, nsIFile* aTopDir)
-    : mPreviousFileListLength(0)
-    , mInput(aInput)
-    , mTopDir(aTopDir)
-    , mFileListLength(0)
-    , mCanceled(false)
-  {}
-
-  NS_IMETHOD Run() {
-    if (!NS_IsMainThread()) {
-      // Build up list of File objects on this dedicated thread:
-      nsCOMPtr<nsISimpleEnumerator> iter =
-        new DirPickerRecursiveFileEnumerator(mTopDir);
-      bool hasMore = true;
-      nsCOMPtr<nsISupports> tmp;
-      while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
-        iter->GetNext(getter_AddRefs(tmp));
-        nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(tmp);
-        MOZ_ASSERT(domBlob);
-        mFileList.AppendElement(static_cast<File*>(domBlob.get()));
-        mFileListLength = mFileList.Length();
-        if (mCanceled) {
-          MOZ_ASSERT(!mInput, "This is bad - how did this happen?");
-          // There's no point dispatching to the main thread (that doesn't
-          // guarantee that we'll be destroyed there).
-          return NS_OK;
-        }
-      }
-      return NS_DispatchToMainThread(this);
-    }
-
-    // Now back on the main thread, set the list on our HTMLInputElement:
-    if (mCanceled || mFileList.IsEmpty()) {
-      return NS_OK;
-    }
-    MOZ_ASSERT(mInput->mDirPickerFileListBuilderTask,
-               "But we aren't canceled!");
-    if (mInput->mProgressTimer) {
-      mInput->mProgressTimerIsActive = false;
-      mInput->mProgressTimer->Cancel();
-    }
-
-    mInput->MaybeDispatchProgressEvent(true);        // Last progress event.
-    mInput->mDirPickerFileListBuilderTask = nullptr; // Now null out.
-
-    if (mCanceled) { // The last progress event may have canceled us
-      return NS_OK;
-    }
-
-    // Recreate File with the correct parent object.
-    nsCOMPtr<nsIGlobalObject> global = mInput->OwnerDoc()->GetScopeObject();
-    for (uint32_t i = 0; i < mFileList.Length(); ++i) {
-      MOZ_ASSERT(!mFileList[i]->GetParentObject());
-      mFileList[i] = File::Create(global, mFileList[i]->Impl());
-      MOZ_ASSERT(mFileList[i]);
-    }
-
-    // The text control frame (if there is one) isn't going to send a change
-    // event because it will think this is done by a script.
-    // So, we can safely send one by ourself.
-    mInput->SetFiles(mFileList, true);
-    nsresult rv =
-      nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
-                                           static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
-                                           NS_LITERAL_STRING("change"), true,
-                                           false);
-    // Clear mInput to make sure that it can't lose its last strong ref off the
-    // main thread (which may happen if our dtor runs off the main thread)!
-    mInput = nullptr;
-    return rv;
-  }
-
-  void Cancel()
-  {
-    MOZ_ASSERT(NS_IsMainThread() && !mCanceled);
-    // Clear mInput to make sure that it can't lose its last strong ref off the
-    // main thread (which may happen if our dtor runs off the main thread)!
-    mInput = nullptr;
-    mCanceled = true;
-  }
-
-  uint32_t GetFileListLength() const
-  {
-    return mFileListLength;
-  }
-
-  /**
-   * The number of files added to the FileList at the time the last progress
-   * event was fired.
-   *
-   * This is only read/set by HTMLInputElement on the main thread. The reason
-   * that this member is stored here rather than on HTMLInputElement is so that
-   * we don't increase the size of HTMLInputElement for something that's rarely
-   * used.
-   */
-  uint32_t mPreviousFileListLength;
-
-private:
-  nsRefPtr<HTMLInputElement> mInput;
-  nsCOMPtr<nsIFile> mTopDir;
-  nsTArray<nsRefPtr<File>> mFileList;
-
-  // We access the list length on both threads, so we need the indirection of
-  // this atomic member to make the access thread safe:
-  mozilla::Atomic<uint32_t> mFileListLength;
-
-  mozilla::Atomic<bool> mCanceled;
-};
-
 
 NS_IMETHODIMP
 HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
 {
   mInput->PickerClosed();
 
   if (aResult == nsIFilePicker::returnCancel) {
     return NS_OK;
   }
 
-  mInput->CancelDirectoryPickerScanIfRunning();
-
   int16_t mode;
   mFilePicker->GetMode(&mode);
 
-  if (mode == static_cast<int16_t>(nsIFilePicker::modeGetFolder)) {
-    // Directory picking is different, since we still need to do more I/O to
-    // build up the list of File objects. Since this may block for a
-    // long time, we need to build the list off on another dedicated thread to
-    // avoid blocking any other activities that the browser is carrying out.
-
-    // The user selected this directory, so we always save this dir, even if
-    // no files are found under it.
-    nsCOMPtr<nsIFile> pickedDir;
-    mFilePicker->GetFile(getter_AddRefs(pickedDir));
-
-#ifdef DEBUG
-    {
-      bool isDir;
-      pickedDir->IsDirectory(&isDir);
-      MOZ_ASSERT(isDir);
-    }
-#endif
-
-    HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
-      mInput->OwnerDoc(), pickedDir);
-
-    nsCOMPtr<nsIEventTarget> target
-      = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
-    NS_ASSERTION(target, "Must have stream transport service");
-
-    mInput->StartProgressEventTimer();
-
-    // DirPickerFileListBuilderTask takes care of calling SetFiles() and
-    // dispatching the "change" event.
-    mInput->mDirPickerFileListBuilderTask =
-      new DirPickerFileListBuilderTask(mInput.get(), pickedDir.get());
-    return target->Dispatch(mInput->mDirPickerFileListBuilderTask,
-                            NS_DISPATCH_NORMAL);
-  }
-
   // Collect new selected filenames
   nsTArray<nsRefPtr<File>> newFiles;
   if (mode == static_cast<int16_t>(nsIFilePicker::modeOpenMultiple)) {
     nsCOMPtr<nsISimpleEnumerator> iter;
     nsresult rv = mFilePicker->GetDomfiles(getter_AddRefs(iter));
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (!iter) {
@@ -1159,17 +847,16 @@ HTMLInputElement::HTMLInputElement(alrea
   , mInInternalActivate(false)
   , mCheckedIsToggled(false)
   , mIndeterminate(false)
   , mInhibitRestoration(aFromParser & FROM_PARSER_FRAGMENT)
   , mCanShowValidUI(true)
   , mCanShowInvalidUI(true)
   , mHasRange(false)
   , mIsDraggingRange(false)
-  , mProgressTimerIsActive(false)
   , mNumberControlSpinnerIsSpinning(false)
   , mNumberControlSpinnerSpinsUp(false)
   , mPickerRunning(false)
   , mSelectionCached(true)
 {
   // We are in a type=text so we now we currenty need a nsTextEditorState.
   mInputData.mState = new nsTextEditorState(this);
 
@@ -1263,17 +950,16 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
   NS_INTERFACE_TABLE_INHERITED(HTMLInputElement,
                                nsIDOMHTMLInputElement,
                                nsITextControlElement,
                                nsIPhonetic,
                                imgINotificationObserver,
                                nsIImageLoadingContent,
                                imgIOnloadBlocker,
                                nsIDOMNSEditableElement,
-                               nsITimerCallback,
                                nsIConstraintValidation)
 NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLFormElementWithState)
 
 // nsIConstraintValidation
 NS_IMPL_NSICONSTRAINTVALIDATION_EXCEPT_SETCUSTOMVALIDITY(HTMLInputElement)
 
 // nsIDOMNode
 
@@ -2780,68 +2466,16 @@ HTMLInputElement::GetFiles()
   if (!mFileList) {
     mFileList = new FileList(static_cast<nsIContent*>(this));
     UpdateFileList();
   }
 
   return mFileList;
 }
 
-void
-HTMLInputElement::OpenDirectoryPicker(ErrorResult& aRv)
-{
-  if (mType != NS_FORM_INPUT_FILE) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
-  }
-  InitFilePicker(FILE_PICKER_DIRECTORY);
-}
-
-void
-HTMLInputElement::CancelDirectoryPickerScanIfRunning()
-{
-  if (!mDirPickerFileListBuilderTask) {
-    return;
-  }
-  if (mProgressTimer) {
-    mProgressTimerIsActive = false;
-    mProgressTimer->Cancel();
-  }
-  mDirPickerFileListBuilderTask->Cancel();
-  mDirPickerFileListBuilderTask = nullptr;
-}
-
-void
-HTMLInputElement::StartProgressEventTimer()
-{
-  if (!mProgressTimer) {
-    mProgressTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
-  }
-  if (mProgressTimer) {
-    mProgressTimerIsActive = true;
-    mProgressTimer->Cancel();
-    mProgressTimer->InitWithCallback(this, kProgressEventInterval,
-                                           nsITimer::TYPE_ONE_SHOT);
-  }
-}
-
-// nsITimerCallback's only method
-NS_IMETHODIMP
-HTMLInputElement::Notify(nsITimer* aTimer)
-{
-  if (mProgressTimer == aTimer) {
-    mProgressTimerIsActive = false;
-    MaybeDispatchProgressEvent(false);
-    return NS_OK;
-  }
-
-  // Just in case some JS user wants to QI to nsITimerCallback and play with us...
-  NS_WARNING("Unexpected timer!");
-  return NS_ERROR_INVALID_POINTER;
-}
-
 /* static */ void
 HTMLInputElement::HandleNumberControlSpin(void* aData)
 {
   HTMLInputElement* input = static_cast<HTMLInputElement*>(aData);
 
   NS_ASSERTION(input->mNumberControlSpinnerIsSpinning,
                "Should have called nsRepeatService::Stop()");
 
@@ -2852,75 +2486,16 @@ HTMLInputElement::HandleNumberControlSpi
     // or else we've lost our frame. Either way, stop the timer and don't do
     // anything else.
     input->StopNumberControlSpinnerSpin();
   } else {
     input->StepNumberControlForUserEvent(input->mNumberControlSpinnerSpinsUp ? 1 : -1);
   }
 }
 
-void
-HTMLInputElement::MaybeDispatchProgressEvent(bool aFinalProgress)
-{
-  nsRefPtr<HTMLInputElement> kungFuDeathGrip;
-
-  if (aFinalProgress && mProgressTimerIsActive) {
-    // mProgressTimer may hold the last reference to us, so take another strong
-    // ref to make sure we don't die under Cancel() and leave this method
-    // running on deleted memory.
-    kungFuDeathGrip = this;
-
-    mProgressTimerIsActive = false;
-    mProgressTimer->Cancel();
-  }
-
-  uint32_t fileListLength = mDirPickerFileListBuilderTask->GetFileListLength();
-
-  if (mProgressTimerIsActive ||
-      fileListLength == mDirPickerFileListBuilderTask->mPreviousFileListLength) {
-    return;
-  }
-
-  if (!aFinalProgress) {
-    StartProgressEventTimer();
-  }
-
-  mDirPickerFileListBuilderTask->mPreviousFileListLength = fileListLength;
-
-  DispatchProgressEvent(NS_LITERAL_STRING(PROGRESS_STR),
-                        false,
-                        mDirPickerFileListBuilderTask->mPreviousFileListLength,
-                        0);
-}
-
-void
-HTMLInputElement::DispatchProgressEvent(const nsAString& aType,
-                                        bool aLengthComputable,
-                                        uint64_t aLoaded, uint64_t aTotal)
-{
-  NS_ASSERTION(!aType.IsEmpty(), "missing event type");
-
-  ProgressEventInit init;
-  init.mBubbles = false;
-  init.mCancelable = true; // XXXkhuey why?
-  init.mLengthComputable = aLengthComputable;
-  init.mLoaded = aLoaded;
-  init.mTotal = (aTotal == UINT64_MAX) ? 0 : aTotal;
-
-  nsRefPtr<ProgressEvent> event =
-    ProgressEvent::Constructor(this, aType, init);
-  event->SetTrusted(true);
-
-  bool doDefaultAction;
-  nsresult rv = DispatchEvent(event, &doDefaultAction);
-  if (NS_SUCCEEDED(rv) && !doDefaultAction) {
-    CancelDirectoryPickerScanIfRunning();
-  }
-}
-
 nsresult
 HTMLInputElement::UpdateFileList()
 {
   if (mFileList) {
     mFileList->Clear();
 
     const nsTArray<nsRefPtr<File>>& files = GetFilesInternal();
     for (uint32_t i = 0; i < files.Length(); ++i) {
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -31,17 +31,16 @@ class nsIRadioVisitor;
 namespace mozilla {
 
 class EventChainPostVisitor;
 class EventChainPreVisitor;
 
 namespace dom {
 
 class Date;
-class DirPickerFileListBuilderTask;
 class File;
 class FileList;
 
 class UploadLastDir final : public nsIObserver, public nsSupportsWeakReference {
 
   ~UploadLastDir() {}
 
 public:
@@ -89,21 +88,18 @@ public:
 };
 
 class HTMLInputElement final : public nsGenericHTMLFormElementWithState,
                                public nsImageLoadingContent,
                                public nsIDOMHTMLInputElement,
                                public nsITextControlElement,
                                public nsIPhonetic,
                                public nsIDOMNSEditableElement,
-                               public nsITimerCallback,
                                public nsIConstraintValidation
 {
-  friend class DirPickerFileListBuilderTask;
-
 public:
   using nsIConstraintValidation::GetValidationMessage;
   using nsIConstraintValidation::CheckValidity;
   using nsIConstraintValidation::WillValidate;
   using nsIConstraintValidation::Validity;
   using nsGenericHTMLFormElementWithState::GetForm;
 
   HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
@@ -271,24 +267,16 @@ public:
     mSelectionCached = false;
   }
   nsTextEditorState::SelectionProperties& GetSelectionProperties()
   {
     MOZ_ASSERT(mType == NS_FORM_INPUT_NUMBER);
     return mSelectionProperties;
   }
 
-  // nsITimerCallback
-  NS_DECL_NSITIMERCALLBACK
-
-  // Avoid warning about the implementation of nsITimerCallback::Notify hiding
-  // our nsImageLoadingContent base class' implementation of
-  // imgINotificationObserver::Notify:
-  using nsImageLoadingContent::Notify;
-
   // nsIConstraintValidation
   bool     IsTooLong();
   bool     IsValueMissing() const;
   bool     HasTypeMismatch() const;
   bool     HasPatternMismatch() const;
   bool     IsRangeOverflow() const;
   bool     IsRangeUnderflow() const;
   bool     HasStepMismatch(bool aUseZeroIfValueNaN = false) const;
@@ -441,25 +429,16 @@ public:
   {
     SetHTMLBoolAttr(nsGkAtoms::disabled, aValue, aRv);
   }
 
   // XPCOM GetForm() is OK
 
   FileList* GetFiles();
 
-  void OpenDirectoryPicker(ErrorResult& aRv);
-  void CancelDirectoryPickerScanIfRunning();
-
-  void StartProgressEventTimer();
-  void MaybeDispatchProgressEvent(bool aFinalProgress);
-  void DispatchProgressEvent(const nsAString& aType,
-                             bool aLengthComputable,
-                             uint64_t aLoaded, uint64_t aTotal);
-
   // XPCOM GetFormAction() is OK
   void SetFormAction(const nsAString& aValue, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::formaction, aValue, aRv);
   }
 
   // XPCOM GetFormEnctype() is OK
   void SetFormEnctype(const nsAString& aValue, ErrorResult& aRv)
@@ -1271,18 +1250,16 @@ protected:
   /**
    * Hack for bug 1086684: Stash the .value when we're a file picker.
    */
   nsString mFirstFilePath;
 #endif
 
   nsRefPtr<FileList>  mFileList;
 
-  nsRefPtr<DirPickerFileListBuilderTask> mDirPickerFileListBuilderTask;
-
   nsString mStaticDocFileList;
   
   /** 
    * The value of the input element when first initialized and it is updated
    * when the element is either changed through a script, focused or dispatches   
    * a change event. This is to ensure correct future change event firing.
    * NB: This is ONLY applicable where the element is a text control. ie,
    * where type= "text", "email", "search", "tel", "url" or "password".
@@ -1292,23 +1269,16 @@ protected:
   /**
    * If mIsDraggingRange is true, this is the value that the input had before
    * the drag started. Used to reset the input to its old value if the drag is
    * canceled.
    */
   Decimal mRangeThumbDragStartValue;
 
   /**
-   * Timer that is used when mType == NS_FORM_INPUT_FILE and the user selects a
-   * directory. It is used to fire progress events while the list of files
-   * under that directory tree is built.
-   */
-  nsCOMPtr<nsITimer> mProgressTimer;
-
-  /**
    * The selection properties cache for number controls.  This is needed because
    * the number controls don't recycle their text field, so the normal cache in
    * nsTextEditorState cannot do its job.
    */
   nsTextEditorState::SelectionProperties mSelectionProperties;
 
   // Step scale factor values, for input types that have one.
   static const Decimal kStepScaleFactorDate;
@@ -1341,17 +1311,16 @@ protected:
   bool                     mInInternalActivate  : 1;
   bool                     mCheckedIsToggled    : 1;
   bool                     mIndeterminate       : 1;
   bool                     mInhibitRestoration  : 1;
   bool                     mCanShowValidUI      : 1;
   bool                     mCanShowInvalidUI    : 1;
   bool                     mHasRange            : 1;
   bool                     mIsDraggingRange     : 1;
-  bool                     mProgressTimerIsActive : 1;
   bool                     mNumberControlSpinnerIsSpinning : 1;
   bool                     mNumberControlSpinnerSpinsUp : 1;
   bool                     mPickerRunning : 1;
   bool                     mSelectionCached : 1;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
--- a/dom/inputmethod/mochitest/mochitest.ini
+++ b/dom/inputmethod/mochitest/mochitest.ini
@@ -19,8 +19,9 @@ support-files =
 [test_bug1026997.html]
 [test_bug1043828.html]
 [test_bug1059163.html]
 [test_bug1066515.html]
 [test_sendkey_cancel.html]
 [test_sync_edit.html]
 [test_two_inputs.html]
 [test_two_selects.html]
+[test_unload.html]
new file mode 100644
--- /dev/null
+++ b/dom/inputmethod/mochitest/test_unload.html
@@ -0,0 +1,167 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1122463
+https://bugzilla.mozilla.org/show_bug.cgi?id=820057
+-->
+<head>
+  <title>Test focus when page unloads</title>
+  <script type="application/javascript;version=1.7" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript;version=1.7" src="inputmethod_common.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=1122463">Mozilla Bug 1122463</a>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=820057">Mozilla Bug 820057</a>
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="application/javascript;version=1.7">
+
+inputmethod_setup(function() {
+  runTest();
+});
+
+let appFrameScript = function appFrameScript() {
+  let form1 = content.document.body.firstElementChild;
+  let input1 = form1.firstElementChild;
+  let submit1 = form1.lastElementChild;
+  let input2;
+
+  let cancelSubmit = function(evt) {
+    evt.preventDefault();
+  };
+
+  // Content of the second page.
+  form1.action = 'data:text/html,<html><body><input value="Second"></body></html>';
+
+  let i = 1;
+
+  input1.focus();
+
+  addMessageListener('test:next', function() {
+    i++;
+    switch (i) {
+      case 2:
+        // Click the submit button, trigger the submit event and make our
+        // installed event listener preventing the submission.
+        form1.addEventListener('submit', cancelSubmit);
+        submit1.click();
+
+        sendAsyncMessage('test:step');
+
+        break;
+
+      case 3:
+        // Actually submit the form.
+        form1.removeEventListener('submit', cancelSubmit);
+        submit1.click();
+
+        break;
+
+      case 4:
+        if (!content.document.body) {
+          content.onload = function() {
+            content.onload = null;
+
+            let input2 = content.document.body.firstElementChild;
+            input2.focus();
+          };
+
+          return;
+        }
+
+        input2 = content.document.body.firstElementChild;
+        input2.focus();
+
+        break;
+
+      case 5:
+        content.location.href = 'data:text/html,Hello!';
+
+        break;
+    }
+  });
+};
+
+function runTest() {
+  let im = navigator.mozInputMethod;
+
+  let i = 0;
+  function nextStep() {
+    let inputcontext = navigator.mozInputMethod.inputcontext;
+
+    i++;
+    switch (i) {
+      // focus on the first input receives the first input context.
+      case 1:
+        ok(!!inputcontext, '1) Receving the first input context');
+        is(inputcontext.textAfterCursor, 'First');
+
+        mm.sendAsyncMessage('test:next');
+        break;
+
+      // Cancelled submission should not cause us lost focus.
+      case 2:
+        ok(!!inputcontext, '2) Receving the first input context');
+        is(inputcontext.textAfterCursor, 'First');
+
+        mm.sendAsyncMessage('test:next');
+        break;
+
+      // Real submit and page transition should cause us lost focus.
+      // XXX: Unless we could delay the page transition, we does not know if
+      // the inputcontext is lost because of the submit or the pagehide/beforeload
+      // event.
+      case 3:
+        is(inputcontext, null, '3) Receving null inputcontext');
+
+        mm.sendAsyncMessage('test:next');
+
+        break;
+
+      // Regaining focus of input in the second page.
+      case 4:
+        ok(!!inputcontext, '4) Receving the second input context');
+        is(inputcontext.textAfterCursor, 'Second');
+
+        mm.sendAsyncMessage('test:next');
+
+        break;
+
+      // Page transition should cause us lost focus
+      case 5:
+        is(inputcontext, null, '5) Receving null inputcontext');
+
+        inputmethod_cleanup();
+
+        break;
+    }
+  }
+
+  // Set current page as an input method.
+  SpecialPowers.wrap(im).setActive(true);
+
+  let iframe = document.createElement('iframe');
+  iframe.src = 'data:text/html,<html><body><form id="form"><input value="First"><input type="submit"></form></body></html>';
+  iframe.setAttribute('mozbrowser', true);
+  document.body.appendChild(iframe);
+
+  let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
+  im.oninputcontextchange = nextStep;
+
+  let frameScriptLoaded = false;
+  iframe.addEventListener('mozbrowserloadend', function() {
+    if (frameScriptLoaded)
+      return;
+
+    frameScriptLoaded = true;
+    mm.addMessageListener('test:step', nextStep);
+    mm.loadFrameScript('data:,(' + encodeURIComponent(appFrameScript.toString()) + ')();', false);
+  });
+}
+
+</script>
+</pre>
+</body>
+</html>
+
--- a/dom/media/TrackUnionStream.cpp
+++ b/dom/media/TrackUnionStream.cpp
@@ -41,17 +41,17 @@ namespace mozilla {
 #ifdef STREAM_LOG
 #undef STREAM_LOG
 #endif
 
 PRLogModuleInfo* gTrackUnionStreamLog;
 #define STREAM_LOG(type, msg) MOZ_LOG(gTrackUnionStreamLog, type, msg)
 
 TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
-  ProcessedMediaStream(aWrapper)
+  ProcessedMediaStream(aWrapper), mNextAvailableTrackID(1)
 {
   if (!gTrackUnionStreamLog) {
     gTrackUnionStreamLog = PR_NewLogModule("TrackUnionStream");
   }
 }
 
   void TrackUnionStream::RemoveInput(MediaInputPort* aPort)
   {
@@ -156,33 +156,33 @@ TrackUnionStream::TrackUnionStream(DOMMe
           SetTrackEnabled(mTrackMap[i].mInputTrackID, aEnabled);
       }
     }
   }
 
   uint32_t TrackUnionStream::AddTrack(MediaInputPort* aPort, StreamBuffer::Track* aTrack,
                     GraphTime aFrom)
   {
-    // Use the ID of the source track if it's not already assigned to a track,
-    // otherwise allocate a new unique ID.
     TrackID id = aTrack->GetID();
-    TrackID maxTrackID = 0;
-    for (uint32_t i = 0; i < mTrackMap.Length(); ++i) {
-      TrackID outID = mTrackMap[i].mOutputTrackID;
-      maxTrackID = std::max(maxTrackID, outID);
-    }
-    // Note: we might have removed it here, but it might still be in the
-    // StreamBuffer if the TrackUnionStream sees its input stream flip from
-    // A to B, where both A and B have a track with the same ID
-    while (1) {
-      // search until we find one not in use here, and not in mBuffer
-      if (!mBuffer.FindTrack(id)) {
-        break;
+    if (id > mNextAvailableTrackID &&
+       mUsedTracks.BinaryIndexOf(id) == mUsedTracks.NoIndex) {
+      // Input id available. Mark it used in mUsedTracks.
+      mUsedTracks.InsertElementSorted(id);
+    } else {
+      // Input id taken, allocate a new one.
+      id = mNextAvailableTrackID;
+
+      // Update mNextAvailableTrackID and prune any mUsedTracks members it now
+      // covers.
+      while (1) {
+        if (!mUsedTracks.RemoveElementSorted(++mNextAvailableTrackID)) {
+          // Not in use. We're done.
+          break;
+        }
       }
-      id = ++maxTrackID;
     }
 
     // Round up the track start time so the track, if anything, starts a
     // little later than the true time. This means we'll have enough
     // samples in our input stream to go just beyond the destination time.
     StreamTime outputStart = GraphTimeToStreamTime(aFrom);
 
     nsAutoPtr<MediaSegment> segment;
--- a/dom/media/TrackUnionStream.h
+++ b/dom/media/TrackUnionStream.h
@@ -45,21 +45,30 @@ protected:
     // when a finished track is forgotten.) When we need a Track*,
     // we call StreamBuffer::FindTrack, which will return null if
     // the track has been deleted.
     TrackID mInputTrackID;
     TrackID mOutputTrackID;
     nsAutoPtr<MediaSegment> mSegment;
   };
 
+  // Add the track to this stream, retaining its TrackID if it has never
+  // been previously used in this stream, allocating a new TrackID otherwise.
   uint32_t AddTrack(MediaInputPort* aPort, StreamBuffer::Track* aTrack,
                     GraphTime aFrom);
   void EndTrack(uint32_t aIndex);
   void CopyTrackData(StreamBuffer::Track* aInputTrack,
                      uint32_t aMapIndex, GraphTime aFrom, GraphTime aTo,
                      bool* aOutputTrackFinished);
 
   nsTArray<TrackMapEntry> mTrackMap;
+
+  // The next available TrackID, starting at 1 and progressing upwards.
+  // All TrackIDs in [1, mNextAvailableTrackID) have implicitly been used.
+  TrackID mNextAvailableTrackID;
+
+  // Sorted array of used TrackIDs that require manual tracking.
+  nsTArray<TrackID> mUsedTracks;
 };
 
 }
 
 #endif /* MOZILLA_MEDIASTREAMGRAPH_H_ */
--- a/dom/media/eme/GMPVideoDecoderTrialCreator.cpp
+++ b/dom/media/eme/GMPVideoDecoderTrialCreator.cpp
@@ -8,16 +8,17 @@
 #include "mozilla/Preferences.h"
 #include "prsystem.h"
 #include "GMPVideoHost.h"
 #include "mozilla/EMEUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "GMPService.h"
 #include "VideoUtils.h"
 #include "nsPrintfCString.h"
+#include "nsXULAppAPI.h"
 
 namespace mozilla {
 namespace dom {
 
 static already_AddRefed<nsIThread>
 GetGMPThread()
 {
   nsCOMPtr<mozIGeckoMediaPluginService> gmps =
@@ -487,16 +488,22 @@ TestGMPVideoDecoder::CreateGMPVideoDecod
 
 void
 GMPVideoDecoderTrialCreator::MaybeAwaitTrialCreate(const nsAString& aKeySystem,
                                                    AbstractPromiseLike* aPromisey,
                                                    nsPIDOMWindow* aParent)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    // Currently broken with e10s...
+    aPromisey->Resolve();
+    return;
+  }
+
   if (!mTestCreate.Contains(aKeySystem)) {
     mTestCreate.Put(aKeySystem, new TrialCreateData(aKeySystem));
   }
   TrialCreateData* data = mTestCreate.Get(aKeySystem);
   MOZ_ASSERT(data);
 
   switch (data->mStatus) {
     case TrialCreateState::Succeeded: {
--- a/dom/security/nsCSPService.cpp
+++ b/dom/security/nsCSPService.cpp
@@ -246,16 +246,19 @@ CSPService::ShouldProcess(uint32_t      
                           nsIURI           *aContentLocation,
                           nsIURI           *aRequestOrigin,
                           nsISupports      *aRequestContext,
                           const nsACString &aMimeTypeGuess,
                           nsISupports      *aExtra,
                           nsIPrincipal     *aRequestPrincipal,
                           int16_t          *aDecision)
 {
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   if (!aContentLocation)
     return NS_ERROR_FAILURE;
 
   *aDecision = nsIContentPolicy::ACCEPT;
   return NS_OK;
 }
 
 /* nsIChannelEventSink implementation */
--- a/dom/security/nsMixedContentBlocker.cpp
+++ b/dom/security/nsMixedContentBlocker.cpp
@@ -782,16 +782,19 @@ nsMixedContentBlocker::ShouldProcess(uin
                                      nsIURI* aContentLocation,
                                      nsIURI* aRequestingLocation,
                                      nsISupports* aRequestingContext,
                                      const nsACString& aMimeGuess,
                                      nsISupports* aExtra,
                                      nsIPrincipal* aRequestPrincipal,
                                      int16_t* aDecision)
 {
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   if (!aContentLocation) {
     // aContentLocation may be null when a plugin is loading without an associated URI resource
     if (aContentType == TYPE_OBJECT) {
        *aDecision = ACCEPT;
        return NS_OK;
     } else {
        *aDecision = REJECT_REQUEST;
        return NS_ERROR_FAILURE;
--- a/dom/webidl/HTMLInputElement.webidl
+++ b/dom/webidl/HTMLInputElement.webidl
@@ -35,18 +35,16 @@ interface HTMLInputElement : HTMLElement
   [Pure]
            attribute boolean checked;
            // Bug 850337 - attribute DOMString dirName;
   [Pure, SetterThrows]
            attribute boolean disabled;
   readonly attribute HTMLFormElement? form;
   [Pure]
   readonly attribute FileList? files;
-  [Throws, Pref="dom.input.dirpicker"]
-  void openDirectoryPicker();
   [Pure, SetterThrows]
            attribute DOMString formAction;
   [Pure, SetterThrows]
            attribute DOMString formEnctype;
   [Pure, SetterThrows]
            attribute DOMString formMethod;
   [Pure, SetterThrows]
            attribute boolean formNoValidate;
--- a/embedding/browser/nsWebBrowserContentPolicy.cpp
+++ b/embedding/browser/nsWebBrowserContentPolicy.cpp
@@ -29,16 +29,19 @@ nsWebBrowserContentPolicy::ShouldLoad(ui
                                       nsISupports* aRequestingContext,
                                       const nsACString& aMimeGuess,
                                       nsISupports* aExtra,
                                       nsIPrincipal* aRequestPrincipal,
                                       int16_t* aShouldLoad)
 {
   NS_PRECONDITION(aShouldLoad, "Null out param");
 
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   *aShouldLoad = nsIContentPolicy::ACCEPT;
 
   nsIDocShell* shell = NS_CP_GetDocShellFromContext(aRequestingContext);
   /* We're going to dereference shell, so make sure it isn't null */
   if (!shell) {
     return NS_OK;
   }
 
@@ -79,16 +82,19 @@ nsWebBrowserContentPolicy::ShouldProcess
                                          nsISupports* aRequestingContext,
                                          const nsACString& aMimeGuess,
                                          nsISupports* aExtra,
                                          nsIPrincipal* aRequestPrincipal,
                                          int16_t* aShouldProcess)
 {
   NS_PRECONDITION(aShouldProcess, "Null out param");
 
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   *aShouldProcess = nsIContentPolicy::ACCEPT;
 
   // Object tags will always open channels with TYPE_OBJECT, but may end up
   // loading with TYPE_IMAGE or TYPE_DOCUMENT as their final type, so we block
   // actual-plugins at the process stage
   if (aContentType != nsIContentPolicy::TYPE_OBJECT) {
     return NS_OK;
   }
--- a/extensions/permissions/nsContentBlocker.cpp
+++ b/extensions/permissions/nsContentBlocker.cpp
@@ -9,16 +9,17 @@
 #include "nsIDocShellTreeItem.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIDocShell.h"
 #include "nsString.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIObjectLoadingContent.h"
 #include "mozilla/ArrayUtils.h"
+#include "nsContentUtils.h"
 
 // Possible behavior pref values
 // Those map to the nsIPermissionManager values where possible
 #define BEHAVIOR_ACCEPT nsIPermissionManager::ALLOW_ACTION
 #define BEHAVIOR_REJECT nsIPermissionManager::DENY_ACTION
 #define BEHAVIOR_NOFOREIGN 3
 
 // From nsIContentPolicy
@@ -145,16 +146,19 @@ nsContentBlocker::ShouldLoad(uint32_t   
                              nsIURI           *aContentLocation,
                              nsIURI           *aRequestingLocation,
                              nsISupports      *aRequestingContext,
                              const nsACString &aMimeGuess,
                              nsISupports      *aExtra,
                              nsIPrincipal     *aRequestPrincipal,
                              int16_t          *aDecision)
 {
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   *aDecision = nsIContentPolicy::ACCEPT;
   nsresult rv;
 
   // Ony support NUMBER_OF_TYPES content types. that all there is at the
   // moment, but you never know...
   if (aContentType > NUMBER_OF_TYPES)
     return NS_OK;
   
@@ -196,16 +200,19 @@ nsContentBlocker::ShouldProcess(uint32_t
                                 nsIURI           *aContentLocation,
                                 nsIURI           *aRequestingLocation,
                                 nsISupports      *aRequestingContext,
                                 const nsACString &aMimeGuess,
                                 nsISupports      *aExtra,
                                 nsIPrincipal     *aRequestPrincipal,
                                 int16_t          *aDecision)
 {
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   // For loads where aRequestingContext is chrome, we should just
   // accept.  Those are most likely toplevel loads in windows, and
   // chrome generally knows what it's doing anyway.
   nsCOMPtr<nsIDocShellTreeItem> item =
     do_QueryInterface(NS_CP_GetDocShellFromContext(aRequestingContext));
 
   if (item && item->ItemType() == nsIDocShellTreeItem::typeChrome) {
     *aDecision = nsIContentPolicy::ACCEPT;
--- a/image/imgRequestProxy.h
+++ b/image/imgRequestProxy.h
@@ -199,17 +199,20 @@ private:
   friend imgRequestProxy* NewStaticProxy(imgRequestProxy* aThis);
 
   // The URI of our request.
   nsRefPtr<ImageURL> mURI;
 
   // mListener is only promised to be a weak ref (see imgILoader.idl),
   // but we actually keep a strong ref to it until we've seen our
   // first OnStopRequest.
-  imgINotificationObserver* mListener;
+  imgINotificationObserver* MOZ_UNSAFE_REF("Observers must call Cancel() or "
+                                           "CancelAndForgetObserver() before "
+                                           "they are destroyed") mListener;
+
   nsCOMPtr<nsILoadGroup> mLoadGroup;
 
   nsLoadFlags mLoadFlags;
   uint32_t    mLockCount;
   uint32_t    mAnimationConsumers;
   bool mCanceled;
   bool mIsInLoadGroup;
   bool mListenerIsStrongRef;
--- a/ipc/chromium/src/base/message_loop.cc
+++ b/ipc/chromium/src/base/message_loop.cc
@@ -27,16 +27,17 @@
 #include "base/message_pump_qt.h"
 #endif
 #endif
 #ifdef ANDROID
 #include "base/message_pump_android.h"
 #endif
 #ifdef MOZ_TASK_TRACER
 #include "GeckoTaskTracer.h"
+#include "TracedTaskCommon.h"
 #endif
 
 #include "MessagePump.h"
 
 using base::Time;
 using base::TimeDelta;
 using base::TimeTicks;
 
@@ -282,30 +283,32 @@ void MessageLoop::PostNonNestableDelayed
 }
 
 void MessageLoop::PostIdleTask(
     const tracked_objects::Location& from_here, Task* task) {
   DCHECK(current() == this);
 
 #ifdef MOZ_TASK_TRACER
   task = mozilla::tasktracer::CreateTracedTask(task);
+  (static_cast<mozilla::tasktracer::TracedTask*>(task))->DispatchTask();
 #endif
 
   task->SetBirthPlace(from_here);
   PendingTask pending_task(task, false);
   deferred_non_nestable_work_queue_.push(pending_task);
 }
 
 // Possibly called on a background thread!
 void MessageLoop::PostTask_Helper(
     const tracked_objects::Location& from_here, Task* task, int delay_ms,
     bool nestable) {
 
 #ifdef MOZ_TASK_TRACER
   task = mozilla::tasktracer::CreateTracedTask(task);
+  (static_cast<mozilla::tasktracer::TracedTask*>(task))->DispatchTask(delay_ms);
 #endif
 
   task->SetBirthPlace(from_here);
 
   PendingTask pending_task(task, nestable);
 
   if (delay_ms > 0) {
     pending_task.delayed_run_time =
--- a/js/src/asmjs/AsmJSValidate.cpp
+++ b/js/src/asmjs/AsmJSValidate.cpp
@@ -1163,17 +1163,20 @@ class MOZ_STACK_CLASS ModuleCompiler
             struct {
                 Type::Which type_;
                 uint32_t index_;
                 AsmJSNumLit literalValue_;
             } varOrConst;
             uint32_t funcIndex_;
             uint32_t funcPtrTableIndex_;
             uint32_t ffiIndex_;
-            Scalar::Type viewType_;
+            struct {
+                Scalar::Type viewType_;
+                bool isSharedView_;
+            } viewInfo;
             AsmJSMathBuiltinFunction mathBuiltinFunc_;
             AsmJSAtomicsBuiltinFunction atomicsBuiltinFunc_;
             AsmJSSimdType simdCtorType_;
             struct {
                 AsmJSSimdType type_;
                 AsmJSSimdOperation which_;
             } simdOp;
             struct {
@@ -1218,17 +1221,21 @@ class MOZ_STACK_CLASS ModuleCompiler
             MOZ_ASSERT(which_ == FFI);
             return u.ffiIndex_;
         }
         bool isAnyArrayView() const {
             return which_ == ArrayView || which_ == ArrayViewCtor;
         }
         Scalar::Type viewType() const {
             MOZ_ASSERT(isAnyArrayView());
-            return u.viewType_;
+            return u.viewInfo.viewType_;
+        }
+        bool viewIsSharedView() const {
+            MOZ_ASSERT(isAnyArrayView());
+            return u.viewInfo.isSharedView_;
         }
         bool isMathFunction() const {
             return which_ == MathBuiltinFunction;
         }
         AsmJSMathBuiltinFunction mathBuiltinFunction() const {
             MOZ_ASSERT(which_ == MathBuiltinFunction);
             return u.mathBuiltinFunc_;
         }
@@ -1795,26 +1802,28 @@ class MOZ_STACK_CLASS ModuleCompiler
     bool addArrayView(PropertyName* varName, Scalar::Type vt, PropertyName* maybeField, bool isSharedView) {
         if (!arrayViews_.append(ArrayView(varName, vt)))
             return false;
         Global* global = moduleLifo_.new_<Global>(Global::ArrayView);
         if (!global)
             return false;
         if (!module_->addArrayView(vt, maybeField, isSharedView))
             return false;
-        global->u.viewType_ = vt;
+        global->u.viewInfo.viewType_ = vt;
+        global->u.viewInfo.isSharedView_ = isSharedView;
         return globals_.putNew(varName, global);
     }
     bool addArrayViewCtor(PropertyName* varName, Scalar::Type vt, PropertyName* fieldName, bool isSharedView) {
         Global* global = moduleLifo_.new_<Global>(Global::ArrayViewCtor);
         if (!global)
             return false;
         if (!module_->addArrayViewCtor(vt, fieldName, isSharedView))
             return false;
-        global->u.viewType_ = vt;
+        global->u.viewInfo.viewType_ = vt;
+        global->u.viewInfo.isSharedView_ = isSharedView;
         return globals_.putNew(varName, global);
     }
     bool addMathBuiltinFunction(PropertyName* varName, AsmJSMathBuiltinFunction func, PropertyName* fieldName) {
         if (!module_->addMathBuiltinFunction(func, fieldName))
             return false;
         Global* global = moduleLifo_.new_<Global>(Global::MathBuiltinFunction);
         if (!global)
             return false;
@@ -3976,16 +3985,17 @@ CheckNewArrayView(ModuleCompiler& m, Pro
         if (!global)
             return m.failName(ctorExpr, "%s not found in module global scope", globalName);
 
         if (global->which() != ModuleCompiler::Global::ArrayViewCtor)
             return m.failName(ctorExpr, "%s must be an imported array view constructor", globalName);
 
         field = nullptr;
         type = global->viewType();
+        shared = global->viewIsSharedView();
     }
 
     if (!CheckNewArrayViewArgs(m, ctorExpr, bufferName))
         return false;
 
     if (!m.module().isValidViewSharedness(shared))
         return m.failName(ctorExpr, "%s has different sharedness than previous view constructors", globalName);
 
@@ -9222,16 +9232,21 @@ CheckModule(ExclusiveContext* cx, AsmJSP
     if (!CheckModuleProcessingDirectives(m))
         return false;
 
     if (!CheckModuleGlobals(m))
         return false;
 
     m.startFunctionBodies();
 
+#if !defined(ENABLE_SHARED_ARRAY_BUFFER)
+    if (m.module().hasArrayView() && m.module().isSharedView())
+        return m.fail(nullptr, "shared views not supported by this build");
+#endif
+
     if (!CheckFunctions(m))
         return false;
 
     m.finishFunctionBodies();
 
     if (!CheckFuncPtrTables(m))
         return false;
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/gating.js
@@ -0,0 +1,69 @@
+// Check gating of shared memory features in asm.js (bug 1171540).
+//
+// When run with -w this should produce a slew of warnings if shared
+// memory is not enabled.  There are several cases here because there
+// are various checks within Odin.
+//
+// Note code is not run, so the only issue here is whether it compiles
+// properly as asm.js.
+
+if (!isAsmJSCompilationAvailable())
+    quit(0);
+
+function module_a(stdlib, foreign, heap) {
+    "use asm";
+
+    // Without shared memory, this will be flagged as illegal view type
+    var view = stdlib.SharedInt32Array;
+    var i32a = new view(heap);
+    var ld = stdlib.Atomics.load;
+
+    function do_load() {
+	var v = 0;
+	v = ld(i32a, 0)|0;
+	return v|0;
+    }
+
+    return { load: do_load };
+}
+
+if (this.SharedArrayBuffer)
+    assertEq(isAsmJSModule(module_a), true);
+
+function module_b(stdlib, foreign, heap) {
+    "use asm";
+
+    // Without shared memory, this will be flagged as illegal view type
+    var i32a = new stdlib.SharedInt32Array(heap);
+    var ld = stdlib.Atomics.load;
+
+    function do_load() {
+	var v = 0;
+	v = ld(i32a, 0)|0;
+	return v|0;
+    }
+
+    return { load: do_load };
+}
+
+if (this.SharedArrayBuffer)
+    assertEq(isAsmJSModule(module_b), true);
+
+function module_d(stdlib, foreign, heap) {
+    "use asm";
+
+    var i32a = new stdlib.Int32Array(heap);
+    var ld = stdlib.Atomics.load;
+
+    function do_load() {
+	var v = 0;
+	// This should be flagged as a type error (needs shared view) regardless
+	// of whether shared memory is enabled.
+	v = ld(i32a, 0)|0;
+	return v|0;
+    }
+
+    return { load: do_load };
+}
+
+// module_d should never load properly.
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -676,52 +676,95 @@ ErrorReport::~ErrorReport()
         size_t i = 0;
         while (ownedReport.messageArgs[i])
             js_free(const_cast<char16_t*>(ownedReport.messageArgs[i++]));
         js_free(ownedReport.messageArgs);
     }
     js_free(const_cast<char16_t*>(ownedReport.ucmessage));
 }
 
+void
+ErrorReport::ReportAddonExceptionToTelementry(JSContext* cx)
+{
+    MOZ_ASSERT(exnObject);
+    RootedObject unwrapped(cx, UncheckedUnwrap(exnObject));
+    MOZ_ASSERT(unwrapped, "UncheckedUnwrap failed?");
+
+    // There is not much we can report if the exception is not an ErrorObject, let's ignore those.
+    if (!unwrapped->is<ErrorObject>())
+        return;
+
+    Rooted<ErrorObject*> errObj(cx, &unwrapped->as<ErrorObject>());
+    RootedObject stack(cx, errObj->stack());
+
+    // Let's ignore TOP level exceptions. For regular add-ons those will not be reported anyway,
+    // for SDK based once it should not be a valid case either.
+    // At this point the frame stack is unwound but the exception object stored the stack so let's
+    // use that for getting the function name.
+    if (!stack)
+        return;
+
+    JSCompartment* comp = stack->compartment();
+    JSAddonId* addonId = comp->addonId;
+
+    // We only want to send the report if the scope that just have thrown belongs to an add-on.
+    // Let's check the compartment of the youngest function on the stack, to determine that.
+    if (!addonId)
+        return;
+
+    RootedString funnameString(cx);
+    JS::SavedFrameResult result = GetSavedFrameFunctionDisplayName(cx, stack, &funnameString);
+    // AccessDenied should never be the case here for add-ons but let's not risk it.
+    JSAutoByteString bytes;
+    const char* funname = nullptr;
+    bool denied = result == JS::SavedFrameResult::AccessDenied;
+    funname = denied ? "unknown"
+                     : funnameString ? AtomToPrintableString(cx,
+                                                             &funnameString->asAtom(),
+                                                             &bytes)
+                                     : "anonymous";
+
+    UniqueChars addonIdChars(JS_EncodeString(cx, addonId));
+
+    const char* filename = nullptr;
+    if (reportp && reportp->filename) {
+        filename = strrchr(reportp->filename, '/');
+        if (filename)
+            filename++;
+    }
+    if (!filename) {
+        filename = "FILE_NOT_FOUND";
+    }
+    char histogramKey[64];
+    JS_snprintf(histogramKey, sizeof(histogramKey),
+                "%s %s %s %u",
+                addonIdChars.get(),
+                funname,
+                filename,
+                (reportp ? reportp->lineno : 0) );
+    cx->runtime()->addTelemetry(JS_TELEMETRY_ADDON_EXCEPTIONS, 1, histogramKey);
+}
+
 bool
 ErrorReport::init(JSContext* cx, HandleValue exn)
 {
     MOZ_ASSERT(!cx->isExceptionPending());
 
-    /*
-     * Because ToString below could error and an exception object could become
-     * unrooted, we must root our exception object, if any.
-     */
     if (exn.isObject()) {
+        // Because ToString below could error and an exception object could become
+        // unrooted, we must root our exception object, if any.
         exnObject = &exn.toObject();
         reportp = ErrorFromException(cx, exnObject);
 
-        JSCompartment* comp = exnObject->compartment();
-        JSAddonId* addonId = comp->addonId;
-        if (addonId) {
-            UniqueChars addonIdChars(JS_EncodeString(cx, addonId));
+        // Let's see if the exception is from add-on code, if so, it should be reported
+        // to telementry.
+        ReportAddonExceptionToTelementry(cx);
+    }
 
-            const char* filename = nullptr;
-            if (reportp && reportp->filename) {
-                filename = strrchr(reportp->filename, '/');
-                if (filename)
-                    filename++;
-            }
-            if (!filename) {
-                filename = "FILE_NOT_FOUND";
-            }
-            char histogramKey[64];
-            JS_snprintf(histogramKey, sizeof(histogramKey),
-                        "%s %s %u",
-                        addonIdChars.get(),
-                        filename,
-                        (reportp ? reportp->lineno : 0) );
-            cx->runtime()->addTelemetry(JS_TELEMETRY_ADDON_EXCEPTIONS, 1, histogramKey);
-        }
-    }
+
     // Be careful not to invoke ToString if we've already successfully extracted
     // an error report, since the exception might be wrapped in a security
     // wrapper, and ToString-ing it might throw.
     if (reportp)
         str = ErrorReportToString(cx, reportp);
     else
         str = ToString<CanGC>(cx, exn);
 
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -1391,16 +1391,19 @@ struct MOZ_STACK_CLASS JS_FRIEND_API(Err
     // but fills in an ErrorReport instead of reporting it.  Uses varargs to
     // make it simpler to call js::ExpandErrorArgumentsVA.
     //
     // Returns false if we fail to actually populate the ErrorReport
     // for some reason (probably out of memory).
     bool populateUncaughtExceptionReport(JSContext* cx, ...);
     bool populateUncaughtExceptionReportVA(JSContext* cx, va_list ap);
 
+    // Reports exceptions from add-on scopes to telementry.
+    void ReportAddonExceptionToTelementry(JSContext* cx);
+
     // We may have a provided JSErrorReport, so need a way to represent that.
     JSErrorReport* reportp;
 
     // And we may have a message.
     const char* message_;
 
     // Or we may need to synthesize a JSErrorReport one of our own.
     JSErrorReport ownedReport;
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -4314,55 +4314,196 @@ GetIntrinsicCoord(const nsStyleCoord& aS
 }
 
 #undef  DEBUG_INTRINSIC_WIDTH
 
 #ifdef DEBUG_INTRINSIC_WIDTH
 static int32_t gNoiseIndent = 0;
 #endif
 
+/**
+ * Add aOffsets which describes what to add on outside of the content box
+ * aContentSize (controlled by 'box-sizing') and apply min/max properties.
+ * We have to account for these properties after getting all the offsets
+ * (margin, border, padding) because percentages do not operate linearly.
+ * Doing this is ok because although percentages aren't handled linearly,
+ * they are handled monotonically.
+ *
+ * @param aContentSize the content size calculated so far
+                       (@see IntrinsicForContainer)
+ * @param aContentMinSize ditto min content size
+ * @param aStyleSize a 'width' or 'height' property value
+ * @param aFixedMinSize if aStyleMinSize is a definite size then this points to
+ *                      the value, otherwise nullptr
+ * @param aStyleMinSize a 'min-width' or 'min-height' property value
+ * @param aFixedMaxSize if aStyleMaxSize is a definite size then this points to
+ *                      the value, otherwise nullptr
+ * @param aStyleMaxSize a 'max-width' or 'max-height' property value
+ * @param aFlags same as for IntrinsicForContainer
+ * @param aContainerWM the container's WM
+ */
+static nscoord
+AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
+                       nsIFrame* aFrame,
+                       const nsIFrame::IntrinsicISizeOffsetData& aOffsets,
+                       nsLayoutUtils::IntrinsicISizeType aType,
+                       uint8_t aBoxSizing,
+                       nscoord aContentSize,
+                       nscoord aContentMinSize,
+                       const nsStyleCoord& aStyleSize,
+                       const nscoord* aFixedMinSize,
+                       const nsStyleCoord& aStyleMinSize,
+                       const nscoord* aFixedMaxSize,
+                       const nsStyleCoord& aStyleMaxSize,
+                       uint32_t aFlags,
+                       PhysicalAxis aAxis)
+{
+  nscoord result = aContentSize;
+  nscoord min = aContentMinSize;
+  nscoord coordOutsideSize = 0;
+  float pctOutsideSize = 0;
+  float pctTotal = 0.0f;
+
+  if (!(aFlags & nsLayoutUtils::IGNORE_PADDING)) {
+    coordOutsideSize += aOffsets.hPadding;
+    pctOutsideSize += aOffsets.hPctPadding;
+
+    if (aBoxSizing == NS_STYLE_BOX_SIZING_PADDING) {
+      min += coordOutsideSize;
+      result = NSCoordSaturatingAdd(result, coordOutsideSize);
+      pctTotal += pctOutsideSize;
+
+      coordOutsideSize = 0;
+      pctOutsideSize = 0.0f;
+    }
+  }
+
+  coordOutsideSize += aOffsets.hBorder;
+
+  if (aBoxSizing == NS_STYLE_BOX_SIZING_BORDER) {
+    min += coordOutsideSize;
+    result = NSCoordSaturatingAdd(result, coordOutsideSize);
+    pctTotal += pctOutsideSize;
+
+    coordOutsideSize = 0;
+    pctOutsideSize = 0.0f;
+  }
+
+  coordOutsideSize += aOffsets.hMargin;
+  pctOutsideSize += aOffsets.hPctMargin;
+
+  min += coordOutsideSize;
+  result = NSCoordSaturatingAdd(result, coordOutsideSize);
+  pctTotal += pctOutsideSize;
+
+  nscoord size;
+  if (GetAbsoluteCoord(aStyleSize, size) ||
+      GetIntrinsicCoord(aStyleSize, aRenderingContext, aFrame,
+                        PROP_WIDTH, size)) {
+    result = AddPercents(aType, size + coordOutsideSize, pctOutsideSize);
+  } else if (aType == nsLayoutUtils::MIN_ISIZE &&
+             // The only cases of coord-percent-calc() units that
+             // GetAbsoluteCoord didn't handle are percent and calc()s
+             // containing percent.
+             aStyleSize.IsCoordPercentCalcUnit() &&
+             aFrame->IsFrameOfType(nsIFrame::eReplaced)) {
+    // A percentage width on replaced elements means they can shrink to 0.
+    result = 0; // let |min| handle padding/border/margin
+  } else {
+    // NOTE: We could really do a lot better for percents and for some
+    // cases of calc() containing percent (certainly including any where
+    // the coefficient on the percent is positive and there are no max()
+    // expressions).  However, doing better for percents wouldn't be
+    // backwards compatible.
+    result = AddPercents(aType, result, pctTotal);
+  }
+
+  nscoord maxSize = aFixedMaxSize ? *aFixedMaxSize : 0;
+  if (aFixedMaxSize ||
+      GetIntrinsicCoord(aStyleMaxSize, aRenderingContext, aFrame,
+                        PROP_MAX_WIDTH, maxSize)) {
+    maxSize = AddPercents(aType, maxSize + coordOutsideSize, pctOutsideSize);
+    if (result > maxSize) {
+      result = maxSize;
+    }
+  }
+
+  nscoord minSize = aFixedMinSize ? *aFixedMinSize : 0;
+  if (aFixedMinSize ||
+      GetIntrinsicCoord(aStyleMinSize, aRenderingContext, aFrame,
+                        PROP_MIN_WIDTH, minSize)) {
+    minSize = AddPercents(aType, minSize + coordOutsideSize, pctOutsideSize);
+    if (result < minSize) {
+      result = minSize;
+    }
+  }
+
+  min = AddPercents(aType, min, pctTotal);
+  if (result < min) {
+    result = min;
+  }
+
+  const nsStyleDisplay* disp = aFrame->StyleDisplay();
+  if (aFrame->IsThemed(disp)) {
+    LayoutDeviceIntSize devSize;
+    bool canOverride = true;
+    nsPresContext* pc = aFrame->PresContext();
+    pc->GetTheme()->GetMinimumWidgetSize(pc, aFrame, disp->mAppearance,
+                                         &devSize, &canOverride);
+    nscoord themeSize =
+      pc->DevPixelsToAppUnits(aAxis == eAxisVertical ? devSize.height
+                                                     : devSize.width);
+    // GetMinimumWidgetSize() returns a border-box width.
+    themeSize += aOffsets.hMargin;
+    themeSize = AddPercents(aType, themeSize, aOffsets.hPctMargin);
+
+    if (themeSize > result || !canOverride) {
+      result = themeSize;
+    }
+  }
+  return result;
+}
+
 /* static */ nscoord
-nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
-                                     nsIFrame *aFrame,
-                                     IntrinsicISizeType aType,
-                                     uint32_t aFlags)
+nsLayoutUtils::IntrinsicForAxis(PhysicalAxis        aAxis,
+                                nsRenderingContext* aRenderingContext,
+                                nsIFrame*           aFrame,
+                                IntrinsicISizeType  aType,
+                                uint32_t            aFlags)
 {
   NS_PRECONDITION(aFrame, "null frame");
   NS_PRECONDITION(aFrame->GetParent(),
-                  "IntrinsicForContainer called on frame not in tree");
+                  "IntrinsicForAxis called on frame not in tree");
   NS_PRECONDITION(aType == MIN_ISIZE || aType == PREF_ISIZE, "bad type");
 
+  const bool horizontalAxis = MOZ_LIKELY(aAxis == eAxisHorizontal);
 #ifdef DEBUG_INTRINSIC_WIDTH
   nsFrame::IndentBy(stderr, gNoiseIndent);
   static_cast<nsFrame*>(aFrame)->ListTag(stderr);
-  printf_stderr(" %s intrinsic inline-size for container:\n",
-         aType == MIN_ISIZE ? "min" : "pref");
+  printf_stderr(" %s %s intrinsic size for container:\n",
+                aType == MIN_ISIZE ? "min" : "pref",
+                horizontalAxis ? "horizontal" : "vertical");
 #endif
 
   // If aFrame is a container for font size inflation, then shrink
   // wrapping inside of it should not apply font size inflation.
   AutoMaybeDisableFontInflation an(aFrame);
 
-  nsIFrame::IntrinsicISizeOffsetData offsets =
-    aFrame->IntrinsicISizeOffsets(aRenderingContext);
-
   // We want the size this frame will contribute to the parent's inline-size,
   // so we work in the parent's writing mode; but if aFrame is orthogonal to
   // its parent, we'll need to look at its BSize instead of min/pref-ISize.
-  WritingMode wm = aFrame->GetParent()->GetWritingMode();
-  WritingMode ourWM = aFrame->GetWritingMode();
-  bool isOrthogonal = ourWM.IsOrthogonalTo(wm);
-  bool isVertical = wm.IsVertical();
-
-  const nsStylePosition *stylePos = aFrame->StylePosition();
+  const nsStylePosition* stylePos = aFrame->StylePosition();
   uint8_t boxSizing = stylePos->mBoxSizing;
 
-  const nsStyleCoord& styleISize = stylePos->ISize(wm);
-  const nsStyleCoord& styleMinISize = stylePos->MinISize(wm);
-  const nsStyleCoord& styleMaxISize = stylePos->MaxISize(wm);
+  const nsStyleCoord& styleISize =
+    horizontalAxis ? stylePos->mWidth : stylePos->mHeight;
+  const nsStyleCoord& styleMinISize =
+    horizontalAxis ? stylePos->mMinWidth : stylePos->mMinHeight;
+  const nsStyleCoord& styleMaxISize =
+    horizontalAxis ? stylePos->mMaxWidth : stylePos->mMaxHeight;
 
   // We build up two values starting with the content box, and then
   // adding padding, border and margin.  The result is normally
   // |result|.  Then, when we handle 'width', 'min-width', and
   // 'max-width', we use the results we've been building in |min| as a
   // minimum, overriding 'min-width'.  This ensures two things:
   //   * that we don't let a value of 'box-sizing' specifying a width
   //     smaller than the padding/border inside the box-sizing box give
@@ -4383,16 +4524,18 @@ nsLayoutUtils::IntrinsicForContainer(nsR
     // flex items' min-sizes are intentionally ignored until the flex
     // container explicitly considers them during space distribution.
     minISize = 0;
     haveFixedMinISize = true;
   } else {
     haveFixedMinISize = GetAbsoluteCoord(styleMinISize, minISize);
   }
 
+  PhysicalAxis ourInlineAxis =
+    aFrame->GetWritingMode().PhysicalAxis(eLogicalAxisInline);
   // If we have a specified width (or a specified 'min-width' greater
   // than the specified 'max-width', which works out to the same thing),
   // don't even bother getting the frame's intrinsic width, because in
   // this case GetAbsoluteCoord(styleISize, w) will always succeed, so
   // we'll never need the intrinsic dimensions.
   if (styleISize.GetUnit() == eStyleUnit_Enumerated &&
       (styleISize.GetIntValue() == NS_STYLE_WIDTH_MAX_CONTENT ||
        styleISize.GetIntValue() == NS_STYLE_WIDTH_MIN_CONTENT)) {
@@ -4401,19 +4544,18 @@ nsLayoutUtils::IntrinsicForContainer(nsR
     // For -moz-max-content and -moz-min-content, we handle them like
     // specified widths, but ignore box-sizing.
     boxSizing = NS_STYLE_BOX_SIZING_CONTENT;
   } else if (!styleISize.ConvertsToLength() &&
              !(haveFixedMinISize && haveFixedMaxISize && maxISize <= minISize)) {
 #ifdef DEBUG_INTRINSIC_WIDTH
     ++gNoiseIndent;
 #endif
-    if (isOrthogonal) {
-      // We need aFrame's block-dir size, which will become its inline-size
-      // contribution in the container.
+    if (MOZ_UNLIKELY(aAxis != ourInlineAxis)) {
+      // We need aFrame's block-dir size.
       // XXX Unfortunately, we probably don't know this yet, so this is wrong...
       // but it's not clear what we should do. If aFrame's inline size hasn't
       // been determined yet, we can't necessarily figure out its block size
       // either. For now, authors who put orthogonal elements into things like
       // buttons or table cells may have to explicitly provide sizes rather
       // than expecting intrinsic sizing to work "perfectly" in underspecified
       // cases.
       result = aFrame->BSize();
@@ -4421,54 +4563,62 @@ nsLayoutUtils::IntrinsicForContainer(nsR
       result = aType == MIN_ISIZE
                ? aFrame->GetMinISize(aRenderingContext)
                : aFrame->GetPrefISize(aRenderingContext);
     }
 #ifdef DEBUG_INTRINSIC_WIDTH
     --gNoiseIndent;
     nsFrame::IndentBy(stderr, gNoiseIndent);
     static_cast<nsFrame*>(aFrame)->ListTag(stderr);
-    printf_stderr(" %s intrinsic inline-size from frame is %d.\n",
-           aType == MIN_ISIZE ? "min" : "pref", result);
+    printf_stderr(" %s %s intrinsic size from frame is %d.\n",
+                  aType == MIN_ISIZE ? "min" : "pref",
+                  horizontalAxis ? "horizontal" : "vertical",
+                  result);
 #endif
 
     // Handle elements with an intrinsic ratio (or size) and a specified
     // height, min-height, or max-height.
     // NOTE: We treat "min-height:auto" as "0" for the purpose of this code,
     // since that's what it means in all cases except for on flex items -- and
     // even there, we're supposed to ignore it (i.e. treat it as 0) until the
     // flex container explicitly considers it.
-    const nsStyleCoord& styleBSize = stylePos->BSize(wm);
-    const nsStyleCoord& styleMinBSize = stylePos->MinBSize(wm);
-    const nsStyleCoord& styleMaxBSize = stylePos->MaxBSize(wm);
+    const nsStyleCoord& styleBSize =
+      horizontalAxis ? stylePos->mHeight : stylePos->mWidth;
+    const nsStyleCoord& styleMinBSize =
+      horizontalAxis ? stylePos->mMinHeight : stylePos->mMinWidth;
+    const nsStyleCoord& styleMaxBSize =
+      horizontalAxis ? stylePos->mMaxHeight : stylePos->mMaxWidth;
 
     if (styleBSize.GetUnit() != eStyleUnit_Auto ||
         !(styleMinBSize.GetUnit() == eStyleUnit_Auto ||
           (styleMinBSize.GetUnit() == eStyleUnit_Coord &&
            styleMinBSize.GetCoordValue() == 0)) ||
         styleMaxBSize.GetUnit() != eStyleUnit_None) {
 
-      LogicalSize ratio(wm, aFrame->GetIntrinsicRatio());
-
-      if (ratio.BSize(wm) != 0) {
+      nsSize ratio(aFrame->GetIntrinsicRatio());
+      nscoord ratioISize = (horizontalAxis ? ratio.width  : ratio.height);
+      nscoord ratioBSize = (horizontalAxis ? ratio.height : ratio.width);
+      if (ratioBSize != 0) {
         nscoord bSizeTakenByBoxSizing = 0;
         switch (boxSizing) {
         case NS_STYLE_BOX_SIZING_BORDER: {
           const nsStyleBorder* styleBorder = aFrame->StyleBorder();
           bSizeTakenByBoxSizing +=
-            wm.IsVertical() ? styleBorder->GetComputedBorder().LeftRight()
-                            : styleBorder->GetComputedBorder().TopBottom();
+            horizontalAxis ? styleBorder->GetComputedBorder().TopBottom()
+                           : styleBorder->GetComputedBorder().LeftRight();
           // fall through
         }
         case NS_STYLE_BOX_SIZING_PADDING: {
           if (!(aFlags & IGNORE_PADDING)) {
             const nsStyleSides& stylePadding =
               aFrame->StylePadding()->mPadding;
-            const nsStyleCoord& paddingStart = stylePadding.GetBStart(wm);
-            const nsStyleCoord& paddingEnd = stylePadding.GetBEnd(wm);
+            const nsStyleCoord& paddingStart =
+              stylePadding.Get(horizontalAxis ? NS_SIDE_TOP : NS_SIDE_LEFT);
+            const nsStyleCoord& paddingEnd =
+              stylePadding.Get(horizontalAxis ? NS_SIDE_BOTTOM : NS_SIDE_RIGHT);
             nscoord pad;
             if (GetAbsoluteCoord(paddingStart, pad) ||
                 GetPercentBSize(paddingStart, aFrame, pad)) {
               bSizeTakenByBoxSizing += pad;
             }
             if (GetAbsoluteCoord(paddingEnd, pad) ||
                 GetPercentBSize(paddingEnd, aFrame, pad)) {
               bSizeTakenByBoxSizing += pad;
@@ -4480,163 +4630,81 @@ nsLayoutUtils::IntrinsicForContainer(nsR
         default:
           break;
         }
 
         nscoord h;
         if (GetAbsoluteCoord(styleBSize, h) ||
             GetPercentBSize(styleBSize, aFrame, h)) {
           h = std::max(0, h - bSizeTakenByBoxSizing);
-          result = NSCoordMulDiv(h, ratio.ISize(wm), ratio.BSize(wm));
+          result = NSCoordMulDiv(h, ratioISize, ratioBSize);
         }
 
         if (GetAbsoluteCoord(styleMaxBSize, h) ||
             GetPercentBSize(styleMaxBSize, aFrame, h)) {
           h = std::max(0, h - bSizeTakenByBoxSizing);
-          nscoord maxISize = NSCoordMulDiv(h, ratio.ISize(wm), ratio.BSize(wm));
+          nscoord maxISize = NSCoordMulDiv(h, ratioISize, ratioBSize);
           if (maxISize < result)
             result = maxISize;
         }
 
         if (GetAbsoluteCoord(styleMinBSize, h) ||
             GetPercentBSize(styleMinBSize, aFrame, h)) {
           h = std::max(0, h - bSizeTakenByBoxSizing);
-          nscoord minISize = NSCoordMulDiv(h, ratio.ISize(wm), ratio.BSize(wm));
+          nscoord minISize = NSCoordMulDiv(h, ratioISize, ratioBSize);
           if (minISize > result)
             result = minISize;
         }
       }
     }
   }
 
   if (aFrame->GetType() == nsGkAtoms::tableFrame) {
     // Tables can't shrink smaller than their intrinsic minimum width,
     // no matter what.
     min = aFrame->GetMinISize(aRenderingContext);
   }
 
-  // We also need to track what has been added on outside of the box
-  // (controlled by 'box-sizing') where 'width', 'min-width' and
-  // 'max-width' are applied.  We have to account for these properties
-  // after getting all the offsets (margin, border, padding) because
-  // percentages do not operate linearly.
-  // Doing this is ok because although percentages aren't handled
-  // linearly, they are handled monotonically.
-  nscoord coordOutsideISize = 0;
-  float pctOutsideISize = 0;
-  float pctTotal = 0.0f;
-
-  if (!(aFlags & IGNORE_PADDING)) {
-    coordOutsideISize += offsets.hPadding;
-    pctOutsideISize += offsets.hPctPadding;
-
-    if (boxSizing == NS_STYLE_BOX_SIZING_PADDING) {
-      min += coordOutsideISize;
-      result = NSCoordSaturatingAdd(result, coordOutsideISize);
-      pctTotal += pctOutsideISize;
-
-      coordOutsideISize = 0;
-      pctOutsideISize = 0.0f;
-    }
-  }
-
-  coordOutsideISize += offsets.hBorder;
-
-  if (boxSizing == NS_STYLE_BOX_SIZING_BORDER) {
-    min += coordOutsideISize;
-    result = NSCoordSaturatingAdd(result, coordOutsideISize);
-    pctTotal += pctOutsideISize;
-
-    coordOutsideISize = 0;
-    pctOutsideISize = 0.0f;
-  }
-
-  coordOutsideISize += offsets.hMargin;
-  pctOutsideISize += offsets.hPctMargin;
-
-  min += coordOutsideISize;
-  result = NSCoordSaturatingAdd(result, coordOutsideISize);
-  pctTotal += pctOutsideISize;
-
-  nscoord w;
-  if (GetAbsoluteCoord(styleISize, w) ||
-      GetIntrinsicCoord(styleISize, aRenderingContext, aFrame,
-                        PROP_WIDTH, w)) {
-    result = AddPercents(aType, w + coordOutsideISize, pctOutsideISize);
-  }
-  else if (aType == MIN_ISIZE &&
-           // The only cases of coord-percent-calc() units that
-           // GetAbsoluteCoord didn't handle are percent and calc()s
-           // containing percent.
-           styleISize.IsCoordPercentCalcUnit() &&
-           aFrame->IsFrameOfType(nsIFrame::eReplaced)) {
-    // A percentage width on replaced elements means they can shrink to 0.
-    result = 0; // let |min| handle padding/border/margin
-  }
-  else {
-    // NOTE: We could really do a lot better for percents and for some
-    // cases of calc() containing percent (certainly including any where
-    // the coefficient on the percent is positive and there are no max()
-    // expressions).  However, doing better for percents wouldn't be
-    // backwards compatible.
-    result = AddPercents(aType, result, pctTotal);
-  }
-
-  if (haveFixedMaxISize ||
-      GetIntrinsicCoord(styleMaxISize, aRenderingContext, aFrame,
-                        PROP_MAX_WIDTH, maxISize)) {
-    maxISize = AddPercents(aType, maxISize + coordOutsideISize, pctOutsideISize);
-    if (result > maxISize)
-      result = maxISize;
-  }
-
-  if (haveFixedMinISize ||
-      GetIntrinsicCoord(styleMinISize, aRenderingContext, aFrame,
-                        PROP_MIN_WIDTH, minISize)) {
-    minISize = AddPercents(aType, minISize + coordOutsideISize, pctOutsideISize);
-    if (result < minISize)
-      result = minISize;
-  }
-
-  min = AddPercents(aType, min, pctTotal);
-  if (result < min)
-    result = min;
-
-  const nsStyleDisplay *disp = aFrame->StyleDisplay();
-  if (aFrame->IsThemed(disp)) {
-    LayoutDeviceIntSize size;
-    bool canOverride = true;
-    nsPresContext *presContext = aFrame->PresContext();
-    presContext->GetTheme()->
-      GetMinimumWidgetSize(presContext, aFrame, disp->mAppearance,
-                           &size, &canOverride);
-
-    nscoord themeISize =
-      presContext->DevPixelsToAppUnits(isVertical ? size.height : size.width);
-
-    // GMWS() returns a border-box width
-    themeISize += offsets.hMargin;
-    themeISize = AddPercents(aType, themeISize, offsets.hPctMargin);
-
-    if (themeISize > result || !canOverride) {
-      result = themeISize;
-    }
-  }
+  nsIFrame::IntrinsicISizeOffsetData offsets =
+    MOZ_LIKELY(aAxis == ourInlineAxis) ? aFrame->IntrinsicISizeOffsets()
+                                       : aFrame->IntrinsicBSizeOffsets();
+  result = AddIntrinsicSizeOffset(aRenderingContext, aFrame, offsets, aType,
+                                  boxSizing, result, min, styleISize,
+                                  haveFixedMinISize ? &minISize : nullptr,
+                                  styleMinISize,
+                                  haveFixedMaxISize ? &maxISize : nullptr,
+                                  styleMaxISize,
+                                  aFlags, aAxis);
 
 #ifdef DEBUG_INTRINSIC_WIDTH
   nsFrame::IndentBy(stderr, gNoiseIndent);
   static_cast<nsFrame*>(aFrame)->ListTag(stderr);
-  printf_stderr(" %s intrinsic inline-size for container is %d twips.\n",
-         aType == MIN_ISIZE ? "min" : "pref", result);
+  printf_stderr(" %s %s intrinsic size for container is %d twips.\n",
+                aType == MIN_ISIZE ? "min" : "pref",
+                horizontalAxis ? "horizontal" : "vertical",
+                result);
 #endif
 
   return result;
 }
 
 /* static */ nscoord
+nsLayoutUtils::IntrinsicForContainer(nsRenderingContext* aRenderingContext,
+                                     nsIFrame* aFrame,
+                                     IntrinsicISizeType aType,
+                                     uint32_t aFlags)
+{
+  MOZ_ASSERT(aFrame && aFrame->GetParent());
+  // We want the size aFrame will contribute to its parent's inline-size.
+  PhysicalAxis axis =
+    aFrame->GetParent()->GetWritingMode().PhysicalAxis(eLogicalAxisInline);
+  return IntrinsicForAxis(axis, aRenderingContext, aFrame, aType, aFlags);
+}
+
+/* static */ nscoord
 nsLayoutUtils::ComputeCBDependentValue(nscoord aPercentBasis,
                                        const nsStyleCoord& aCoord)
 {
   NS_WARN_IF_FALSE(aPercentBasis != NS_UNCONSTRAINEDSIZE,
                    "have unconstrained width or height; this should only "
                    "result from very large sizes, not attempts at intrinsic "
                    "size calculation");
 
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -1294,28 +1294,37 @@ public:
    * @param aFrame the checking frame.
    * @return true if the frame is a part of the scrollbar or scrollcorner of
    *         the root content.
    */
   static bool IsViewportScrollbarFrame(nsIFrame* aFrame);
 
   /**
    * Get the contribution of aFrame to its containing block's intrinsic
-   * width.  This considers the child's intrinsic width, its 'width',
-   * 'min-width', and 'max-width' properties, and its padding, border,
-   * and margin.
+   * size for the given physical axis.  This considers the child's intrinsic
+   * width, its 'width', 'min-width', and 'max-width' properties (or 'height'
+   * variations if that's what matches aAxis) and its padding, border and margin
+   * in the corresponding dimension.
    */
   enum IntrinsicISizeType { MIN_ISIZE, PREF_ISIZE };
   enum {
     IGNORE_PADDING = 0x01
   };
+  static nscoord IntrinsicForAxis(mozilla::PhysicalAxis aAxis,
+                                  nsRenderingContext*   aRenderingContext,
+                                  nsIFrame*             aFrame,
+                                  IntrinsicISizeType    aType,
+                                  uint32_t              aFlags = 0);
+  /**
+   * Calls IntrinsicForAxis with aFrame's parent's inline physical axis.
+   */
   static nscoord IntrinsicForContainer(nsRenderingContext* aRenderingContext,
-                                       nsIFrame* aFrame,
-                                       IntrinsicISizeType aType,
-                                       uint32_t aFlags = 0);
+                                       nsIFrame*           aFrame,
+                                       IntrinsicISizeType  aType,
+                                       uint32_t            aFlags = 0);
 
   /*
    * Convert nsStyleCoord to nscoord when percentages depend on the
    * containing block size.
    * @param aPercentBasis The width or height of the containing block
    * (whichever the client wants to use for resolving percentages).
    */
   static nscoord ComputeCBDependentValue(nscoord aPercentBasis,
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6937,21 +6937,21 @@ PresShell::HandleEvent(nsIFrame* aFrame,
                        bool aDontRetargetEvents,
                        nsEventStatus* aEventStatus,
                        nsIContent** aTargetContent)
 {
 #ifdef MOZ_TASK_TRACER
   // Make touch events, mouse events and hardware key events to be the source
   // events of TaskTracer, and originate the rest correlation tasks from here.
   SourceEventType type = SourceEventType::Unknown;
-  if (WidgetTouchEvent* inputEvent = aEvent->AsTouchEvent()) {
+  if (aEvent->AsTouchEvent()) {
     type = SourceEventType::Touch;
-  } else if (WidgetMouseEvent* inputEvent = aEvent->AsMouseEvent()) {
+  } else if (aEvent->AsMouseEvent()) {
     type = SourceEventType::Mouse;
-  } else if (WidgetKeyboardEvent* inputEvent = aEvent->AsKeyboardEvent()) {
+  } else if (aEvent->AsKeyboardEvent()) {
     type = SourceEventType::Key;
   }
   AutoSourceEvent taskTracerEvent(type);
 #endif
 
   NS_ASSERTION(aFrame, "aFrame should be not null");
 
   if (sPointerEventEnabled) {
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4050,17 +4050,16 @@ nsIFrame::InlinePrefISizeData::ForceBrea
     NSCoordSaturatingSubtract(currentLine, trailingWhitespace, nscoord_MAX);
   prevLines = std::max(prevLines, currentLine);
   currentLine = trailingWhitespace = 0;
   skipWhitespace = true;
 }
 
 static void
 AddCoord(const nsStyleCoord& aStyle,
-         nsRenderingContext* aRenderingContext,
          nsIFrame* aFrame,
          nscoord* aCoord, float* aPercent,
          bool aClampNegativeToZero)
 {
   switch (aStyle.GetUnit()) {
     case eStyleUnit_Coord: {
       NS_ASSERTION(!aClampNegativeToZero || aStyle.GetCoordValue() >= 0,
                    "unexpected negative value");
@@ -4086,75 +4085,88 @@ AddCoord(const nsStyleCoord& aStyle,
       return;
     }
     default: {
       return;
     }
   }
 }
 
-/* virtual */ nsIFrame::IntrinsicISizeOffsetData
-nsFrame::IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext)
-{
-  IntrinsicISizeOffsetData result;
-
-  WritingMode wm = GetWritingMode();
-
-  const nsStyleMargin *styleMargin = StyleMargin();
-  AddCoord(wm.IsVertical() ? styleMargin->mMargin.GetTop()
-                           : styleMargin->mMargin.GetLeft(),
-           aRenderingContext, this, &result.hMargin, &result.hPctMargin,
+static nsIFrame::IntrinsicISizeOffsetData
+IntrinsicSizeOffsets(nsIFrame* aFrame, bool aForISize)
+{
+  nsIFrame::IntrinsicISizeOffsetData result;
+  WritingMode wm = aFrame->GetWritingMode();
+  const nsStyleMargin* styleMargin = aFrame->StyleMargin();
+  bool verticalAxis = aForISize == wm.IsVertical();
+  AddCoord(verticalAxis ? styleMargin->mMargin.GetTop()
+                        : styleMargin->mMargin.GetLeft(),
+           aFrame, &result.hMargin, &result.hPctMargin,
            false);
-  AddCoord(wm.IsVertical() ? styleMargin->mMargin.GetBottom()
-                           : styleMargin->mMargin.GetRight(),
-           aRenderingContext, this, &result.hMargin, &result.hPctMargin,
+  AddCoord(verticalAxis ? styleMargin->mMargin.GetBottom()
+                        : styleMargin->mMargin.GetRight(),
+           aFrame, &result.hMargin, &result.hPctMargin,
            false);
 
-  const nsStylePadding *stylePadding = StylePadding();
-  AddCoord(wm.IsVertical() ? stylePadding->mPadding.GetTop()
-                           : stylePadding->mPadding.GetLeft(),
-           aRenderingContext, this, &result.hPadding, &result.hPctPadding,
+  const nsStylePadding* stylePadding = aFrame->StylePadding();
+  AddCoord(verticalAxis ? stylePadding->mPadding.GetTop()
+                        : stylePadding->mPadding.GetLeft(),
+           aFrame, &result.hPadding, &result.hPctPadding,
            true);
-  AddCoord(wm.IsVertical() ? stylePadding->mPadding.GetBottom()
-                           : stylePadding->mPadding.GetRight(),
-           aRenderingContext, this, &result.hPadding, &result.hPctPadding,
+  AddCoord(verticalAxis ? stylePadding->mPadding.GetBottom()
+                        : stylePadding->mPadding.GetRight(),
+           aFrame, &result.hPadding, &result.hPctPadding,
            true);
 
-  const nsStyleBorder *styleBorder = StyleBorder();
-  result.hBorder += styleBorder->GetComputedBorderWidth(
-    wm.PhysicalSideForInlineAxis(eLogicalEdgeStart));
-  result.hBorder += styleBorder->GetComputedBorderWidth(
-    wm.PhysicalSideForInlineAxis(eLogicalEdgeEnd));
-
-  const nsStyleDisplay *disp = StyleDisplay();
-  if (IsThemed(disp)) {
-    nsPresContext *presContext = PresContext();
+  const nsStyleBorder* styleBorder = aFrame->StyleBorder();
+  if (verticalAxis) {
+    result.hBorder += styleBorder->GetComputedBorderWidth(NS_SIDE_TOP);
+    result.hBorder += styleBorder->GetComputedBorderWidth(NS_SIDE_BOTTOM);
+  } else {
+    result.hBorder += styleBorder->GetComputedBorderWidth(NS_SIDE_LEFT);
+    result.hBorder += styleBorder->GetComputedBorderWidth(NS_SIDE_RIGHT);
+  }
+
+  const nsStyleDisplay* disp = aFrame->StyleDisplay();
+  if (aFrame->IsThemed(disp)) {
+    nsPresContext* presContext = aFrame->PresContext();
 
     nsIntMargin border;
     presContext->GetTheme()->GetWidgetBorder(presContext->DeviceContext(),
-                                             this, disp->mAppearance,
+                                             aFrame, disp->mAppearance,
                                              &border);
     result.hBorder =
-      presContext->DevPixelsToAppUnits(wm.IsVertical() ? border.TopBottom()
-                                                       : border.LeftRight());
+      presContext->DevPixelsToAppUnits(verticalAxis ? border.TopBottom()
+                                                    : border.LeftRight());
 
     nsIntMargin padding;
     if (presContext->GetTheme()->GetWidgetPadding(presContext->DeviceContext(),
-                                                  this, disp->mAppearance,
+                                                  aFrame, disp->mAppearance,
                                                   &padding)) {
       result.hPadding =
-        presContext->DevPixelsToAppUnits(wm.IsVertical() ? padding.TopBottom()
-                                                         : padding.LeftRight());
+        presContext->DevPixelsToAppUnits(verticalAxis ? padding.TopBottom()
+                                                      : padding.LeftRight());
       result.hPctPadding = 0;
     }
   }
-
   return result;
 }
 
+/* virtual */ nsIFrame::IntrinsicISizeOffsetData
+nsFrame::IntrinsicISizeOffsets()
+{
+  return IntrinsicSizeOffsets(this, true);
+}
+
+nsIFrame::IntrinsicISizeOffsetData
+nsIFrame::IntrinsicBSizeOffsets()
+{
+  return IntrinsicSizeOffsets(this, false);
+}
+
 /* virtual */ IntrinsicSize
 nsFrame::GetIntrinsicSize()
 {
   return IntrinsicSize(); // default is width/height set to eStyleUnit_None
 }
 
 /* virtual */ nsSize
 nsFrame::GetIntrinsicRatio()
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -245,18 +245,17 @@ public:
 
   virtual void MarkIntrinsicISizesDirty() override;
   virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
   virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
   virtual void AddInlineMinISize(nsRenderingContext *aRenderingContext,
                                  InlineMinISizeData *aData) override;
   virtual void AddInlinePrefISize(nsRenderingContext *aRenderingContext,
                                   InlinePrefISizeData *aData) override;
-  virtual IntrinsicISizeOffsetData
-    IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext) override;
+  virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override;
   virtual mozilla::IntrinsicSize GetIntrinsicSize() override;
   virtual nsSize GetIntrinsicRatio() override;
 
   virtual mozilla::LogicalSize
   ComputeSize(nsRenderingContext *aRenderingContext,
               mozilla::WritingMode aWritingMode,
               const mozilla::LogicalSize& aCBSize,
               nscoord aAvailableISize,
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1643,18 +1643,23 @@ public:
     nscoord hPadding, hBorder, hMargin;
     float hPctPadding, hPctMargin;
 
     IntrinsicISizeOffsetData()
       : hPadding(0), hBorder(0), hMargin(0)
       , hPctPadding(0.0f), hPctMargin(0.0f)
     {}
   };
-  virtual IntrinsicISizeOffsetData
-    IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext) = 0;
+  virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() = 0;
+
+  /**
+   * Return the bsize components of padding, border, and margin
+   * that contribute to the intrinsic width that applies to the parent.
+   */
+  IntrinsicISizeOffsetData IntrinsicBSizeOffsets();
 
   virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0;
 
   /*
    * Get the intrinsic ratio of this element, or nsSize(0,0) if it has
    * no intrinsic ratio.  The intrinsic ratio is the ratio of the
    * height/width of a box with an intrinsic size or the intrinsic
    * aspect ratio of a scalable vector image without an intrinsic size.
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-similar-to-text-unthemed-vertical-lr-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html style="writing-mode:vertical-lr;">
+  <body>
+    <input type="text" style="-moz-appearance:none; height:200px;" value="123">
+    <!-- div to cover spin box area -->
+    <div style="position:absolute; background-color:black; width:100px; height:200px; top:100px; left:0px;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-similar-to-text-unthemed-vertical-lr.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html style="writing-mode:vertical-lr;">
+  <body>
+    <input type="number" style="-moz-appearance:none; height:200px;" value="123">
+    <!-- div to cover spin box area -->
+    <div style="position:absolute; background-color:black; width:100px; height:200px; top:100px; left:0px;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-similar-to-text-unthemed-vertical-rl-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html style="writing-mode:vertical-rl;">
+  <body>
+    <input type="text" style="-moz-appearance:none; height:200px;" value="123">
+    <!-- div to cover spin box area -->
+    <div style="position:absolute; background-color:black; width:100px; height:200px; top:100px; right:0px;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-similar-to-text-unthemed-vertical-rl.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html style="writing-mode:vertical-rl;">
+  <body>
+    <input type="number" style="-moz-appearance:none; height:200px;" value="123">
+    <!-- div to cover spin box area -->
+    <div style="position:absolute; background-color:black; width:100px; height:200px; top:100px; right:0px;">
+  </body>
+</html>
--- a/layout/reftests/forms/input/number/reftest.list
+++ b/layout/reftests/forms/input/number/reftest.list
@@ -5,16 +5,18 @@ default-preferences pref(dom.forms.numbe
 skip-if(Android||B2G||Mulet) != not-other-type-unthemed-1.html not-other-type-unthemed-1a-notref.html # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(Android||B2G||Mulet) != not-other-type-unthemed-1.html not-other-type-unthemed-1b-notref.html # Initial mulet triage: parity with B2G/B2G Desktop
 # only valid on Android/B2G where type=number looks the same as type=text
 skip-if(!Android&&!B2G&&!Mulet) == number-same-as-text-unthemed.html number-same-as-text-unthemed-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 
 # should look the same as type=text, except for the spin box
 == number-similar-to-text-unthemed.html number-similar-to-text-unthemed-ref.html
 == number-similar-to-text-unthemed-rtl.html number-similar-to-text-unthemed-rtl-ref.html
+pref(layout.css.vertical-text.enabled,true) == number-similar-to-text-unthemed-vertical-lr.html number-similar-to-text-unthemed-vertical-lr-ref.html
+pref(layout.css.vertical-text.enabled,true) == number-similar-to-text-unthemed-vertical-rl.html number-similar-to-text-unthemed-vertical-rl-ref.html
 
 # dynamic type changes:
 fuzzy-if(/^Windows\x20NT\x205\.1/.test(http.oscpu),64,4) fuzzy-if(cocoaWidget,63,4) == to-number-from-other-type-unthemed-1.html to-number-from-other-type-unthemed-1-ref.html
 == from-number-to-other-type-unthemed-1.html from-number-to-other-type-unthemed-1-ref.html
 
 # dynamic value changes:
 == show-value.html show-value-ref.html
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/writing-mode/1174450-intrinsic-sizing-ref.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <meta charset="utf-8">
+  <title>Testcase for bug 1174450</title>
+  <style type="text/css">
+body,html { color:black; background:white; font-size:12px; line-height:16px; padding:0; margin:0; }
+	
+div.v, div.h {
+  display: block;
+  position: relative;
+  border: 1px dashed silver;
+  width:92px;
+  height:60px;
+}
+div.h {
+  width:124px;
+  height:98px;
+}
+.h span { 
+  margin: 7px 13px 62px 25px;
+  padding: 1px 3px 12px 37px;
+}
+.v span { 
+  margin: 7px 13px 30px 12px;
+  padding: 1px 3px 6px 18px;
+}
+
+span { 
+  display: block;
+  position: absolute;
+  width: 30px;
+  height: 10px;
+  background: lime;
+  border-width: 5px 9px 1px 7px;
+  border-style: solid;
+}
+
+.a { position:absolute; }
+.t2 {top:100px;}
+.t3 {top:200px;}
+.t4 {top:300px;}
+  
+  </style>
+</head>
+<body>
+
+
+<div class="a t1">
+<pre>vertical container, horizontal child</pre>
+<div class="v"><span class="h"></span></div>
+</div>
+<div class="a t2">
+<pre>vertical container, vertical child</pre>
+<div class="v"><span class="v"></span></div>
+</div>
+<div class="a t3">
+<pre>horizontal container, horizontal child</pre>
+<div class="h"><span class="h"></span></div>
+</div>
+<div class="a t4">
+<pre>horizontal container, vertical child</pre>
+<div class="h"><span class="v"></span></div>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/writing-mode/1174450-intrinsic-sizing.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <meta charset="utf-8">
+  <title>Testcase for bug 1174450</title>
+  <style type="text/css">
+body,html { color:black; background:white; font-size:12px; line-height:16px; padding:0; margin:0; }
+	
+div.h, div.v {
+  display: block;
+  border: 1px dashed silver;
+  float: left;
+}
+.v { 
+  writing-mode: vertical-lr;
+}
+.h { 
+  writing-mode: horizontal-tb;
+}
+
+span { 
+  display: block;
+  width: 30px;
+  height: 10px;
+  background: lime;
+  margin: 7px 13px 50% 20%;
+  padding: 1px 3px 10% 30%;
+  border-width: 5px 9px 1px 7px;
+  border-style: solid;
+}
+
+.a { position:absolute; }
+.t2 {top:100px;}
+.t3 {top:200px;}
+.t4 {top:300px;}
+  
+  </style>
+</head>
+<body>
+
+
+<div class="a t1">
+<pre>vertical container, horizontal child</pre>
+<div class="v"><span class="h"></span></div>
+</div>
+<div class="a t2">
+<pre>vertical container, vertical child</pre>
+<div class="v"><span class="v"></span></div>
+</div>
+<div class="a t3">
+<pre>horizontal container, horizontal child</pre>
+<div class="h"><span class="h"></span></div>
+</div>
+<div class="a t4">
+<pre>horizontal container, vertical child</pre>
+<div class="h"><span class="v"></span></div>
+</div>
+
+</body>
+</html>
--- a/layout/reftests/writing-mode/reftest.list
+++ b/layout/reftests/writing-mode/reftest.list
@@ -143,11 +143,12 @@ fails == 1147834-relative-overconstraine
 == 1172774-percent-margin-1.html 1172774-percent-horizontal-ref.html
 == 1172774-percent-margin-2.html 1172774-percent-horizontal-ref.html
 == 1172774-percent-margin-3.html 1172774-percent-vertical-ref.html
 == 1172774-percent-margin-4.html 1172774-percent-vertical-ref.html
 == 1172774-percent-padding-1.html 1172774-percent-horizontal-ref.html
 == 1172774-percent-padding-2.html 1172774-percent-horizontal-ref.html
 == 1172774-percent-padding-3.html 1172774-percent-vertical-ref.html
 == 1172774-percent-padding-4.html 1172774-percent-vertical-ref.html
+== 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing-ref.html
 
 # Suite of tests from GĂ©rard Talbot in bug 1079151
 include abspos/reftest.list
--- a/layout/style/forms.css
+++ b/layout/style/forms.css
@@ -985,27 +985,34 @@ input[type=number]::-moz-number-text {
   flex: 1;
   min-inline-size: 0;
   padding: 0;
   border: 0;
   margin: 0;
 }
 
 input[type=number]::-moz-number-spin-box {
+  writing-mode: horizontal-tb;
   display: flex;
   flex-direction: column;
 %ifdef XP_WIN
   /* The Window's Theme's spin buttons have a very narrow minimum width, so
    * make it something reasonable:
-   * XXX What about vertical mode? How will the spin buttons be arranged?
-   * This may need to be adjusted when bug 1123299 is implemented.
    */
   width: 16px;
 %endif
-  height: 0;
+  /* If the spin-box has auto height, it ends up enlarging the default height
+   * of the control, so we limit it to 1em here. The height doesn't affect
+   * the rendering of the spinner-buttons; it's only for layout purposes.
+   *
+   * This is a temporary hack until we implement better positioning for the
+   * spin-box in vertical mode; it works OK at default size but less well
+   * if the font-size is made substantially larger or smaller. (Bug 1175074.)
+   */
+  max-height: 1em;
   align-self: center;
   justify-content: center;
 }
 
 input[type=number]::-moz-number-spin-up {
   -moz-appearance: spinner-upbutton;
   display: block; /* bug 926670 */
   flex: none;
--- a/layout/style/number-control.css
+++ b/layout/style/number-control.css
@@ -3,17 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* This file exists purely because we need the styling for input[type=number]
  * to apply only if the pref dom.forms.number is true. Once bug 677302 is
  * fixed this rule can move back to forms.css.
  */
 
 input[type="number"] {
-  writing-mode: horizontal-tb !important; /* XXX remove when bug 1123299 is done */
   -moz-appearance: number-input;
   /* Has to revert some properties applied by the generic input rule. */
   -moz-binding: none;
   inline-size: 20ch; /* It'd be nice if this matched the default inline-size
                         of <input type=text>, but that's not easy to achieve
                         due to platform differences. */
 }
 
--- a/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/layout/tables/BasicTableLayoutStrategy.cpp
@@ -38,84 +38,87 @@ BasicTableLayoutStrategy::BasicTableLayo
 /* virtual */
 BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
 {
 }
 
 /* virtual */ nscoord
 BasicTableLayoutStrategy::GetMinISize(nsRenderingContext* aRenderingContext)
 {
-    DISPLAY_MIN_WIDTH(mTableFrame, mMinWidth);
-    if (mMinWidth == NS_INTRINSIC_WIDTH_UNKNOWN)
+    DISPLAY_MIN_WIDTH(mTableFrame, mMinISize);
+    if (mMinISize == NS_INTRINSIC_WIDTH_UNKNOWN) {
         ComputeIntrinsicISizes(aRenderingContext);
-    return mMinWidth;
+    }
+    return mMinISize;
 }
 
 /* virtual */ nscoord
 BasicTableLayoutStrategy::GetPrefISize(nsRenderingContext* aRenderingContext,
                                        bool aComputingSize)
 {
-    DISPLAY_PREF_WIDTH(mTableFrame, mPrefWidth);
-    NS_ASSERTION((mPrefWidth == NS_INTRINSIC_WIDTH_UNKNOWN) ==
-                 (mPrefWidthPctExpand == NS_INTRINSIC_WIDTH_UNKNOWN),
+    DISPLAY_PREF_WIDTH(mTableFrame, mPrefISize);
+    NS_ASSERTION((mPrefISize == NS_INTRINSIC_WIDTH_UNKNOWN) ==
+                 (mPrefISizePctExpand == NS_INTRINSIC_WIDTH_UNKNOWN),
                  "dirtyness out of sync");
-    if (mPrefWidth == NS_INTRINSIC_WIDTH_UNKNOWN)
+    if (mPrefISize == NS_INTRINSIC_WIDTH_UNKNOWN) {
         ComputeIntrinsicISizes(aRenderingContext);
-    return aComputingSize ? mPrefWidthPctExpand : mPrefWidth;
+    }
+    return aComputingSize ? mPrefISizePctExpand : mPrefISize;
 }
 
-struct CellWidthInfo {
-    CellWidthInfo(nscoord aMinCoord, nscoord aPrefCoord,
-                  float aPrefPercent, bool aHasSpecifiedWidth)
-        : hasSpecifiedWidth(aHasSpecifiedWidth)
+struct CellISizeInfo {
+    CellISizeInfo(nscoord aMinCoord, nscoord aPrefCoord,
+                  float aPrefPercent, bool aHasSpecifiedISize)
+        : hasSpecifiedISize(aHasSpecifiedISize)
         , minCoord(aMinCoord)
         , prefCoord(aPrefCoord)
         , prefPercent(aPrefPercent)
     {
     }
 
-    bool hasSpecifiedWidth;
+    bool hasSpecifiedISize;
     nscoord minCoord;
     nscoord prefCoord;
     float prefPercent;
 };
 
 // Used for both column and cell calculations.  The parts needed only
 // for cells are skipped when aIsCell is false.
-static CellWidthInfo
-GetWidthInfo(nsRenderingContext *aRenderingContext,
-             nsIFrame *aFrame, bool aIsCell)
+static CellISizeInfo
+GetISizeInfo(nsRenderingContext *aRenderingContext,
+             nsIFrame *aFrame, WritingMode aWM, bool aIsCell)
 {
     nscoord minCoord, prefCoord;
     const nsStylePosition *stylePos = aFrame->StylePosition();
     bool isQuirks = aFrame->PresContext()->CompatibilityMode() ==
                     eCompatibility_NavQuirks;
     nscoord boxSizingToBorderEdge = 0;
     if (aIsCell) {
         // If aFrame is a container for font size inflation, then shrink
         // wrapping inside of it should not apply font size inflation.
         AutoMaybeDisableFontInflation an(aFrame);
 
         minCoord = aFrame->GetMinISize(aRenderingContext);
         prefCoord = aFrame->GetPrefISize(aRenderingContext);
         // Until almost the end of this function, minCoord and prefCoord
-        // represent the box-sizing based width values (which mean they
-        // should include horizontal padding and border width when
+        // represent the box-sizing based isize values (which mean they
+        // should include inline padding and border width when
         // box-sizing is set to border-box).
-        // Note that this function returns border-box width, we add the
+        // Note that this function returns border-box isize, we add the
         // outer edges near the end of this function.
 
         // XXX Should we ignore percentage padding?
-        nsIFrame::IntrinsicISizeOffsetData offsets = aFrame->IntrinsicISizeOffsets(aRenderingContext);
+        nsIFrame::IntrinsicISizeOffsetData offsets =
+            aFrame->IntrinsicISizeOffsets();
 
-        // In quirks mode, table cell width should be content-box,
-        // but height should be border box.
+        // In quirks mode, table cell isize should be content-box,
+        // but bsize should be border box.
         // Because of this historic anomaly, we do not use quirk.css.
-        // (We can't specify one value of box-sizing for width and another
-        // for height).
+        // (We can't specify one value of box-sizing for isize and another
+        // for bsize).
         // For this reason, we also do not use box-sizing for just one of
         // them, as this may be confusing.
         if (isQuirks) {
             boxSizingToBorderEdge = offsets.hPadding + offsets.hBorder;
         }
         else {
             switch (stylePos->mBoxSizing) {
                 case NS_STYLE_BOX_SIZING_CONTENT:
@@ -133,232 +136,236 @@ GetWidthInfo(nsRenderingContext *aRender
                     break;
             }
         }
     } else {
         minCoord = 0;
         prefCoord = 0;
     }
     float prefPercent = 0.0f;
-    bool hasSpecifiedWidth = false;
+    bool hasSpecifiedISize = false;
 
-    const nsStyleCoord &width = stylePos->mWidth;
-    nsStyleUnit unit = width.GetUnit();
+    const nsStyleCoord& iSize = stylePos->ISize(aWM);
+    nsStyleUnit unit = iSize.GetUnit();
     // NOTE: We're ignoring calc() units with percentages here, for lack of a
     // sensible idea for what to do with them.  This means calc() with
     // percentages is basically handled like 'auto' for table cells and
     // columns.
-    if (width.ConvertsToLength()) {
-        hasSpecifiedWidth = true;
-        // Note: since ComputeWidthValue was designed to return content-box
-        // width, it will (in some cases) subtract the box-sizing edges.
+    if (iSize.ConvertsToLength()) {
+        hasSpecifiedISize = true;
+        // Note: since ComputeISizeValue was designed to return content-box
+        // isize, it will (in some cases) subtract the box-sizing edges.
         // We prevent this unwanted behavior by calling it with
         // aContentEdgeToBoxSizing and aBoxSizingToMarginEdge set to 0.
-        nscoord w = nsLayoutUtils::ComputeWidthValue(aRenderingContext,
-                                                     aFrame, 0, 0, 0, width);
+        nscoord c = nsLayoutUtils::ComputeISizeValue(aRenderingContext,
+                                                     aFrame, 0, 0, 0, iSize);
         // Quirk: A cell with "nowrap" set and a coord value for the
-        // width which is bigger than the intrinsic minimum width uses
-        // that coord value as the minimum width.
+        // isize which is bigger than the intrinsic minimum isize uses
+        // that coord value as the minimum isize.
         // This is kept up-to-date with dynamic changes to nowrap by code in
         // nsTableCellFrame::AttributeChanged
-        if (aIsCell && w > minCoord && isQuirks &&
+        if (aIsCell && c > minCoord && isQuirks &&
             aFrame->GetContent()->HasAttr(kNameSpaceID_None,
                                           nsGkAtoms::nowrap)) {
-            minCoord = w;
+            minCoord = c;
         }
-        prefCoord = std::max(w, minCoord);
+        prefCoord = std::max(c, minCoord);
     } else if (unit == eStyleUnit_Percent) {
-        prefPercent = width.GetPercentValue();
+        prefPercent = iSize.GetPercentValue();
     } else if (unit == eStyleUnit_Enumerated && aIsCell) {
-        switch (width.GetIntValue()) {
+        switch (iSize.GetIntValue()) {
             case NS_STYLE_WIDTH_MAX_CONTENT:
-                // 'width' only affects pref width, not min
-                // width, so don't change anything
+                // 'inline-size' only affects pref isize, not min
+                // isize, so don't change anything
                 break;
             case NS_STYLE_WIDTH_MIN_CONTENT:
                 prefCoord = minCoord;
                 break;
             case NS_STYLE_WIDTH_FIT_CONTENT:
             case NS_STYLE_WIDTH_AVAILABLE:
-                // act just like 'width: auto'
+                // act just like 'inline-size: auto'
                 break;
             default:
                 NS_NOTREACHED("unexpected enumerated value");
         }
     }
 
-    nsStyleCoord maxWidth(stylePos->mMaxWidth);
-    if (maxWidth.GetUnit() == eStyleUnit_Enumerated) {
-        if (!aIsCell || maxWidth.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE)
-            maxWidth.SetNoneValue();
-        else if (maxWidth.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT)
-            // for 'max-width', '-moz-fit-content' is like
+    nsStyleCoord maxISize(stylePos->MaxISize(aWM));
+    if (maxISize.GetUnit() == eStyleUnit_Enumerated) {
+        if (!aIsCell || maxISize.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE) {
+            maxISize.SetNoneValue();
+        } else if (maxISize.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT) {
+            // for 'max-inline-size', '-moz-fit-content' is like
             // '-moz-max-content'
-            maxWidth.SetIntValue(NS_STYLE_WIDTH_MAX_CONTENT,
+            maxISize.SetIntValue(NS_STYLE_WIDTH_MAX_CONTENT,
                                  eStyleUnit_Enumerated);
+        }
     }
-    unit = maxWidth.GetUnit();
-    // XXX To really implement 'max-width' well, we'd need to store
+    unit = maxISize.GetUnit();
+    // XXX To really implement 'max-inline-size' well, we'd need to store
     // it separately on the columns.
-    if (maxWidth.ConvertsToLength() || unit == eStyleUnit_Enumerated) {
-        nscoord w =
-            nsLayoutUtils::ComputeWidthValue(aRenderingContext, aFrame,
-                                             0, 0, 0, maxWidth);
-        if (w < minCoord)
-            minCoord = w;
-        if (w < prefCoord)
-            prefCoord = w;
+    if (maxISize.ConvertsToLength() || unit == eStyleUnit_Enumerated) {
+        nscoord c =
+            nsLayoutUtils::ComputeISizeValue(aRenderingContext, aFrame,
+                                             0, 0, 0, maxISize);
+        minCoord = std::min(c, minCoord);
+        prefCoord = std::min(c, prefCoord);
     } else if (unit == eStyleUnit_Percent) {
-        float p = stylePos->mMaxWidth.GetPercentValue();
-        if (p < prefPercent)
+        float p = stylePos->MaxISize(aWM).GetPercentValue();
+        if (p < prefPercent) {
             prefPercent = p;
+        }
     }
-    // treat calc() with percentages on max-width just like 'none'.
+    // treat calc() with percentages on max-inline-size just like 'none'.
 
-    nsStyleCoord minWidth(stylePos->mMinWidth);
-    if (minWidth.GetUnit() == eStyleUnit_Enumerated) {
-        if (!aIsCell || minWidth.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE)
-            minWidth.SetCoordValue(0);
-        else if (minWidth.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT)
-            // for 'min-width', '-moz-fit-content' is like
+    nsStyleCoord minISize(stylePos->MinISize(aWM));
+    if (minISize.GetUnit() == eStyleUnit_Enumerated) {
+        if (!aIsCell || minISize.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE) {
+            minISize.SetCoordValue(0);
+        } else if (minISize.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT) {
+            // for 'min-inline-size', '-moz-fit-content' is like
             // '-moz-min-content'
-            minWidth.SetIntValue(NS_STYLE_WIDTH_MIN_CONTENT,
+            minISize.SetIntValue(NS_STYLE_WIDTH_MIN_CONTENT,
                                  eStyleUnit_Enumerated);
+        }
     }
-    unit = minWidth.GetUnit();
-    if (minWidth.ConvertsToLength() || unit == eStyleUnit_Enumerated) {
-        nscoord w =
-            nsLayoutUtils::ComputeWidthValue(aRenderingContext, aFrame,
-                                             0, 0, 0, minWidth);
-        if (w > minCoord)
-            minCoord = w;
-        if (w > prefCoord)
-            prefCoord = w;
+    unit = minISize.GetUnit();
+    if (minISize.ConvertsToLength() || unit == eStyleUnit_Enumerated) {
+        nscoord c =
+            nsLayoutUtils::ComputeISizeValue(aRenderingContext, aFrame,
+                                             0, 0, 0, minISize);
+        minCoord = std::max(c, minCoord);
+        prefCoord = std::max(c, prefCoord);
     } else if (unit == eStyleUnit_Percent) {
-        float p = stylePos->mMinWidth.GetPercentValue();
-        if (p > prefPercent)
+        float p = stylePos->MinISize(aWM).GetPercentValue();
+        if (p > prefPercent) {
             prefPercent = p;
+        }
     }
-    // treat calc() with percentages on min-width just like '0'.
+    // treat calc() with percentages on min-inline-size just like '0'.
 
     // XXX Should col frame have border/padding considered?
     if (aIsCell) {
         minCoord += boxSizingToBorderEdge;
         prefCoord = NSCoordSaturatingAdd(prefCoord, boxSizingToBorderEdge);
     }
 
-    return CellWidthInfo(minCoord, prefCoord, prefPercent, hasSpecifiedWidth);
+    return CellISizeInfo(minCoord, prefCoord, prefPercent, hasSpecifiedISize);
 }
 
-static inline CellWidthInfo
-GetCellWidthInfo(nsRenderingContext *aRenderingContext,
-                 nsTableCellFrame *aCellFrame)
+static inline CellISizeInfo
+GetCellISizeInfo(nsRenderingContext *aRenderingContext,
+                 nsTableCellFrame *aCellFrame, WritingMode aWM)
 {
-    return GetWidthInfo(aRenderingContext, aCellFrame, true);
+    return GetISizeInfo(aRenderingContext, aCellFrame, aWM, true);
 }
 
-static inline CellWidthInfo
-GetColWidthInfo(nsRenderingContext *aRenderingContext,
-                nsIFrame *aFrame)
+static inline CellISizeInfo
+GetColISizeInfo(nsRenderingContext *aRenderingContext,
+                nsIFrame *aFrame, WritingMode aWM)
 {
-    return GetWidthInfo(aRenderingContext, aFrame, false);
+    return GetISizeInfo(aRenderingContext, aFrame, aWM, false);
 }
 
 
 /**
  * The algorithm in this function, in addition to meeting the
  * requirements of Web-compatibility, is also invariant under reordering
  * of the rows within a table (something that most, but not all, other
  * browsers are).
  */
 void
 BasicTableLayoutStrategy::ComputeColumnIntrinsicISizes(nsRenderingContext* aRenderingContext)
 {
     nsTableFrame *tableFrame = mTableFrame;
     nsTableCellMap *cellMap = tableFrame->GetCellMap();
+    WritingMode wm = tableFrame->GetWritingMode();
 
     mozilla::AutoStackArena arena;
     SpanningCellSorter spanningCells;
 
     // Loop over the columns to consider the columns and cells *without*
     // a colspan.
     int32_t col, col_end;
     for (col = 0, col_end = cellMap->GetColCount(); col < col_end; ++col) {
         nsTableColFrame *colFrame = tableFrame->GetColFrame(col);
         if (!colFrame) {
             NS_ERROR("column frames out of sync with cell map");
             continue;
         }
         colFrame->ResetIntrinsics();
         colFrame->ResetSpanIntrinsics();
 
-        // Consider the widths on the column.
-        CellWidthInfo colInfo = GetColWidthInfo(aRenderingContext, colFrame);
+        // Consider the isizes on the column.
+        CellISizeInfo colInfo = GetColISizeInfo(aRenderingContext,
+                                                colFrame, wm);
         colFrame->AddCoords(colInfo.minCoord, colInfo.prefCoord,
-                            colInfo.hasSpecifiedWidth);
+                            colInfo.hasSpecifiedISize);
         colFrame->AddPrefPercent(colInfo.prefPercent);
 
-        // Consider the widths on the column-group.  Note that we follow
-        // what the HTML spec says here, and make the width apply to
+        // Consider the isizes on the column-group.  Note that we follow
+        // what the HTML spec says here, and make the isize apply to
         // each column in the group, not the group as a whole.
 
-        // If column has width, column-group doesn't override width.
+        // If column has isize, column-group doesn't override isize.
         if (colInfo.minCoord == 0 && colInfo.prefCoord == 0 &&
             colInfo.prefPercent == 0.0f) {
             NS_ASSERTION(colFrame->GetParent()->GetType() ==
                              nsGkAtoms::tableColGroupFrame,
                          "expected a column-group");
-            colInfo = GetColWidthInfo(aRenderingContext, colFrame->GetParent());
+            colInfo = GetColISizeInfo(aRenderingContext,
+                                      colFrame->GetParent(), wm);
             colFrame->AddCoords(colInfo.minCoord, colInfo.prefCoord,
-                                colInfo.hasSpecifiedWidth);
+                                colInfo.hasSpecifiedISize);
             colFrame->AddPrefPercent(colInfo.prefPercent);
         }
 
-        // Consider the contents of and the widths on the cells without
+        // Consider the contents of and the isizes on the cells without
         // colspans.
         nsCellMapColumnIterator columnIter(cellMap, col);
         int32_t row, colSpan;
         nsTableCellFrame* cellFrame;
         while ((cellFrame = columnIter.GetNextFrame(&row, &colSpan))) {
             if (colSpan > 1) {
                 spanningCells.AddCell(colSpan, row, col);
                 continue;
             }
 
-            CellWidthInfo info = GetCellWidthInfo(aRenderingContext, cellFrame);
+            CellISizeInfo info = GetCellISizeInfo(aRenderingContext,
+                                                  cellFrame, wm);
 
             colFrame->AddCoords(info.minCoord, info.prefCoord,
-                                info.hasSpecifiedWidth);
+                                info.hasSpecifiedISize);
             colFrame->AddPrefPercent(info.prefPercent);
         }
 #ifdef DEBUG_dbaron_off
         printf("table %p col %d nonspan: min=%d pref=%d spec=%d pct=%f\n",
                mTableFrame, col, colFrame->GetMinCoord(),
                colFrame->GetPrefCoord(), colFrame->GetHasSpecifiedCoord(),
                colFrame->GetPrefPercent());
 #endif
     }
 #ifdef DEBUG_TABLE_STRATEGY
     printf("ComputeColumnIntrinsicISizes single\n");
     mTableFrame->Dump(false, true, false);
 #endif
 
     // Consider the cells with a colspan that we saved in the loop above
     // into the spanning cell sorter.  We consider these cells by seeing
-    // if they require adding to the widths resulting only from cells
+    // if they require adding to the isizes resulting only from cells
     // with a smaller colspan, and therefore we must process them sorted
     // in increasing order by colspan.  For each colspan group, we
     // accumulate new values to accumulate in the column frame's Span*
     // members.
     //
-    // Considering things only relative to the widths resulting from
+    // Considering things only relative to the isizes resulting from
     // cells with smaller colspans (rather than incrementally including
     // the results from spanning cells, or doing spanning and
     // non-spanning cells in a single pass) means that layout remains
-    // row-order-invariant and (except for percentage widths that add to
+    // row-order-invariant and (except for percentage isizes that add to
     // more than 100%) column-order invariant.
     //
     // Starting with smaller colspans makes it more likely that we
     // satisfy all the constraints given and don't distribute space to
     // columns where we don't need it.
     SpanningCellSorter::Item *item;
     int32_t colSpan;
     while ((item = spanningCells.GetNext(&colSpan))) {
@@ -369,26 +376,27 @@ BasicTableLayoutStrategy::ComputeColumnI
             col = item->col;
             CellData *cellData = cellMap->GetDataAt(row, col);
             NS_ASSERTION(cellData && cellData->IsOrig(),
                          "bogus result from spanning cell sorter");
 
             nsTableCellFrame *cellFrame = cellData->GetCellFrame();
             NS_ASSERTION(cellFrame, "bogus result from spanning cell sorter");
 
-            CellWidthInfo info = GetCellWidthInfo(aRenderingContext, cellFrame);
+            CellISizeInfo info =
+                GetCellISizeInfo(aRenderingContext, cellFrame, wm);
 
             if (info.prefPercent > 0.0f) {
-                DistributePctWidthToColumns(info.prefPercent,
+                DistributePctISizeToColumns(info.prefPercent,
                                             col, colSpan);
             }
-            DistributeWidthToColumns(info.minCoord, col, colSpan, 
-                                     BTLS_MIN_WIDTH, info.hasSpecifiedWidth);
-            DistributeWidthToColumns(info.prefCoord, col, colSpan, 
-                                     BTLS_PREF_WIDTH, info.hasSpecifiedWidth);
+            DistributeISizeToColumns(info.minCoord, col, colSpan, 
+                                     BTLS_MIN_ISIZE, info.hasSpecifiedISize);
+            DistributeISizeToColumns(info.prefCoord, col, colSpan, 
+                                     BTLS_PREF_ISIZE, info.hasSpecifiedISize);
         } while ((item = item->next));
 
         // Combine the results of the span analysis into the main results,
         // for each increment of colspan.
 
         for (col = 0, col_end = cellMap->GetColCount(); col < col_end; ++col) {
             nsTableColFrame *colFrame = tableFrame->GetColFrame(col);
             if (!colFrame) {
@@ -451,17 +459,17 @@ BasicTableLayoutStrategy::ComputeIntrins
         }
         if (mTableFrame->ColumnHasCellSpacingBefore(col)) {
             add += mTableFrame->GetColSpacing(col - 1);
         }
         min += colFrame->GetMinCoord();
         pref = NSCoordSaturatingAdd(pref, colFrame->GetPrefCoord());
 
         // Percentages are of the table, so we have to reverse them for
-        // intrinsic widths.
+        // intrinsic isizes.
         float p = colFrame->GetPrefPercent();
         if (p > 0.0f) {
             nscoord colPref = colFrame->GetPrefCoord();
             nscoord new_small_pct_expand = 
                 (colPref == nscoord_MAX ?
                  nscoord_MAX : nscoord(float(colPref) / p));
             if (new_small_pct_expand > max_small_pct_pref) {
                 max_small_pct_pref = new_small_pct_expand;
@@ -470,28 +478,28 @@ BasicTableLayoutStrategy::ComputeIntrins
         } else {
             nonpct_pref_total = NSCoordSaturatingAdd(nonpct_pref_total, 
                                                      colFrame->GetPrefCoord());
         }
     }
 
     nscoord pref_pct_expand = pref;
 
-    // Account for small percentages expanding the preferred width of
+    // Account for small percentages expanding the preferred isize of
     // *other* columns.
     if (max_small_pct_pref > pref_pct_expand) {
         pref_pct_expand = max_small_pct_pref;
     }
 
-    // Account for large percentages expanding the preferred width of
+    // Account for large percentages expanding the preferred isize of
     // themselves.  There's no need to iterate over the columns multiple
     // times, since when there is such a need, the small percentage
     // effect is bigger anyway.  (I think!)
     NS_ASSERTION(0.0f <= pct_total && pct_total <= 1.0f,
-                 "column percentage widths not adjusted down to 100%");
+                 "column percentage inline-sizes not adjusted down to 100%");
     if (pct_total == 1.0f) {
         if (nonpct_pref_total > 0) {
             pref_pct_expand = nscoord_MAX;
             // XXX Or should I use some smaller value?  (Test this using
             // nested tables!)
         }
     } else {
         nscoord large_pct_pref =
@@ -504,288 +512,290 @@ BasicTableLayoutStrategy::ComputeIntrins
 
     // border-spacing isn't part of the basis for percentages
     if (colCount > 0) {
         min += add;
         pref = NSCoordSaturatingAdd(pref, add);
         pref_pct_expand = NSCoordSaturatingAdd(pref_pct_expand, add);
     }
 
-    mMinWidth = min;
-    mPrefWidth = pref;
-    mPrefWidthPctExpand = pref_pct_expand;
+    mMinISize = min;
+    mPrefISize = pref;
+    mPrefISizePctExpand = pref_pct_expand;
 }
 
 /* virtual */ void
 BasicTableLayoutStrategy::MarkIntrinsicISizesDirty()
 {
-    mMinWidth = NS_INTRINSIC_WIDTH_UNKNOWN;
-    mPrefWidth = NS_INTRINSIC_WIDTH_UNKNOWN;
-    mPrefWidthPctExpand = NS_INTRINSIC_WIDTH_UNKNOWN;
-    mLastCalcWidth = nscoord_MIN;
+    mMinISize = NS_INTRINSIC_WIDTH_UNKNOWN;
+    mPrefISize = NS_INTRINSIC_WIDTH_UNKNOWN;
+    mPrefISizePctExpand = NS_INTRINSIC_WIDTH_UNKNOWN;
+    mLastCalcISize = nscoord_MIN;
 }
 
 /* virtual */ void
 BasicTableLayoutStrategy::ComputeColumnISizes(const nsHTMLReflowState& aReflowState)
 {
-    nscoord width = aReflowState.ComputedWidth();
-
-    if (mLastCalcWidth == width)
-        return;
-    mLastCalcWidth = width;
+    nscoord iSize = aReflowState.ComputedISize();
 
-    NS_ASSERTION((mMinWidth == NS_INTRINSIC_WIDTH_UNKNOWN) ==
-                 (mPrefWidth == NS_INTRINSIC_WIDTH_UNKNOWN),
+    if (mLastCalcISize == iSize) {
+        return;
+    }
+    mLastCalcISize = iSize;
+
+    NS_ASSERTION((mMinISize == NS_INTRINSIC_WIDTH_UNKNOWN) ==
+                 (mPrefISize == NS_INTRINSIC_WIDTH_UNKNOWN),
                  "dirtyness out of sync");
-    NS_ASSERTION((mMinWidth == NS_INTRINSIC_WIDTH_UNKNOWN) ==
-                 (mPrefWidthPctExpand == NS_INTRINSIC_WIDTH_UNKNOWN),
+    NS_ASSERTION((mMinISize == NS_INTRINSIC_WIDTH_UNKNOWN) ==
+                 (mPrefISizePctExpand == NS_INTRINSIC_WIDTH_UNKNOWN),
                  "dirtyness out of sync");
     // XXX Is this needed?
-    if (mMinWidth == NS_INTRINSIC_WIDTH_UNKNOWN)
+    if (mMinISize == NS_INTRINSIC_WIDTH_UNKNOWN) {
         ComputeIntrinsicISizes(aReflowState.rendContext);
+    }
 
     nsTableCellMap *cellMap = mTableFrame->GetCellMap();
     int32_t colCount = cellMap->GetColCount();
     if (colCount <= 0)
         return; // nothing to do
 
-    DistributeWidthToColumns(width, 0, colCount, BTLS_FINAL_WIDTH, false);
+    DistributeISizeToColumns(iSize, 0, colCount, BTLS_FINAL_ISIZE, false);
 
 #ifdef DEBUG_TABLE_STRATEGY
     printf("ComputeColumnISizes final\n");
     mTableFrame->Dump(false, true, false);
 #endif
 }
 
 void
-BasicTableLayoutStrategy::DistributePctWidthToColumns(float aSpanPrefPct,
+BasicTableLayoutStrategy::DistributePctISizeToColumns(float aSpanPrefPct,
                                                       int32_t aFirstCol,
                                                       int32_t aColCount)
 {
     // First loop to determine:
-    int32_t nonPctColCount = 0; // number of spanned columns without % width
-    nscoord nonPctTotalPrefWidth = 0; // total pref width of those columns
-    // and to reduce aSpanPrefPct by columns that already have % width
+    int32_t nonPctColCount = 0; // number of spanned columns without % isize
+    nscoord nonPctTotalPrefISize = 0; // total pref isize of those columns
+    // and to reduce aSpanPrefPct by columns that already have % isize
 
     int32_t scol, scol_end;
     nsTableCellMap *cellMap = mTableFrame->GetCellMap();
     for (scol = aFirstCol, scol_end = aFirstCol + aColCount;
          scol < scol_end; ++scol) {
         nsTableColFrame *scolFrame = mTableFrame->GetColFrame(scol);
         if (!scolFrame) {
             NS_ERROR("column frames out of sync with cell map");
             continue;
         }
         float scolPct = scolFrame->GetPrefPercent();
         if (scolPct == 0.0f) {
-            nonPctTotalPrefWidth += scolFrame->GetPrefCoord();
+            nonPctTotalPrefISize += scolFrame->GetPrefCoord();
             if (cellMap->GetNumCellsOriginatingInCol(scol) > 0) {
                 ++nonPctColCount;
             }
         } else {
             aSpanPrefPct -= scolPct;
         }
     }
 
     if (aSpanPrefPct <= 0.0f || nonPctColCount == 0) {
-        // There's no %-width on the colspan left over to distribute,
-        // or there are no columns to which we could distribute %-width
+        // There's no %-isize on the colspan left over to distribute,
+        // or there are no columns to which we could distribute %-isize
         return;
     }
 
     // Second loop, to distribute what remains of aSpanPrefPct
-    // between the non-percent-width spanned columns
-    const bool spanHasNonPctPref = nonPctTotalPrefWidth > 0; // Loop invariant
+    // between the non-percent-isize spanned columns
+    const bool spanHasNonPctPref = nonPctTotalPrefISize > 0; // Loop invariant
     for (scol = aFirstCol, scol_end = aFirstCol + aColCount;
          scol < scol_end; ++scol) {
         nsTableColFrame *scolFrame = mTableFrame->GetColFrame(scol);
         if (!scolFrame) {
             NS_ERROR("column frames out of sync with cell map");
             continue;
         }
 
         if (scolFrame->GetPrefPercent() == 0.0f) {
             NS_ASSERTION((!spanHasNonPctPref ||
-                          nonPctTotalPrefWidth != 0) &&
+                          nonPctTotalPrefISize != 0) &&
                          nonPctColCount != 0,
                          "should not be zero if we haven't allocated "
                          "all pref percent");
 
-            float allocatedPct; // % width to be given to this column
+            float allocatedPct; // % isize to be given to this column
             if (spanHasNonPctPref) {
                 // Group so we're multiplying by 1.0f when we need
                 // to use up aSpanPrefPct.
                 allocatedPct = aSpanPrefPct *
                     (float(scolFrame->GetPrefCoord()) /
-                     float(nonPctTotalPrefWidth));
+                     float(nonPctTotalPrefISize));
             } else if (cellMap->GetNumCellsOriginatingInCol(scol) > 0) {
-                // distribute equally when all pref widths are 0
+                // distribute equally when all pref isizes are 0
                 allocatedPct = aSpanPrefPct / float(nonPctColCount);
             } else {
                 allocatedPct = 0.0f;
             }
             // Allocate the percent
             scolFrame->AddSpanPrefPercent(allocatedPct);
 
             // To avoid accumulating rounding error from division,
             // subtract this column's values from the totals.
             aSpanPrefPct -= allocatedPct;
-            nonPctTotalPrefWidth -= scolFrame->GetPrefCoord();
+            nonPctTotalPrefISize -= scolFrame->GetPrefCoord();
             if (cellMap->GetNumCellsOriginatingInCol(scol) > 0) {
                 --nonPctColCount;
             }
 
             if (!aSpanPrefPct) {
-                // No more span-percent-width to distribute --> we're done.
+                // No more span-percent-isize to distribute --> we're done.
                 NS_ASSERTION(spanHasNonPctPref ? 
-                             nonPctTotalPrefWidth == 0 :
+                             nonPctTotalPrefISize == 0 :
                              nonPctColCount == 0,
-                             "No more pct width to distribute, but there are "
-                             "still cols that need some.");
+                             "No more pct inline-size to distribute, "
+                             "but there are still cols that need some.");
                 return;
             }
         }
     }
 }
 
 void
-BasicTableLayoutStrategy::DistributeWidthToColumns(nscoord aWidth, 
-                                                   int32_t aFirstCol, 
+BasicTableLayoutStrategy::DistributeISizeToColumns(nscoord aISize,
+                                                   int32_t aFirstCol,
                                                    int32_t aColCount,
-                                                   BtlsWidthType aWidthType,
-                                                   bool aSpanHasSpecifiedWidth)
+                                                   BtlsISizeType aISizeType,
+                                                   bool aSpanHasSpecifiedISize)
 {
-    NS_ASSERTION(aWidthType != BTLS_FINAL_WIDTH || 
+    NS_ASSERTION(aISizeType != BTLS_FINAL_ISIZE ||
                  (aFirstCol == 0 && 
                   aColCount == mTableFrame->GetCellMap()->GetColCount()),
-            "Computing final column widths, but didn't get full column range");
-
+            "Computing final column isizes, but didn't get full column range");
 
     nscoord subtract = 0;
-    // aWidth initially includes border-spacing for the boundaries in between
+    // aISize initially includes border-spacing for the boundaries in between
     // each of the columns. We start at aFirstCol + 1 because the first
     // in-between boundary would be at the left edge of column aFirstCol + 1
     for (int32_t col = aFirstCol + 1; col < aFirstCol + aColCount; ++col) {
         if (mTableFrame->ColumnHasCellSpacingBefore(col)) {
             // border-spacing isn't part of the basis for percentages.
             subtract += mTableFrame->GetColSpacing(col - 1);
         }
     }
-    if (aWidthType == BTLS_FINAL_WIDTH) {
-        // If we're computing final col-width, then aWidth initially includes
-        // border spacing on the table's far left + far right edge, too.  Need
+    if (aISizeType == BTLS_FINAL_ISIZE) {
+        // If we're computing final col-isize, then aISize initially includes
+        // border spacing on the table's far istart + far iend edge, too.  Need
         // to subtract those out, too.
         subtract += (mTableFrame->GetColSpacing(-1) +
                      mTableFrame->GetColSpacing(aColCount));
     }
-    aWidth = NSCoordSaturatingSubtract(aWidth, subtract, nscoord_MAX);
+    aISize = NSCoordSaturatingSubtract(aISize, subtract, nscoord_MAX);
 
     /*
-     * The goal of this function is to distribute |aWidth| between the
-     * columns by making an appropriate AddSpanCoords or SetFinalWidth
+     * The goal of this function is to distribute |aISize| between the
+     * columns by making an appropriate AddSpanCoords or SetFinalISize
      * call for each column.  (We call AddSpanCoords if we're 
-     * distributing a column-spanning cell's minimum or preferred width
-     * to its spanned columns.  We call SetFinalWidth if we're 
-     * distributing a table's final width to its columns.)
+     * distributing a column-spanning cell's minimum or preferred isize
+     * to its spanned columns.  We call SetFinalISize if we're 
+     * distributing a table's final isize to its columns.)
      *
-     * The idea is to either assign one of the following sets of widths
-     * or a weighted average of two adjacent sets of widths.  It is not
+     * The idea is to either assign one of the following sets of isizes
+     * or a weighted average of two adjacent sets of isizes.  It is not
      * possible to assign values smaller than the smallest set of
-     * widths.  However, see below for handling the case of assigning
-     * values larger than the largest set of widths.  From smallest to
+     * isizes.  However, see below for handling the case of assigning
+     * values larger than the largest set of isizes.  From smallest to
      * largest, these are:
      *
-     * 1. [guess_min] Assign all columns their min width.
+     * 1. [guess_min] Assign all columns their min isize.
      *
-     * 2. [guess_min_pct] Assign all columns with percentage widths
-     * their percentage width, and all other columns their min width.
+     * 2. [guess_min_pct] Assign all columns with percentage isizes
+     * their percentage isize, and all other columns their min isize.
      *
-     * 3. [guess_min_spec] Assign all columns with percentage widths
-     * their percentage width, all columns with specified coordinate
-     * widths their pref width (since it doesn't matter whether it's the
-     * largest contributor to the pref width that was the specified
-     * contributor), and all other columns their min width.
+     * 3. [guess_min_spec] Assign all columns with percentage isizes
+     * their percentage isize, all columns with specified coordinate
+     * isizes their pref isize (since it doesn't matter whether it's the
+     * largest contributor to the pref isize that was the specified
+     * contributor), and all other columns their min isize.
      *
-     * 4. [guess_pref] Assign all columns with percentage widths their
-     * specified width, and all other columns their pref width.
+     * 4. [guess_pref] Assign all columns with percentage isizes their
+     * specified isize, and all other columns their pref isize.
      *
-     * If |aWidth| is *larger* than what we would assign in (4), then we
+     * If |aISize| is *larger* than what we would assign in (4), then we
      * expand the columns:
      *
-     *   a. if any columns without a specified coordinate width or
-     *   percent width have nonzero pref width, in proportion to pref
-     *   width [total_flex_pref]
+     *   a. if any columns without a specified coordinate isize or
+     *   percent isize have nonzero pref isize, in proportion to pref
+     *   isize [total_flex_pref]
      *
      *   b. otherwise, if any columns without a specified coordinate
-     *   width or percent width, but with cells originating in them,
-     *   have zero pref width, equally between these
-     *   [numNonSpecZeroWidthCols]
+     *   isize or percent isize, but with cells originating in them,
+     *   have zero pref isize, equally between these
+     *   [numNonSpecZeroISizeCols]
      *
-     *   c. otherwise, if any columns without percent width have nonzero
-     *   pref width, in proportion to pref width [total_fixed_pref]
+     *   c. otherwise, if any columns without percent isize have nonzero
+     *   pref isize, in proportion to pref isize [total_fixed_pref]
      *
-     *   d. otherwise, if any columns have nonzero percentage widths, in
-     *   proportion to the percentage widths [total_pct]
+     *   d. otherwise, if any columns have nonzero percentage isizes, in
+     *   proportion to the percentage isizes [total_pct]
      *
      *   e. otherwise, equally.
      */
 
     // Loop #1 over the columns, to figure out the four values above so
     // we know which case we're dealing with.
 
     nscoord guess_min = 0,
             guess_min_pct = 0,
             guess_min_spec = 0,
             guess_pref = 0,
             total_flex_pref = 0,
             total_fixed_pref = 0;
     float total_pct = 0.0f; // 0.0f to 1.0f
-    int32_t numInfiniteWidthCols = 0;
-    int32_t numNonSpecZeroWidthCols = 0;
+    int32_t numInfiniteISizeCols = 0;
+    int32_t numNonSpecZeroISizeCols = 0;
 
     int32_t col;
     nsTableCellMap *cellMap = mTableFrame->GetCellMap();
     for (col = aFirstCol; col < aFirstCol + aColCount; ++col) {
         nsTableColFrame *colFrame = mTableFrame->GetColFrame(col);
         if (!colFrame) {
             NS_ERROR("column frames out of sync with cell map");
             continue;
         }
-        nscoord min_width = colFrame->GetMinCoord();
-        guess_min += min_width;
+        nscoord min_iSize = colFrame->GetMinCoord();
+        guess_min += min_iSize;
         if (colFrame->GetPrefPercent() != 0.0f) {
             float pct = colFrame->GetPrefPercent();
             total_pct += pct;
-            nscoord val = nscoord(float(aWidth) * pct);
-            if (val < min_width)
-                val = min_width;
+            nscoord val = nscoord(float(aISize) * pct);
+            if (val < min_iSize) {
+                val = min_iSize;
+            }
             guess_min_pct += val;
             guess_pref = NSCoordSaturatingAdd(guess_pref, val);
         } else {
-            nscoord pref_width = colFrame->GetPrefCoord();
-            if (pref_width == nscoord_MAX) {
-                ++numInfiniteWidthCols;
+            nscoord pref_iSize = colFrame->GetPrefCoord();
+            if (pref_iSize == nscoord_MAX) {
+                ++numInfiniteISizeCols;
             }
-            guess_pref = NSCoordSaturatingAdd(guess_pref, pref_width);
-            guess_min_pct += min_width;
+            guess_pref = NSCoordSaturatingAdd(guess_pref, pref_iSize);
+            guess_min_pct += min_iSize;
             if (colFrame->GetHasSpecifiedCoord()) {
                 // we'll add on the rest of guess_min_spec outside the
                 // loop
-                nscoord delta = NSCoordSaturatingSubtract(pref_width, 
-                                                          min_width, 0);
+                nscoord delta = NSCoordSaturatingSubtract(pref_iSize, 
+                                                          min_iSize, 0);
                 guess_min_spec = NSCoordSaturatingAdd(guess_min_spec, delta);
                 total_fixed_pref = NSCoordSaturatingAdd(total_fixed_pref, 
-                                                        pref_width);
-            } else if (pref_width == 0) {
+                                                        pref_iSize);
+            } else if (pref_iSize == 0) {
                 if (cellMap->GetNumCellsOriginatingInCol(col) > 0) {
-                    ++numNonSpecZeroWidthCols;
+                    ++numNonSpecZeroISizeCols;
                 }
             } else {
                 total_flex_pref = NSCoordSaturatingAdd(total_flex_pref,
-                                                       pref_width);
+                                                       pref_iSize);
             }
         }
     }
     guess_min_spec = NSCoordSaturatingAdd(guess_min_spec, guess_min_pct);
 
     // Determine what we're flexing:
     enum Loop2Type {
         FLEX_PCT_SMALL, // between (1) and (2) above
@@ -797,265 +807,267 @@ BasicTableLayoutStrategy::DistributeWidt
         FLEX_PCT_LARGE, // greater than (4) above, case (d)
         FLEX_ALL_LARGE // greater than (4) above, case (e)
     };
 
     Loop2Type l2t;
     // These are constants (over columns) for each case's math.  We use
     // a pair of nscoords rather than a float so that we can subtract
     // each column's allocation so we avoid accumulating rounding error.
-    nscoord space; // the amount of extra width to allocate
+    nscoord space; // the amount of extra isize to allocate
     union {
         nscoord c;
         float f;
     } basis; // the sum of the statistic over columns to divide it
-    if (aWidth < guess_pref) {
-        if (aWidthType != BTLS_FINAL_WIDTH && aWidth <= guess_min) {
+    if (aISize < guess_pref) {
+        if (aISizeType != BTLS_FINAL_ISIZE && aISize <= guess_min) {
             // Return early -- we don't have any extra space to distribute.
             return;
         }
-        NS_ASSERTION(!(aWidthType == BTLS_FINAL_WIDTH && aWidth < guess_min),
-                     "Table width is less than the "
-                     "sum of its columns' min widths");
-        if (aWidth < guess_min_pct) {
+        NS_ASSERTION(!(aISizeType == BTLS_FINAL_ISIZE && aISize < guess_min),
+                     "Table inline-size is less than the "
+                     "sum of its columns' min inline-sizes");
+        if (aISize < guess_min_pct) {
             l2t = FLEX_PCT_SMALL;
-            space = aWidth - guess_min;
+            space = aISize - guess_min;
             basis.c = guess_min_pct - guess_min;
-        } else if (aWidth < guess_min_spec) {
+        } else if (aISize < guess_min_spec) {
             l2t = FLEX_FIXED_SMALL;
-            space = aWidth - guess_min_pct;
+            space = aISize - guess_min_pct;
             basis.c = NSCoordSaturatingSubtract(guess_min_spec, guess_min_pct,
                                                 nscoord_MAX);
         } else {
             l2t = FLEX_FLEX_SMALL;
-            space = aWidth - guess_min_spec;
+            space = aISize - guess_min_spec;
             basis.c = NSCoordSaturatingSubtract(guess_pref, guess_min_spec,
                                                 nscoord_MAX);
         }
     } else {
-        space = NSCoordSaturatingSubtract(aWidth, guess_pref, nscoord_MAX);
+        space = NSCoordSaturatingSubtract(aISize, guess_pref, nscoord_MAX);
         if (total_flex_pref > 0) {
             l2t = FLEX_FLEX_LARGE;
             basis.c = total_flex_pref;
-        } else if (numNonSpecZeroWidthCols > 0) {
+        } else if (numNonSpecZeroISizeCols > 0) {
             l2t = FLEX_FLEX_LARGE_ZERO;
-            basis.c = numNonSpecZeroWidthCols;
+            basis.c = numNonSpecZeroISizeCols;
         } else if (total_fixed_pref > 0) {
             l2t = FLEX_FIXED_LARGE;
             basis.c = total_fixed_pref;
         } else if (total_pct > 0.0f) {
             l2t = FLEX_PCT_LARGE;
             basis.f = total_pct;
         } else {
             l2t = FLEX_ALL_LARGE;
             basis.c = aColCount;
         }
     }
 
 #ifdef DEBUG_dbaron_off
-    printf("ComputeColumnISizes: %d columns in width %d,\n"
+    printf("ComputeColumnISizes: %d columns in isize %d,\n"
            "  guesses=[%d,%d,%d,%d], totals=[%d,%d,%f],\n"
            "  l2t=%d, space=%d, basis.c=%d\n",
-           aColCount, aWidth,
+           aColCount, aISize,
            guess_min, guess_min_pct, guess_min_spec, guess_pref,
            total_flex_pref, total_fixed_pref, total_pct,
            l2t, space, basis.c);
 #endif
 
     for (col = aFirstCol; col < aFirstCol + aColCount; ++col) {
         nsTableColFrame *colFrame = mTableFrame->GetColFrame(col);
         if (!colFrame) {
             NS_ERROR("column frames out of sync with cell map");
             continue;
         }
-        nscoord col_width;
+        nscoord col_iSize;
 
         float pct = colFrame->GetPrefPercent();
         if (pct != 0.0f) {
-            col_width = nscoord(float(aWidth) * pct);
+            col_iSize = nscoord(float(aISize) * pct);
             nscoord col_min = colFrame->GetMinCoord();
-            if (col_width < col_min)
-                col_width = col_min;
+            if (col_iSize < col_min) {
+                col_iSize = col_min;
+            }
         } else {
-            col_width = colFrame->GetPrefCoord();
+            col_iSize = colFrame->GetPrefCoord();
         }
 
-        nscoord col_width_before_adjust = col_width;
+        nscoord col_iSize_before_adjust = col_iSize;
 
         switch (l2t) {
             case FLEX_PCT_SMALL:
-                col_width = col_width_before_adjust = colFrame->GetMinCoord();
+                col_iSize = col_iSize_before_adjust = colFrame->GetMinCoord();
                 if (pct != 0.0f) {
                     nscoord pct_minus_min =
-                        nscoord(float(aWidth) * pct) - col_width;
+                        nscoord(float(aISize) * pct) - col_iSize;
                     if (pct_minus_min > 0) {
                         float c = float(space) / float(basis.c);
                         basis.c -= pct_minus_min;
-                        col_width += NSToCoordRound(float(pct_minus_min) * c);
+                        col_iSize += NSToCoordRound(float(pct_minus_min) * c);
                     }
                 }
                 break;
             case FLEX_FIXED_SMALL:
                 if (pct == 0.0f) {
-                    NS_ASSERTION(col_width == colFrame->GetPrefCoord(),
-                                 "wrong width assigned");
+                    NS_ASSERTION(col_iSize == colFrame->GetPrefCoord(),
+                                 "wrong inline-size assigned");
                     if (colFrame->GetHasSpecifiedCoord()) {
                         nscoord col_min = colFrame->GetMinCoord();
-                        nscoord pref_minus_min = col_width - col_min;
-                        col_width = col_width_before_adjust = col_min;
+                        nscoord pref_minus_min = col_iSize - col_min;
+                        col_iSize = col_iSize_before_adjust = col_min;
                         if (pref_minus_min != 0) {
                             float c = float(space) / float(basis.c);
                             basis.c -= pref_minus_min;
-                            col_width += NSToCoordRound(
+                            col_iSize += NSToCoordRound(
                                 float(pref_minus_min) * c);
                         }
                     } else
-                        col_width = col_width_before_adjust =
+                        col_iSize = col_iSize_before_adjust =
                             colFrame->GetMinCoord();
                 }
                 break;
             case FLEX_FLEX_SMALL:
                 if (pct == 0.0f &&
                     !colFrame->GetHasSpecifiedCoord()) {
-                    NS_ASSERTION(col_width == colFrame->GetPrefCoord(),
-                                 "wrong width assigned");
+                    NS_ASSERTION(col_iSize == colFrame->GetPrefCoord(),
+                                 "wrong inline-size assigned");
                     nscoord col_min = colFrame->GetMinCoord();
                     nscoord pref_minus_min = 
-                        NSCoordSaturatingSubtract(col_width, col_min, 0);
-                    col_width = col_width_before_adjust = col_min;
+                        NSCoordSaturatingSubtract(col_iSize, col_min, 0);
+                    col_iSize = col_iSize_before_adjust = col_min;
                     if (pref_minus_min != 0) {
                         float c = float(space) / float(basis.c);
-                        // If we have infinite-width cols, then the standard
-                        // adjustment to col_width using 'c' won't work,
+                        // If we have infinite-isize cols, then the standard
+                        // adjustment to col_iSize using 'c' won't work,
                         // because basis.c and pref_minus_min are both
                         // nscoord_MAX and will cancel each other out in the
-                        // col_width adjustment (making us assign all the
-                        // space to the first inf-width col).  To correct for
-                        // this, we'll also divide by numInfiniteWidthCols to
-                        // spread the space equally among the inf-width cols.
-                        if (numInfiniteWidthCols) {
+                        // col_iSize adjustment (making us assign all the
+                        // space to the first inf-isize col).  To correct for
+                        // this, we'll also divide by numInfiniteISizeCols to
+                        // spread the space equally among the inf-isize cols.
+                        if (numInfiniteISizeCols) {
                             if (colFrame->GetPrefCoord() == nscoord_MAX) {
-                                c = c / float(numInfiniteWidthCols);
-                                --numInfiniteWidthCols;
+                                c = c / float(numInfiniteISizeCols);
+                                --numInfiniteISizeCols;
                             } else {
                                 c = 0.0f;
                             }
                         }
                         basis.c = NSCoordSaturatingSubtract(basis.c, 
                                                             pref_minus_min,
                                                             nscoord_MAX);
-                        col_width += NSToCoordRound(
+                        col_iSize += NSToCoordRound(
                             float(pref_minus_min) * c);
                     }
                 }
                 break;
             case FLEX_FLEX_LARGE:
                 if (pct == 0.0f &&
                     !colFrame->GetHasSpecifiedCoord()) {
-                    NS_ASSERTION(col_width == colFrame->GetPrefCoord(),
-                                 "wrong width assigned");
-                    if (col_width != 0) {
+                    NS_ASSERTION(col_iSize == colFrame->GetPrefCoord(),
+                                 "wrong inline-size assigned");
+                    if (col_iSize != 0) {
                         if (space == nscoord_MAX) {
-                            basis.c -= col_width;
-                            col_width = nscoord_MAX;
+                            basis.c -= col_iSize;
+                            col_iSize = nscoord_MAX;
                         } else {
                             float c = float(space) / float(basis.c);
-                            basis.c -= col_width;
-                            col_width += NSToCoordRound(float(col_width) * c);
+                            basis.c -= col_iSize;
+                            col_iSize += NSToCoordRound(float(col_iSize) * c);
                         }
                     }
                 }
                 break;
             case FLEX_FLEX_LARGE_ZERO:
                 if (pct == 0.0f &&
                     !colFrame->GetHasSpecifiedCoord() &&
                     cellMap->GetNumCellsOriginatingInCol(col) > 0) {
 
-                    NS_ASSERTION(col_width == 0 &&
+                    NS_ASSERTION(col_iSize == 0 &&
                                  colFrame->GetPrefCoord() == 0,
                                  "Since we're in FLEX_FLEX_LARGE_ZERO case, "
-                                 "all auto-width cols should have zero pref "
-                                 "width.");
+                                 "all auto-inline-size cols should have zero "
+                                 "pref inline-size.");
                     float c = float(space) / float(basis.c);
-                    col_width += NSToCoordRound(c);
+                    col_iSize += NSToCoordRound(c);
                     --basis.c;
                 }
                 break;
             case FLEX_FIXED_LARGE:
                 if (pct == 0.0f) {
-                    NS_ASSERTION(col_width == colFrame->GetPrefCoord(),
-                                 "wrong width assigned");
+                    NS_ASSERTION(col_iSize == colFrame->GetPrefCoord(),
+                                 "wrong inline-size assigned");
                     NS_ASSERTION(colFrame->GetHasSpecifiedCoord() ||
                                  colFrame->GetPrefCoord() == 0,
                                  "wrong case");
-                    if (col_width != 0) {
+                    if (col_iSize != 0) {
                         float c = float(space) / float(basis.c);
-                        basis.c -= col_width;
-                        col_width += NSToCoordRound(float(col_width) * c);
+                        basis.c -= col_iSize;
+                        col_iSize += NSToCoordRound(float(col_iSize) * c);
                     }
                 }
                 break;
             case FLEX_PCT_LARGE:
                 NS_ASSERTION(pct != 0.0f || colFrame->GetPrefCoord() == 0,
                              "wrong case");
                 if (pct != 0.0f) {
                     float c = float(space) / basis.f;
-                    col_width += NSToCoordRound(pct * c);
+                    col_iSize += NSToCoordRound(pct * c);
                     basis.f -= pct;
                 }
                 break;
             case FLEX_ALL_LARGE:
                 {
                     float c = float(space) / float(basis.c);
-                    col_width += NSToCoordRound(c);
+                    col_iSize += NSToCoordRound(c);
                     --basis.c;
                 }
                 break;
         }
 
         // Only subtract from space if it's a real number.
         if (space != nscoord_MAX) {
-            NS_ASSERTION(col_width != nscoord_MAX,
-                 "How is col_width nscoord_MAX if space isn't?");
-            NS_ASSERTION(col_width_before_adjust != nscoord_MAX,
-                 "How is col_width_before_adjust nscoord_MAX if space isn't?");
-            space -= col_width - col_width_before_adjust;
+            NS_ASSERTION(col_iSize != nscoord_MAX,
+                 "How is col_iSize nscoord_MAX if space isn't?");
+            NS_ASSERTION(col_iSize_before_adjust != nscoord_MAX,
+                 "How is col_iSize_before_adjust nscoord_MAX if space isn't?");
+            space -= col_iSize - col_iSize_before_adjust;
         }
 
-        NS_ASSERTION(col_width >= colFrame->GetMinCoord(),
-                     "assigned width smaller than min");
+        NS_ASSERTION(col_iSize >= colFrame->GetMinCoord(),
+                     "assigned inline-size smaller than min");
         
-        // Apply the new width
-        switch (aWidthType) {
-            case BTLS_MIN_WIDTH:
+        // Apply the new isize
+        switch (aISizeType) {
+            case BTLS_MIN_ISIZE:
                 {
-                    // Note: AddSpanCoords requires both a min and pref width.
-                    // For the pref width, we'll just pass in our computed
-                    // min width, because the real pref width will be at least
+                    // Note: AddSpanCoords requires both a min and pref isize.
+                    // For the pref isize, we'll just pass in our computed
+                    // min isize, because the real pref isize will be at least
                     // as big
-                    colFrame->AddSpanCoords(col_width, col_width, 
-                                            aSpanHasSpecifiedWidth);
+                    colFrame->AddSpanCoords(col_iSize, col_iSize, 
+                                            aSpanHasSpecifiedISize);
                 }
                 break;
-            case BTLS_PREF_WIDTH:
+            case BTLS_PREF_ISIZE:
                 {
-                    // Note: AddSpanCoords requires both a min and pref width.
-                    // For the min width, we'll just pass in 0, because
-                    // the real min width will be at least 0
-                    colFrame->AddSpanCoords(0, col_width, 
-                                            aSpanHasSpecifiedWidth);
+                    // Note: AddSpanCoords requires both a min and pref isize.
+                    // For the min isize, we'll just pass in 0, because
+                    // the real min isize will be at least 0
+                    colFrame->AddSpanCoords(0, col_iSize, 
+                                            aSpanHasSpecifiedISize);
                 }
                 break;
-            case BTLS_FINAL_WIDTH:
+            case BTLS_FINAL_ISIZE:
                 {
                     nscoord old_final = colFrame->GetFinalISize();
-                    colFrame->SetFinalISize(col_width);
+                    colFrame->SetFinalISize(col_iSize);
                     
-                    if (old_final != col_width)
+                    if (old_final != col_iSize) {
                         mTableFrame->DidResizeColumns();
+                    }
                 }
                 break;                
         }
     }
     NS_ASSERTION((space == 0 || space == nscoord_MAX) &&
                  ((l2t == FLEX_PCT_LARGE)
                     ? (-0.001f < basis.f && basis.f < 0.001f)
                     : (basis.c == 0 || basis.c == nscoord_MAX)),
--- a/layout/tables/BasicTableLayoutStrategy.h
+++ b/layout/tables/BasicTableLayoutStrategy.h
@@ -28,54 +28,54 @@ public:
     virtual nscoord GetPrefISize(nsRenderingContext* aRenderingContext,
                                  bool aComputingSize) override;
     virtual void MarkIntrinsicISizesDirty() override;
     virtual void ComputeColumnISizes(const nsHTMLReflowState& aReflowState) override;
 
 private:
     // NOTE: Using prefix "BTLS" to avoid overlapping names with
     // the values of nsLayoutUtils::IntrinsicISizeType
-    enum BtlsWidthType { BTLS_MIN_WIDTH,
-                         BTLS_PREF_WIDTH,
-                         BTLS_FINAL_WIDTH };
+    enum BtlsISizeType { BTLS_MIN_ISIZE,
+                         BTLS_PREF_ISIZE,
+                         BTLS_FINAL_ISIZE };
 
-    // Compute intrinsic width member variables on the columns.
+    // Compute intrinsic isize member variables on the columns.
     void ComputeColumnIntrinsicISizes(nsRenderingContext* aRenderingContext);
 
-    // Distribute a colspanning cell's percent width (if any) to its columns.
-    void DistributePctWidthToColumns(float aSpanPrefPct,
+    // Distribute a colspanning cell's percent isize (if any) to its columns.
+    void DistributePctISizeToColumns(float aSpanPrefPct,
                                      int32_t aFirstCol,
                                      int32_t aColCount);
 
-    // Distribute a width of some BltsWidthType type to a set of columns.
-    //  aWidth: The amount of width to be distributed
+    // Distribute an isize of some BltsISizeType type to a set of columns.
+    //  aISize: The amount of isize to be distributed
     //  aFirstCol: The index (in the table) of the first column to be
-    //             considered for receiving width
+    //             considered for receiving isize
     //  aColCount: The number of consecutive columns (starting with aFirstCol)
-    //             to be considered for receiving width
-    //  aWidthType: The type of width being distributed.  (BTLS_MIN_WIDTH and
-    //              BTLS_PREF_WIDTH are intended to be used for dividing up
-    //              colspan's min & pref width.  BTLS_FINAL_WIDTH is intended
-    //              to be used for distributing the table's final width across
+    //             to be considered for receiving isize
+    //  aISizeType: The type of isize being distributed.  (BTLS_MIN_ISIZE and
+    //              BTLS_PREF_ISIZE are intended to be used for dividing up
+    //              colspan's min & pref isize.  BTLS_FINAL_ISIZE is intended
+    //              to be used for distributing the table's final isize across
     //              all its columns)
-    //  aSpanHasSpecifiedWidth: Should be true iff:
+    //  aSpanHasSpecifiedISize: Should be true iff:
     //                           - We're distributing a colspanning cell's
-    //                             pref or min width to its columns
-    //                           - The colspanning cell has a specified width.
-    void DistributeWidthToColumns(nscoord aWidth,
+    //                             pref or min isize to its columns
+    //                           - The colspanning cell has a specified isize.
+    void DistributeISizeToColumns(nscoord aISize,
                                   int32_t aFirstCol,
                                   int32_t aColCount,
-                                  BtlsWidthType aWidthType,
-                                  bool aSpanHasSpecifiedWidth);
+                                  BtlsISizeType aISizeType,
+                                  bool aSpanHasSpecifiedISize);
 
 
-    // Compute the min and pref widths of the table from the width
+    // Compute the min and pref isizes of the table from the isize
     // variables on the columns.
     void ComputeIntrinsicISizes(nsRenderingContext* aRenderingContext);
 
     nsTableFrame *mTableFrame;
-    nscoord mMinWidth;
-    nscoord mPrefWidth;
-    nscoord mPrefWidthPctExpand;
-    nscoord mLastCalcWidth;
+    nscoord mMinISize;
+    nscoord mPrefISize;
+    nscoord mPrefISizePctExpand;
+    nscoord mLastCalcISize;
 };
 
 #endif /* !defined(BasicTableLayoutStrategy_h_) */
--- a/layout/tables/FixedTableLayoutStrategy.cpp
+++ b/layout/tables/FixedTableLayoutStrategy.cpp
@@ -243,17 +243,17 @@ FixedTableLayoutStrategy::ComputeColumnI
                     // with GetMinISize above, just in case there is a
                     // difference.
                     colWidth = nsLayoutUtils::IntrinsicForContainer(
                                  aReflowState.rendContext,
                                  cellFrame, nsLayoutUtils::MIN_ISIZE);
                 } else if (styleWidth->GetUnit() == eStyleUnit_Percent) {
                     // XXX This should use real percentage padding
                     nsIFrame::IntrinsicISizeOffsetData offsets =
-                        cellFrame->IntrinsicISizeOffsets(aReflowState.rendContext);
+                        cellFrame->IntrinsicISizeOffsets();
                     float pct = styleWidth->GetPercentValue();
                     colWidth = NSToCoordFloor(pct * float(tableWidth));
 
                     nscoord boxSizingAdjust = 0;
                     switch (cellFrame->StylePosition()->mBoxSizing) {
                       case NS_STYLE_BOX_SIZING_CONTENT:
                         boxSizingAdjust += offsets.hPadding;
                         // Fall through
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -783,20 +783,19 @@ nsTableCellFrame::GetPrefISize(nsRenderi
 
   nsIFrame *inner = mFrames.FirstChild();
   result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner,
                                                 nsLayoutUtils::PREF_ISIZE);
   return result;
 }
 
 /* virtual */ nsIFrame::IntrinsicISizeOffsetData
-nsTableCellFrame::IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext)
+nsTableCellFrame::IntrinsicISizeOffsets()
 {
-  IntrinsicISizeOffsetData result =
-    nsContainerFrame::IntrinsicISizeOffsets(aRenderingContext);
+  IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets();
 
   result.hMargin = 0;
   result.hPctMargin = 0;
 
   WritingMode wm = GetWritingMode();
   result.hBorder = GetBorderWidth(wm).IStartEnd(wm);
 
   return result;
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -112,18 +112,17 @@ public:
 
  
   virtual nsresult ProcessBorders(nsTableFrame* aFrame,
                                   nsDisplayListBuilder* aBuilder,
                                   const nsDisplayListSet& aLists);
 
   virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
   virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
-  virtual IntrinsicISizeOffsetData
-    IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext) override;
+  virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override;
 
   virtual void Reflow(nsPresContext*      aPresContext,
                       nsHTMLReflowMetrics& aDesiredSize,
                       const nsHTMLReflowState& aReflowState,
                       nsReflowStatus&      aStatus) override;
 
   /**
    * Get the "type" of the frame
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1537,20 +1537,19 @@ nsTableFrame::GetPrefISize(nsRenderingCo
     CalcBCBorders();
 
   ReflowColGroups(aRenderingContext);
 
   return LayoutStrategy()->GetPrefISize(aRenderingContext, false);
 }
 
 /* virtual */ nsIFrame::IntrinsicISizeOffsetData
-nsTableFrame::IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext)
-{
-  IntrinsicISizeOffsetData result =
-    nsContainerFrame::IntrinsicISizeOffsets(aRenderingContext);
+nsTableFrame::IntrinsicISizeOffsets()
+{
+  IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets();
 
   result.hMargin = 0;
   result.hPctMargin = 0;
 
   if (IsBorderCollapse()) {
     result.hPadding = 0;
     result.hPctPadding = 0;
 
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -314,18 +314,17 @@ public:
   void PaintBCBorders(nsRenderingContext& aRenderingContext,
                       const nsRect&        aDirtyRect);
 
   virtual void MarkIntrinsicISizesDirty() override;
   // For border-collapse tables, the caller must not add padding and
   // border to the results of these functions.
   virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
   virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
-  virtual IntrinsicISizeOffsetData
-    IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext) override;
+  virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override;
 
   virtual mozilla::LogicalSize
   ComputeSize(nsRenderingContext *aRenderingContext,
               mozilla::WritingMode aWritingMode,
               const mozilla::LogicalSize& aCBSize,
               nscoord aAvailableISize,
               const mozilla::LogicalSize& aMargin,
               const mozilla::LogicalSize& aBorder,
--- a/media/mtransport/build/moz.build
+++ b/media/mtransport/build/moz.build
@@ -7,17 +7,16 @@
 EXPORTS.mtransport += [
     '../dtlsidentity.h',
     '../m_cpp_utils.h',
     '../nricectx.h',
     '../nricemediastream.h',
     '../nriceresolverfake.h',
     '../rlogringbuffer.h',
     '../runnable_utils.h',
-    '../runnable_utils_generated.h',
     '../sigslot.h',
     '../simpletokenbucket.h',
     '../stun_udp_socket_filter.h',
     '../transportflow.h',
     '../transportlayer.h',
     '../transportlayerdtls.h',
     '../transportlayerice.h',
     '../transportlayerlog.h',
--- a/media/mtransport/gonk_addrs.cpp
+++ b/media/mtransport/gonk_addrs.cpp
@@ -124,17 +124,17 @@ nr_stun_get_addrs(nr_local_addr aAddrs[]
   nsresult rv;
   int r;
 
   // Get network interface list.
   std::vector<NetworkInterface> interfaces;
   nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
   mozilla::SyncRunnable::DispatchToThread(
     mainThread.get(),
-    mozilla::WrapRunnableNMRet(&GetInterfaces, &interfaces, &rv),
+    mozilla::WrapRunnableNMRet(&rv, &GetInterfaces, &interfaces),
     false);
   if (NS_FAILED(rv)) {
     return R_FAILED;
   }
 
   // Translate to nr_transport_addr.
   int32_t n = 0;
   size_t num_interface = std::min(interfaces.size(), (size_t)aMaxAddrs);
--- a/media/mtransport/runnable_utils.h
+++ b/media/mtransport/runnable_utils.h
@@ -5,17 +5,19 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Original author: ekr@rtfm.com
 
 #ifndef runnable_utils_h__
 #define runnable_utils_h__
 
 #include "nsThreadUtils.h"
+#include "mozilla/IndexSequence.h"
 #include "mozilla/RefPtr.h"
+#include "mozilla/Tuple.h"
 
 // Abstract base class for all of our templates
 namespace mozilla {
 
 namespace detail {
 
 enum RunnableResult {
   NoResult,
@@ -48,34 +50,169 @@ RunOnThreadInternal(nsIEventTarget *thre
 }
 
 template<RunnableResult result>
 class runnable_args_base : public nsRunnable {
  public:
   NS_IMETHOD Run() = 0;
 };
 
+
+template<typename R>
+struct RunnableFunctionCallHelper
+{
+  template<typename FunType, typename... Args, size_t... Indices>
+  static R apply(FunType func, Tuple<Args...>& args, IndexSequence<Indices...>)
+  {
+    return func(Get<Indices>(args)...);
+  }
+};
+
+// A void specialization is needed in the case where the template instantiator
+// knows we don't want to return a value, but we don't know whether the called
+// function returns void or something else.
+template<>
+struct RunnableFunctionCallHelper<void>
+{
+  template<typename FunType, typename... Args, size_t... Indices>
+  static void apply(FunType func, Tuple<Args...>& args, IndexSequence<Indices...>)
+  {
+    func(Get<Indices>(args)...);
+  }
+};
+
+template<typename R>
+struct RunnableMethodCallHelper
+{
+  template<typename Class, typename M, typename... Args, size_t... Indices>
+  static R apply(Class obj, M method, Tuple<Args...>& args, IndexSequence<Indices...>)
+  {
+    return ((*obj).*method)(Get<Indices>(args)...);
+  }
+};
+
+// A void specialization is needed in the case where the template instantiator
+// knows we don't want to return a value, but we don't know whether the called
+// method returns void or something else.
+template<>
+struct RunnableMethodCallHelper<void>
+{
+  template<typename Class, typename M, typename... Args, size_t... Indices>
+  static void apply(Class obj, M method, Tuple<Args...>& args, IndexSequence<Indices...>)
+  {
+    ((*obj).*method)(Get<Indices>(args)...);
+  }
+};
+
+}
+
+template<typename FunType, typename... Args>
+class runnable_args_func : public detail::runnable_args_base<detail::NoResult>
+{
+public:
+  // |explicit| to pacify static analysis when there are no |args|.
+  explicit runnable_args_func(FunType f, Args... args)
+    : mFunc(f), mArgs(args...)
+  {}
+
+  NS_IMETHOD Run() {
+    detail::RunnableFunctionCallHelper<void>::apply(mFunc, mArgs, typename IndexSequenceFor<Args...>::Type());
+    return NS_OK;
+  }
+
+private:
+  FunType mFunc;
+  Tuple<Args...> mArgs;
+};
+
+template<typename FunType, typename... Args>
+runnable_args_func<FunType, Args...>*
+WrapRunnableNM(FunType f, Args... args)
+{
+  return new runnable_args_func<FunType, Args...>(f, args...);
 }
 
-// The generated file contains four major function templates
-// (in variants for arbitrary numbers of arguments up to 10,
-// which is why it is machine generated). The four templates
-// are:
-//
-// WrapRunnable(o, m, ...) -- wraps a member function m of an object ptr o
-// WrapRunnableRet(o, m, ..., r) -- wraps a member function m of an object ptr o
-//                                  the function returns something that can
-//                                  be assigned to *r
-// WrapRunnableNM(f, ...) -- wraps a function f
-// WrapRunnableNMRet(f, ..., r) -- wraps a function f that returns something
-//                                 that can be assigned to *r
-//
-// All of these template functions return a Runnable* which can be passed
-// to Dispatch().
-#include "runnable_utils_generated.h"
+template<typename Ret, typename FunType, typename... Args>
+class runnable_args_func_ret : public detail::runnable_args_base<detail::ReturnsResult>
+{
+public:
+  runnable_args_func_ret(Ret* ret, FunType f, Args... args)
+    : mReturn(ret), mFunc(f), mArgs(args...)
+  {}
+
+  NS_IMETHOD Run() {
+    *mReturn = detail::RunnableFunctionCallHelper<Ret>::apply(mFunc, mArgs, typename IndexSequenceFor<Args...>::Type());
+    return NS_OK;
+  }
+
+private:
+  Ret* mReturn;
+  FunType mFunc;
+  Tuple<Args...> mArgs;
+};
+
+template<typename R, typename FunType, typename... Args>
+runnable_args_func_ret<R, FunType, Args...>*
+WrapRunnableNMRet(R* ret, FunType f, Args... args)
+{
+  return new runnable_args_func_ret<R, FunType, Args...>(ret, f, args...);
+}
+
+template<typename Class, typename M, typename... Args>
+class runnable_args_memfn : public detail::runnable_args_base<detail::NoResult>
+{
+public:
+  runnable_args_memfn(Class obj, M method, Args... args)
+    : mObj(obj), mMethod(method), mArgs(args...)
+  {}
+
+  NS_IMETHOD Run() {
+    detail::RunnableMethodCallHelper<void>::apply(mObj, mMethod, mArgs, typename IndexSequenceFor<Args...>::Type());
+    return NS_OK;
+  }
+
+private:
+  Class mObj;
+  M mMethod;
+  Tuple<Args...> mArgs;
+};
+
+template<typename Class, typename M, typename... Args>
+runnable_args_memfn<Class, M, Args...>*
+WrapRunnable(Class obj, M method, Args... args)
+{
+  return new runnable_args_memfn<Class, M, Args...>(obj, method, args...);
+}
+
+template<typename Ret, typename Class, typename M, typename... Args>
+class runnable_args_memfn_ret : public detail::runnable_args_base<detail::ReturnsResult>
+{
+public:
+  runnable_args_memfn_ret(Ret* ret, Class obj, M method, Args... args)
+    : mReturn(ret), mObj(obj), mMethod(method), mArgs(args...)
+  {}
+
+  NS_IMETHOD Run() {
+    *mReturn = detail::RunnableMethodCallHelper<Ret>::apply(mObj, mMethod, mArgs, typename IndexSequenceFor<Args...>::Type());
+    return NS_OK;
+  }
+
+private:
+  Ret* mReturn;
+  Class mObj;
+  M mMethod;
+  Tuple<Args...> mArgs;
+};
+
+template<typename R, typename Class, typename M, typename... Args>
+runnable_args_memfn_ret<R, Class, M, Args...>*
+WrapRunnableRet(R* ret, Class obj, M method, Args... args)
+{
+  return new runnable_args_memfn_ret<R, Class, M, Args...>(ret, obj, method, args...);
+}
 
 static inline nsresult RUN_ON_THREAD(nsIEventTarget *thread, detail::runnable_args_base<detail::NoResult> *runnable, uint32_t flags) {
   return detail::RunOnThreadInternal(thread, static_cast<nsIRunnable *>(runnable), flags);
 }
 
 static inline nsresult
 RUN_ON_THREAD(nsIEventTarget *thread, detail::runnable_args_base<detail::ReturnsResult> *runnable)
 {
deleted file mode 100644
--- a/media/mtransport/runnable_utils.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MAX_ARGS = 15
-
-boilerplate = "/* This Source Code Form is subject to the terms of the Mozilla Public\n\
- * License, v. 2.0. If a copy of the MPL was not distributed with this\n\
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n"
-
-def get_args_count(args, member):
-    if member:
-        return args + 2
-    return args + 1
-
-def gen_args_type(args, member):
-    if member:
-        ret = ["C o"]
-    else:
-        ret = []
-    ret.append("M m")
-    for arg in range(0, args):
-        ret.append("A%d a%d"%(arg, arg))
-    return ", ".join(ret)
-
-def gen_args(args, member):
-    if member:
-        ret = ["o"]
-    else:
-        ret = []
-    ret.append("m")
-    for arg in range(0, args):
-        ret.append("a%d"%(arg))
-    return ", ".join(ret)
-
-def gen_args_(args):
-    ret = []
-    for arg in range(0, args):
-        ret.append("a%d_"%(arg))
-    return ", ".join(ret)
-
-def gen_init(args, r = False, member = False):
-    if member:
-        ret = ["o_(o)"]
-    else:
-        ret = []
-    ret.append("m_(m)")
-
-    if r:
-        ret.append("r_(r)")
-
-    for arg in range(0, args):
-        ret.append("a%d_(a%d)"%(arg, arg))
-    return ", ".join(ret)
-
-def gen_typenames(args, member):
-    if member:
-        ret = ["typename C"]
-    else:
-        ret = []
-    ret.append("typename M")
-
-    for arg in range(0, args):
-        ret.append("typename A%d"%(arg))
-    return ", ".join(ret)
-
-def gen_types(args, member):
-    if member:
-        ret = ["C"]
-    else:
-        ret = []
-    ret.append("M")
-    for arg in range(0, args):
-        ret.append("A%d"%(arg))
-    return ", ".join(ret)
-
-
-def runnable_class_name(args, ret=False, member=True):
-    if member:
-        nm = "m"
-    else:
-        nm = "nm"
-
-    if ret:
-        class_suffix = "_ret"
-        enum_specializer = "detail::ReturnsResult"
-    else:
-        class_suffix = ""
-        enum_specializer = "detail::NoResult"
-
-    return "runnable_args_%s_%d%s" % (nm, args, class_suffix), enum_specializer
-
-def generate_class_template(args, ret = False, member = True):
-    print "// %d arguments --"%args
-
-    class_name, specializer = runnable_class_name(args, ret, member)
-    base_class = "detail::runnable_args_base<%s>" % specializer
-
-    if not ret:
-        print "template<"+ gen_typenames(args, member) + "> class %s : public %s {" % (class_name, base_class)
-    else:
-        print "template<"+ gen_typenames(args, member) + ", typename R> class %s : public %s {" % (class_name, base_class)
-
-    print " public:"
-
-    if not ret:
-        explicit = ""
-        if get_args_count(args, member) == 1:
-            explicit = "explicit "
-        print "  %s%s(" % (explicit, class_name) + gen_args_type(args, member) + ") :"
-        print "    " + gen_init(args, False, member) + "  {}"
-    else:
-        print "  %s(" % class_name + gen_args_type(args, member) + ", R *r) :"
-        print "    " + gen_init(args, True, member) + "  {}"
-    print
-    print "  NS_IMETHOD Run() {"
-    if ret:
-        print "    *r_ =",
-    else:
-        print "   ",
-    if member:
-        print "((*o_).*m_)(" + gen_args_(args) + ");"
-    else:
-        print "m_(" + gen_args_(args) + ");"
-
-    print "    return NS_OK;"
-    print "  }"
-    print
-    print " private:"
-    if member:
-        print "  C o_;"
-    print "  M m_;"
-    if ret:
-        print "  R* r_;"
-    for arg in range(0, args):
-        print "  A%d a%d_;"%(arg, arg)
-    print "};"
-    print
-    print
-    print
-
-def generate_function_template(args, member):
-    if member:
-        NM = "";
-    else:
-        NM = "NM";
-
-    class_name, _ = runnable_class_name(args, False, member)
-
-    print "// %d arguments --"%args
-    print "template<" + gen_typenames(args, member) + ">"
-    print "%s<" % class_name + gen_types(args, member) + ">* WrapRunnable%s("%NM + gen_args_type(args, member) + ") {"
-    print "  return new %s<" % class_name + gen_types(args, member) + ">"
-    print "    (" + gen_args(args, member) + ");"
-    print "}"
-    print
-
-def generate_function_template_ret(args, member):
-    if member:
-        NM = "";
-    else:
-        NM = "NM";
-
-    class_name, _ = runnable_class_name(args, True, member)
-
-    print "// %d arguments --"%args
-    print "template<" + gen_typenames(args, member) + ", typename R>"
-    print "%s<" % class_name + gen_types(args, member) + ", R>* WrapRunnable%sRet("%NM + gen_args_type(args, member) + ", R* r) {"
-    print "  return new %s<" % class_name + gen_types(args, member) + ", R>"
-    print "    (" + gen_args(args, member) + ", r);"
-    print "}"
-    print
-
-
-print boilerplate
-print
-
-for num_args in range (0, MAX_ARGS):
-    generate_class_template(num_args, False, False)
-    generate_class_template(num_args, True, False)
-    generate_class_template(num_args, False, True)
-    generate_class_template(num_args, True, True)
-
-
-print
-print
-print
-
-for num_args in range(0, MAX_ARGS):
-    generate_function_template(num_args, False)
-    generate_function_template_ret(num_args, False)
-    generate_function_template(num_args, True)
-    generate_function_template_ret(num_args, True)
-
-
-
deleted file mode 100644
--- a/media/mtransport/runnable_utils_generated.h
+++ /dev/null
@@ -1,1928 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-// 0 arguments --
-template<typename M> class runnable_args_nm_0 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  explicit runnable_args_nm_0(M m) :
-    m_(m)  {}
-
-  NS_IMETHOD Run() {
-    m_();
-    return NS_OK;
-  }
-
- private:
-  M m_;
-};
-
-
-
-// 0 arguments --
-template<typename M, typename R> class runnable_args_nm_0_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_0_ret(M m, R *r) :
-    m_(m), r_(r)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_();
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-};
-
-
-
-// 0 arguments --
-template<typename C, typename M> class runnable_args_m_0 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_0(C o, M m) :
-    o_(o), m_(m)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)();
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-};
-
-
-
-// 0 arguments --
-template<typename C, typename M, typename R> class runnable_args_m_0_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_0_ret(C o, M m, R *r) :
-    o_(o), m_(m), r_(r)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)();
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-};
-
-
-
-// 1 arguments --
-template<typename M, typename A0> class runnable_args_nm_1 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_1(M m, A0 a0) :
-    m_(m), a0_(a0)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-};
-
-
-
-// 1 arguments --
-template<typename M, typename A0, typename R> class runnable_args_nm_1_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_1_ret(M m, A0 a0, R *r) :
-    m_(m), r_(r), a0_(a0)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-};
-
-
-
-// 1 arguments --
-template<typename C, typename M, typename A0> class runnable_args_m_1 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_1(C o, M m, A0 a0) :
-    o_(o), m_(m), a0_(a0)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-};
-
-
-
-// 1 arguments --
-template<typename C, typename M, typename A0, typename R> class runnable_args_m_1_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_1_ret(C o, M m, A0 a0, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-};
-
-
-
-// 2 arguments --
-template<typename M, typename A0, typename A1> class runnable_args_nm_2 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_2(M m, A0 a0, A1 a1) :
-    m_(m), a0_(a0), a1_(a1)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-};
-
-
-
-// 2 arguments --
-template<typename M, typename A0, typename A1, typename R> class runnable_args_nm_2_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_2_ret(M m, A0 a0, A1 a1, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-};
-
-
-
-// 2 arguments --
-template<typename C, typename M, typename A0, typename A1> class runnable_args_m_2 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_2(C o, M m, A0 a0, A1 a1) :
-    o_(o), m_(m), a0_(a0), a1_(a1)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-};
-
-
-
-// 2 arguments --
-template<typename C, typename M, typename A0, typename A1, typename R> class runnable_args_m_2_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_2_ret(C o, M m, A0 a0, A1 a1, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-};
-
-
-
-// 3 arguments --
-template<typename M, typename A0, typename A1, typename A2> class runnable_args_nm_3 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_3(M m, A0 a0, A1 a1, A2 a2) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-};
-
-
-
-// 3 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename R> class runnable_args_nm_3_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_3_ret(M m, A0 a0, A1 a1, A2 a2, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-};
-
-
-
-// 3 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2> class runnable_args_m_3 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_3(C o, M m, A0 a0, A1 a1, A2 a2) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-};
-
-
-
-// 3 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename R> class runnable_args_m_3_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_3_ret(C o, M m, A0 a0, A1 a1, A2 a2, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-};
-
-
-
-// 4 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3> class runnable_args_nm_4 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_4(M m, A0 a0, A1 a1, A2 a2, A3 a3) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-};
-
-
-
-// 4 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename R> class runnable_args_nm_4_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_4_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-};
-
-
-
-// 4 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3> class runnable_args_m_4 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_4(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-};
-
-
-
-// 4 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename R> class runnable_args_m_4_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_4_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-};
-
-
-
-// 5 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4> class runnable_args_nm_5 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_5(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-};
-
-
-
-// 5 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename R> class runnable_args_nm_5_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_5_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-};
-
-
-
-// 5 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4> class runnable_args_m_5 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_5(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-};
-
-
-
-// 5 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename R> class runnable_args_m_5_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_5_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-};
-
-
-
-// 6 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> class runnable_args_nm_6 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_6(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_, a5_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-};
-
-
-
-// 6 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename R> class runnable_args_nm_6_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_6_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-};
-
-
-
-// 6 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> class runnable_args_m_6 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_6(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-};
-
-
-
-// 6 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename R> class runnable_args_m_6_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_6_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-};
-
-
-
-// 7 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> class runnable_args_nm_7 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_7(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-};
-
-
-
-// 7 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename R> class runnable_args_nm_7_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_7_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-};
-
-
-
-// 7 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> class runnable_args_m_7 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_7(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-};
-
-
-
-// 7 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename R> class runnable_args_m_7_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_7_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-};
-
-
-
-// 8 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> class runnable_args_nm_8 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_8(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-};
-
-
-
-// 8 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename R> class runnable_args_nm_8_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_8_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-};
-
-
-
-// 8 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> class runnable_args_m_8 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_8(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-};
-
-
-
-// 8 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename R> class runnable_args_m_8_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_8_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-};
-
-
-
-// 9 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> class runnable_args_nm_9 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_9(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-};
-
-
-
-// 9 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename R> class runnable_args_nm_9_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_9_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-};
-
-
-
-// 9 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> class runnable_args_m_9 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_9(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-};
-
-
-
-// 9 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename R> class runnable_args_m_9_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_9_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-};
-
-
-
-// 10 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> class runnable_args_nm_10 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_10(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-};
-
-
-
-// 10 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R> class runnable_args_nm_10_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_10_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-};
-
-
-
-// 10 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> class runnable_args_m_10 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_10(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-};
-
-
-
-// 10 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R> class runnable_args_m_10_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_10_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-};
-
-
-
-// 11 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> class runnable_args_nm_11 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_11(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-};
-
-
-
-// 11 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R> class runnable_args_nm_11_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_11_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-};
-
-
-
-// 11 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> class runnable_args_m_11 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_11(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-};
-
-
-
-// 11 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R> class runnable_args_m_11_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_11_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-};
-
-
-
-// 12 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11> class runnable_args_nm_12 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_12(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-};
-
-
-
-// 12 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R> class runnable_args_nm_12_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_12_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-};
-
-
-
-// 12 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11> class runnable_args_m_12 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_12(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-};
-
-
-
-// 12 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R> class runnable_args_m_12_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_12_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-};
-
-
-
-// 13 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12> class runnable_args_nm_13 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_13(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-  A12 a12_;
-};
-
-
-
-// 13 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R> class runnable_args_nm_13_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_13_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-  A12 a12_;
-};
-
-
-
-// 13 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12> class runnable_args_m_13 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_13(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-  A12 a12_;
-};
-
-
-
-// 13 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R> class runnable_args_m_13_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_13_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-  A12 a12_;
-};
-
-
-
-// 14 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13> class runnable_args_nm_14 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_nm_14(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) :
-    m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13)  {}
-
-  NS_IMETHOD Run() {
-    m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-  A12 a12_;
-  A13 a13_;
-};
-
-
-
-// 14 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R> class runnable_args_nm_14_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_nm_14_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R *r) :
-    m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
-    return NS_OK;
-  }
-
- private:
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-  A12 a12_;
-  A13 a13_;
-};
-
-
-
-// 14 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13> class runnable_args_m_14 : public detail::runnable_args_base<detail::NoResult> {
- public:
-  runnable_args_m_14(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) :
-    o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13)  {}
-
-  NS_IMETHOD Run() {
-    ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-  A12 a12_;
-  A13 a13_;
-};
-
-
-
-// 14 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R> class runnable_args_m_14_ret : public detail::runnable_args_base<detail::ReturnsResult> {
- public:
-  runnable_args_m_14_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R *r) :
-    o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13)  {}
-
-  NS_IMETHOD Run() {
-    *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
-    return NS_OK;
-  }
-
- private:
-  C o_;
-  M m_;
-  R* r_;
-  A0 a0_;
-  A1 a1_;
-  A2 a2_;
-  A3 a3_;
-  A4 a4_;
-  A5 a5_;
-  A6 a6_;
-  A7 a7_;
-  A8 a8_;
-  A9 a9_;
-  A10 a10_;
-  A11 a11_;
-  A12 a12_;
-  A13 a13_;
-};
-
-
-
-
-
-
-// 0 arguments --
-template<typename M>
-runnable_args_nm_0<M>* WrapRunnableNM(M m) {
-  return new runnable_args_nm_0<M>
-    (m);
-}
-
-// 0 arguments --
-template<typename M, typename R>
-runnable_args_nm_0_ret<M, R>* WrapRunnableNMRet(M m, R* r) {
-  return new runnable_args_nm_0_ret<M, R>
-    (m, r);
-}
-
-// 0 arguments --
-template<typename C, typename M>
-runnable_args_m_0<C, M>* WrapRunnable(C o, M m) {
-  return new runnable_args_m_0<C, M>
-    (o, m);
-}
-
-// 0 arguments --
-template<typename C, typename M, typename R>
-runnable_args_m_0_ret<C, M, R>* WrapRunnableRet(C o, M m, R* r) {
-  return new runnable_args_m_0_ret<C, M, R>
-    (o, m, r);
-}
-
-// 1 arguments --
-template<typename M, typename A0>
-runnable_args_nm_1<M, A0>* WrapRunnableNM(M m, A0 a0) {
-  return new runnable_args_nm_1<M, A0>
-    (m, a0);
-}
-
-// 1 arguments --
-template<typename M, typename A0, typename R>
-runnable_args_nm_1_ret<M, A0, R>* WrapRunnableNMRet(M m, A0 a0, R* r) {
-  return new runnable_args_nm_1_ret<M, A0, R>
-    (m, a0, r);
-}
-
-// 1 arguments --
-template<typename C, typename M, typename A0>
-runnable_args_m_1<C, M, A0>* WrapRunnable(C o, M m, A0 a0) {
-  return new runnable_args_m_1<C, M, A0>
-    (o, m, a0);
-}
-
-// 1 arguments --
-template<typename C, typename M, typename A0, typename R>
-runnable_args_m_1_ret<C, M, A0, R>* WrapRunnableRet(C o, M m, A0 a0, R* r) {
-  return new runnable_args_m_1_ret<C, M, A0, R>
-    (o, m, a0, r);
-}
-
-// 2 arguments --
-template<typename M, typename A0, typename A1>
-runnable_args_nm_2<M, A0, A1>* WrapRunnableNM(M m, A0 a0, A1 a1) {
-  return new runnable_args_nm_2<M, A0, A1>
-    (m, a0, a1);
-}
-
-// 2 arguments --
-template<typename M, typename A0, typename A1, typename R>
-runnable_args_nm_2_ret<M, A0, A1, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, R* r) {
-  return new runnable_args_nm_2_ret<M, A0, A1, R>
-    (m, a0, a1, r);
-}
-
-// 2 arguments --
-template<typename C, typename M, typename A0, typename A1>
-runnable_args_m_2<C, M, A0, A1>* WrapRunnable(C o, M m, A0 a0, A1 a1) {
-  return new runnable_args_m_2<C, M, A0, A1>
-    (o, m, a0, a1);
-}
-
-// 2 arguments --
-template<typename C, typename M, typename A0, typename A1, typename R>
-runnable_args_m_2_ret<C, M, A0, A1, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, R* r) {
-  return new runnable_args_m_2_ret<C, M, A0, A1, R>
-    (o, m, a0, a1, r);
-}
-
-// 3 arguments --
-template<typename M, typename A0, typename A1, typename A2>
-runnable_args_nm_3<M, A0, A1, A2>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2) {
-  return new runnable_args_nm_3<M, A0, A1, A2>
-    (m, a0, a1, a2);
-}
-
-// 3 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename R>
-runnable_args_nm_3_ret<M, A0, A1, A2, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, R* r) {
-  return new runnable_args_nm_3_ret<M, A0, A1, A2, R>
-    (m, a0, a1, a2, r);
-}
-
-// 3 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2>
-runnable_args_m_3<C, M, A0, A1, A2>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2) {
-  return new runnable_args_m_3<C, M, A0, A1, A2>
-    (o, m, a0, a1, a2);
-}
-
-// 3 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename R>
-runnable_args_m_3_ret<C, M, A0, A1, A2, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, R* r) {
-  return new runnable_args_m_3_ret<C, M, A0, A1, A2, R>
-    (o, m, a0, a1, a2, r);
-}
-
-// 4 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3>
-runnable_args_nm_4<M, A0, A1, A2, A3>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3) {
-  return new runnable_args_nm_4<M, A0, A1, A2, A3>
-    (m, a0, a1, a2, a3);
-}
-
-// 4 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename R>
-runnable_args_nm_4_ret<M, A0, A1, A2, A3, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, R* r) {
-  return new runnable_args_nm_4_ret<M, A0, A1, A2, A3, R>
-    (m, a0, a1, a2, a3, r);
-}
-
-// 4 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3>
-runnable_args_m_4<C, M, A0, A1, A2, A3>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3) {
-  return new runnable_args_m_4<C, M, A0, A1, A2, A3>
-    (o, m, a0, a1, a2, a3);
-}
-
-// 4 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename R>
-runnable_args_m_4_ret<C, M, A0, A1, A2, A3, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, R* r) {
-  return new runnable_args_m_4_ret<C, M, A0, A1, A2, A3, R>
-    (o, m, a0, a1, a2, a3, r);
-}
-
-// 5 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4>
-runnable_args_nm_5<M, A0, A1, A2, A3, A4>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
-  return new runnable_args_nm_5<M, A0, A1, A2, A3, A4>
-    (m, a0, a1, a2, a3, a4);
-}
-
-// 5 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename R>
-runnable_args_nm_5_ret<M, A0, A1, A2, A3, A4, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, R* r) {
-  return new runnable_args_nm_5_ret<M, A0, A1, A2, A3, A4, R>
-    (m, a0, a1, a2, a3, a4, r);
-}
-
-// 5 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4>
-runnable_args_m_5<C, M, A0, A1, A2, A3, A4>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
-  return new runnable_args_m_5<C, M, A0, A1, A2, A3, A4>
-    (o, m, a0, a1, a2, a3, a4);
-}
-
-// 5 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename R>
-runnable_args_m_5_ret<C, M, A0, A1, A2, A3, A4, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, R* r) {
-  return new runnable_args_m_5_ret<C, M, A0, A1, A2, A3, A4, R>
-    (o, m, a0, a1, a2, a3, a4, r);
-}
-
-// 6 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
-runnable_args_nm_6<M, A0, A1, A2, A3, A4, A5>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
-  return new runnable_args_nm_6<M, A0, A1, A2, A3, A4, A5>
-    (m, a0, a1, a2, a3, a4, a5);
-}
-
-// 6 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename R>
-runnable_args_nm_6_ret<M, A0, A1, A2, A3, A4, A5, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, R* r) {
-  return new runnable_args_nm_6_ret<M, A0, A1, A2, A3, A4, A5, R>
-    (m, a0, a1, a2, a3, a4, a5, r);
-}
-
-// 6 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
-runnable_args_m_6<C, M, A0, A1, A2, A3, A4, A5>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
-  return new runnable_args_m_6<C, M, A0, A1, A2, A3, A4, A5>
-    (o, m, a0, a1, a2, a3, a4, a5);
-}
-
-// 6 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename R>
-runnable_args_m_6_ret<C, M, A0, A1, A2, A3, A4, A5, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, R* r) {
-  return new runnable_args_m_6_ret<C, M, A0, A1, A2, A3, A4, A5, R>
-    (o, m, a0, a1, a2, a3, a4, a5, r);
-}
-
-// 7 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
-runnable_args_nm_7<M, A0, A1, A2, A3, A4, A5, A6>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
-  return new runnable_args_nm_7<M, A0, A1, A2, A3, A4, A5, A6>
-    (m, a0, a1, a2, a3, a4, a5, a6);
-}
-
-// 7 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename R>
-runnable_args_nm_7_ret<M, A0, A1, A2, A3, A4, A5, A6, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, R* r) {
-  return new runnable_args_nm_7_ret<M, A0, A1, A2, A3, A4, A5, A6, R>
-    (m, a0, a1, a2, a3, a4, a5, a6, r);
-}
-
-// 7 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
-runnable_args_m_7<C, M, A0, A1, A2, A3, A4, A5, A6>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
-  return new runnable_args_m_7<C, M, A0, A1, A2, A3, A4, A5, A6>
-    (o, m, a0, a1, a2, a3, a4, a5, a6);
-}
-
-// 7 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename R>
-runnable_args_m_7_ret<C, M, A0, A1, A2, A3, A4, A5, A6, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, R* r) {
-  return new runnable_args_m_7_ret<C, M, A0, A1, A2, A3, A4, A5, A6, R>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, r);
-}
-
-// 8 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
-runnable_args_nm_8<M, A0, A1, A2, A3, A4, A5, A6, A7>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
-  return new runnable_args_nm_8<M, A0, A1, A2, A3, A4, A5, A6, A7>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7);
-}
-
-// 8 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename R>
-runnable_args_nm_8_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, R* r) {
-  return new runnable_args_nm_8_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, R>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, r);
-}
-
-// 8 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
-runnable_args_m_8<C, M, A0, A1, A2, A3, A4, A5, A6, A7>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
-  return new runnable_args_m_8<C, M, A0, A1, A2, A3, A4, A5, A6, A7>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7);
-}
-
-// 8 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename R>
-runnable_args_m_8_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, R* r) {
-  return new runnable_args_m_8_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, R>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, r);
-}
-
-// 9 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
-runnable_args_nm_9<M, A0, A1, A2, A3, A4, A5, A6, A7, A8>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
-  return new runnable_args_nm_9<M, A0, A1, A2, A3, A4, A5, A6, A7, A8>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8);
-}
-
-// 9 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename R>
-runnable_args_nm_9_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, R* r) {
-  return new runnable_args_nm_9_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, R>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, r);
-}
-
-// 9 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
-runnable_args_m_9<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
-  return new runnable_args_m_9<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8);
-}
-
-// 9 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename R>
-runnable_args_m_9_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, R* r) {
-  return new runnable_args_m_9_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, R>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, r);
-}
-
-// 10 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
-runnable_args_nm_10<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
-  return new runnable_args_nm_10<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
-}
-
-// 10 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R>
-runnable_args_nm_10_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R* r) {
-  return new runnable_args_nm_10_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, R>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, r);
-}
-
-// 10 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
-runnable_args_m_10<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
-  return new runnable_args_m_10<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
-}
-
-// 10 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R>
-runnable_args_m_10_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R* r) {
-  return new runnable_args_m_10_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, R>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, r);
-}
-
-// 11 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
-runnable_args_nm_11<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) {
-  return new runnable_args_nm_11<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
-}
-
-// 11 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R>
-runnable_args_nm_11_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R* r) {
-  return new runnable_args_nm_11_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, r);
-}
-
-// 11 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
-runnable_args_m_11<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) {
-  return new runnable_args_m_11<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
-}
-
-// 11 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R>
-runnable_args_m_11_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R* r) {
-  return new runnable_args_m_11_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, r);
-}
-
-// 12 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11>
-runnable_args_nm_12<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) {
-  return new runnable_args_nm_12<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
-}
-
-// 12 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R>
-runnable_args_nm_12_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R* r) {
-  return new runnable_args_nm_12_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, r);
-}
-
-// 12 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11>
-runnable_args_m_12<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) {
-  return new runnable_args_m_12<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
-}
-
-// 12 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R>
-runnable_args_m_12_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R* r) {
-  return new runnable_args_m_12_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, r);
-}
-
-// 13 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12>
-runnable_args_nm_13<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) {
-  return new runnable_args_nm_13<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
-}
-
-// 13 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R>
-runnable_args_nm_13_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R* r) {
-  return new runnable_args_nm_13_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, r);
-}
-
-// 13 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12>
-runnable_args_m_13<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) {
-  return new runnable_args_m_13<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
-}
-
-// 13 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R>
-runnable_args_m_13_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R* r) {
-  return new runnable_args_m_13_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, r);
-}
-
-// 14 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13>
-runnable_args_nm_14<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) {
-  return new runnable_args_nm_14<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
-}
-
-// 14 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R>
-runnable_args_nm_14_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R* r) {
-  return new runnable_args_nm_14_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R>
-    (m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, r);
-}
-
-// 14 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13>
-runnable_args_m_14<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) {
-  return new runnable_args_m_14<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
-}
-
-// 14 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R>
-runnable_args_m_14_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R* r) {
-  return new runnable_args_m_14_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R>
-    (o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, r);
-}
-
--- a/media/mtransport/test/ice_unittest.cpp
+++ b/media/mtransport/test/ice_unittest.cpp
@@ -376,17 +376,17 @@ class IceTestPeer : public sigslot::has_
     ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetResolver(
         dns_resolver_->AllocateResolver())));
   }
 
   void Gather() {
     nsresult res;
 
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(ice_ctx_, &NrIceCtx::StartGathering, &res),
+        WrapRunnableRet(&res, ice_ctx_, &NrIceCtx::StartGathering),
         NS_DISPATCH_SYNC);
 
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void UseNat() {
     nat_->enabled_ = true;
   }
@@ -415,17 +415,17 @@ class IceTestPeer : public sigslot::has_
     return attrs;
   }
 
    std::vector<std::string> GetCandidates(size_t stream) {
     std::vector<std::string> v;
 
     RUN_ON_THREAD(
         test_utils->sts_target(),
-        WrapRunnableRet(this, &IceTestPeer::GetCandidates_s, stream, &v));
+        WrapRunnableRet(&v, this, &IceTestPeer::GetCandidates_s, stream));
 
     return v;
   }
 
   std::string FilterCandidate(const std::string& candidate) {
     if (candidate_filter_) {
       return candidate_filter_(candidate);
     }
@@ -475,17 +475,17 @@ class IceTestPeer : public sigslot::has_
       return false;
     }
     return streams_[stream]->state() == NrIceMediaStream::ICE_OPEN;
   }
   bool is_ready(size_t stream)
   {
     bool result;
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(this, &IceTestPeer::is_ready_s, stream, &result),
+        WrapRunnableRet(&result, this, &IceTestPeer::is_ready_s, stream),
         NS_DISPATCH_SYNC);
     return result;
   }
   bool ice_complete() { return ice_complete_; }
   bool ice_reached_checking() { return ice_reached_checking_; }
   size_t received() { return received_; }
   size_t sent() { return sent_; }
 
@@ -701,17 +701,17 @@ class IceTestPeer : public sigslot::has_
     remote_ = nullptr;
   }
 
   void StartChecks() {
     nsresult res;
 
     // Now start checks
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(ice_ctx_, &NrIceCtx::StartChecks, &res),
+        WrapRunnableRet(&res, ice_ctx_, &NrIceCtx::StartChecks),
         NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   // Handle events
   void GatheringStateChange(NrIceCtx* ctx,
                             NrIceCtx::GatheringState state) {
     (void)ctx;
@@ -778,21 +778,20 @@ class IceTestPeer : public sigslot::has_
 
     return streams_[stream_index]->GetCandidatePairs(pairs);
   }
 
   nsresult GetCandidatePairs(size_t stream_index,
                              std::vector<NrIceCandidatePair>* pairs) {
     nsresult v;
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(this,
+        WrapRunnableRet(&v, this,
                         &IceTestPeer::GetCandidatePairs_s,
                         stream_index,
-                        pairs,
-                        &v),
+                        pairs),
         NS_DISPATCH_SYNC);
     return v;
   }
 
   void DumpCandidatePair(const NrIceCandidatePair& pair) {
       std::cerr << std::endl;
       DumpCandidate("Local", pair.local);
       DumpCandidate("Remote", pair.remote);
@@ -988,20 +987,19 @@ class IceTestPeer : public sigslot::has_
         NS_DISPATCH_SYNC);
   }
 
   int trickled() { return trickled_; }
 
   void SetControlling(NrIceCtx::Controlling controlling) {
     nsresult res;
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(ice_ctx_,
+        WrapRunnableRet(&res, ice_ctx_,
                         &NrIceCtx::SetControlling,
-                        controlling,
-                        &res),
+                        controlling),
         NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void SetTiebreaker(uint64_t tiebreaker) {
     test_utils->sts_target()->Dispatch(
         WrapRunnable(this,
                      &IceTestPeer::SetTiebreaker_s,
--- a/media/mtransport/test/nrappkit_unittest.cpp
+++ b/media/mtransport/test/nrappkit_unittest.cpp
@@ -33,27 +33,27 @@ namespace {
 class TimerTest : public ::testing::Test {
  public:
   TimerTest() : handle_(nullptr), fired_(false) {}
 
   int ArmTimer(int timeout) {
     int ret;
 
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(this, &TimerTest::ArmTimer_w, timeout, &ret),
+        WrapRunnableRet(&ret, this, &TimerTest::ArmTimer_w, timeout),
         NS_DISPATCH_SYNC);
 
     return ret;
   }
 
   int ArmCancelTimer(int timeout) {
     int ret;
 
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(this, &TimerTest::ArmCancelTimer_w, timeout, &ret),
+        WrapRunnableRet(&ret, this, &TimerTest::ArmCancelTimer_w, timeout),
         NS_DISPATCH_SYNC);
 
     return ret;
   }
 
   int ArmTimer_w(int timeout) {
     return NR_ASYNC_TIMER_SET(timeout, cb, this, &handle_);
   }
@@ -66,31 +66,31 @@ class TimerTest : public ::testing::Test
 
     return CancelTimer_w();
   }
 
   int CancelTimer() {
     int ret;
 
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(this, &TimerTest::CancelTimer_w, &ret),
+        WrapRunnableRet(&ret, this, &TimerTest::CancelTimer_w),
         NS_DISPATCH_SYNC);
 
     return ret;
   }
 
   int CancelTimer_w() {
     return NR_async_timer_cancel(handle_);
   }
 
   int Schedule() {
     int ret;
 
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(this, &TimerTest::Schedule_w, &ret),
+        WrapRunnableRet(&ret, this, &TimerTest::Schedule_w),
         NS_DISPATCH_SYNC);
 
     return ret;
   }
 
   int Schedule_w() {
     NR_ASYNC_SCHEDULE(cb, this);
 
--- a/media/mtransport/test/runnable_utils_unittest.cpp
+++ b/media/mtransport/test/runnable_utils_unittest.cpp
@@ -133,17 +133,17 @@ class DispatchTest : public ::testing::T
                       NS_DISPATCH_SYNC);
     ASSERT_TRUE(x);
   }
 
   void TestRet() {
     int z;
     int x = 10;
 
-    target_->Dispatch(WrapRunnableRet(&cl_, &TargetClass::return_int, x, &z),
+    target_->Dispatch(WrapRunnableRet(&z, &cl_, &TargetClass::return_int, x),
                       NS_DISPATCH_SYNC);
     ASSERT_EQ(10, z);
   }
 
  protected:
   int ran_;
   TargetClass cl_;
   nsCOMPtr<nsIEventTarget> target_;
@@ -190,17 +190,17 @@ TEST_F(DispatchTest, TestNonMethod) {
 
   ASSERT_EQ(1, ran_);
 }
 
 TEST_F(DispatchTest, TestNonMethodRet) {
   int z;
 
   test_utils->sts_target()->Dispatch(
-      WrapRunnableNMRet(SetNonMethodRet, &cl_, 10, &z), NS_DISPATCH_SYNC);
+      WrapRunnableNMRet(&z, SetNonMethodRet, &cl_, 10), NS_DISPATCH_SYNC);
 
   ASSERT_EQ(1, ran_);
   ASSERT_EQ(10, z);
 }
 
 TEST_F(DispatchTest, TestDestructor) {
   bool destroyed = false;
   RefPtr<Destructor> destructor = new Destructor(&destroyed);
--- a/media/mtransport/test/test_nr_socket_unittest.cpp
+++ b/media/mtransport/test/test_nr_socket_unittest.cpp
@@ -91,21 +91,21 @@ class TestNrSocketTest : public ::testin
       public_addrs_.push_back(sock);
     }
   }
 
   nsRefPtr<TestNat> CreatePrivateAddrs(size_t size,
                                        const char* ip_str = "127.0.0.1") {
     nsRefPtr<TestNat> result;
     sts_->Dispatch(
-        WrapRunnableRet(this,
+        WrapRunnableRet(&result,
+                        this,
                         &TestNrSocketTest::CreatePrivateAddrs_s,
                         size,
-                        ip_str,
-                        &result),
+                        ip_str),
         NS_DISPATCH_SYNC);
     return result;
   }
 
   nsRefPtr<TestNat> CreatePrivateAddrs_s(size_t count, const char* ip_str) {
     nsRefPtr<TestNat> nat(new TestNat);
     while (count--) {
       auto sock = CreateTestNrSocket_s(ip_str, nat);
@@ -127,41 +127,41 @@ class TestNrSocketTest : public ::testin
       nr_transport_addr *sender_external_address = nullptr) {
     MOZ_ASSERT(from);
 
     if (!WaitForWriteable(from)) {
       return false;
     }
 
     int result = 0;
-    sts_->Dispatch(WrapRunnableRet(this,
+    sts_->Dispatch(WrapRunnableRet(&result,
+                                   this,
                                    &TestNrSocketTest::SendData_s,
                                    from,
-                                   via,
-                                   &result),
+                                   via),
                    NS_DISPATCH_SYNC);
     if (result) {
       return false;
     }
 
     if (!WaitForReadable(to)) {
       return false;
     }
 
     nr_transport_addr dummy_outparam;
     if (!sender_external_address) {
       sender_external_address = &dummy_outparam;
     }
 
     MOZ_ASSERT(to);
-    sts_->Dispatch(WrapRunnableRet(this,
+    sts_->Dispatch(WrapRunnableRet(&result,
+                                   this,
                                    &TestNrSocketTest::RecvData_s,
                                    to,
-                                   sender_external_address,
-                                   &result),
+                                   sender_external_address),
                    NS_DISPATCH_SYNC);
 
     return !result;
   }
 
   bool CheckConnectivity(
       TestNrSocket *from,
       TestNrSocket *to,
@@ -177,21 +177,21 @@ class TestNrSocketTest : public ::testin
                                 destination_address,
                                 sender_external_address);
   }
 
   int GetAddress(TestNrSocket *sock, nr_transport_addr_ *address) {
     MOZ_ASSERT(sock);
     MOZ_ASSERT(address);
     int r;
-    sts_->Dispatch(WrapRunnableRet(this,
+    sts_->Dispatch(WrapRunnableRet(&r,
+                                   this,
                                    &TestNrSocketTest::GetAddress_s,
                                    sock,
-                                   address,
-                                   &r),
+                                   address),
                    NS_DISPATCH_SYNC);
     return r;
   }
 
   int GetAddress_s(TestNrSocket *sock, nr_transport_addr *address) {
     return sock->getaddr(address);
   }
 
--- a/media/mtransport/test/transport_unittests.cpp
+++ b/media/mtransport/test/transport_unittests.cpp
@@ -628,28 +628,28 @@ class TransportTestPeer : public sigslot
 
     // Assemble the stack
     nsAutoPtr<std::queue<mozilla::TransportLayer *> > layers(
       new std::queue<mozilla::TransportLayer *>);
     layers->push(ice_);
     layers->push(dtls_);
 
     test_utils->sts_target()->Dispatch(
-      WrapRunnableRet(flow_, &TransportFlow::PushLayers, layers, &res),
+      WrapRunnableRet(&res, flow_, &TransportFlow::PushLayers, layers),
       NS_DISPATCH_SYNC);
 
     ASSERT_EQ((nsresult)NS_OK, res);
 
     // Listen for media events
     flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
     flow_->SignalStateChange.connect(this, &TransportTestPeer::StateChanged);
 
     // Start gathering
     test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(ice_ctx_, &NrIceCtx::StartGathering, &res),
+        WrapRunnableRet(&res, ice_ctx_, &NrIceCtx::StartGathering),
         NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void ConnectIce(TransportTestPeer *peer) {
     peer_ = peer;
 
     // If gathering is already complete, push the candidates over
@@ -679,41 +679,41 @@ class TransportTestPeer : public sigslot
     // Don't send to the other side
     if (!peer_) {
       gathering_complete_ = true;
       return;
     }
 
     // First send attributes
     test_utils->sts_target()->Dispatch(
-      WrapRunnableRet(peer_->ice_ctx_,
+      WrapRunnableRet(&res, peer_->ice_ctx_,
                       &NrIceCtx::ParseGlobalAttributes,
-                      ice_ctx_->GetGlobalAttributes(), &res),
+                      ice_ctx_->GetGlobalAttributes()),
       NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
 
     for (size_t i=0; i<streams_.size(); ++i) {
       test_utils->sts_target()->Dispatch(
-        WrapRunnableRet(peer_->streams_[i], &NrIceMediaStream::ParseAttributes,
-                        candidates_[streams_[i]->name()], &res), NS_DISPATCH_SYNC);
+        WrapRunnableRet(&res, peer_->streams_[i], &NrIceMediaStream::ParseAttributes,
+                        candidates_[streams_[i]->name()]), NS_DISPATCH_SYNC);
 
       ASSERT_TRUE(NS_SUCCEEDED(res));
     }
 
     // Start checks on the other peer.
     test_utils->sts_target()->Dispatch(
-      WrapRunnableRet(peer_->ice_ctx_, &NrIceCtx::StartChecks, &res),
+      WrapRunnableRet(&res, peer_->ice_ctx_, &NrIceCtx::StartChecks),
       NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   TransportResult SendPacket(const unsigned char* data, size_t len) {
     TransportResult ret;
     test_utils->sts_target()->Dispatch(
-      WrapRunnableRet(flow_, &TransportFlow::SendPacket, data, len, &ret),
+      WrapRunnableRet(&ret, flow_, &TransportFlow::SendPacket, data, len),
       NS_DISPATCH_SYNC);
 
     return ret;
   }
 
 
   void StateChanged(TransportFlow *flow, TransportLayer::State state) {
     if (state == TransportLayer::TS_OPEN) {
@@ -750,17 +750,17 @@ class TransportTestPeer : public sigslot
   void SetReuseECDHEKey() {
     reuse_dhe_key_ = true;
   }
 
   TransportLayer::State state() {
     TransportLayer::State tstate;
 
     RUN_ON_THREAD(test_utils->sts_target(),
-                  WrapRunnableRet(flow_, &TransportFlow::state, &tstate));
+                  WrapRunnableRet(&tstate, flow_, &TransportFlow::state));
 
     return tstate;
   }
 
   bool connected() {
     return state() == TransportLayer::TS_OPEN;
   }
 
@@ -769,31 +769,31 @@ class TransportTestPeer : public sigslot
   }
 
   size_t received() { return received_; }
 
   uint16_t cipherSuite() const {
     nsresult rv;
     uint16_t cipher;
     RUN_ON_THREAD(test_utils->sts_target(),
-                  WrapRunnableRet(dtls_, &TransportLayerDtls::GetCipherSuite,
-                                  &cipher, &rv));
+                  WrapRunnableRet(&rv, dtls_, &TransportLayerDtls::GetCipherSuite,
+                                  &cipher));
 
     if (NS_FAILED(rv)) {
       return TLS_NULL_WITH_NULL_NULL; // i.e., not good
     }
     return cipher;
   }
 
   uint16_t srtpCipher() const {
     nsresult rv;
     uint16_t cipher;
     RUN_ON_THREAD(test_utils->sts_target(),
-                  WrapRunnableRet(dtls_, &TransportLayerDtls::GetSrtpCipher,
-                                  &cipher, &rv));
+                  WrapRunnableRet(&rv, dtls_, &TransportLayerDtls::GetSrtpCipher,
+                                  &cipher));
     if (NS_FAILED(rv)) {
       return 0; // the SRTP equivalent of TLS_NULL_WITH_NULL_NULL
     }
     return cipher;
   }
 
  private:
   std::string name_;
--- a/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp
+++ b/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp
@@ -272,22 +272,21 @@ WebrtcGmpVideoEncoder::Encode(const webr
 
     if (initDone->Result() != WEBRTC_VIDEO_CODEC_OK) {
       return initDone->Result();
     }
   }
 
   int32_t ret;
   mozilla::SyncRunnable::DispatchToThread(mGMPThread,
-                WrapRunnableRet(this,
+                WrapRunnableRet(&ret, this,
                                 &WebrtcGmpVideoEncoder::Encode_g,
                                 &aInputImage,
                                 aCodecSpecificInfo,
-                                aFrameTypes,
-                                &ret));
+                                aFrameTypes));
 
   return ret;
 }
 
 void
 WebrtcGmpVideoEncoder::RegetEncoderForResolutionChange(const webrtc::I420VideoFrame* aInputImage,
                                                        InitDoneRunnable* aInitDone)
 {
@@ -405,20 +404,19 @@ WebrtcGmpVideoEncoder::SetChannelParamet
 }
 
 int32_t
 WebrtcGmpVideoEncoder::SetRates(uint32_t aNewBitRate, uint32_t aFrameRate)
 {
   int32_t ret;
   MOZ_ASSERT(mGMPThread);
   mozilla::SyncRunnable::DispatchToThread(mGMPThread,
-                WrapRunnableRet(this,
+                WrapRunnableRet(&ret, this,
                                 &WebrtcGmpVideoEncoder::SetRates_g,
-                                aNewBitRate, aFrameRate,
-                                &ret));
+                                aNewBitRate, aFrameRate));
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t
 WebrtcGmpVideoEncoder::SetRates_g(uint32_t aNewBitRate, uint32_t aFrameRate)
 {
   if (!mGMP) {
@@ -676,24 +674,23 @@ WebrtcGmpVideoDecoder::Decode(const webr
                               bool aMissingFrames,
                               const webrtc::RTPFragmentationHeader* aFragmentation,
                               const webrtc::CodecSpecificInfo* aCodecSpecificInfo,
                               int64_t aRenderTimeMs)
 {
   int32_t ret;
   MOZ_ASSERT(mGMPThread);
   mozilla::SyncRunnable::DispatchToThread(mGMPThread,
-                WrapRunnableRet(this,
+                WrapRunnableRet(&ret, this,
                                 &WebrtcGmpVideoDecoder::Decode_g,
                                 aInputImage,
                                 aMissingFrames,
                                 aFragmentation,
                                 aCodecSpecificInfo,
-                                aRenderTimeMs,
-                                &ret));
+                                aRenderTimeMs));
 
   return ret;
 }
 
 int32_t
 WebrtcGmpVideoDecoder::Decode_g(const webrtc::EncodedImage& aInputImage,
                                 bool aMissingFrames,
                                 const webrtc::RTPFragmentationHeader* aFragmentation,
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -886,29 +886,29 @@ NewData(MediaStreamGraph* graph, TrackID
         StreamTime offset,
         uint32_t events,
         const MediaSegment& media) {
   if (!active_) {
     MOZ_MTLOG(ML_DEBUG, "Discarding packets because transport not ready");
     return;
   }
 
-  if (track_id_ != TRACK_INVALID) {
-    if (tid != track_id_) {
-      return;
-    }
-  } else if (conduit_->type() !=
-             (media.GetType() == MediaSegment::AUDIO ? MediaSessionConduit::AUDIO :
-                                                       MediaSessionConduit::VIDEO)) {
-    // Ignore data in case we have a muxed stream
+  if (conduit_->type() !=
+      (media.GetType() == MediaSegment::AUDIO ? MediaSessionConduit::AUDIO :
+                                                MediaSessionConduit::VIDEO)) {
+    // Ignore data of wrong kind in case we have a muxed stream
     return;
-  } else {
+  }
+
+  if (track_id_ == TRACK_INVALID) {
     // Don't lock during normal media flow except on first sample
     MutexAutoLock lock(mMutex);
     track_id_ = track_id_external_ = tid;
+  } else if (tid != track_id_) {
+    return;
   }
 
   // TODO(ekr@rtfm.com): For now assume that we have only one
   // track type and it's destined for us
   // See bug 784517
   if (media.GetType() == MediaSegment::AUDIO) {
     AudioSegment* audio = const_cast<AudioSegment *>(
         static_cast<const AudioSegment *>(&media));
--- a/media/webrtc/signaling/test/mediaconduit_unittests.cpp
+++ b/media/webrtc/signaling/test/mediaconduit_unittests.cpp
@@ -527,26 +527,24 @@ class TransportConduitTest : public ::te
   }
 
   //1. Dump audio samples to dummy external transport
   void TestDummyAudioAndTransport()
   {
     //get pointer to AudioSessionConduit
     int err=0;
     mozilla::SyncRunnable::DispatchToThread(gMainThread,
-                                            WrapRunnableNMRet(
-                                                &mozilla::AudioSessionConduit::Create,
-                                                &mAudioSession));
+                                            WrapRunnableNMRet(&mAudioSession,
+                                                &mozilla::AudioSessionConduit::Create));
     if( !mAudioSession )
       ASSERT_NE(mAudioSession, (void*)nullptr);
 
     mozilla::SyncRunnable::DispatchToThread(gMainThread,
-                                            WrapRunnableNMRet(
-                                                &mozilla::AudioSessionConduit::Create,
-                                                &mAudioSession2));
+                                            WrapRunnableNMRet(&mAudioSession2,
+                                                &mozilla::AudioSessionConduit::Create));
     if( !mAudioSession2 )
       ASSERT_NE(mAudioSession2, (void*)nullptr);
 
     WebrtcMediaTransport* xport = new WebrtcMediaTransport();
     ASSERT_NE(xport, (void*)nullptr);
     xport->SetAudioSession(mAudioSession, mAudioSession2);
     mAudioTransport = xport;
 
@@ -591,27 +589,25 @@ class TransportConduitTest : public ::te
   }
 
   //2. Dump audio samples to dummy external transport
   void TestDummyVideoAndTransport(bool send_vp8 = true, const char *source_file = nullptr)
   {
     int err = 0;
     //get pointer to VideoSessionConduit
     mozilla::SyncRunnable::DispatchToThread(gMainThread,
-                                            WrapRunnableNMRet(
-                                                &mozilla::VideoSessionConduit::Create,
-                                                &mVideoSession));
+                                            WrapRunnableNMRet(&mVideoSession,
+                                                &mozilla::VideoSessionConduit::Create));
     if( !mVideoSession )
       ASSERT_NE(mVideoSession, (void*)nullptr);
 
    // This session is for other one
     mozilla::SyncRunnable::DispatchToThread(gMainThread,
-                                            WrapRunnableNMRet(
-                                                &mozilla::VideoSessionConduit::Create,
-                                                &mVideoSession2));
+                                            WrapRunnableNMRet(&mVideoSession2,
+                                                &mozilla::VideoSessionConduit::Create));
     if( !mVideoSession2 )
       ASSERT_NE(mVideoSession2,(void*)nullptr);
 
     if (!send_vp8) {
       SetGmpCodecs();
     }
 
     mVideoRenderer = new DummyVideoTarget();
@@ -689,19 +685,18 @@ class TransportConduitTest : public ::te
   }
 
  void TestVideoConduitCodecAPI()
   {
     int err = 0;
     mozilla::RefPtr<mozilla::VideoSessionConduit> videoSession;
     //get pointer to VideoSessionConduit
     mozilla::SyncRunnable::DispatchToThread(gMainThread,
-                                            WrapRunnableNMRet(
-                                                &mozilla::VideoSessionConduit::Create,
-                                                &videoSession));
+                                            WrapRunnableNMRet(&videoSession,
+                                                &mozilla::VideoSessionConduit::Create));
     if( !videoSession )
       ASSERT_NE(videoSession, (void*)nullptr);
 
     //Test Configure Recv Codec APIS
     cerr << "   *************************************************" << endl;
     cerr << "    Test Receive Codec Configuration API Now " << endl;
     cerr << "   *************************************************" << endl;
 
@@ -800,19 +795,18 @@ class TransportConduitTest : public ::te
   // Calculate new resolution for sending video by applying max-fs constraint.
   void GetVideoResolutionWithMaxFs(int orig_width, int orig_height, int max_fs,
                                    int *new_width, int *new_height)
   {
     int err = 0;
 
     // Get pointer to VideoSessionConduit.
     mozilla::SyncRunnable::DispatchToThread(gMainThread,
-                                            WrapRunnableNMRet(
-                                                &mozilla::VideoSessionConduit::Create,
-                                                &mVideoSession));
+                                            WrapRunnableNMRet(&mVideoSession,
+                                                &mozilla::VideoSessionConduit::Create));
     if( !mVideoSession )
       ASSERT_NE(mVideoSession, (void*)nullptr);
 
     // Configure send codecs on the conduit.
     mozilla::VideoCodecConfig cinst1(120, "VP8", max_fs);
 
     err = mVideoSession->ConfigureSendMediaCodec(&cinst1);
     ASSERT_EQ(mozilla::kMediaConduitNoError, err);
@@ -1041,17 +1035,17 @@ int main(int argc, char **argv)
 
   // Now create the GTest thread and run all of the tests on it
   // When it is complete it will set gTestsComplete
   NS_NewNamedThread("gtest_thread", &thread);
   gGtestThread = thread;
 
   int result;
   gGtestThread->Dispatch(
-    mozilla::WrapRunnableNMRet(gtest_main, argc, argv, &result), NS_DISPATCH_NORMAL);
+    mozilla::WrapRunnableNMRet(&result, gtest_main, argc, argv), NS_DISPATCH_NORMAL);
 
   // Here we handle the event queue for dispatches to the main thread
   // When the GTest thread is complete it will send one more dispatch
   // with gTestsComplete == true.
   while (!gTestsComplete && NS_ProcessNextEvent());
 
   gGtestThread->Shutdown();
 
--- a/media/webrtc/signaling/test/mediapipeline_unittest.cpp
+++ b/media/webrtc/signaling/test/mediapipeline_unittest.cpp
@@ -156,17 +156,17 @@ class TestAgent {
 
   void Start() {
     nsresult ret;
 
     MOZ_MTLOG(ML_DEBUG, "Starting");
 
     mozilla::SyncRunnable::DispatchToThread(
       test_utils->sts_target(),
-      WrapRunnableRet(audio_->GetStream(), &Fake_MediaStream::Start, &ret));
+      WrapRunnableRet(&ret, audio_->GetStream(), &Fake_MediaStream::Start));
 
     ASSERT_TRUE(NS_SUCCEEDED(ret));
   }
 
   void StopInt() {
     audio_->GetStream()->Stop();
   }
 
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -657,18 +657,18 @@ class PCDispatchWrapper : public nsSuppo
     } else {
       // It would have been preferable here to dispatch directly to
       // PeerConnectionImpl::Initialize but since all the PC methods
       // have overrides clang will throw a 'couldn't infer template
       // argument' error.
       // Instead we are dispatching back to the same method for
       // all of these.
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::Initialize,
-          aObserver, aWindow, aConfiguration, aThread, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::Initialize,
+          aObserver, aWindow, aConfiguration, aThread),
         NS_DISPATCH_SYNC);
       rv = NS_OK;
     }
 
     return rv;
   }
 
   NS_IMETHODIMP CreateOffer(const mozilla::JsepOfferOptions& aOptions) {
@@ -680,197 +680,193 @@ class PCDispatchWrapper : public nsSuppo
       if (NS_FAILED(rv))
         return rv;
       EXPECT_EQ(TestObserver::stateSuccess, observer_->state);
       if (observer_->state != TestObserver::stateSuccess) {
         return NS_ERROR_FAILURE;
       }
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::CreateOffer,
-          aOptions, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::CreateOffer, aOptions),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   NS_IMETHODIMP CreateAnswer() {
     nsresult rv;
 
     if (NS_IsMainThread()) {
       rv = pc_->CreateAnswer();
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::CreateAnswer, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::CreateAnswer),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   NS_IMETHODIMP SetLocalDescription (int32_t aAction, const char* aSDP) {
     nsresult rv;
 
     if (NS_IsMainThread()) {
       rv = pc_->SetLocalDescription(aAction, aSDP);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::SetLocalDescription,
-          aAction, aSDP, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::SetLocalDescription,
+          aAction, aSDP),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   NS_IMETHODIMP SetRemoteDescription (int32_t aAction, const char* aSDP) {
     nsresult rv;
 
     if (NS_IsMainThread()) {
       rv = pc_->SetRemoteDescription(aAction, aSDP);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::SetRemoteDescription,
-          aAction, aSDP, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::SetRemoteDescription,
+          aAction, aSDP),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   NS_IMETHODIMP AddIceCandidate(const char* aCandidate, const char* aMid,
                                 unsigned short aLevel) {
     nsresult rv;
 
     if (NS_IsMainThread()) {
       rv = pc_->AddIceCandidate(aCandidate, aMid, aLevel);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::AddIceCandidate,
-          aCandidate, aMid, aLevel, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::AddIceCandidate,
+          aCandidate, aMid, aLevel),
         NS_DISPATCH_SYNC);
     }
     return rv;
   }
 
   NS_IMETHODIMP AddTrack(MediaStreamTrack *aTrack,
                          DOMMediaStream *aMediaStream)
   {
     nsresult rv;
 
     if (NS_IsMainThread()) {
       rv = pc_->AddTrack(*aTrack, *aMediaStream);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::AddTrack, aTrack,
-                        aMediaStream, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::AddTrack, aTrack,
+                        aMediaStream),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   NS_IMETHODIMP RemoveTrack(MediaStreamTrack *aTrack) {
     nsresult rv;
 
     if (NS_IsMainThread()) {
       rv = pc_->RemoveTrack(*aTrack);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::RemoveTrack, aTrack, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::RemoveTrack, aTrack),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   NS_IMETHODIMP GetLocalDescription(char** aSDP) {
     nsresult rv;
 
     if (NS_IsMainThread()) {
       rv = pc_->GetLocalDescription(aSDP);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::GetLocalDescription,
-          aSDP, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::GetLocalDescription,
+          aSDP),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   NS_IMETHODIMP GetRemoteDescription(char** aSDP) {
     nsresult rv;
 
     if (NS_IsMainThread()) {
       rv = pc_->GetRemoteDescription(aSDP);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::GetRemoteDescription,
-          aSDP, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::GetRemoteDescription,
+          aSDP),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   mozilla::dom::PCImplSignalingState SignalingState() {
     mozilla::dom::PCImplSignalingState result;
 
     if (NS_IsMainThread()) {
       result = pc_->SignalingState();
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::SignalingState,
-          &result),
+        WrapRunnableRet(&result, this, &PCDispatchWrapper::SignalingState),
         NS_DISPATCH_SYNC);
     }
 
     return result;
   }
 
   mozilla::dom::PCImplIceConnectionState IceConnectionState() {
     mozilla::dom::PCImplIceConnectionState result;
 
     if (NS_IsMainThread()) {
       result = pc_->IceConnectionState();
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::IceConnectionState,
-          &result),
+        WrapRunnableRet(&result, this, &PCDispatchWrapper::IceConnectionState),
         NS_DISPATCH_SYNC);
     }
 
     return result;
   }
 
   mozilla::dom::PCImplIceGatheringState IceGatheringState() {
     mozilla::dom::PCImplIceGatheringState result;
 
     if (NS_IsMainThread()) {
       result = pc_->IceGatheringState();
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::IceGatheringState,
-          &result),
+        WrapRunnableRet(&result, this, &PCDispatchWrapper::IceGatheringState),
         NS_DISPATCH_SYNC);
     }
 
     return result;
   }
 
   NS_IMETHODIMP Close() {
     nsresult rv;
 
     if (NS_IsMainThread()) {
       rv = pc_->Close();
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::Close, &rv),
+        WrapRunnableRet(&rv, this, &PCDispatchWrapper::Close),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
  private:
   nsRefPtr<PeerConnectionImpl> pc_;
@@ -1062,17 +1058,17 @@ class SignalingAgent {
       // Useful default
       // Create a media stream as if it came from GUM
       Fake_AudioStreamSource *audio_stream =
         new Fake_AudioStreamSource();
 
       nsresult ret;
       mozilla::SyncRunnable::DispatchToThread(
         test_utils->sts_target(),
-        WrapRunnableRet(audio_stream, &Fake_MediaStream::Start, &ret));
+        WrapRunnableRet(&ret, audio_stream, &Fake_MediaStream::Start));
 
       ASSERT_TRUE(NS_SUCCEEDED(ret));
       stream = audio_stream;
     }
 
     nsRefPtr<DOMMediaStream> domMediaStream = new DOMMediaStream(stream);
     domMediaStream->SetHintContents(hint);
 
@@ -1122,30 +1118,29 @@ class SignalingAgent {
 
   void CheckLocalPipeline(const std::string& streamId,
                           const std::string& trackId,
                           SdpMediaSection::MediaType type,
                           int pipelineCheckFlags = 0) const
   {
     LocalSourceStreamInfo* info;
     mozilla::SyncRunnable::DispatchToThread(
-      gMainThread, WrapRunnableRet(
+      gMainThread, WrapRunnableRet(&info,
         pc->media(), &PeerConnectionMedia::GetLocalStreamById,
-        streamId, &info));
+        streamId));
 
     ASSERT_TRUE(info) << "No such local stream id: " << streamId;
 
     RefPtr<MediaPipeline> pipeline;
 
     mozilla::SyncRunnable::DispatchToThread(
         gMainThread,
-        WrapRunnableRet(info,
+        WrapRunnableRet(&pipeline, info,
                         &SourceStreamInfo::GetPipelineByTrackId_m,
-                        trackId,
-                        &pipeline));
+                        trackId));
 
     ASSERT_TRUE(pipeline) << "No such local track id: " << trackId;
 
     if (type == SdpMediaSection::kVideo) {
       ASSERT_TRUE(pipeline->IsVideo()) << "Local track " << trackId
                                        << " was not video";
       ASSERT_EQ(mExpectRtcpMuxVideo, pipeline->IsDoingRtcpMux())
         << "Pipeline for remote track " << trackId
@@ -1170,30 +1165,29 @@ class SignalingAgent {
 
   void CheckRemotePipeline(const std::string& streamId,
                            const std::string& trackId,
                            SdpMediaSection::MediaType type,
                            int pipelineCheckFlags = 0) const
   {
     RemoteSourceStreamInfo* info;
     mozilla::SyncRunnable::DispatchToThread(
-      gMainThread, WrapRunnableRet(
+      gMainThread, WrapRunnableRet(&info,
         pc->media(), &PeerConnectionMedia::GetRemoteStreamById,
-        streamId, &info));
+        streamId));
 
     ASSERT_TRUE(info) << "No such remote stream id: " << streamId;
 
     RefPtr<MediaPipeline> pipeline;
 
     mozilla::SyncRunnable::DispatchToThread(
         gMainThread,
-        WrapRunnableRet(info,
+        WrapRunnableRet(&pipeline, info,
                         &SourceStreamInfo::GetPipelineByTrackId_m,
-                        trackId,
-                        &pipeline));
+                        trackId));
 
     ASSERT_TRUE(pipeline) << "No such remote track id: " << trackId;
 
     if (type == SdpMediaSection::kVideo) {
       ASSERT_TRUE(pipeline->IsVideo()) << "Remote track " << trackId
                                        << " was not video";
       mozilla::MediaSessionConduit *conduit = pipeline->Conduit();
       ASSERT_TRUE(conduit);
@@ -1295,17 +1289,17 @@ class SignalingAgent {
                     PCImplSignalingState::SignalingHaveRemoteOffer) {
     // Create a media stream as if it came from GUM
     Fake_AudioStreamSource *audio_stream =
       new Fake_AudioStreamSource();
 
     nsresult ret;
     mozilla::SyncRunnable::DispatchToThread(
       test_utils->sts_target(),
-      WrapRunnableRet(audio_stream, &Fake_MediaStream::Start, &ret));
+      WrapRunnableRet(&ret, audio_stream, &Fake_MediaStream::Start));
 
     ASSERT_TRUE(NS_SUCCEEDED(ret));
 
     uint32_t aHintContents = 0;
     if (offerAnswerFlags & ANSWER_AUDIO) {
       aHintContents |= DOMMediaStream::HINT_CONTENTS_AUDIO;
     }
     if (offerAnswerFlags & ANSWER_VIDEO) {
@@ -1504,24 +1498,24 @@ class SignalingAgent {
   // the SDP. For now, we just specify audio/video, since a given DOMMediaStream
   // can have only one of each anyway. Once this is fixed, we will need to
   // pass a real track id if we want to test that case.
   mozilla::RefPtr<mozilla::MediaPipeline> GetMediaPipeline(
     bool local, size_t stream, bool video) {
     SourceStreamInfo* streamInfo;
     if (local) {
       mozilla::SyncRunnable::DispatchToThread(
-        gMainThread, WrapRunnableRet(
+        gMainThread, WrapRunnableRet(&streamInfo,
           pc->media(), &PeerConnectionMedia::GetLocalStreamByIndex,
-          stream, &streamInfo));
+          stream));
     } else {
       mozilla::SyncRunnable::DispatchToThread(
-        gMainThread, WrapRunnableRet(
+        gMainThread, WrapRunnableRet(&streamInfo,
           pc->media(), &PeerConnectionMedia::GetRemoteStreamByIndex,
-          stream, &streamInfo));
+          stream));
     }
 
     if (!streamInfo) {
       return nullptr;
     }
 
     const auto &pipelines = streamInfo->GetPipelines();
 
@@ -4724,17 +4718,17 @@ int main(int argc, char **argv) {
 
   // Now create the GTest thread and run all of the tests on it
   // When it is complete it will set gTestsComplete
   NS_NewNamedThread("gtest_thread", &thread);
   gGtestThread = thread;
 
   int result;
   gGtestThread->Dispatch(
-    WrapRunnableNMRet(gtest_main, argc, argv, &result), NS_DISPATCH_NORMAL);
+    WrapRunnableNMRet(&result, gtest_main, argc, argv), NS_DISPATCH_NORMAL);
 
   // Here we handle the event queue for dispatches to the main thread
   // When the GTest thread is complete it will send one more dispatch
   // with gTestsComplete == true.
   while (!gTestsComplete && NS_ProcessNextEvent());
 
   gGtestThread->Shutdown();
 
--- a/python/mozbuild/mozbuild/base.py
+++ b/python/mozbuild/mozbuild/base.py
@@ -38,18 +38,18 @@ def ancestors(path):
         newpath = os.path.dirname(path)
         if newpath == path:
             break
         path = newpath
 
 def samepath(path1, path2):
     if hasattr(os.path, 'samefile'):
         return os.path.samefile(path1, path2)
-    return os.path.normpath(os.path.realpath(path1)) == \
-        os.path.normpath(os.path.realpath(path2))
+    return os.path.normcase(os.path.realpath(path1)) == \
+        os.path.normcase(os.path.realpath(path2))
 
 class BadEnvironmentException(Exception):
     """Base class for errors raised when the build environment is not sane."""
 
 
 class BuildEnvironmentNotFoundException(BadEnvironmentException):
     """Raised when we could not find a build environment."""
 
--- a/testing/mochitest/tests/SimpleTest/MemoryStats.js
+++ b/testing/mochitest/tests/SimpleTest/MemoryStats.js
@@ -61,35 +61,40 @@ MemoryStats.dump = function (testNumber,
     // Use dump because treeherder uses --quiet, which drops 'info'
     // from the structured logger.
     var info = function(message) {
         dump(message + "\n");
     };
 
     var mrm = MemoryStats._getService("@mozilla.org/memory-reporter-manager;1",
                                       "nsIMemoryReporterManager");
+    var statMessage = "";
     for (var stat in MemoryStats._hasMemoryStatistics) {
         var supported = MemoryStats._hasMemoryStatistics[stat];
         var firstAccess = false;
         if (supported == MEM_STAT_UNKNOWN) {
             firstAccess = true;
             try {
                 var value = mrm[stat];
                 supported = MEM_STAT_SUPPORTED;
             } catch (e) {
                 supported = MEM_STAT_UNSUPPORTED;
             }
             MemoryStats._hasMemoryStatistics[stat] = supported;
         }
         if (supported == MEM_STAT_SUPPORTED) {
-            info("MEMORY STAT " + stat + " after test: " + mrm[stat]);
+            var sizeInMB = Math.round(mrm[stat] / (1024 * 1024));
+            statMessage += " | " + stat + " " + sizeInMB + "MB";
         } else if (firstAccess) {
             info("MEMORY STAT " + stat + " not supported in this build configuration.");
         }
     }
+    if (statMessage.length > 0) {
+        info("MEMORY STAT" + statMessage);
+    }
 
     if (dumpAboutMemory) {
         var basename = "about-memory-" + testNumber + ".json.gz";
         var dumpfile = MemoryStats.constructPathname(dumpOutputDirectory,
                                                      basename);
         info(testURL + " | MEMDUMP-START " + dumpfile);
         var md = MemoryStats._getService("@mozilla.org/memory-info-dumper;1",
                                          "nsIMemoryInfoDumper");
--- a/testing/mozharness/mozharness.json
+++ b/testing/mozharness/mozharness.json
@@ -1,4 +1,4 @@
 {
     "repo": "https://hg.mozilla.org/build/mozharness",
-    "revision": "526075bc2e35"
+    "revision": "321d9dcec7b2"
 }
--- a/tools/profiler/GeckoTaskTracer.cpp
+++ b/tools/profiler/GeckoTaskTracer.cpp
@@ -307,25 +307,37 @@ GetCurTraceInfo(uint64_t* aOutSourceEven
   *aOutParentTaskId = info->mCurTaskId;
   *aOutSourceEventType = info->mCurTraceSourceType;
 }
 
 void
 LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId, uint64_t aSourceEventId,
             SourceEventType aSourceEventType)
 {
+  LogDispatch(aTaskId, aParentTaskId, aSourceEventId, aSourceEventType, 0);
+}
+
+void
+LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId, uint64_t aSourceEventId,
+            SourceEventType aSourceEventType, int aDelayTimeMs)
+{
   TraceInfo* info = GetOrCreateTraceInfo();
   ENSURE_TRUE_VOID(info);
 
+  // aDelayTimeMs is the expected delay time in milliseconds, thus the dispatch
+  // time calculated of it might be slightly off in the real world.
+  uint64_t time = (aDelayTimeMs <= 0) ? GetTimestamp() :
+                  GetTimestamp() + aDelayTimeMs;
+
   // Log format:
   // [0 taskId dispatchTime sourceEventId sourceEventType parentTaskId]
   nsCString* log = info->AppendLog();
   if (log) {
     log->AppendPrintf("%d %lld %lld %lld %d %lld",
-                      ACTION_DISPATCH, aTaskId, GetTimestamp(), aSourceEventId,
+                      ACTION_DISPATCH, aTaskId, time, aSourceEventId,
                       aSourceEventType, aParentTaskId);
   }
 }
 
 void
 LogBegin(uint64_t aTaskId, uint64_t aSourceEventId)
 {
   TraceInfo* info = GetOrCreateTraceInfo();
--- a/tools/profiler/GeckoTaskTracer.h
+++ b/tools/profiler/GeckoTaskTracer.h
@@ -32,20 +32,16 @@ namespace mozilla {
 
 class TimeStamp;
 
 namespace tasktracer {
 
 enum {
   FORKED_AFTER_NUWA = 1 << 0
 };
-void InitTaskTracer(uint32_t aFlags = 0);
-void ShutdownTaskTracer();
-
-class FakeTracedTask;
 
 enum SourceEventType {
   Unknown = 0,
   Touch,
   Mouse,
   Key,
   Bluetooth,
   Unixsocket,
@@ -54,16 +50,19 @@ enum SourceEventType {
 
 class AutoSourceEvent
 {
 public:
   AutoSourceEvent(SourceEventType aType);
   ~AutoSourceEvent();
 };
 
+void InitTaskTracer(uint32_t aFlags = 0);
+void ShutdownTaskTracer();
+
 // Add a label to the currently running task, aFormat is the message to log,
 // followed by corresponding parameters.
 void AddLabel(const char* aFormat, ...);
 
 void StartLogging();
 void StopLogging();
 nsTArray<nsCString>* GetLoggedData(TimeStamp aStartTime);
 
@@ -73,18 +72,16 @@ const PRTime GetStartTime();
 /**
  * Internal functions.
  */
 
 Task* CreateTracedTask(Task* aTask);
 
 already_AddRefed<nsIRunnable> CreateTracedRunnable(nsIRunnable* aRunnable);
 
-already_AddRefed<FakeTracedTask> CreateFakeTracedTask(int* aVptr);
-
 // Free the TraceInfo allocated on a thread's TLS. Currently we are wrapping
 // tasks running on nsThreads and base::thread, so FreeTraceInfo is called at
 // where nsThread and base::thread release themselves.
 void FreeTraceInfo();
 
 const char* GetJSLabelPrefix();
 
 } // namespace tasktracer
--- a/tools/profiler/GeckoTaskTracerImpl.h
+++ b/tools/profiler/GeckoTaskTracerImpl.h
@@ -81,16 +81,20 @@ enum ActionType {
   ACTION_END,
   ACTION_ADD_LABEL,
   ACTION_GET_VTABLE
 };
 
 void LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId,
                  uint64_t aSourceEventId, SourceEventType aSourceEventType);
 
+void LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId,
+                 uint64_t aSourceEventId, SourceEventType aSourceEventType,
+                 int aDelayTimeMs);
+
 void LogBegin(uint64_t aTaskId, uint64_t aSourceEventId);
 
 void LogEnd(uint64_t aTaskId, uint64_t aSourceEventId);
 
 void LogVirtualTablePtr(uint64_t aTaskId, uint64_t aSourceEventId, int* aVptr);
 
 } // namespace mozilla
 } // namespace tasktracer
--- a/tools/profiler/TracedTaskCommon.cpp
+++ b/tools/profiler/TracedTaskCommon.cpp
@@ -2,143 +2,150 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GeckoTaskTracerImpl.h"
 #include "TracedTaskCommon.h"
 
+// NS_ENSURE_TRUE_VOID() without the warning on the debug build.
+#define ENSURE_TRUE_VOID(x)   \
+  do {                        \
+    if (MOZ_UNLIKELY(!(x))) { \
+       return;                \
+    }                         \
+  } while(0)
+
 namespace mozilla {
 namespace tasktracer {
 
 TracedTaskCommon::TracedTaskCommon()
-  : mSourceEventId(0)
-  , mSourceEventType(SourceEventType::Unknown)
+  : mSourceEventType(SourceEventType::Unknown)
+  , mSourceEventId(0)
+  , mParentTaskId(0)
+  , mTaskId(0)
+  , mIsTraceInfoInit(false)
 {
-  Init();
+}
+
+TracedTaskCommon::~TracedTaskCommon()
+{
 }
 
 void
 TracedTaskCommon::Init()
 {
   TraceInfo* info = GetOrCreateTraceInfo();
-  NS_ENSURE_TRUE_VOID(info);
+  ENSURE_TRUE_VOID(info);
 
   mTaskId = GenNewUniqueTaskId();
   mSourceEventId = info->mCurTraceSourceId;
   mSourceEventType = info->mCurTraceSourceType;
+  mParentTaskId = info->mCurTaskId;
+  mIsTraceInfoInit = true;
+}
 
-  LogDispatch(mTaskId, info->mCurTaskId, mSourceEventId, mSourceEventType);
+void
+TracedTaskCommon::DispatchTask(int aDelayTimeMs)
+{
+  LogDispatch(mTaskId, mParentTaskId, mSourceEventId, mSourceEventType,
+              aDelayTimeMs);
 }
 
 void
-TracedTaskCommon::SetTraceInfo()
+TracedTaskCommon::GetTLSTraceInfo()
 {
   TraceInfo* info = GetOrCreateTraceInfo();
-  if (!info) {
-    return;
-  }
+  ENSURE_TRUE_VOID(info);
 
-  info->mCurTraceSourceId = mSourceEventId;
-  info->mCurTraceSourceType = mSourceEventType;
-  info->mCurTaskId = mTaskId;
+  mSourceEventType = info->mCurTraceSourceType;
+  mSourceEventId = info->mCurTraceSourceId;
+  mTaskId = info->mCurTaskId;
+  mIsTraceInfoInit = true;
 }
 
 void
-TracedTaskCommon::ClearTraceInfo()
+TracedTaskCommon::SetTLSTraceInfo()
 {
   TraceInfo* info = GetOrCreateTraceInfo();
-  if (!info) {
-    return;
+  ENSURE_TRUE_VOID(info);
+
+  if (mIsTraceInfoInit) {
+    info->mCurTraceSourceId = mSourceEventId;
+    info->mCurTraceSourceType = mSourceEventType;
+    info->mCurTaskId = mTaskId;
   }
+}
+
+void
+TracedTaskCommon::ClearTLSTraceInfo()
+{
+  TraceInfo* info = GetOrCreateTraceInfo();
+  ENSURE_TRUE_VOID(info);
 
   info->mCurTraceSourceId = 0;
   info->mCurTraceSourceType = SourceEventType::Unknown;
   info->mCurTaskId = 0;
 }
 
 /**
  * Implementation of class TracedRunnable.
  */
 TracedRunnable::TracedRunnable(nsIRunnable* aOriginalObj)
   : TracedTaskCommon()
   , mOriginalObj(aOriginalObj)
 {
+  Init();
   LogVirtualTablePtr(mTaskId, mSourceEventId, *(int**)(aOriginalObj));
 }
 
+TracedRunnable::~TracedRunnable()
+{
+}
+
 NS_IMETHODIMP
 TracedRunnable::Run()
 {
+  SetTLSTraceInfo();
   LogBegin(mTaskId, mSourceEventId);
-
-  SetTraceInfo();
   nsresult rv = mOriginalObj->Run();
-  ClearTraceInfo();
+  LogEnd(mTaskId, mSourceEventId);
+  ClearTLSTraceInfo();
 
-  LogEnd(mTaskId, mSourceEventId);
   return rv;
 }
 
 /**
  * Implementation of class TracedTask.
  */
 TracedTask::TracedTask(Task* aOriginalObj)
   : TracedTaskCommon()
   , mOriginalObj(aOriginalObj)
 {
+  Init();
   LogVirtualTablePtr(mTaskId, mSourceEventId, *(int**)(aOriginalObj));
 }
 
+TracedTask::~TracedTask()
+{
+  if (mOriginalObj) {
+    delete mOriginalObj;
+    mOriginalObj = nullptr;
+  }
+}
+
 void
 TracedTask::Run()
 {
-  LogBegin(mTaskId, mSourceEventId);
-
-  SetTraceInfo();
-  mOriginalObj->Run();
-  ClearTraceInfo();
-
-  LogEnd(mTaskId, mSourceEventId);
-}
-
-FakeTracedTask::FakeTracedTask(int* aVptr)
-  : TracedTaskCommon()
-{
-  LogVirtualTablePtr(mTaskId, mSourceEventId, aVptr);
-}
-
-void
-FakeTracedTask::BeginFakeTracedTask()
-{
+  SetTLSTraceInfo();
   LogBegin(mTaskId, mSourceEventId);
-  SetTraceInfo();
-}
-
-void
-FakeTracedTask::EndFakeTracedTask()
-{
-  ClearTraceInfo();
+  mOriginalObj->Run();
   LogEnd(mTaskId, mSourceEventId);
-}
-
-AutoRunFakeTracedTask::AutoRunFakeTracedTask(FakeTracedTask* aFakeTracedTask)
-  : mFakeTracedTask(aFakeTracedTask)
-{
-  if (mFakeTracedTask) {
-    mFakeTracedTask->BeginFakeTracedTask();
-  }
-}
-
-AutoRunFakeTracedTask::~AutoRunFakeTracedTask()
-{
-  if (mFakeTracedTask) {
-    mFakeTracedTask->EndFakeTracedTask();
-  }
+  ClearTLSTraceInfo();
 }
 
 /**
  * CreateTracedRunnable() returns a TracedRunnable wrapping the original
  * nsIRunnable object, aRunnable.
  */
 already_AddRefed<nsIRunnable>
 CreateTracedRunnable(nsIRunnable* aRunnable)
@@ -153,21 +160,10 @@ CreateTracedRunnable(nsIRunnable* aRunna
  */
 Task*
 CreateTracedTask(Task* aTask)
 {
   Task* task = new TracedTask(aTask);
   return task;
 }
 
-/**
- * CreateFakeTracedTask() returns a FakeTracedTask tracking the event which is
- * not dispatched from its parent task directly, such as timer events.
- */
-already_AddRefed<FakeTracedTask>
-CreateFakeTracedTask(int* aVptr)
-{
-  nsRefPtr<FakeTracedTask> task(new FakeTracedTask(aVptr));
-  return task.forget();
-}
-
 } // namespace tasktracer
 } // namespace mozilla
--- a/tools/profiler/TracedTaskCommon.h
+++ b/tools/profiler/TracedTaskCommon.h
@@ -14,91 +14,60 @@
 
 namespace mozilla {
 namespace tasktracer {
 
 class TracedTaskCommon
 {
 public:
   TracedTaskCommon();
-  virtual ~TracedTaskCommon() {}
+  virtual ~TracedTaskCommon();
+
+  void DispatchTask(int aDelayTimeMs = 0);
+
+  void SetTLSTraceInfo();
+  void GetTLSTraceInfo();
+  void ClearTLSTraceInfo();
 
 protected:
   void Init();
 
-  // Sets up the metadata on the current thread's TraceInfo for this task.
-  // After Run(), ClearTraceInfo is called to reset the metadata.
-  void SetTraceInfo();
-  void ClearTraceInfo();
-
-  // Its own task Id, an unique number base on its thread Id and a last unique
-  // task Id stored in its TraceInfo.
+  // TraceInfo of TLS will be set by the following parameters, including source
+  // event type, source event ID, parent task ID, and task ID of this traced
+  // task/runnable.
+  SourceEventType mSourceEventType;
+  uint64_t mSourceEventId;
+  uint64_t mParentTaskId;
   uint64_t mTaskId;
-
-  uint64_t mSourceEventId;
-  SourceEventType mSourceEventType;
+  bool mIsTraceInfoInit;
 };
 
 class TracedRunnable : public TracedTaskCommon
                      , public nsRunnable
 {
 public:
   NS_DECL_NSIRUNNABLE
 
   TracedRunnable(nsIRunnable* aOriginalObj);
 
 private:
-  virtual ~TracedRunnable() {}
+  virtual ~TracedRunnable();
 
   nsCOMPtr<nsIRunnable> mOriginalObj;
 };
 
 class TracedTask : public TracedTaskCommon
                  , public Task
 {
 public:
   TracedTask(Task* aOriginalObj);
-  ~TracedTask()
-  {
-    if (mOriginalObj) {
-      delete mOriginalObj;
-      mOriginalObj = nullptr;
-    }
-  }
+  ~TracedTask();
 
   virtual void Run();
 
 private:
   Task* mOriginalObj;
 };
 
-// FakeTracedTask is for tracking events that are not directly dispatched from
-// their parents, e.g. The timer events.
-class FakeTracedTask : public TracedTaskCommon
-{
-public:
-  NS_INLINE_DECL_REFCOUNTING(FakeTracedTask)
-
-  FakeTracedTask(int* aVptr);
-  void BeginFakeTracedTask();
-  void EndFakeTracedTask();
-private:
-  virtual ~FakeTracedTask() {}
-
-  // No copy allowed.
-  FakeTracedTask() = delete;
-  FakeTracedTask(const FakeTracedTask& aTask) = delete;
-  FakeTracedTask& operator=(const FakeTracedTask& aTask) = delete;
-};
-
-class AutoRunFakeTracedTask
-{
-public:
-  AutoRunFakeTracedTask(FakeTracedTask* aFakeTracedTask);
-  ~AutoRunFakeTracedTask();
-private:
-  nsRefPtr<FakeTracedTask> mFakeTracedTask;
-};
-
 } // namespace tasktracer
 } // namespace mozilla
 
 #endif
--- a/xpcom/threads/TimerThread.cpp
+++ b/xpcom/threads/TimerThread.cpp
@@ -447,19 +447,19 @@ TimerThread::AddTimerInternal(nsTimerImp
   if (!insertSlot) {
     return -1;
   }
 
   aTimer->mArmed = true;
   NS_ADDREF(aTimer);
 
 #ifdef MOZ_TASK_TRACER
-  // Create a FakeTracedTask, and dispatch it here. This is the start point of
-  // the latency.
-  aTimer->DispatchTracedTask();
+  // Caller of AddTimer is the parent task of its timer event, so we store the
+  // TraceInfo here for later used.
+  aTimer->GetTLSTraceInfo();
 #endif
 
   return insertSlot - mTimers.Elements();
 }
 
 bool
 TimerThread::RemoveTimerInternal(nsTimerImpl* aTimer)
 {
--- a/xpcom/threads/nsThread.cpp
+++ b/xpcom/threads/nsThread.cpp
@@ -67,16 +67,17 @@
 #include "nsStackWalk.h"
 #endif
 #ifdef NS_FUNCTION_TIMER
 #include "nsCRT.h"
 #endif
 
 #ifdef MOZ_TASK_TRACER
 #include "GeckoTaskTracer.h"
+#include "TracedTaskCommon.h"
 using namespace mozilla::tasktracer;
 #endif
 
 using namespace mozilla;
 
 static PRLogModuleInfo*
 GetThreadLog()
 {
@@ -535,16 +536,17 @@ nsThread::DispatchInternal(nsIRunnable* 
   }
 
   if (gXPCOMThreadsShutDown && MAIN_THREAD != mIsMainThread && !aTarget) {
     return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
   }
 
 #ifdef MOZ_TASK_TRACER
   nsCOMPtr<nsIRunnable> tracedRunnable = CreateTracedRunnable(aEvent);
+  (static_cast<TracedRunnable*>(tracedRunnable.get()))->DispatchTask();
   aEvent = tracedRunnable;
 #endif
 
   if (aFlags & DISPATCH_SYNC) {
     nsThread* thread = nsThreadManager::get()->GetCurrentThread();
     if (NS_WARN_IF(!thread)) {
       return NS_ERROR_NOT_AVAILABLE;
     }
--- a/xpcom/threads/nsTimerImpl.cpp
+++ b/xpcom/threads/nsTimerImpl.cpp
@@ -12,16 +12,20 @@
 #include "plarena.h"
 #include "pratom.h"
 #include "GeckoProfiler.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/Logging.h"
 #ifdef MOZ_NUWA_PROCESS
 #include "ipc/Nuwa.h"
 #endif
+#ifdef MOZ_TASK_TRACER
+#include "GeckoTaskTracerImpl.h"
+using namespace mozilla::tasktracer;
+#endif
 
 using mozilla::Atomic;
 using mozilla::LogLevel;
 using mozilla::TimeDuration;
 using mozilla::TimeStamp;
 
 static Atomic<int32_t>  gGenerator;
 static TimerThread*     gThread = nullptr;
@@ -551,23 +555,16 @@ nsTimerImpl::Fire()
     return;
   }
 
 #if !defined(MOZILLA_XPCOMRT_API)
   PROFILER_LABEL("Timer", "Fire",
                  js::ProfileEntry::Category::OTHER);
 #endif
 
-#ifdef MOZ_TASK_TRACER
-  // mTracedTask is an instance of FakeTracedTask created by
-  // DispatchTracedTask(). AutoRunFakeTracedTask logs the begin/end time of the
-  // timer/FakeTracedTask instance in ctor/dtor.
-  mozilla::tasktracer::AutoRunFakeTracedTask runTracedTask(mTracedTask);
-#endif
-
   TimeStamp now = TimeStamp::Now();
   if (MOZ_LOG_TEST(GetTimerLog(), LogLevel::Debug)) {
     TimeDuration   a = now - mStart; // actual delay in intervals
     TimeDuration   b = TimeDuration::FromMilliseconds(mDelay); // expected delay in intervals
     TimeDuration   delta = (a > b) ? a - b : b - a;
     uint32_t       d = delta.ToMilliseconds(); // delta in ms
     sDeltaSum += d;
     sDeltaSumSquared += double(d) * double(d);
@@ -747,16 +744,24 @@ nsTimerImpl::PostTimerEvent(already_AddR
     if (gThread && timer->mType == TYPE_REPEATING_PRECISE) {
       nsresult rv = gThread->AddTimer(timer);
       if (NS_FAILED(rv)) {
         return timer.forget();
       }
     }
   }
 
+#ifdef MOZ_TASK_TRACER
+  // During the dispatch of TimerEvent, we overwrite the current TraceInfo
+  // partially with the info saved in timer earlier, and restore it back by
+  // AutoSaveCurTraceInfo.
+  AutoSaveCurTraceInfo saveCurTraceInfo;
+  (timer->GetTracedTask()).SetTLSTraceInfo();
+#endif
+
   nsIEventTarget* target = timer->mEventTarget;
   event->SetTimer(timer.forget());
 
   nsresult rv = target->Dispatch(event, NS_DISPATCH_NORMAL);
   if (NS_FAILED(rv)) {
     timer = event->ForgetTimer();
     if (gThread) {
       gThread->RemoveTimer(timer);
@@ -790,8 +795,23 @@ nsTimerImpl::SetDelayInternal(uint32_t a
   }
 }
 
 size_t
 nsTimerImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
+
+#ifdef MOZ_TASK_TRACER
+void
+nsTimerImpl::GetTLSTraceInfo()
+{
+  mTracedTask.GetTLSTraceInfo();
+}
+
+TracedTaskCommon
+nsTimerImpl::GetTracedTask()
+{
+  return mTracedTask;
+}
+#endif
+
--- a/xpcom/threads/nsTimerImpl.h
+++ b/xpcom/threads/nsTimerImpl.h
@@ -54,20 +54,18 @@ public:
   NS_DECL_NSITIMER
 
   int32_t GetGeneration()
   {
     return mGeneration;
   }
 
 #ifdef MOZ_TASK_TRACER
-  void DispatchTracedTask()
-  {
-    mTracedTask = mozilla::tasktracer::CreateFakeTracedTask(*(int**)(this));
-  }
+  void GetTLSTraceInfo();
+  mozilla::tasktracer::TracedTaskCommon GetTracedTask();
 #endif
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
 private:
   enum class CallbackType : uint8_t {
     Unknown = 0,
     Interface = 1,
@@ -145,17 +143,17 @@ private:
   // initialized so one-shot timers can be canceled and re-initialized by the
   // arming thread without any bad race conditions.
   int32_t               mGeneration;
 
   uint32_t              mDelay;
   TimeStamp             mTimeout;
 
 #ifdef MOZ_TASK_TRACER
-  nsRefPtr<mozilla::tasktracer::FakeTracedTask> mTracedTask;
+  mozilla::tasktracer::TracedTaskCommon mTracedTask;
 #endif
 
   TimeStamp             mStart, mStart2;
   static double         sDeltaSum;
   static double         sDeltaSumSquared;
   static double         sDeltaNum;
 };