Bug 1353542 - script-generated patch to remove .bind(this) calls we no longer need now that generator functions have been replaced with async functions, r=Mossop.
authorFlorian Quèze <florian@queze.net>
Fri, 12 May 2017 14:47:41 +0200
changeset 406189 586c752c204ac58c3155ef438edf559cc3e648c9
parent 406188 b31650bb06c14be3c39b953e71560357ec1c569e
child 406190 0929827f535f2c57eef31d3c28fdebb84bc87d95
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop
bugs1353542
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1353542 - script-generated patch to remove .bind(this) calls we no longer need now that generator functions have been replaced with async functions, r=Mossop.
browser/base/content/browser-places.js
browser/components/customizableui/CustomizeMode.jsm
browser/components/customizableui/PanelMultiView.jsm
browser/components/customizableui/content/panelUI.js
browser/components/extensions/ExtensionPopups.jsm
browser/components/extensions/ext-devtools.js
browser/components/migration/360seProfileMigrator.js
browser/components/migration/MSMigrationUtils.jsm
browser/components/migration/SafariProfileMigrator.js
browser/components/newtab/NewTabSearchProvider.jsm
browser/components/nsBrowserGlue.js
browser/components/places/content/bookmarkProperties.js
browser/components/places/content/editBookmarkOverlay.js
browser/components/places/content/moveBookmarks.js
browser/components/translation/BingTranslator.jsm
browser/components/translation/TranslationDocument.jsm
browser/components/translation/YandexTranslator.jsm
browser/components/uitour/UITour.jsm
browser/experiments/Experiments.jsm
browser/modules/ContentSearch.jsm
browser/modules/DirectoryLinksProvider.jsm
toolkit/components/crashes/CrashManager.jsm
toolkit/components/extensions/Extension.jsm
toolkit/components/formautofill/content/requestAutocomplete.js
toolkit/components/jsdownloads/src/DownloadCore.jsm
toolkit/components/jsdownloads/src/DownloadImport.jsm
toolkit/components/jsdownloads/src/DownloadList.jsm
toolkit/components/jsdownloads/src/DownloadStore.jsm
toolkit/components/jsdownloads/src/Downloads.jsm
toolkit/components/osfile/modules/osfile_async_front.jsm
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/nsLoginManager.js
toolkit/components/passwordmgr/storage-json.js
toolkit/components/places/BookmarkHTMLUtils.jsm
toolkit/components/places/Bookmarks.jsm
toolkit/components/places/PlacesBackups.jsm
toolkit/components/places/PlacesTransactions.jsm
toolkit/components/places/PlacesUtils.jsm
toolkit/components/places/nsLivemarkService.js
toolkit/components/places/nsPlacesExpiration.js
toolkit/components/places/tests/chrome/test_favicon_annotations.xul
toolkit/components/search/nsSearchService.js
toolkit/components/telemetry/TelemetryController.jsm
toolkit/components/telemetry/TelemetrySend.jsm
toolkit/components/telemetry/TelemetrySession.jsm
toolkit/components/thumbnails/PageThumbs.jsm
toolkit/modules/DeferredTask.jsm
toolkit/modules/JSONFile.jsm
toolkit/modules/Log.jsm
toolkit/modules/Sqlite.jsm
toolkit/mozapps/downloads/nsHelperAppDlg.js
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/internal/AddonRepository.jsm
toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
toolkit/mozapps/extensions/internal/GMPProvider.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -352,19 +352,19 @@ var StarUI = {
   // we start a PlacesTransactions batch when the star UI panel is shown, and
   // we keep the batch ongoing until the panel is hidden.
   _batchBlockingDeferred: null,
   beginBatch() {
     if (this._batching)
       return;
     if (PlacesUIUtils.useAsyncTransactions) {
       this._batchBlockingDeferred = PromiseUtils.defer();
-      PlacesTransactions.batch(async function() {
+      PlacesTransactions.batch(async () => {
         await this._batchBlockingDeferred.promise;
-      }.bind(this));
+      });
     } else {
       PlacesUtils.transactionManager.beginBatch(null);
     }
     this._batching = true;
   },
 
   endBatch() {
     if (!this._batching)
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -240,17 +240,17 @@ CustomizeMode.prototype = {
 
     this._handler.isEnteringCustomizeMode = true;
 
     // Always disable the reset button at the start of customize mode, it'll be re-enabled
     // if necessary when we finish entering:
     let resetButton = this.document.getElementById("customization-reset-button");
     resetButton.setAttribute("disabled", "true");
 
-    (async function() {
+    (async () => {
       // We shouldn't start customize mode until after browser-delayed-startup has finished:
       if (!this.window.gBrowserInit.delayedStartupFinished) {
         await new Promise(resolve => {
           let delayedStartupObserver = aSubject => {
             if (aSubject == this.window) {
               Services.obs.removeObserver(delayedStartupObserver, "browser-delayed-startup-finished");
               resolve();
             }
@@ -399,17 +399,17 @@ CustomizeMode.prototype = {
           this.panelUIContents.setAttribute("showoutline", "true");
         }
         delete this._enableOutlinesTimeout;
       }, 0);
 
       if (!this._wantToBeInCustomizeMode) {
         this.exit();
       }
-    }.bind(this))().then(null, e => {
+    })().then(null, e => {
       log.error("Error entering customize mode", e);
       // We should ensure this has been called, and calling it again doesn't hurt:
       window.PanelUI.endBatchUpdate();
       this._handler.isEnteringCustomizeMode = false;
       // Exit customize mode to ensure proper clean-up when entering failed.
       this.exit();
     });
   },
@@ -476,17 +476,17 @@ CustomizeMode.prototype = {
 
     // Disable the reset and undo reset buttons while transitioning:
     let resetButton = this.document.getElementById("customization-reset-button");
     let undoResetButton = this.document.getElementById("customization-undo-reset-button");
     undoResetButton.hidden = resetButton.disabled = true;
 
     this._transitioning = true;
 
-    (async function() {
+    (async () => {
       await this.depopulatePalette();
 
       await this._doTransition(false);
       this.updateLWTStyling({});
 
       Services.obs.removeObserver(this, "lightweight-theme-window-updated");
 
       if (this.browser.selectedTab == gTab) {
@@ -569,17 +569,17 @@ CustomizeMode.prototype = {
       this._transitioning = false;
       this._handler.isExitingCustomizeMode = false;
       CustomizableUI.dispatchToolboxEvent("aftercustomization", {}, window);
       CustomizableUI.notifyEndCustomizing(window);
 
       if (this._wantToBeInCustomizeMode) {
         this.enter();
       }
-    }.bind(this))().then(null, e => {
+    })().then(null, e => {
       log.error("Error exiting customize mode", e);
       if (!gPhotonStructure) {
         // We should ensure this has been called, and calling it again doesn't hurt:
         window.PanelUI.endBatchUpdate();
       }
       this._handler.isExitingCustomizeMode = false;
     });
   },
@@ -811,17 +811,17 @@ CustomizeMode.prototype = {
     }
 
     let wrapper = this.createOrUpdateWrapper(widgetNode, aPlace);
     wrapper.appendChild(widgetNode);
     return wrapper;
   },
 
   depopulatePalette() {
-    return (async function() {
+    return (async () => {
       this.visiblePalette.hidden = true;
       let paletteChild = this.visiblePalette.firstChild;
       let nextChild;
       while (paletteChild) {
         nextChild = paletteChild.nextElementSibling;
         let provider = CustomizableUI.getWidget(paletteChild.id).provider;
         if (provider == CustomizableUI.PROVIDER_XUL) {
           let unwrappedPaletteItem =
@@ -837,17 +837,17 @@ CustomizeMode.prototype = {
         } else if (provider == CustomizableUI.PROVIDER_SPECIAL) {
           this.visiblePalette.removeChild(paletteChild);
         }
 
         paletteChild = nextChild;
       }
       this.visiblePalette.hidden = false;
       this.window.gNavToolbox.palette = this._stowedPalette;
-    }.bind(this))().then(null, log.error);
+    })().then(null, log.error);
   },
 
   isCustomizableItem(aNode) {
     return aNode.localName == "toolbarbutton" ||
            aNode.localName == "toolbaritem" ||
            aNode.localName == "toolbarseparator" ||
            aNode.localName == "toolbarspring" ||
            aNode.localName == "toolbarspacer";
@@ -1110,27 +1110,27 @@ CustomizeMode.prototype = {
     for (let toolbarItem of target.children) {
       if (this.isWrappedToolbarItem(toolbarItem)) {
         this.unwrapToolbarItem(toolbarItem);
       }
     }
   },
 
   _unwrapToolbarItems() {
-    return (async function() {
+    return (async () => {
       for (let target of this.areas) {
         for (let toolbarItem of target.children) {
           if (this.isWrappedToolbarItem(toolbarItem)) {
             await this.deferredUnwrapToolbarItem(toolbarItem);
           }
         }
         this._removeDragHandlers(target);
       }
       this.areas.clear();
-    }.bind(this))().then(null, log.error);
+    })().then(null, log.error);
   },
 
   _removeExtraToolbarsIfEmpty() {
     let toolbox = this.window.gNavToolbox;
     for (let child of toolbox.children) {
       if (child.hasAttribute("customindex")) {
         let placements = CustomizableUI.getWidgetIdsInArea(child.id);
         if (!placements.length) {
@@ -1154,17 +1154,17 @@ CustomizeMode.prototype = {
   },
 
   reset() {
     this.resetting = true;
     // Disable the reset button temporarily while resetting:
     let btn = this.document.getElementById("customization-reset-button");
     BrowserUITelemetry.countCustomizationEvent("reset");
     btn.disabled = true;
-    return (async function() {
+    return (async () => {
       this._removePanelCustomizationPlaceholders();
       await this.depopulatePalette();
       await this._unwrapToolbarItems();
 
       CustomizableUI.reset();
 
       this._updateLWThemeButtonIcon();
 
@@ -1176,23 +1176,23 @@ CustomizeMode.prototype = {
       this._updateResetButton();
       this._updateUndoResetButton();
       this._updateEmptyPaletteNotice();
       this._showPanelCustomizationPlaceholders();
       this.resetting = false;
       if (!this._wantToBeInCustomizeMode) {
         this.exit();
       }
-    }.bind(this))().then(null, log.error);
+    })().then(null, log.error);
   },
 
   undoReset() {
     this.resetting = true;
 
-    return (async function() {
+    return (async () => {
       this._removePanelCustomizationPlaceholders();
       await this.depopulatePalette();
       await this._unwrapToolbarItems();
 
       CustomizableUI.undoReset();
 
       this._updateLWThemeButtonIcon();
 
@@ -1200,17 +1200,17 @@ CustomizeMode.prototype = {
       this.populatePalette();
 
       this.persistCurrentSets(true);
 
       this._updateResetButton();
       this._updateUndoResetButton();
       this._updateEmptyPaletteNotice();
       this.resetting = false;
-    }.bind(this))().then(null, log.error);
+    })().then(null, log.error);
   },
 
   _onToolbarVisibilityChange(aEvent) {
     let toolbar = aEvent.target;
     if (aEvent.detail.visible && toolbar.getAttribute("customizable") == "true") {
       toolbar.setAttribute("customizing", "true");
     } else {
       toolbar.removeAttribute("customizing");
--- a/browser/components/customizableui/PanelMultiView.jsm
+++ b/browser/components/customizableui/PanelMultiView.jsm
@@ -355,17 +355,17 @@ this.PanelMultiView = class {
       }
 
       this._shiftMainView();
     }
   }
 
   showSubView(aViewId, aAnchor, aPreviousView, aAdopted = false) {
     const {document, window} = this;
-    return (async function() {
+    return (async () => {
       // Support passing in the node directly.
       let viewNode = typeof aViewId == "string" ? this.node.querySelector("#" + aViewId) : aViewId;
       if (!viewNode) {
         viewNode = document.getElementById(aViewId);
         if (viewNode) {
           if (this.panelViews) {
             this._viewStack.appendChild(viewNode);
             this.panelViews.push(viewNode);
@@ -572,17 +572,17 @@ this.PanelMultiView = class {
 
         this._subViewObserver.observe(viewNode, {
           attributes: true,
           characterData: true,
           childList: true,
           subtree: true
         });
       }
-    }.bind(this))();
+    })();
   }
 
   _setViewContainerHeight(aHeight) {
     let container = this._viewContainer;
     this._transitioning = true;
 
     let onTransitionEnd = () => {
       container.removeEventListener("transitionend", onTransitionEnd);
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -402,17 +402,17 @@ const PanelUI = {
     }
     this._ensureEventListenersAdded();
     if (gPhotonStructure) {
       this.panel.hidden = false;
       this._readyPromise = Promise.resolve();
       this._isReady = true;
       return this._readyPromise;
     }
-    this._readyPromise = (async function() {
+    this._readyPromise = (async () => {
       if (!this._initialized) {
         await new Promise(resolve => {
           let delayedStartupObserver = (aSubject, aTopic, aData) => {
             if (aSubject == window) {
               Services.obs.removeObserver(delayedStartupObserver, "browser-delayed-startup-finished");
               resolve();
             }
           };
@@ -450,17 +450,17 @@ const PanelUI = {
           CustomizableUI.registerMenuPanel(this.contents, CustomizableUI.AREA_PANEL);
         } finally {
           this.endBatchUpdate();
         }
       }
       this._updateQuitTooltip();
       this.panel.hidden = false;
       this._isReady = true;
-    }.bind(this))().then(null, Cu.reportError);
+    })().then(null, Cu.reportError);
 
     return this._readyPromise;
   },
 
   /**
    * Switch the panel to the main view if it's not already
    * in that view.
    */
--- a/browser/components/extensions/ExtensionPopups.jsm
+++ b/browser/components/extensions/ExtensionPopups.jsm
@@ -442,17 +442,17 @@ class ViewPopup extends BasePopup {
    * @param {Element} viewNode
    *        The node to attach the browser to.
    * @returns {Promise<boolean>}
    *        Resolves when the browser is ready. Resolves to `false` if the
    *        browser was destroyed before it was fully loaded, and the popup
    *        should be closed, or `true` otherwise.
    */
   attach(viewNode) {
-    return (async function() {
+    return (async () => {
       this.viewNode = viewNode;
       this.viewNode.addEventListener(this.DESTROY_EVENT, this);
 
       // Wait until the browser element is fully initialized, and give it at least
       // a short grace period to finish loading its initial content, if necessary.
       //
       // In practice, the browser that was created by the mousdown handler should
       // nearly always be ready by this point.
@@ -524,17 +524,17 @@ class ViewPopup extends BasePopup {
 
       let event = new this.window.CustomEvent("WebExtPopupLoaded", {
         bubbles: true,
         detail: {extension: this.extension},
       });
       this.browser.dispatchEvent(event);
 
       return true;
-    }.bind(this))();
+    })();
   }
 
   destroy() {
     return super.destroy().then(() => {
       if (this.tempPanel) {
         this.tempPanel.remove();
         this.tempPanel = null;
       }
--- a/browser/components/extensions/ext-devtools.js
+++ b/browser/components/extensions/ext-devtools.js
@@ -113,17 +113,17 @@ class DevToolsPage extends HiddenExtensi
     this.unwatchExtensionProxyContextLoad = null;
 
     this.waitForTopLevelContext = new Promise(resolve => {
       this.resolveTopLevelContext = resolve;
     });
   }
 
   build() {
-    return (async function() {
+    return (async () => {
       await this.createBrowserElement();
 
       // Listening to new proxy contexts.
       this.unwatchExtensionProxyContextLoad = watchExtensionProxyContextLoad(this, context => {
         // Keep track of the toolbox and target associated to the context, which is
         // needed by the API methods implementation.
         context.devToolsToolbox = this.toolbox;
 
@@ -142,17 +142,17 @@ class DevToolsPage extends HiddenExtensi
         devtoolsToolboxInfo: {
           inspectedWindowTabId: getTargetTabIdForToolbox(this.toolbox),
         },
       });
 
       this.browser.loadURI(this.url);
 
       await this.waitForTopLevelContext;
-    }.bind(this))();
+    })();
   }
 
   close() {
     if (this.closed) {
       throw new Error("Unable to shutdown a closed DevToolsPage instance");
     }
 
     this.closed = true;
--- a/browser/components/migration/360seProfileMigrator.js
+++ b/browser/components/migration/360seProfileMigrator.js
@@ -104,17 +104,17 @@ function Bookmarks(aProfileFolder) {
 Bookmarks.prototype = {
   type: MigrationUtils.resourceTypes.BOOKMARKS,
 
   get exists() {
     return this._file.exists() && this._file.isReadable();
   },
 
   migrate(aCallback) {
-    return (async function() {
+    return (async () => {
       let idToGuid = new Map();
       let folderGuid = PlacesUtils.bookmarks.toolbarGuid;
       if (!MigrationUtils.isStartupMigration) {
         folderGuid =
           await MigrationUtils.createImportedBookmarksFolder("360se", folderGuid);
       }
       idToGuid.set(0, folderGuid);
 
@@ -170,17 +170,17 @@ Bookmarks.prototype = {
             }
           } catch (ex) {
             Cu.reportError(ex);
           }
         }
       } finally {
         await connection.close();
       }
-    }.bind(this))().then(() => aCallback(true),
+    })().then(() => aCallback(true),
                         e => { Cu.reportError(e); aCallback(false) });
   }
 };
 
 function Qihoo360seProfileMigrator() {
   let paths = [
     // for v6 and above
     {
--- a/browser/components/migration/MSMigrationUtils.jsm
+++ b/browser/components/migration/MSMigrationUtils.jsm
@@ -358,25 +358,25 @@ Bookmarks.prototype = {
       } else {
         this.__toolbarFolderName = "Links";
       }
     }
     return this.__toolbarFolderName;
   },
 
   migrate: function B_migrate(aCallback) {
-    return (async function() {
+    return (async () => {
       // Import to the bookmarks menu.
       let folderGuid = PlacesUtils.bookmarks.menuGuid;
       if (!MigrationUtils.isStartupMigration) {
         folderGuid =
           await MigrationUtils.createImportedBookmarksFolder(this.importedAppLabel, folderGuid);
       }
       await this._migrateFolder(this._favoritesFolder, folderGuid);
-    }.bind(this))().then(() => aCallback(true),
+    })().then(() => aCallback(true),
                        e => { Cu.reportError(e); aCallback(false) });
   },
 
   async _migrateFolder(aSourceFolder, aDestFolderGuid) {
     let bookmarks = await this._getBookmarksInFolder(aSourceFolder);
     if (bookmarks.length) {
       await MigrationUtils.insertManyBookmarksWrapper(bookmarks, aDestFolderGuid);
     }
--- a/browser/components/migration/SafariProfileMigrator.js
+++ b/browser/components/migration/SafariProfileMigrator.js
@@ -30,30 +30,30 @@ Cu.importGlobalProperties(["URL"]);
 
 function Bookmarks(aBookmarksFile) {
   this._file = aBookmarksFile;
 }
 Bookmarks.prototype = {
   type: MigrationUtils.resourceTypes.BOOKMARKS,
 
   migrate: function B_migrate(aCallback) {
-    return (async function() {
+    return (async () => {
       let dict = await new Promise(resolve =>
         PropertyListUtils.read(this._file, resolve)
       );
       if (!dict)
         throw new Error("Could not read Bookmarks.plist");
       let children = dict.get("Children");
       if (!children)
         throw new Error("Invalid Bookmarks.plist format");
 
       let collection = dict.get("Title") == "com.apple.ReadingList" ?
         this.READING_LIST_COLLECTION : this.ROOT_COLLECTION;
       await this._migrateCollection(children, collection);
-    }.bind(this))().then(() => aCallback(true),
+    })().then(() => aCallback(true),
                         e => { Cu.reportError(e); aCallback(false) });
   },
 
   // Bookmarks collections in Safari.  Constants for migrateCollection.
   ROOT_COLLECTION:         0,
   MENU_COLLECTION:         1,
   TOOLBAR_COLLECTION:      2,
   READING_LIST_COLLECTION: 3,
--- a/browser/components/newtab/NewTabSearchProvider.jsm
+++ b/browser/components/newtab/NewTabSearchProvider.jsm
@@ -24,25 +24,25 @@ function SearchProvider() {
 }
 
 SearchProvider.prototype = {
 
   observe(subject, topic, data) { // jshint unused:false
     // all other topics are not relevant to content searches and can be
     // ignored by NewTabSearchProvider
     if (data === "engine-current" && topic === CURRENT_ENGINE) {
-      (async function() {
+      (async () => {
         try {
           let state = await ContentSearch.currentStateObj(true);
           let engine = state.currentEngine;
           this.emit(CURRENT_ENGINE, engine);
         } catch (e) {
           Cu.reportError(e);
         }
-      }.bind(this))();
+      })();
     }
   },
 
   init() {
     try {
       Services.obs.addObserver(this, CURRENT_ENGINE, true);
     } catch (e) {
       Cu.reportError(e);
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1491,17 +1491,17 @@ BrowserGlue.prototype = {
     if (autoExportHTML) {
       // Sqlite.jsm and Places shutdown happen at profile-before-change, thus,
       // to be on the safe side, this should run earlier.
       AsyncShutdown.profileChangeTeardown.addBlocker(
         "Places: export bookmarks.html",
         () => BookmarkHTMLUtils.exportToFile(BookmarkHTMLUtils.defaultPath));
     }
 
-    (async function() {
+    (async () => {
       // Check if Safe Mode or the user has required to restore bookmarks from
       // default profile's bookmarks.html
       let restoreDefaultBookmarks = false;
       try {
         restoreDefaultBookmarks =
           Services.prefs.getBoolPref("browser.bookmarks.restore_default_bookmarks");
         if (restoreDefaultBookmarks) {
           // Ensure that we already have a bookmarks backup for today.
@@ -1626,17 +1626,17 @@ BrowserGlue.prototype = {
 
             if (backupAge > BOOKMARKS_BACKUP_MAX_INTERVAL_DAYS)
               this._bookmarksBackupIdleTime /= 2;
           }
         }
         this._idleService.addIdleObserver(this, this._bookmarksBackupIdleTime);
       }
 
-    }.bind(this))().catch(ex => {
+    })().catch(ex => {
       Cu.reportError(ex);
     }).then(() => {
       // NB: deliberately after the catch so that we always do this, even if
       // we threw halfway through initializing in the Task above.
       Services.obs.notifyObservers(null, "places-browser-init-complete");
     });
   },
 
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -375,19 +375,19 @@ var BookmarkPropertiesPanel = {
 	// instant-apply code. For all the details see the comment above beginBatch
 	// in browser-places.js
   _batchBlockingDeferred: null,
   _beginBatch() {
     if (this._batching)
       return;
     if (PlacesUIUtils.useAsyncTransactions) {
       this._batchBlockingDeferred = PromiseUtils.defer();
-      PlacesTransactions.batch(async function() {
+      PlacesTransactions.batch(async () => {
         await this._batchBlockingDeferred.promise;
-      }.bind(this));
+      });
     } else {
       PlacesUtils.transactionManager.beginBatch(null);
     }
     this._batching = true;
   },
 
   _endBatch() {
     if (!this._batching)
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -794,21 +794,21 @@ var gEditItemOverlay = {
       return;
     }
 
     // Move the item
     let containerId = this._getFolderIdFromMenuList();
     if (PlacesUtils.bookmarks.getFolderIdForItem(this._paneInfo.itemId) != containerId &&
         this._paneInfo.itemId != containerId) {
       if (PlacesUIUtils.useAsyncTransactions) {
-        (async function() {
+        (async () => {
           let newParentGuid = await PlacesUtils.promiseItemGuid(containerId);
           let guid = this._paneInfo.itemGuid;
           await PlacesTransactions.Move({ guid, newParentGuid }).transact();
-        }.bind(this))();
+        })();
       } else {
         let txn = new PlacesMoveItemTransaction(this._paneInfo.itemId,
                                                 containerId,
                                                 PlacesUtils.bookmarks.DEFAULT_INDEX);
         PlacesUtils.transactionManager.doTransaction(txn);
       }
 
       // Mark the containing folder as recently-used if it isn't in the
--- a/browser/components/places/content/moveBookmarks.js
+++ b/browser/components/places/content/moveBookmarks.js
@@ -40,26 +40,26 @@ var gMoveBookmarksDialog = {
       }
       if (transactions.length != 0) {
         let txn = new PlacesAggregatedTransaction("Move Items", transactions);
         PlacesUtils.transactionManager.doTransaction(txn);
       }
       return;
     }
 
-    PlacesTransactions.batch(async function() {
+    PlacesTransactions.batch(async () => {
       let newParentGuid = await PlacesUtils.promiseItemGuid(selectedFolderId);
       for (let node of this._nodes) {
         // Nothing to do if the node is already under the selected folder.
         if (node.parent.itemId == selectedFolderId)
           continue;
         await PlacesTransactions.Move({ guid: node.bookmarkGuid
                                       , newParentGuid }).transact();
       }
-    }.bind(this)).then(null, Components.utils.reportError);
+    }).then(null, Components.utils.reportError);
   },
 
   newFolder: function MBD_newFolder() {
     // The command is disabled when the tree is not focused
     this.foldersTree.focus();
     goDoCommand("placesCmd_new:folder");
   }
 };
--- a/browser/components/translation/BingTranslator.jsm
+++ b/browser/components/translation/BingTranslator.jsm
@@ -53,17 +53,17 @@ this.BingTranslator.prototype = {
   /**
    * Performs the translation, splitting the document into several chunks
    * respecting the data limits of the API.
    *
    * @returns {Promise}          A promise that will resolve when the translation
    *                             task is finished.
    */
   translate() {
-    return (async function() {
+    return (async () => {
       let currentIndex = 0;
       this._onFinishedDeferred = Promise.defer();
 
       // Let's split the document into various requests to be sent to
       // Bing's Translation API.
       for (let requestCount = 0; requestCount < MAX_REQUESTS; requestCount++) {
         // Generating the text for each request can be expensive, so
         // let's take the opportunity of the chunkification process to
@@ -85,17 +85,17 @@ this.BingTranslator.prototype = {
 
         currentIndex = request.lastIndex;
         if (request.finished) {
           break;
         }
       }
 
       return this._onFinishedDeferred.promise;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Resets the expiration time of the current token, in order to
    * force the token manager to ask for a new token during the next request.
    */
   _resetToken() {
     // Force the token manager to get update token
@@ -280,17 +280,17 @@ function BingRequest(translationData, so
   this.characterCount = 0;
 }
 
 BingRequest.prototype = {
   /**
    * Initiates the request
    */
   fireRequest() {
-    return (async function() {
+    return (async () => {
       // Prepare authentication.
       let token = await BingTokenManager.getToken();
       let auth = "Bearer " + token;
 
       // Prepare URL.
       let url = getUrlParam("https://api.microsofttranslator.com/v2/Http.svc/TranslateArray",
                             "browser.translation.bing.translateArrayURL");
 
@@ -332,17 +332,17 @@ BingRequest.prototype = {
 
       // Fire the request.
       let request = httpRequest(url, options);
 
       // Override the response MIME type.
       request.overrideMimeType("text/xml");
       this.networkRequest = request;
       return deferred.promise;
-    }.bind(this))();
+    })();
   }
 };
 
 /**
  * Authentication Token manager for the API
  */
 var BingTokenManager = {
   _currentToken: null,
--- a/browser/components/translation/TranslationDocument.jsm
+++ b/browser/components/translation/TranslationDocument.jsm
@@ -203,30 +203,30 @@ this.TranslationDocument.prototype = {
   /**
    * Swap the document with the resulting translation,
    * or back with the original content.
    *
    * @param target   A string that is either "translation"
    *                 or "original".
    */
   _swapDocumentContent(target) {
-    (async function() {
+    (async () => {
       // Let the event loop breath on every 100 nodes
       // that are replaced.
       const YIELD_INTERVAL = 100;
       let count = YIELD_INTERVAL;
 
       for (let root of this.roots) {
         root.swapText(target);
         if (count-- == 0) {
           count = YIELD_INTERVAL;
           await CommonUtils.laterTickResolvingPromise();
         }
       }
-    }.bind(this))();
+    })();
   }
 };
 
 /**
  * This class represents an item for translation. It's basically our
  * wrapper class around a node returned by getTranslationNode, with
  * more data and structural information on it.
  *
--- a/browser/components/translation/YandexTranslator.jsm
+++ b/browser/components/translation/YandexTranslator.jsm
@@ -71,17 +71,17 @@ this.YandexTranslator.prototype = {
   /**
    * Performs the translation, splitting the document into several chunks
    * respecting the data limits of the API.
    *
    * @returns {Promise}          A promise that will resolve when the translation
    *                             task is finished.
    */
   translate() {
-    return (async function() {
+    return (async () => {
       let currentIndex = 0;
       this._onFinishedDeferred = Promise.defer();
 
       // Let's split the document into various requests to be sent to
       // Yandex's Translation API.
       for (let requestCount = 0; requestCount < MAX_REQUESTS; requestCount++) {
         // Generating the text for each request can be expensive, so
         // let's take the opportunity of the chunkification process to
@@ -103,17 +103,17 @@ this.YandexTranslator.prototype = {
 
         currentIndex = request.lastIndex;
         if (request.finished) {
           break;
         }
       }
 
       return this._onFinishedDeferred.promise;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Function called when a request sent to the server completed successfully.
    * This function handles calling the function to parse the result and the
    * function to resolve the promise returned by the public `translate()`
    * method when there are no pending requests left.
    *
@@ -287,17 +287,17 @@ function YandexRequest(translationData, 
   this.characterCount = 0;
 }
 
 YandexRequest.prototype = {
   /**
    * Initiates the request
    */
   fireRequest() {
-    return (async function() {
+    return (async () => {
       // Prepare URL.
       let url = getUrlParam("https://translate.yandex.net/api/v1.5/tr.json/translate",
                             "browser.translation.yandex.translateURLOverride");
 
       // Prepare the request body.
       let apiKey = getUrlParam("%YANDEX_API_KEY%", "browser.translation.yandex.apiKeyOverride");
       let params = [
         ["key", apiKey],
@@ -321,17 +321,17 @@ YandexRequest.prototype = {
         },
         postData: params
       };
 
       // Fire the request.
       this.networkRequest = httpRequest(url, options);
 
       return deferred.promise;
-    }.bind(this))();
+    })();
   }
 };
 
 /**
  * Fetch an auth token (clientID or client secret), which may be overridden by
  * a pref if it's set.
  */
 function getUrlParam(paramValue, prefName) {
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -1876,17 +1876,17 @@ this.UITour = {
         break;
       default:
         log.error("setConfiguration: Unknown configuration requested: " + aConfiguration);
         break;
     }
   },
 
   getAvailableTargets(aMessageManager, aChromeWindow, aCallbackID) {
-    (async function() {
+    (async () => {
       let window = aChromeWindow;
       let data = this.availableTargetsCache.get(window);
       if (data) {
         log.debug("getAvailableTargets: Using cached targets list", data.targets.join(","));
         this.sendPageCallback(aMessageManager, aCallbackID, data);
         return;
       }
 
@@ -1902,17 +1902,17 @@ this.UITour = {
           targetNames.push(targetObject.targetName);
       }
 
       data = {
         targets: targetNames,
       };
       this.availableTargetsCache.set(window, data);
       this.sendPageCallback(aMessageManager, aCallbackID, data);
-    }.bind(this))().catch(err => {
+    })().catch(err => {
       log.error(err);
       this.sendPageCallback(aMessageManager, aCallbackID, {
         targets: [],
       });
     });
   },
 
   addNavBarWidget(aTarget, aMessageManager, aCallbackID) {
--- a/browser/experiments/Experiments.jsm
+++ b/browser/experiments/Experiments.jsm
@@ -610,17 +610,17 @@ Experiments.Experiments.prototype = {
    *   endDate: <integer>, // epoch ms
    *   detailURL: <string>,
    *   ... // possibly extended later
    * }
    *
    * @return Promise<Array<ExperimentInfo>> Array of experiment info objects.
    */
   getExperiments() {
-    return (async function() {
+    return (async () => {
       await this._loadTask;
       let list = [];
 
       for (let [id, experiment] of this._experiments) {
         if (!experiment.startDate) {
           // We only collect experiments that are or were active.
           continue;
         }
@@ -634,17 +634,17 @@ Experiments.Experiments.prototype = {
           detailURL: experiment._homepageURL,
           branch: experiment.branch,
         });
       }
 
       // Sort chronologically, descending.
       list.sort((a, b) => b.endDate - a.endDate);
       return list;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Returns the ExperimentInfo for the active experiment, or null
    * if there is none.
    */
   getActiveExperiment() {
     let experiment = this._getActiveExperiment();
@@ -728,39 +728,39 @@ Experiments.Experiments.prototype = {
    *
    * If no experiment was active today, this resolves to nothing.
    *
    * Assumption: Only a single experiment can be active at a time.
    *
    * @return Promise<object>
    */
   lastActiveToday() {
-    return (async function getMostRecentActiveExperimentTask() {
+    return (async () => {
       let experiments = await this.getExperiments();
 
       // Assumption: Ordered chronologically, descending, with active always
       // first.
       for (let experiment of experiments) {
         if (experiment.active) {
           return experiment;
         }
 
         if (experiment.endDate && this._dateIsTodayUTC(experiment.endDate)) {
           return experiment;
         }
       }
       return null;
-    }.bind(this))();
+    })();
   },
 
   _run() {
     this._log.trace("_run");
     this._checkForShutdown();
     if (!this._mainTask) {
-      this._mainTask = (async function() {
+      this._mainTask = (async () => {
         try {
           await this._main();
         } catch (e) {
           // In the CacheWriteError case we want to reschedule
           if (!(e instanceof CacheWriteError)) {
             this._log.error("_main caught error: " + e);
             return;
           }
@@ -771,17 +771,17 @@ Experiments.Experiments.prototype = {
         try {
           await this._scheduleNextRun();
         } catch (ex) {
           // We error out of tasks after shutdown via this exception.
           if (!(ex instanceof AlreadyShutdownError)) {
             throw ex;
           }
         }
-      }.bind(this))();
+      })();
     }
     return this._mainTask;
   },
 
   async _main() {
     do {
       this._log.trace("_main iteration");
       await this._loadTask;
--- a/browser/modules/ContentSearch.jsm
+++ b/browser/modules/ContentSearch.jsm
@@ -345,26 +345,26 @@ this.ContentSearch = {
 
   _processEventQueue() {
     if (this._currentEventPromise || !this._eventQueue.length) {
       return;
     }
 
     let event = this._eventQueue.shift();
 
-    this._currentEventPromise = (async function() {
+    this._currentEventPromise = (async () => {
       try {
         await this["_on" + event.type](event.data);
       } catch (err) {
         Cu.reportError(err);
       } finally {
         this._currentEventPromise = null;
         this._processEventQueue();
       }
-    }.bind(this))();
+    })();
   },
 
   _cancelSuggestions(msg) {
     let cancelled = false;
     // cancel active suggestion request
     if (this._currentSuggestion && this._currentSuggestion.target === msg.target) {
       this._currentSuggestion.controller.stop();
       cancelled = true;
--- a/browser/modules/DirectoryLinksProvider.jsm
+++ b/browser/modules/DirectoryLinksProvider.jsm
@@ -325,26 +325,26 @@ var DirectoryLinksProvider = {
   init: function DirectoryLinksProvider_init() {
     this._setDefaultEnhanced();
     this._addPrefsObserver();
     Services.obs.addObserver(this, "intl:requested-locales-changed");
     // setup directory file path and last download timestamp
     this._directoryFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, DIRECTORY_LINKS_FILE);
     this._lastDownloadMS = 0;
 
-    return (async function() {
+    return (async () => {
       // get the last modified time of the links file if it exists
       let doesFileExists = await OS.File.exists(this._directoryFilePath);
       if (doesFileExists) {
         let fileInfo = await OS.File.stat(this._directoryFilePath);
         this._lastDownloadMS = Date.parse(fileInfo.lastModificationDate);
       }
       // fetch directory on startup without force
       await this._fetchAndCacheLinksIfNecessary();
-    }.bind(this))();
+    })();
   },
 
   /**
    * Return the object to its pre-init state
    */
   reset: function DirectoryLinksProvider_reset() {
     delete this.__linksURL;
     this._removePrefsObserver();
--- a/toolkit/components/crashes/CrashManager.jsm
+++ b/toolkit/components/crashes/CrashManager.jsm
@@ -321,17 +321,17 @@ this.CrashManager.prototype = Object.fre
    *
    * @return promise<int> The number of event files that were examined.
    */
   aggregateEventsFiles() {
     if (this._aggregatePromise) {
       return this._aggregatePromise;
     }
 
-    return this._aggregatePromise = (async function() {
+    return this._aggregatePromise = (async () => {
       if (this._aggregatePromise) {
         return this._aggregatePromise;
       }
 
       try {
         let unprocessedFiles = await this._getUnprocessedEventsFiles();
 
         let deletePaths = [];
@@ -389,44 +389,44 @@ this.CrashManager.prototype = Object.fre
         }
 
         return unprocessedFiles.length;
 
       } finally {
         this._aggregatePromise = false;
         this._storeProtectedCount--;
       }
-    }.bind(this))();
+    })();
   },
 
   /**
    * Prune old crash data.
    *
    * @param date
    *        (Date) The cutoff point for pruning. Crashes without data newer
    *        than this will be pruned.
    */
   pruneOldCrashes(date) {
-    return (async function() {
+    return (async () => {
       let store = await this._getStore();
       store.pruneOldCrashes(date);
       await store.save();
-    }.bind(this))();
+    })();
   },
 
   /**
    * Run tasks that should be periodically performed.
    */
   runMaintenanceTasks() {
-    return (async function() {
+    return (async () => {
       await this.aggregateEventsFiles();
 
       let offset = this.PURGE_OLDER_THAN_DAYS * MILLISECONDS_IN_DAY;
       await this.pruneOldCrashes(new Date(Date.now() - offset));
-    }.bind(this))();
+    })();
   },
 
   /**
    * Schedule maintenance tasks for some point in the future.
    *
    * @param delay
    *        (integer) Delay in milliseconds when maintenance should occur.
    */
@@ -450,17 +450,17 @@ this.CrashManager.prototype = Object.fre
    * @param crashType (string) One of the CRASH_TYPE constants.
    * @param id (string) Crash ID. Likely a UUID.
    * @param date (Date) When the crash occurred.
    * @param metadata (dictionary) Crash metadata, may be empty.
    *
    * @return promise<null> Resolved when the store has been saved.
    */
   addCrash(processType, crashType, id, date, metadata) {
-    let promise = (async function() {
+    let promise = (async () => {
       let store = await this._getStore();
       if (store.addCrash(processType, crashType, id, date, metadata)) {
         await store.save();
       }
 
       let deferred = this._crashPromises.get(id);
 
       if (deferred) {
@@ -468,17 +468,17 @@ this.CrashManager.prototype = Object.fre
         deferred.resolve();
       }
 
       // Send a telemetry ping for each non-main process crash
       if (processType === this.PROCESS_TYPE_CONTENT ||
           processType === this.PROCESS_TYPE_GPU) {
         this._sendCrashPing(id, processType, date, metadata);
       }
-    }.bind(this))();
+    })();
 
     return promise;
   },
 
   /**
    * Returns a promise that is resolved only the crash with the specified id
    * has been fully recorded.
    *
@@ -573,34 +573,34 @@ this.CrashManager.prototype = Object.fre
   },
 
   /**
    * Obtain the paths of all unprocessed events files.
    *
    * The promise-resolved array is sorted by file mtime, oldest to newest.
    */
   _getUnprocessedEventsFiles() {
-    return (async function() {
+    return (async () => {
       let entries = [];
 
       for (let dir of this._eventsDirs) {
         for (let e of await this._getDirectoryEntries(dir, this.ALL_REGEX)) {
           entries.push(e);
         }
       }
 
       entries.sort((a, b) => { return a.date - b.date; });
 
       return entries;
-    }.bind(this))();
+    })();
   },
 
   // See docs/crash-events.rst for the file format specification.
   _processEventFile(entry) {
-    return (async function() {
+    return (async () => {
       let data = await OS.File.read(entry.path);
       let store = await this._getStore();
 
       let decoder = new TextDecoder();
       data = decoder.decode(data);
 
       let type, time;
       let start = 0;
@@ -625,17 +625,17 @@ this.CrashManager.prototype = Object.fre
         }
 
         start = index + 1;
       }
       let date = new Date(time * 1000);
       let payload = data.substring(start);
 
       return this._handleEventFilePayload(store, entry, type, date, payload);
-    }.bind(this))();
+    })();
   },
 
   _filterAnnotations(annotations) {
     let filteredAnnotations = {};
 
     for (let line in annotations) {
       if (this.ANNOTATION_WHITELIST.includes(line)) {
         filteredAnnotations[line] = annotations[line];
@@ -788,17 +788,17 @@ this.CrashManager.prototype = Object.fre
     })();
   },
 
   _getStore() {
     if (this._getStoreTask) {
       return this._getStoreTask;
     }
 
-    return this._getStoreTask = (async function() {
+    return this._getStoreTask = (async () => {
       try {
         if (!this._store) {
           await OS.File.makeDir(this._storeDir, {
             ignoreExisting: true,
             unixMode: OS.Constants.libc.S_IRWXU,
           });
 
           let store = new CrashStore(this._storeDir,
@@ -835,38 +835,38 @@ this.CrashManager.prototype = Object.fre
 
         this._storeTimer.initWithCallback(timerCB, this.STORE_EXPIRATION_MS,
                                           this._storeTimer.TYPE_ONE_SHOT);
 
         return this._store;
       } finally {
         this._getStoreTask = null;
       }
-    }.bind(this))();
+    })();
   },
 
   /**
    * Obtain information about all known crashes.
    *
    * Returns an array of CrashRecord instances. Instances are read-only.
    */
   getCrashes() {
-    return (async function() {
+    return (async () => {
       let store = await this._getStore();
 
       return store.crashes;
-    }.bind(this))();
+    })();
   },
 
   getCrashCountsByDay() {
-    return (async function() {
+    return (async () => {
       let store = await this._getStore();
 
       return store._countsByDay;
-    }.bind(this))();
+    })();
   },
 });
 
 var gCrashManager;
 
 /**
  * Interface to storage of crash data.
  *
@@ -929,17 +929,17 @@ CrashStore.prototype = Object.freeze({
   },
 
   /**
    * Load data from disk.
    *
    * @return Promise
    */
   load() {
-    return (async function() {
+    return (async () => {
       // Loading replaces data.
       this.reset();
 
       try {
         let decoder = new TextDecoder();
         let data = await OS.File.read(this._storePath, {compression: "lz4"});
         data = JSON.parse(decoder.decode(data));
 
@@ -1020,26 +1020,26 @@ CrashStore.prototype = Object.freeze({
           // and swallow the error.
           //
           // The marking of a corrupted file is intentionally not persisted to
           // disk yet. Instead, we wait until the next save(). This is to give
           // non-permanent failures the opportunity to recover on their own.
           this._data.corruptDate = new Date();
         }
       }
-    }.bind(this))();
+    })();
   },
 
   /**
    * Save data to disk.
    *
    * @return Promise<null>
    */
   save() {
-    return (async function() {
+    return (async () => {
       if (!this._data) {
         return;
       }
 
       let normalized = {
         // The version should be incremented whenever the format
         // changes.
         v: 1,
@@ -1084,17 +1084,17 @@ CrashStore.prototype = Object.freeze({
       let encoder = new TextEncoder();
       let data = encoder.encode(JSON.stringify(normalized));
       let size = await OS.File.writeAtomic(this._storePath, data, {
                                            tmpPath: this._storePath + ".tmp",
                                            compression: "lz4"});
       if (this._telemetrySizeKey) {
         Services.telemetry.getHistogramById(this._telemetrySizeKey).add(size);
       }
-    }.bind(this))();
+    })();
   },
 
   /**
    * Normalize an object into one fit for serialization.
    *
    * This function along with _denormalize() serve to hack around the
    * default handling of Date JSON serialization because Date serialization
    * is undefined by JSON.
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -312,17 +312,17 @@ this.ExtensionData = class {
     }
     if (!this.uuid) {
       this.uuid = UUIDMap.get(this.id);
     }
     return `moz-extension://${this.uuid}/${path}`;
   }
 
   readDirectory(path) {
-    return (async function() {
+    return (async () => {
       if (this.rootURI instanceof Ci.nsIFileURL) {
         let uri = NetUtil.newURI(this.rootURI.resolve("./" + path));
         let fullPath = uri.QueryInterface(Ci.nsIFileURL).file.path;
 
         let iter = new OS.File.DirectoryIterator(fullPath);
         let results = [];
 
         try {
@@ -373,17 +373,17 @@ this.ExtensionData = class {
             });
           }
         }
 
         return results;
       } finally {
         zipReader.close();
       }
-    }.bind(this))();
+    })();
   }
 
   readJSON(path) {
     return new Promise((resolve, reject) => {
       let uri = this.rootURI.resolve(`./${path}`);
 
       NetUtil.asyncFetch({uri, loadUsingSystemPrincipal: true}, (inputStream, status) => {
         if (!Components.isSuccessCode(status)) {
@@ -565,40 +565,40 @@ this.ExtensionData = class {
   // replacing underscores with hyphens.
   normalizeLocaleCode(locale) {
     return locale.replace(/_/g, "-");
   }
 
   // Reads the locale file for the given Gecko-compatible locale code, and
   // stores its parsed contents in |this.localeMessages.get(locale)|.
   readLocaleFile(locale) {
-    return (async function() {
+    return (async () => {
       let locales = await this.promiseLocales();
       let dir = locales.get(locale) || locale;
       let file = `_locales/${dir}/messages.json`;
 
       try {
         let messages = await this.readJSON(file);
         return this.localeData.addLocale(locale, messages, this);
       } catch (e) {
         this.packagingError(`Loading locale file ${file}: ${e}`);
         return new Map();
       }
-    }.bind(this))();
+    })();
   }
 
   // Reads the list of locales available in the extension, and returns a
   // Promise which resolves to a Map upon completion.
   // Each map key is a Gecko-compatible locale code, and each value is the
   // "_locales" subdirectory containing that locale:
   //
   // Map(gecko-locale-code -> locale-directory-name)
   promiseLocales() {
     if (!this._promiseLocales) {
-      this._promiseLocales = (async function() {
+      this._promiseLocales = (async () => {
         let locales = new Map();
 
         let entries = await this.readDirectory("_locales");
         for (let file of entries) {
           if (file.isDir) {
             let locale = this.normalizeLocaleCode(file.name);
             locales.set(locale, file.name);
           }
@@ -606,28 +606,28 @@ this.ExtensionData = class {
 
         this.localeData = new LocaleData({
           defaultLocale: this.defaultLocale,
           locales,
           builtinMessages: this.builtinMessages,
         });
 
         return locales;
-      }.bind(this))();
+      })();
     }
 
     return this._promiseLocales;
   }
 
   // Reads the locale messages for all locales, and returns a promise which
   // resolves to a Map of locale messages upon completion. Each key in the map
   // is a Gecko-compatible locale code, and each value is a locale data object
   // as returned by |readLocaleFile|.
   initAllLocales() {
-    return (async function() {
+    return (async () => {
       let locales = await this.promiseLocales();
 
       await Promise.all(Array.from(locales.keys(),
                                    locale => this.readLocaleFile(locale)));
 
       let defaultLocale = this.defaultLocale;
       if (defaultLocale) {
         if (!locales.has(defaultLocale)) {
@@ -636,45 +636,45 @@ this.ExtensionData = class {
                              JSON.stringify(`_locales/${this.manifest.default_locale}/`));
         }
       } else if (locales.size) {
         this.manifestError('The "default_locale" property is required when a ' +
                            '"_locales/" directory is present.');
       }
 
       return this.localeData.messages;
-    }.bind(this))();
+    })();
   }
 
   // Reads the locale file for the given Gecko-compatible locale code, or the
   // default locale if no locale code is given, and sets it as the currently
   // selected locale on success.
   //
   // Pre-loads the default locale for fallback message processing, regardless
   // of the locale specified.
   //
   // If no locales are unavailable, resolves to |null|.
   initLocale(locale = this.defaultLocale) {
-    return (async function() {
+    return (async () => {
       if (locale == null) {
         return null;
       }
 
       let promises = [this.readLocaleFile(locale)];
 
       let {defaultLocale} = this;
       if (locale != defaultLocale && !this.localeData.has(defaultLocale)) {
         promises.push(this.readLocaleFile(defaultLocale));
       }
 
       let results = await Promise.all(promises);
 
       this.localeData.selectedLocale = locale;
       return results[0];
-    }.bind(this))();
+    })();
   }
 };
 
 const PROXIED_EVENTS = new Set(["test-harness-message", "add-permissions", "remove-permissions"]);
 
 // We create one instance of this class per extension. |addonData|
 // comes directly from bootstrap.js when initializing.
 this.Extension = class extends ExtensionData {
--- a/toolkit/components/formautofill/content/requestAutocomplete.js
+++ b/toolkit/components/formautofill/content/requestAutocomplete.js
@@ -16,26 +16,26 @@ Cu.import("resource://gre/modules/Servic
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
 
 const RequestAutocompleteDialog = {
   resolveFn: null,
   autofillData: null,
 
   onLoad() {
-    (async function() {
+    (async () => {
       let args = window.arguments[0].wrappedJSObject;
       this.resolveFn = args.resolveFn;
       this.autofillData = args.autofillData;
 
       window.sizeToContent();
 
       Services.obs.notifyObservers(window,
                                    "formautofill-window-initialized");
-    }.bind(this))().catch(Cu.reportError);
+    })().catch(Cu.reportError);
   },
 
   onAccept() {
     // TODO: Replace with autofill storage module (bug 1018304).
     const dummyDB = {
       "": {
         "name": "Mozzy La",
         "street-address": "331 E Evelyn Ave",
--- a/toolkit/components/jsdownloads/src/DownloadCore.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadCore.jsm
@@ -423,17 +423,17 @@ this.Download.prototype = {
 
       if (changeMade) {
         this._notifyChange();
       }
     }
 
     // Now that we stored the promise in the download object, we can start the
     // task that will actually execute the download.
-    deferAttempt.resolve((async function task_D_start() {
+    deferAttempt.resolve((async () => {
       // Wait upon any pending operation before restarting.
       if (this._promiseCanceled) {
         await this._promiseCanceled;
       }
       if (this._promiseRemovePartialData) {
         try {
           await this._promiseRemovePartialData;
         } catch (ex) {
@@ -549,17 +549,17 @@ this.Download.prototype = {
           this.stopped = true;
           this.speed = 0;
           this._notifyChange();
           if (this.succeeded) {
             await this._succeed();
           }
         }
       }
-    }.bind(this))());
+    })());
 
     // Notify the new download state before returning.
     this._notifyChange();
     return currentAttempt;
   },
 
   /**
    * Perform the actions necessary when a Download succeeds.
@@ -624,31 +624,31 @@ this.Download.prototype = {
         "Download block has been confirmed, cannot unblock."));
     }
 
     if (!this.hasBlockedData) {
       return Promise.reject(new Error(
         "unblock may only be called on Downloads with blocked data."));
     }
 
-    this._promiseUnblock = (async function() {
+    this._promiseUnblock = (async () => {
       try {
         await OS.File.move(this.target.partFilePath, this.target.path);
         await this.target.refresh();
       } catch (ex) {
         await this.refresh();
         this._promiseUnblock = null;
         throw ex;
       }
 
       this.succeeded = true;
       this.hasBlockedData = false;
       this._notifyChange();
       await this._succeed();
-    }.bind(this))();
+    })();
 
     return this._promiseUnblock;
   },
 
   /**
    * Confirms that a blocked download should be cleaned up.
    *
    * If a download was blocked but retained on disk this method can be used
@@ -668,28 +668,28 @@ this.Download.prototype = {
         "Download is being unblocked, cannot confirmBlock."));
     }
 
     if (!this.hasBlockedData) {
       return Promise.reject(new Error(
         "confirmBlock may only be called on Downloads with blocked data."));
     }
 
-    this._promiseConfirmBlock = (async function() {
+    this._promiseConfirmBlock = (async () => {
       try {
         await OS.File.remove(this.target.partFilePath);
       } catch (ex) {
         await this.refresh();
         this._promiseConfirmBlock = null;
         throw ex;
       }
 
       this.hasBlockedData = false;
       this._notifyChange();
-    }.bind(this))();
+    })();
 
     return this._promiseConfirmBlock;
   },
 
   /*
    * Launches the file after download has completed. This can open
    * the file with the default application for the target MIME type
    * or file extension, or with a custom application if launcherPath
@@ -844,34 +844,34 @@ this.Download.prototype = {
     let promiseRemovePartialData = this._promiseRemovePartialData;
 
     if (!promiseRemovePartialData) {
       let deferRemovePartialData = Promise.defer();
       promiseRemovePartialData = deferRemovePartialData.promise;
       this._promiseRemovePartialData = promiseRemovePartialData;
 
       deferRemovePartialData.resolve(
-        (async function task_D_removePartialData() {
+        (async () => {
           try {
             // Wait upon any pending cancellation request.
             if (this._promiseCanceled) {
               await this._promiseCanceled;
             }
             // Ask the saver object to remove any partial data.
             await this.saver.removePartialData();
             // For completeness, clear the number of bytes transferred.
             if (this.currentBytes != 0 || this.hasPartialData) {
               this.currentBytes = 0;
               this.hasPartialData = false;
               this._notifyChange();
             }
           } finally {
             this._promiseRemovePartialData = null;
           }
-        }.bind(this))());
+        })());
     }
 
     return promiseRemovePartialData;
   },
 
   /**
    * This deferred object contains a promise that is resolved as soon as this
    * download finishes successfully, and is never rejected.  This property is
@@ -905,17 +905,17 @@ this.Download.prototype = {
    * This allows the properties of the download to be updated in case the user
    * moved or deleted the target file or its associated ".part" file.
    *
    * @return {Promise}
    * @resolves When the operation has completed.
    * @rejects Never.
    */
   refresh() {
-    return (async function() {
+    return (async () => {
       if (!this.stopped || this._finalized) {
         return;
       }
 
       if (this.succeeded) {
         let oldExists = this.target.exists;
         let oldSize = this.target.size;
         await this.target.refresh();
@@ -954,17 +954,17 @@ this.Download.prototype = {
           }
 
           this.hasBlockedData = false;
           this.hasPartialData = false;
         }
 
         this._notifyChange();
       }
-    }.bind(this))().then(null, Cu.reportError);
+    })().then(null, Cu.reportError);
   },
 
   /**
    * True if the "finalize" method has been called.  This prevents the download
    * from starting again after having been stopped.
    */
   _finalized: false,
 
@@ -1887,17 +1887,17 @@ this.DownloadCopySaver.prototype = {
 
     this._canceled = false;
 
     let download = this.download;
     let targetPath = download.target.path;
     let partFilePath = download.target.partFilePath;
     let keepPartialData = download.tryToKeepPartialData;
 
-    return (async function task_DCS_execute() {
+    return (async () => {
       // Add the download to history the first time it is started in this
       // session.  If the download is restarted in a different session, a new
       // history visit will be added.  We do this just to avoid the complexity
       // of serializing this state between sessions, since adding a new visit
       // does not have any noticeable side effect.
       if (!this.alreadyAddedToHistory) {
         this.addToHistory();
         this.alreadyAddedToHistory = true;
@@ -2160,17 +2160,17 @@ this.DownloadCopySaver.prototype = {
           // error if the file existed before, and was recently deleted.
           if (!(e2 instanceof OS.File.Error &&
                 (e2.becauseNoSuchFile || e2.becauseAccessDenied))) {
             Cu.reportError(e2);
           }
         }
         throw ex;
       }
-    }.bind(this))();
+    })();
   },
 
   /**
    * Perform the reputation check and cleanup the downloaded data if required.
    * If the download passes the reputation check and is using a part file we
    * will move it to the target path since reputation checking is the final
    * step in the saver.
    *
@@ -2228,27 +2228,27 @@ this.DownloadCopySaver.prototype = {
       this._backgroundFileSaver = null;
     }
   },
 
   /**
    * Implements "DownloadSaver.removePartialData".
    */
   removePartialData() {
-    return (async function task_DCS_removePartialData() {
+    return (async () => {
       if (this.download.target.partFilePath) {
         try {
           await OS.File.remove(this.download.target.partFilePath);
         } catch (ex) {
           if (!(ex instanceof OS.File.Error) || !ex.becauseNoSuchFile) {
             throw ex;
           }
         }
       }
-    }.bind(this))();
+    })();
   },
 
   /**
    * Implements "DownloadSaver.toSerializable".
    */
   toSerializable() {
     // Simplify the representation if we don't have other details.
     if (!this.entityID && !this._unknownProperties) {
@@ -2491,17 +2491,17 @@ this.DownloadLegacySaver.prototype = {
       return this.copySaver.execute.apply(this.copySaver, arguments);
     }
 
     this.setProgressBytesFn = aSetProgressBytesFn;
     if (this.progressWasNotified) {
       this.onProgressBytes(this.currentBytes, this.totalBytes);
     }
 
-    return (async function task_DLS_execute() {
+    return (async () => {
       try {
         // Wait for the component that executes the download to finish.
         await this.deferExecuted.promise;
 
         // At this point, the "request" property has been populated.  Ensure we
         // report the value of "Content-Length", if available, even if the
         // download didn't generate any progress events.
         if (!this.progressWasNotified &&
@@ -2559,17 +2559,17 @@ this.DownloadLegacySaver.prototype = {
         // We don't need the reference to the request anymore.  We must also set
         // deferCanceled to null in order to free any indirect references it
         // may hold to the request.
         this.request = null;
         this.deferCanceled = null;
         // Allow the download to restart through a DownloadCopySaver.
         this.firstExecutionFinished = true;
       }
-    }.bind(this))();
+    })();
   },
 
   _checkReputationAndMove() {
     return DownloadCopySaver.prototype._checkReputationAndMove
                                       .apply(this, arguments);
   },
 
   /**
@@ -2697,17 +2697,17 @@ this.DownloadPDFSaver.prototype = {
    * or while the operation is being canceled.
    */
   _webBrowserPrint: null,
 
   /**
    * Implements "DownloadSaver.execute".
    */
   execute(aSetProgressBytesFn, aSetPropertiesFn) {
-    return (async function task_DCS_execute() {
+    return (async () => {
       if (!this.download.source.windowRef) {
         throw new DownloadError({
           message: "PDF saver must be passed an open window, and cannot be restarted.",
           becauseSourceFailed: true,
         });
       }
 
       let win = this.download.source.windowRef.get();
@@ -2777,17 +2777,17 @@ this.DownloadPDFSaver.prototype = {
         });
       } finally {
         // Remove the print object to avoid leaks
         this._webBrowserPrint = null;
       }
 
       let fileInfo = await OS.File.stat(targetPath);
       aSetProgressBytesFn(fileInfo.size, fileInfo.size, false);
-    }.bind(this))();
+    })();
   },
 
   /**
    * Implements "DownloadSaver.cancel".
    */
   cancel: function DCS_cancel() {
     if (this._webBrowserPrint) {
       this._webBrowserPrint.cancel();
--- a/toolkit/components/jsdownloads/src/DownloadImport.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadImport.jsm
@@ -61,17 +61,17 @@ this.DownloadImport.prototype = {
    * format. Each imported download will be added to the DownloadList
    *
    * @return {Promise}
    * @resolves When the operation has completed (i.e., every download
    *           from the previous database has been read and added to
    *           the DownloadList)
    */
   import() {
-    return (async function task_DI_import() {
+    return (async () => {
       let connection = await Sqlite.openConnection({ path: this.path });
 
       try {
         let schemaVersion = await connection.getSchemaVersion();
         // We don't support schemas older than version 7 (from 2007)
         // - Version 7 added the columns mimeType, preferredApplication
         //   and preferredAction in 2007
         // - Version 8 added the column autoResume in 2007
@@ -179,12 +179,12 @@ this.DownloadImport.prototype = {
           }
         }
 
       } catch (ex) {
         Cu.reportError(ex);
       } finally {
         await connection.close();
       }
-    }.bind(this))();
+    })();
   }
 }
 
--- a/toolkit/components/jsdownloads/src/DownloadList.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadList.jsm
@@ -221,17 +221,17 @@ this.DownloadList.prototype = {
    *
    * @param aFilterFn
    *        The filter function is called with each download as its only
    *        argument, and should return true to remove the download and false
    *        to keep it.  This parameter may be null or omitted to have no
    *        additional filter.
    */
   removeFinished: function DL_removeFinished(aFilterFn) {
-    (async function() {
+    (async () => {
       let list = await this.getAll();
       for (let download of list) {
         // Remove downloads that have been canceled, even if the cancellation
         // operation hasn't completed yet so we don't check "stopped" here.
         // Failed downloads with partial data are also removed.
         if (download.stopped && (!download.hasPartialData || download.error) &&
             (!aFilterFn || aFilterFn(download))) {
           // Remove the download first, so that the views don't get the change
@@ -239,17 +239,17 @@ this.DownloadList.prototype = {
           await this.remove(download);
           // Ensure that the download is stopped and no partial data is kept.
           // This works even if the download state has changed meanwhile.  We
           // don't need to wait for the procedure to be complete before
           // processing the other downloads in the list.
           download.finalize(true).then(null, Cu.reportError);
         }
       }
-    }.bind(this))().then(null, Cu.reportError);
+    })().then(null, Cu.reportError);
   },
 };
 
 // DownloadCombinedList
 
 /**
  * Provides a unified, unordered list combining public and private downloads.
  *
--- a/toolkit/components/jsdownloads/src/DownloadStore.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadStore.jsm
@@ -92,17 +92,17 @@ this.DownloadStore.prototype = {
   /**
    * Loads persistent downloads from the file to the list.
    *
    * @return {Promise}
    * @resolves When the operation finished successfully.
    * @rejects JavaScript exception.
    */
   load: function DS_load() {
-    return (async function task_DS_load() {
+    return (async () => {
       let bytes;
       try {
         bytes = await OS.File.read(this.path);
       } catch (ex) {
         if (!(ex instanceof OS.File.Error) || !ex.becauseNoSuchFile) {
           throw ex;
         }
         // If the file does not exist, there are no downloads to load.
@@ -131,30 +131,30 @@ this.DownloadStore.prototype = {
             // after we have updated its initial state.
             await this.list.add(download);
           }
         } catch (ex) {
           // If an item is unrecognized, don't prevent others from being loaded.
           Cu.reportError(ex);
         }
       }
-    }.bind(this))();
+    })();
   },
 
   /**
    * Saves persistent downloads from the list to the file.
    *
    * If an error occurs, the previous file is not deleted.
    *
    * @return {Promise}
    * @resolves When the operation finished successfully.
    * @rejects JavaScript exception.
    */
   save: function DS_save() {
-    return (async function task_DS_save() {
+    return (async () => {
       let downloads = await this.list.getAll();
 
       // Take a static snapshot of the current state of all the downloads.
       let storeData = { list: [] };
       let atLeastOneDownload = false;
       for (let download of downloads) {
         try {
           if (!this.onsaveitem(download)) {
@@ -188,11 +188,11 @@ this.DownloadStore.prototype = {
           if (!(ex instanceof OS.File.Error) ||
               !(ex.becauseNoSuchFile || ex.becauseAccessDenied)) {
             throw ex;
           }
           // On Windows, we may get an access denied error instead of a no such
           // file error if the file existed before, and was recently deleted.
         }
       }
-    }.bind(this))();
+    })();
   },
 };
--- a/toolkit/components/jsdownloads/src/Downloads.jsm
+++ b/toolkit/components/jsdownloads/src/Downloads.jsm
@@ -164,17 +164,17 @@ this.Downloads = {
    *        the Downloads.PRIVATE list based on their properties.
    *
    * @return {Promise}
    * @resolves The requested DownloadList or DownloadCombinedList object.
    * @rejects JavaScript exception.
    */
   getList(aType) {
     if (!this._promiseListsInitialized) {
-      this._promiseListsInitialized = (async function() {
+      this._promiseListsInitialized = (async () => {
         let publicList = new DownloadList();
         let privateList = new DownloadList();
         let combinedList = new DownloadCombinedList(publicList, privateList);
 
         try {
           await DownloadIntegration.addListObservers(publicList, false);
           await DownloadIntegration.addListObservers(privateList, true);
           await DownloadIntegration.initializePublicDownloadList(publicList);
@@ -188,17 +188,17 @@ this.Downloads = {
 
         await publicSummary.bindToList(publicList);
         await privateSummary.bindToList(privateList);
         await combinedSummary.bindToList(combinedList);
 
         this._lists[Downloads.PUBLIC] = publicList;
         this._lists[Downloads.PRIVATE] = privateList;
         this._lists[Downloads.ALL] = combinedList;
-      }.bind(this))();
+      })();
     }
 
     return this._promiseListsInitialized.then(() => this._lists[aType]);
   },
 
   /**
    * Promise resolved when the initialization of the download lists has
    * completed, or null if initialization has never been requested.
--- a/toolkit/components/osfile/modules/osfile_async_front.jsm
+++ b/toolkit/components/osfile/modules/osfile_async_front.jsm
@@ -274,17 +274,17 @@ var Scheduler = this.Scheduler = {
     // Deactivate the queue, to ensure that no message is sent
     // to an obsolete worker (we reactivate it in the `finally`).
     // This needs to be done right now so that we maintain relative
     // ordering with calls to post(), etc.
     let deferred = Promise.defer();
     let savedQueue = this.queue;
     this.queue = deferred.promise;
 
-    return this._killQueue = (async function() {
+    return this._killQueue = (async () => {
 
       await killQueue;
       // From this point, and until the end of the Task, we are the
       // only call to `kill`, regardless of any `yield`.
 
       await savedQueue;
 
       try {
@@ -354,17 +354,17 @@ var Scheduler = this.Scheduler = {
 
       } finally {
         // Resume accepting messages. If we have set |shutdown| to |true|,
         // any pending/future request will be rejected. Otherwise, any
         // pending/future request will spawn a new worker if necessary.
         deferred.resolve();
       }
 
-    }.bind(this))();
+    })();
   },
 
   /**
    * Push a task at the end of the queue.
    *
    * @param {function} code A function returning a Promise.
    * This function will be executed once all the previously
    * pushed tasks have completed.
@@ -399,17 +399,17 @@ var Scheduler = this.Scheduler = {
 
     if (firstLaunch && SharedAll.Config.DEBUG) {
       // If we have delayed sending SET_DEBUG, do it now.
       this.worker.post("SET_DEBUG", [true]);
       Scheduler.Debugging.messagesSent++;
     }
 
     Scheduler.Debugging.messagesQueued++;
-    return this.push(async function() {
+    return this.push(async () => {
       if (this.shutdown) {
 	LOG("OS.File is not available anymore. The following request has been rejected.",
 	  method, args);
 	throw new Error("OS.File has been shut down. Rejecting request to " + method);
       }
 
       // Update debugging information. As |args| may be quite
       // expensive, we only keep a shortened version of it.
@@ -435,17 +435,17 @@ var Scheduler = this.Scheduler = {
         Scheduler.Debugging.latestReceived = [Date.now(), error.message, error.fileName, error.lineNumber];
         throw error;
       } finally {
         if (firstLaunch) {
           Scheduler._updateTelemetry();
         }
         Scheduler.restartTimer();
       }
-    }.bind(this));
+    });
   },
 
   /**
    * Post Telemetry statistics.
    *
    * This is only useful on first launch.
    */
   _updateTelemetry: function() {
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -395,24 +395,24 @@ var LoginManagerContent = {
     let formLike = LoginFormFactory.createFromField(pwField);
     log("onDOMInputPasswordAdded:", pwField, formLike);
 
     let deferredTask = this._deferredPasswordAddedTasksByRootElement.get(formLike.rootElement);
     if (!deferredTask) {
       log("Creating a DeferredTask to call _fetchLoginsFromParentAndFillForm soon");
       this._formLikeByRootElement.set(formLike.rootElement, formLike);
 
-      deferredTask = new DeferredTask(function deferredInputProcessing() {
+      deferredTask = new DeferredTask(() => {
         // Get the updated formLike instead of the one at the time of creating the DeferredTask via
         // a closure since it could be stale since FormLike.elements isn't live.
         let formLike2 = this._formLikeByRootElement.get(formLike.rootElement);
         log("Running deferred processing of onDOMInputPasswordAdded", formLike2);
         this._deferredPasswordAddedTasksByRootElement.delete(formLike2.rootElement);
         this._fetchLoginsFromParentAndFillForm(formLike2, window);
-      }.bind(this), PASSWORD_INPUT_ADDED_COALESCING_THRESHOLD_MS);
+      }, PASSWORD_INPUT_ADDED_COALESCING_THRESHOLD_MS);
 
       this._deferredPasswordAddedTasksByRootElement.set(formLike.rootElement, deferredTask);
     }
 
     if (deferredTask.isArmed) {
       log("DeferredTask is already armed so just updating the FormLike");
       // We update the FormLike so it (most important .elements) is fresh when the task eventually
       // runs since changes to the elements could affect our field heuristics.
--- a/toolkit/components/passwordmgr/nsLoginManager.js
+++ b/toolkit/components/passwordmgr/nsLoginManager.js
@@ -158,23 +158,23 @@ LoginManager.prototype = {
           log.debug("Oops! Pref not handled, change ignored.");
         }
       } else if (topic == "xpcom-shutdown") {
         delete this._pwmgr.__formFillService;
         delete this._pwmgr._storage;
         delete this._pwmgr._prefBranch;
         this._pwmgr = null;
       } else if (topic == "passwordmgr-storage-replace") {
-        (async function() {
+        (async () => {
           await this._pwmgr._storage.terminate();
           this._pwmgr._initStorage();
           await this._pwmgr.initializationPromise;
           Services.obs.notifyObservers(null,
                        "passwordmgr-storage-replace-complete");
-        }.bind(this))();
+        })();
       } else if (topic == "gather-telemetry") {
         // When testing, the "data" parameter is a string containing the
         // reference time in milliseconds for time-based statistics.
         this._pwmgr._gatherTelemetry(data ? parseInt(data)
                                           : new Date().getTime());
       } else {
         log.debug("Oops! Unexpected notification:", topic);
       }
--- a/toolkit/components/passwordmgr/storage-json.js
+++ b/toolkit/components/passwordmgr/storage-json.js
@@ -46,17 +46,17 @@ this.LoginManagerStorage_json.prototype 
       // See bug 717490 comment 17.
       this._crypto;
 
       // Set the reference to LoginStore synchronously.
       let jsonPath = OS.Path.join(OS.Constants.Path.profileDir,
                                   "logins.json");
       this._store = new LoginStore(jsonPath);
 
-      return (async function() {
+      return (async () => {
         // Load the data asynchronously.
         this.log("Opening database at", this._store.path);
         await this._store.load();
 
         // The import from previous versions operates the first time
         // that this built-in storage back-end is used.  This may be
         // later than expected, in case add-ons have registered an
         // alternate storage that disabled the default one.
@@ -78,17 +78,17 @@ this.LoginManagerStorage_json.prototype 
           // prevent us from marking the operation as completed.
           // At the next startup, we will not try the import again.
           await loginImport.import().catch(Cu.reportError);
           this._store.saveSoon();
         }
 
         // We won't attempt import again on next startup.
         Services.prefs.setBoolPref("signon.importedFromSqlite", true);
-      }.bind(this))().catch(Cu.reportError);
+      })().catch(Cu.reportError);
     } catch (e) {
       this.log("Initialization failed:", e);
       throw new Error("Initialization failed");
     }
   },
 
   /**
    * Internal method used by regression tests only.  It is called before
--- a/toolkit/components/places/BookmarkHTMLUtils.jsm
+++ b/toolkit/components/places/BookmarkHTMLUtils.jsm
@@ -998,17 +998,17 @@ function BookmarkExporter(aBookmarksTree
         this._root.children = [];
       this._root.children.push(root);
     }
   }
 }
 
 BookmarkExporter.prototype = {
   exportToFile: function exportToFile(aFilePath) {
-    return (async function() {
+    return (async () => {
       // Create a file that can be accessed by the current user only.
       let out = FileUtils.openAtomicFileOutputStream(new FileUtils.File(aFilePath));
       try {
         // We need a buffered output stream for performance.  See bug 202477.
         let bufferedOut = Cc["@mozilla.org/network/buffered-output-stream;1"]
                           .createInstance(Ci.nsIBufferedOutputStream);
         bufferedOut.init(out, 4096);
         try {
@@ -1026,17 +1026,17 @@ BookmarkExporter.prototype = {
             this._converterOut = null;
           }
         } finally {
           bufferedOut.close();
         }
       } finally {
         out.close();
       }
-    }.bind(this))();
+    })();
   },
 
   _converterOut: null,
 
   _write(aText) {
     this._converterOut.writeString(aText || "");
   },
 
--- a/toolkit/components/places/Bookmarks.jsm
+++ b/toolkit/components/places/Bookmarks.jsm
@@ -172,17 +172,17 @@ var Bookmarks = Object.freeze({
       , title: { validIf: b => [ this.TYPE_BOOKMARK
                                , this.TYPE_FOLDER ].includes(b.type) }
       , dateAdded: { defaultValue: addedTime }
       , lastModified: { defaultValue: modTime,
                         validIf: b => b.lastModified >= now || (b.dateAdded && b.lastModified >= b.dateAdded) }
       , source: { defaultValue: this.SOURCES.DEFAULT }
       });
 
-    return (async function() {
+    return (async () => {
       // Ensure the parent exists.
       let parent = await fetchBookmark({ guid: insertInfo.parentGuid });
       if (!parent)
         throw new Error("parentGuid must be valid");
 
       // Set index in the appending case.
       if (insertInfo.index == this.DEFAULT_INDEX ||
           insertInfo.index > parent._childCount) {
@@ -216,17 +216,17 @@ var Bookmarks = Object.freeze({
                                                entry.guid, entry.parentGuid,
                                                "", item.source ]);
         }
       }
 
       // Remove non-enumerable properties.
       delete item.source;
       return Object.assign({}, item);
-    }.bind(this))();
+    })();
   },
 
 
   /**
    * Inserts a bookmark-tree into the existing bookmarks tree.
    *
    * All the specified folders and bookmarks will be inserted as new, even
    * if duplicates. There's no merge support at this time.
@@ -450,17 +450,17 @@ var Bookmarks = Object.freeze({
                , validIf: b => b.index >= 0 || b.index == this.DEFAULT_INDEX }
       , source: { defaultValue: this.SOURCES.DEFAULT }
       });
 
     // There should be at last one more property in addition to guid and source.
     if (Object.keys(updateInfo).length < 3)
       throw new Error("Not enough properties to update");
 
-    return (async function() {
+    return (async () => {
       // Ensure the item exists.
       let item = await fetchBookmark(updateInfo);
       if (!item)
         throw new Error("No bookmarks found for the provided GUID");
       if (updateInfo.hasOwnProperty("type") && updateInfo.type != item.type)
         throw new Error("The bookmark type cannot be changed");
 
       // Remove any property that will stay the same.
@@ -477,17 +477,17 @@ var Bookmarks = Object.freeze({
                                   , this.TYPE_FOLDER ].includes(item.type) }
         , lastModified: { defaultValue: now
                         , validIf: b => b.lastModified >= now ||
                                         b.lastModified >= (b.dateAdded || item.dateAdded) }
         , dateAdded: { defaultValue: item.dateAdded }
         });
 
       return PlacesUtils.withConnectionWrapper("Bookmarks.jsm: update",
-        async function(db) {
+        async db => {
         let parent;
         if (updateInfo.hasOwnProperty("parentGuid")) {
           if (item.type == this.TYPE_FOLDER) {
             // Make sure we are not moving a folder into itself or one of its
             // descendants.
             let rows = await db.executeCached(
               `WITH RECURSIVE
                descendants(did) AS (
@@ -581,18 +581,18 @@ var Bookmarks = Object.freeze({
                                              updatedItem.guid, item.parentGuid,
                                              updatedItem.parentGuid,
                                              updatedItem.source ]);
         }
 
         // Remove non-enumerable properties.
         delete updatedItem.source;
         return Object.assign({}, updatedItem);
-      }.bind(this));
-    }.bind(this))();
+      });
+    })();
   },
 
   /**
    * Removes a bookmark-item.
    *
    * @param guidOrInfo
    *        The globally unique identifier of the item to remove, or an
    *        object representing it, as defined above.
@@ -909,17 +909,17 @@ var Bookmarks = Object.freeze({
     if (!Array.isArray(orderedChildrenGuids) || !orderedChildrenGuids.length)
       throw new Error("Must provide a sorted array of children GUIDs.");
     try {
       orderedChildrenGuids.forEach(PlacesUtils.BOOKMARK_VALIDATORS.guid);
     } catch (ex) {
       throw new Error("Invalid GUID found in the sorted children array.");
     }
 
-    return (async function() {
+    return (async () => {
       let parent = await fetchBookmark(info);
       if (!parent || parent.type != this.TYPE_FOLDER)
         throw new Error("No folder found for the provided GUID.");
 
       let sortedChildren = await reorderChildren(parent, orderedChildrenGuids,
                                                  options);
 
       let { source = Bookmarks.SOURCES.DEFAULT } = options;
@@ -929,17 +929,17 @@ var Bookmarks = Object.freeze({
         let child = sortedChildren[i];
         notify(observers, "onItemMoved", [ child._id, child._parentId,
                                            child.index, child._parentId,
                                            i, child.type,
                                            child.guid, child.parentGuid,
                                            child.parentGuid,
                                            source ]);
       }
-    }.bind(this))();
+    })();
   },
 
   /**
    * Searches a list of bookmark-items by a search term, url or title.
    *
    * IMPORTANT:
    * This is intended as an interim API for the web-extensions implementation.
    * It will be removed as soon as we have a new querying API.
--- a/toolkit/components/places/PlacesBackups.jsm
+++ b/toolkit/components/places/PlacesBackups.jsm
@@ -118,25 +118,25 @@ this.PlacesBackups = {
   },
 
   /**
    * Gets backup folder asynchronously.
    * @return {Promise}
    * @resolve the folder (the folder string path).
    */
   getBackupFolder: function PB_getBackupFolder() {
-    return (async function() {
+    return (async () => {
       if (this._backupFolder) {
         return this._backupFolder;
       }
       let profileDir = OS.Constants.Path.profileDir;
       let backupsDirPath = OS.Path.join(profileDir, this.profileRelativeFolderPath);
       await OS.File.makeDir(backupsDirPath, { ignoreExisting: true });
       return this._backupFolder = backupsDirPath;
-    }.bind(this))();
+    })();
   },
 
   get profileRelativeFolderPath() {
     return "bookmarkbackups";
   },
 
   /**
    * Cache current backups in a sorted (by date DESC) array.
@@ -178,17 +178,17 @@ this.PlacesBackups = {
   },
 
   /**
    * Cache current backups in a sorted (by date DESC) array.
    * @return {Promise}
    * @resolve a sorted array of string paths.
    */
   getBackupFiles: function PB_getBackupFiles() {
-    return (async function() {
+    return (async () => {
       if (this._backupFiles)
         return this._backupFiles;
 
       this._backupFiles = [];
 
       let backupFolderPath = await this.getBackupFolder();
       let iterator = new OS.File.DirectoryIterator(backupFolderPath);
       await iterator.forEach(aEntry => {
@@ -214,17 +214,17 @@ this.PlacesBackups = {
 
       this._backupFiles.sort((a, b) => {
         let aDate = this.getDateForFile(a);
         let bDate = this.getDateForFile(b);
         return bDate - aDate;
       });
 
       return this._backupFiles;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Generates a ISO date string (YYYY-MM-DD) from a Date object.
    *
    * @param dateObj
    *        The date object to parse.
    * @return an ISO date string.
@@ -296,26 +296,26 @@ this.PlacesBackups = {
 
    /**
     * Get the most recent backup file.
     *
     * @return {Promise}
     * @result the path to the file.
     */
    getMostRecentBackup: function PB_getMostRecentBackup() {
-     return (async function() {
+     return (async () => {
        let entries = await this.getBackupFiles();
        for (let entry of entries) {
          let rx = /\.json(lz4)?$/;
          if (OS.Path.basename(entry).match(rx)) {
            return entry;
          }
        }
        return null;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Serializes bookmarks using JSON, and writes to the supplied file.
    * Note: any item that should not be backed up must be annotated with
    *       "places/excludeFromBackup".
    *
    * @param aFilePath
@@ -326,17 +326,17 @@ this.PlacesBackups = {
    */
   saveBookmarksToJSONFile: function PB_saveBookmarksToJSONFile(aFilePath) {
     if (aFilePath instanceof Ci.nsIFile) {
       Deprecated.warning("Passing an nsIFile to PlacesBackups.saveBookmarksToJSONFile " +
                          "is deprecated. Please use an OS.File path instead.",
                          "https://developer.mozilla.org/docs/JavaScript_OS.File");
       aFilePath = aFilePath.path;
     }
-    return (async function() {
+    return (async () => {
       let { count: nodeCount, hash: hash } =
         await BookmarkJSONUtils.exportToFile(aFilePath);
 
       let backupFolderPath = await this.getBackupFolder();
       if (OS.Path.dirname(aFilePath) == backupFolderPath) {
         // We are creating a backup in the default backups folder,
         // so just update the internal cache.
         this._entries.unshift(new localFileCtor(aFilePath));
@@ -374,17 +374,17 @@ this.PlacesBackups = {
             this._backupFiles.unshift(newFilePath);
           }
           let jsonString = await OS.File.read(aFilePath);
           await OS.File.writeAtomic(newFilePath, jsonString, { compression: "lz4" });
         }
       }
 
       return nodeCount;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Creates a dated backup in <profile>/bookmarkbackups.
    * Stores the bookmarks using a lz4 compressed JSON file.
    * Note: any item that should not be backed up must be annotated with
    *       "places/excludeFromBackup".
    *
@@ -393,30 +393,30 @@ this.PlacesBackups = {
    *                       all existing backups are removed and aForceBackup is
    *                       ignored, so a new one won't be created.
    * @param [optional] bool aForceBackup
    *                        Forces creating a backup even if one was already
    *                        created that day (overwrites).
    * @return {Promise}
    */
   create: function PB_create(aMaxBackups, aForceBackup) {
-    let limitBackups = async function() {
+    let limitBackups = async () => {
       let backupFiles = await this.getBackupFiles();
       if (typeof aMaxBackups == "number" && aMaxBackups > -1 &&
           backupFiles.length >= aMaxBackups) {
         let numberOfBackupsToDelete = backupFiles.length - aMaxBackups;
         while (numberOfBackupsToDelete--) {
           this._entries.pop();
           let oldestBackup = this._backupFiles.pop();
           await OS.File.remove(oldestBackup);
         }
       }
-    }.bind(this);
+    };
 
-    return (async function() {
+    return (async () => {
       if (aMaxBackups === 0) {
         // Backups are disabled, delete any existing one and bail out.
         await limitBackups(0);
         return;
       }
 
       // Ensure to initialize _backupFiles
       if (!this._backupFiles)
@@ -475,17 +475,17 @@ this.PlacesBackups = {
       // Append metadata to the backup filename.
       let newBackupFileWithMetadata = OS.Path.join(backupFolder, newFilenameWithMetaData);
       await OS.File.move(newBackupFile, newBackupFileWithMetadata);
       this._entries.unshift(new localFileCtor(newBackupFileWithMetadata));
       this._backupFiles.unshift(newBackupFileWithMetadata);
 
       // Limit the number of backups.
       await limitBackups(aMaxBackups);
-    }.bind(this))();
+    })();
   },
 
   /**
    * Gets the bookmark count for backup file.
    *
    * @param aFilePath
    *        File path The backup file.
    *
--- a/toolkit/components/places/PlacesTransactions.jsm
+++ b/toolkit/components/places/PlacesTransactions.jsm
@@ -510,54 +510,54 @@ var TransactionsManager = {
 
     if (this._executedTransactions.has(rawTxn))
       throw new Error("Transactions objects may not be recycled.");
 
     // Add it in advance so one doesn't accidentally do
     // sameTxn.transact(); sameTxn.transact();
     this._executedTransactions.add(rawTxn);
 
-    let promise = this._transactEnqueuer.enqueue(async function() {
+    let promise = this._transactEnqueuer.enqueue(async () => {
       // Don't try to catch exceptions. If execute fails, we better not add the
       // transaction to the undo stack.
       let retval = await rawTxn.execute();
 
       let forceNewEntry = !this._batching || !this._createdBatchEntry;
       TransactionsHistory.add(aTxnProxy, forceNewEntry);
       if (this._batching)
         this._createdBatchEntry = true;
 
       this._updateCommandsOnActiveWindow();
       return retval;
-    }.bind(this));
+    });
     this._mainEnqueuer.alsoWaitFor(promise);
     return promise;
   },
 
   batch(aTask) {
-    return this._mainEnqueuer.enqueue(async function() {
+    return this._mainEnqueuer.enqueue(async () => {
       this._batching = true;
       this._createdBatchEntry = false;
       let rv;
       try {
         // We should return here, but bug 958949 makes that impossible.
         rv = (await (aTask)());
       } finally {
         this._batching = false;
         this._createdBatchEntry = false;
       }
       return rv;
-    }.bind(this));
+    });
   },
 
   /**
    * Undo the top undo entry, if any, and update the undo position accordingly.
    */
   undo() {
-    let promise = this._mainEnqueuer.enqueue(async function() {
+    let promise = this._mainEnqueuer.enqueue(async () => {
       let entry = TransactionsHistory.topUndoEntry;
       if (!entry)
         return;
 
       for (let txnProxy of entry) {
         try {
           await TransactionsHistory.getRawTransaction(txnProxy).undo();
         } catch (ex) {
@@ -566,26 +566,26 @@ var TransactionsManager = {
           console.error(ex,
                         "Couldn't undo a transaction, clearing all undo entries.");
           TransactionsHistory.clearUndoEntries();
           return;
         }
       }
       TransactionsHistory._undoPosition++;
       this._updateCommandsOnActiveWindow();
-    }.bind(this));
+    });
     this._transactEnqueuer.alsoWaitFor(promise);
     return promise;
   },
 
   /**
    * Redo the top redo entry, if any, and update the undo position accordingly.
    */
   redo() {
-    let promise = this._mainEnqueuer.enqueue(async function() {
+    let promise = this._mainEnqueuer.enqueue(async () => {
       let entry = TransactionsHistory.topRedoEntry;
       if (!entry)
         return;
 
       for (let i = entry.length - 1; i >= 0; i--) {
         let transaction = TransactionsHistory.getRawTransaction(entry[i]);
         try {
           if (transaction.redo)
@@ -598,17 +598,17 @@ var TransactionsManager = {
           console.error(ex,
                         "Couldn't redo a transaction, clearing all redo entries.");
           TransactionsHistory.clearRedoEntries();
           return;
         }
       }
       TransactionsHistory._undoPosition--;
       this._updateCommandsOnActiveWindow();
-    }.bind(this));
+    });
 
     this._transactEnqueuer.alsoWaitFor(promise);
     return promise;
   },
 
   clearTransactionsHistory(aUndoEntries, aRedoEntries) {
     let promise = this._mainEnqueuer.enqueue(function() {
       if (aUndoEntries && aRedoEntries)
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -2553,30 +2553,30 @@ var GuidHelper = {
     this.updateCache(itemId, aGuid);
     return itemId;
   },
 
   async getManyItemIds(aGuids) {
     let uncachedGuids = aGuids.filter(guid => !this.idsForGuids.has(guid));
     if (uncachedGuids.length) {
       await PlacesUtils.withConnectionWrapper("GuidHelper.getItemId",
-                                              async function(db) {
+                                              async db => {
         while (uncachedGuids.length) {
           let chunk = uncachedGuids.splice(0, 100);
           let rows = await db.executeCached(
             `SELECT b.id, b.guid from moz_bookmarks b WHERE
              b.guid IN (${"?,".repeat(chunk.length - 1) + "?"})
              LIMIT ${chunk.length}`, chunk);
           if (rows.length < chunk.length)
             throw new Error("Not all items were found!");
           for (let row of rows) {
             this.updateCache(row.getResultByIndex(0), row.getResultByIndex(1));
           }
         }
-      }.bind(this));
+      });
     }
     return new Map(aGuids.map(guid => [guid, this.idsForGuids.get(guid)]));
   },
 
   async getItemGuid(aItemId) {
     let cached = this.guidsForIds.get(aItemId);
     if (cached !== undefined)
       return cached;
@@ -3539,56 +3539,56 @@ this.PlacesEditBookmarkKeywordTransactio
   this.new.postData = aNewPostData
 }
 
 PlacesEditBookmarkKeywordTransaction.prototype = {
   __proto__: BaseTransaction.prototype,
 
   doTransaction: function EBKTXN_doTransaction() {
     let done = false;
-    (async function() {
+    (async () => {
       if (this.item.keyword) {
         let oldEntry = await PlacesUtils.keywords.fetch(this.item.keyword);
         this.item.postData = oldEntry.postData;
         await PlacesUtils.keywords.remove(this.item.keyword);
       }
 
       if (this.new.keyword) {
         await PlacesUtils.keywords.insert({
           url: this.item.href,
           keyword: this.new.keyword,
           postData: this.new.postData || this.item.postData
         });
       }
-    }.bind(this))().catch(Cu.reportError)
+    })().catch(Cu.reportError)
                  .then(() => done = true);
     // TODO: Until we can move to PlacesTransactions.jsm, we must spin the
     // events loop :(
     let thread = Services.tm.currentThread;
     while (!done) {
       thread.processNextEvent(true);
     }
   },
 
   undoTransaction: function EBKTXN_undoTransaction() {
 
     let done = false;
-    (async function() {
+    (async () => {
       if (this.new.keyword) {
         await PlacesUtils.keywords.remove(this.new.keyword);
       }
 
       if (this.item.keyword) {
         await PlacesUtils.keywords.insert({
           url: this.item.href,
           keyword: this.item.keyword,
           postData: this.item.postData
         });
       }
-    }.bind(this))().catch(Cu.reportError)
+    })().catch(Cu.reportError)
                  .then(() => done = true);
     // TODO: Until we can move to PlacesTransactions.jsm, we must spin the
     // events loop :(
     let thread = Services.tm.currentThread;
     while (!done) {
       thread.processNextEvent(true);
     }
   }
--- a/toolkit/components/places/nsLivemarkService.js
+++ b/toolkit/components/places/nsLivemarkService.js
@@ -176,17 +176,17 @@ LivemarkService.prototype = {
         (hasParentGuid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.parentGuid)) ||
         (hasIndex && aLivemarkInfo.index < Ci.nsINavBookmarksService.DEFAULT_INDEX) ||
         !(aLivemarkInfo.feedURI instanceof Ci.nsIURI) ||
         (aLivemarkInfo.siteURI && !(aLivemarkInfo.siteURI instanceof Ci.nsIURI)) ||
         (aLivemarkInfo.guid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid))) {
       throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
     }
 
-    return (async function() {
+    return (async () => {
       if (!aLivemarkInfo.parentGuid)
         aLivemarkInfo.parentGuid = await PlacesUtils.promiseItemGuid(aLivemarkInfo.parentId);
 
       let livemarksMap = await this._promiseLivemarksMap();
 
       // Disallow adding a livemark inside another livemark.
       if (livemarksMap.has(aLivemarkInfo.parentGuid)) {
         throw new Components.Exception("Cannot create a livemark inside a livemark", Cr.NS_ERROR_INVALID_ARG);
@@ -229,43 +229,43 @@ LivemarkService.prototype = {
                                              lastModified: toDate(aLivemarkInfo.lastModified),
                                              source: aLivemarkInfo.source });
         livemark.lastModified = aLivemarkInfo.lastModified;
       }
 
       livemarksMap.set(folder.guid, livemark);
 
       return livemark;
-    }.bind(this))();
+    })();
   },
 
   removeLivemark(aLivemarkInfo) {
     if (!aLivemarkInfo) {
       throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
     }
     // Accept either a guid or an id.
     let hasGuid = "guid" in aLivemarkInfo;
     let hasId = "id" in aLivemarkInfo;
     if ((hasGuid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid)) ||
         (hasId && aLivemarkInfo.id < 1) ||
         (!hasId && !hasGuid)) {
       throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
     }
 
-    return (async function() {
+    return (async () => {
       if (!aLivemarkInfo.guid)
         aLivemarkInfo.guid = await PlacesUtils.promiseItemGuid(aLivemarkInfo.id);
 
       let livemarksMap = await this._promiseLivemarksMap();
       if (!livemarksMap.has(aLivemarkInfo.guid))
         throw new Components.Exception("Invalid livemark", Cr.NS_ERROR_INVALID_ARG);
 
       await PlacesUtils.bookmarks.remove(aLivemarkInfo.guid,
                                          { source: aLivemarkInfo.source });
-    }.bind(this))();
+    })();
   },
 
   reloadLivemarks(aForceUpdate) {
     // Check if there's a currently running reload, to save some useless work.
     let notWorthRestarting =
       this._forceUpdate || // We're already forceUpdating.
       !aForceUpdate;       // The caller didn't request a forced update.
     if (this._reloading && notWorthRestarting) {
@@ -288,26 +288,26 @@ LivemarkService.prototype = {
     let hasGuid = "guid" in aLivemarkInfo;
     let hasId = "id" in aLivemarkInfo;
     if ((hasGuid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid)) ||
         (hasId && aLivemarkInfo.id < 1) ||
         (!hasId && !hasGuid)) {
       throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
     }
 
-    return (async function() {
+    return (async () => {
       if (!aLivemarkInfo.guid)
         aLivemarkInfo.guid = await PlacesUtils.promiseItemGuid(aLivemarkInfo.id);
 
       let livemarksMap = await this._promiseLivemarksMap();
       if (!livemarksMap.has(aLivemarkInfo.guid))
         throw new Components.Exception("Invalid livemark", Cr.NS_ERROR_INVALID_ARG);
 
       return livemarksMap.get(aLivemarkInfo.guid);
-    }.bind(this))();
+    })();
   },
 
   // nsINavBookmarkObserver
 
   onBeginUpdateBatch() {},
   onEndUpdateBatch() {},
   onItemVisited() {},
   onItemAdded() {},
--- a/toolkit/components/places/nsPlacesExpiration.js
+++ b/toolkit/components/places/nsPlacesExpiration.js
@@ -917,17 +917,17 @@ nsPlacesExpiration.prototype = {
    * @param aAction
    *        The ACTION we are expiring for.  See the ACTION const for values.
    * @param aLimit
    *        Whether to use small, large or no limits when expiring.  See the
    *        LIMIT const for values.
    */
   _expireWithActionAndLimit:
   function PEX__expireWithActionAndLimit(aAction, aLimit) {
-    (async function() {
+    (async () => {
       // Ensure that we'll run statements with the most up-to-date pref values.
       // On shutdown we cannot do this, since we must enqueue the expiration
       // statements synchronously before the connection goes away.
       // TODO (Bug 1275878): handle this properly through a shutdown blocker.
       if (!this._shuttingDown)
         await this._loadPrefsPromise;
 
       // Skip expiration during batch mode.
@@ -942,17 +942,17 @@ nsPlacesExpiration.prototype = {
       for (let queryType in EXPIRATION_QUERIES) {
         if (EXPIRATION_QUERIES[queryType].actions & aAction)
           boundStatements.push(this._getBoundStatement(queryType, aLimit, aAction));
       }
 
 
       // Execute statements asynchronously in a transaction.
       this._db.executeAsync(boundStatements, boundStatements.length, this);
-    }.bind(this))().catch(Cu.reportError);
+    })().catch(Cu.reportError);
   },
 
   /**
    * Finalizes all of our mozIStorageStatements so we can properly close the
    * database.
    */
   _finalizeInternalStatements: function PEX__finalizeInternalStatements() {
     for (let queryType in this._cachedStatements) {
--- a/toolkit/components/places/tests/chrome/test_favicon_annotations.xul
+++ b/toolkit/components/places/tests/chrome/test_favicon_annotations.xul
@@ -88,17 +88,17 @@ function loadNextTest()
 
   let img = document.getElementById("favicon");
   img.setAttribute("src", nextURI());
 }
 
 function test()
 {
   SimpleTest.waitForExplicitFinish();
-  (async function() {
+  (async () => {
     await PlacesTestUtils.clearHistory();
 
     info("Inserting new visit");
     await PlacesUtils.history.insert({
       url: "http://example.com/favicon_annotations",
       visits: [{
         transition: PlacesUtils.history.TRANSITIONS.TYPED
       }]
@@ -122,17 +122,17 @@ function test()
     PlacesUtils.favicons.setAndFetchFaviconForPage(
       NetUtil.newURI("http://example.com/favicon_annotations"),
       NetUtil.newURI(tests[1].url),
       true, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, null,
       systemPrincipal);
 
     // And start our test process.
     loadNextTest();
-  }.bind(this))();
+  })();
 }
 
   ]]>
   </script>
 
   <body xmlns="http://www.w3.org/1999/xhtml">
     <img id="favicon" onload="loadEventHandler();"/>
     <p id="display"></p>
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -3094,17 +3094,17 @@ SearchService.prototype = {
     LOG("_asyncLoadEngines: done");
   },
 
   _asyncReInit() {
     LOG("_asyncReInit");
     // Start by clearing the initialized state, so we don't abort early.
     gInitialized = false;
 
-    (async function() {
+    (async () => {
       try {
         if (this._batchTask) {
           LOG("finalizing batch task");
           let task = this._batchTask;
           this._batchTask = null;
           await task.finalize();
         }
 
@@ -3138,17 +3138,17 @@ SearchService.prototype = {
         this._recordEngineTelemetry();
         gInitialized = true;
       } catch (err) {
         LOG("Reinit failed: " + err);
         Services.obs.notifyObservers(null, SEARCH_SERVICE_TOPIC, "reinit-failed");
       } finally {
         Services.obs.notifyObservers(null, SEARCH_SERVICE_TOPIC, "reinit-complete");
       }
-    }.bind(this))();
+    })();
   },
 
   /**
    * Read the cache file synchronously. This also imports data from the old
    * search-metadata.json file if needed.
    *
    * @returns A JS object containing the cached data.
    */
@@ -4665,17 +4665,17 @@ SearchService.prototype = {
       step: "Not started",
       latestError: {
         message: undefined,
         stack: undefined
       }
     };
     OS.File.profileBeforeChange.addBlocker(
       "Search service: shutting down",
-      () => (async function() {
+      () => (async () => {
         if (this._batchTask) {
           shutdownState.step = "Finalizing batched task";
           try {
             await this._batchTask.finalize();
             shutdownState.step = "Batched task finalized";
           } catch (ex) {
             shutdownState.step = "Batched task failed to finalize";
 
@@ -4684,17 +4684,17 @@ SearchService.prototype = {
               shutdownState.latestError.stack = ex.stack || undefined;
             }
 
             // Ensure that error is reported and that it causes tests
             // to fail.
             Promise.reject(ex);
           }
         }
-      }.bind(this))(),
+      })(),
 
       () => shutdownState
     );
   },
   _observersAdded: false,
 
   _removeObservers: function SRCH_SVC_removeObservers() {
     Services.obs.removeObserver(this, SEARCH_ENGINE_TOPIC);
--- a/toolkit/components/telemetry/TelemetryController.jsm
+++ b/toolkit/components/telemetry/TelemetryController.jsm
@@ -702,17 +702,17 @@ var Impl = {
     // We try to cache it in prefs to avoid this, even though this may
     // lead to some stale client ids.
     this._clientID = ClientID.getCachedClientID();
 
     // Delay full telemetry initialization to give the browser time to
     // run various late initializers. Otherwise our gathered memory
     // footprint and other numbers would be too optimistic.
     this._delayedInitTaskDeferred = Promise.defer();
-    this._delayedInitTask = new DeferredTask(async function() {
+    this._delayedInitTask = new DeferredTask(async () => {
       try {
         // TODO: This should probably happen after all the delayed init here.
         this._initialized = true;
         TelemetryEnvironment.delayedInit();
 
         // Load the ClientID.
         this._clientID = await ClientID.getClientID();
 
@@ -741,17 +741,17 @@ var Impl = {
         TelemetryModules.start();
 
         this._delayedInitTaskDeferred.resolve();
       } catch (e) {
         this._delayedInitTaskDeferred.reject(e);
       } finally {
         this._delayedInitTask = null;
       }
-    }.bind(this), this._testMode ? TELEMETRY_TEST_DELAY : TELEMETRY_DELAY);
+    }, this._testMode ? TELEMETRY_TEST_DELAY : TELEMETRY_DELAY);
 
     AsyncShutdown.sendTelemetry.addBlocker("TelemetryController: shutting down",
                                            () => this.shutdown(),
                                            () => this._getState());
 
     this._delayedInitTask.arm();
     return this._delayedInitTaskDeferred.promise;
   },
@@ -886,31 +886,31 @@ var Impl = {
    */
   _onUploadPrefChange() {
     const uploadEnabled = Preferences.get(PREF_FHR_UPLOAD_ENABLED, false);
     if (uploadEnabled) {
       // There's nothing we should do if we are enabling upload.
       return;
     }
 
-    let p = (async function() {
+    let p = (async () => {
       try {
         // Clear the current pings.
         await TelemetrySend.clearCurrentPings();
 
         // Remove all the pending pings, but not the deletion ping.
         await TelemetryStorage.runRemovePendingPingsTask();
       } catch (e) {
         this._log.error("_onUploadPrefChange - error clearing pending pings", e);
       } finally {
         // Always send the deletion ping.
         this._log.trace("_onUploadPrefChange - Sending deletion ping.");
         this.submitExternalPing(PING_TYPE_DELETION, {}, { addClientId: true });
       }
-    }.bind(this))();
+    })();
 
     this._shutdownBarrier.client.addBlocker(
       "TelemetryController: removing pending pings after data upload was disabled", p);
   },
 
   _attachObservers() {
     if (IS_UNIFIED_TELEMETRY) {
       // Watch the FHR upload setting to trigger deletion pings.
@@ -982,23 +982,23 @@ var Impl = {
    * Schedule sending the "new-profile" ping.
    */
   scheduleNewProfilePing() {
     this._log.trace("scheduleNewProfilePing");
 
     const sendDelay =
       Preferences.get(PREF_NEWPROFILE_PING_DELAY, NEWPROFILE_PING_DEFAULT_DELAY);
 
-    this._delayedNewPingTask = new DeferredTask(async function() {
+    this._delayedNewPingTask = new DeferredTask(async () => {
       try {
         await this.sendNewProfilePing();
       } finally {
         this._delayedNewPingTask = null;
       }
-    }.bind(this), sendDelay);
+    }, sendDelay);
 
     this._delayedNewPingTask.arm();
   },
 
   /**
    * Generate and send the new-profile ping
    */
   async sendNewProfilePing() {
--- a/toolkit/components/telemetry/TelemetrySend.jsm
+++ b/toolkit/components/telemetry/TelemetrySend.jsm
@@ -902,27 +902,27 @@ var TelemetrySendImpl = {
     this._pendingPingRequests.clear();
   },
 
   sendPings(currentPings, persistedPingIds) {
     let pingSends = [];
 
     for (let current of currentPings) {
       let ping = current;
-      let p = (async function() {
+      let p = (async () => {
         try {
           await this._doPing(ping, ping.id, false);
         } catch (ex) {
           this._log.info("sendPings - ping " + ping.id + " not sent, saving to disk", ex);
           // Deletion pings must be saved to a special location.
           await savePing(ping);
         } finally {
           this._currentPings.delete(ping.id);
         }
-      }.bind(this))();
+      })();
 
       this._trackPendingPingTask(p);
       pingSends.push(p);
     }
 
     if (persistedPingIds.length > 0) {
       pingSends.push(this._sendPersistedPings(persistedPingIds).catch((ex) => {
         this._log.info("sendPings - persisted pings not sent", ex);
--- a/toolkit/components/telemetry/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/TelemetrySession.jsm
@@ -1613,26 +1613,26 @@ var Impl = {
       this._log.trace("setupContentProcess - base recording is disabled, not initializing");
       return;
     }
 
     Services.obs.addObserver(this, "content-child-shutdown");
     cpml.addMessageListener(MESSAGE_TELEMETRY_GET_CHILD_THREAD_HANGS, this);
     cpml.addMessageListener(MESSAGE_TELEMETRY_GET_CHILD_USS, this);
 
-    let delayedTask = new DeferredTask(function() {
+    let delayedTask = new DeferredTask(() => {
       this._initialized = true;
 
       this.attachObservers();
       this.gatherMemory();
 
       if (Telemetry.canRecordExtended) {
         GCTelemetry.init();
       }
-    }.bind(this), testing ? TELEMETRY_TEST_DELAY : TELEMETRY_DELAY);
+    }, testing ? TELEMETRY_TEST_DELAY : TELEMETRY_DELAY);
 
     delayedTask.arm();
   },
 
   getFlashVersion: function getFlashVersion() {
     let host = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
     let tags = host.getPluginTags();
 
--- a/toolkit/components/thumbnails/PageThumbs.jsm
+++ b/toolkit/components/thumbnails/PageThumbs.jsm
@@ -265,30 +265,30 @@ this.PageThumbs = {
                                                            aBrowser.docShell));
     }
   },
 
   // The background thumbnail service captures to canvas but doesn't want to
   // participate in this service's telemetry, which is why this method exists.
   _captureToCanvas(aBrowser, aCanvas, aArgs, aCallback) {
     if (aBrowser.isRemoteBrowser) {
-      (async function() {
+      (async () => {
         let data =
           await this._captureRemoteThumbnail(aBrowser, aCanvas.width,
                                              aCanvas.height, aArgs);
         let canvas = data.thumbnail;
         let ctx = canvas.getContext("2d");
         let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
         aCanvas.width = canvas.width;
         aCanvas.height = canvas.height;
         aCanvas.getContext("2d").putImageData(imgData, 0, 0);
         if (aCallback) {
           aCallback(aCanvas);
         }
-      }.bind(this))();
+      })();
       return;
     }
     // The content is a local page, grab a thumbnail sync.
     PageThumbUtils.createSnapshotThumbnail(aBrowser.contentWindow,
                                            aCanvas,
                                            aArgs);
 
     if (aCallback) {
@@ -367,17 +367,17 @@ this.PageThumbs = {
     if (!this._prefEnabled()) {
       return;
     }
 
     let url = aBrowser.currentURI.spec;
     let originalURL;
     let channelError = false;
 
-    ((async function task() {
+    (async () => {
       if (!aBrowser.isRemoteBrowser) {
         let channel = aBrowser.docShell.currentDocumentChannel;
         originalURL = channel.originalURI.spec;
         // see if this was an error response.
         channelError = PageThumbUtils.isChannelErrorResponse(channel);
       } else {
         let resp = await new Promise(resolve => {
           let mm = aBrowser.messageManager;
@@ -399,17 +399,17 @@ this.PageThumbs = {
         await this._store(originalURL, url, buffer, channelError);
       } catch (ex) {
         Components.utils.reportError("Exception thrown during thumbnail capture: '" + ex + "'");
         isSuccess = false;
       }
       if (aCallback) {
         aCallback(isSuccess);
       }
-    }).bind(this))();
+    })();
   },
 
   /**
    * Checks if an existing thumbnail for the specified URL is either missing
    * or stale, and if so, captures and stores it.  Once the thumbnail is stored,
    * an observer service notification will be sent, so consumers should observe
    * such notifications if they want to be notified of an updated thumbnail.
    *
--- a/toolkit/modules/DeferredTask.jsm
+++ b/toolkit/modules/DeferredTask.jsm
@@ -265,17 +265,17 @@ this.DeferredTask.prototype = {
     // timer callback, to prevent race conditions and to ensure that all the
     // methods behave consistently even if called from inside the task.  This
     // means that the assignment of "this._runningPromise" must complete before
     // the task gets a chance to start.
     this._timer = null;
     this._armed = false;
     this._runningPromise = runningDeferred.promise;
 
-    runningDeferred.resolve((async function() {
+    runningDeferred.resolve((async () => {
       // Execute the provided function asynchronously.
       await (this._taskFn)().then(null, Cu.reportError);
 
       // Now that the task has finished, we check the state of the object to
       // determine if we should restart the task again.
       if (this._armed) {
         if (!this._finalized) {
           this._startTimer();
@@ -286,11 +286,11 @@ this.DeferredTask.prototype = {
           this._armed = false;
           await (this._taskFn)().then(null, Cu.reportError);
         }
       }
 
       // Indicate that the execution of the task has finished.  This happens
       // synchronously with the previous state changes in the function.
       this._runningPromise = null;
-    }.bind(this))().then(null, Cu.reportError));
+    })().then(null, Cu.reportError));
   },
 };
--- a/toolkit/modules/JSONFile.jsm
+++ b/toolkit/modules/JSONFile.jsm
@@ -307,21 +307,21 @@ JSONFile.prototype = {
    * @resolves When the object is finalized.
    */
   _finalizeInternal() {
     if (this._finalizePromise) {
       // Finalization already in progress; return the pending promise. This is
       // possible if `finalize` is called concurrently with shutdown.
       return this._finalizePromise;
     }
-    this._finalizePromise = (async function() {
+    this._finalizePromise = (async () => {
       await this._saver.finalize();
       this._data = null;
       this.dataReady = false;
-    }.bind(this))();
+    })();
     return this._finalizePromise;
   },
 
   /**
    * Ensures that all data is persisted to disk, and prevents future calls to
    * `saveSoon`. This is called automatically on shutdown, but can also be
    * called explicitly when the file is no longer needed.
    */
--- a/toolkit/modules/Log.jsm
+++ b/toolkit/modules/Log.jsm
@@ -859,28 +859,28 @@ function FileAppender(path, formatter) {
   // This is a promise exposed for testing/debugging the logger itself.
   this._lastWritePromise = null;
 }
 
 FileAppender.prototype = {
   __proto__: Appender.prototype,
 
   _openFile() {
-    return (async function _openFile() {
+    return (async () => {
       try {
         this._file = await OS.File.open(this._path,
                                         {truncate: true});
       } catch (err) {
         if (err instanceof OS.File.Error) {
           this._file = null;
         } else {
           throw err;
         }
       }
-    }.bind(this))();
+    })();
   },
 
   _getFile() {
     if (!this._fileReadyPromise) {
       this._fileReadyPromise = this._openFile();
     }
 
     return this._fileReadyPromise;
--- a/toolkit/modules/Sqlite.jsm
+++ b/toolkit/modules/Sqlite.jsm
@@ -374,23 +374,23 @@ ConnectionData.prototype = Object.freeze
       throw new TypeError("Expected a Promise");
     }
     let key = `${this._identifier}: ${name} (${this._getOperationId()})`;
     let promiseComplete = promiseResult.catch(() => {});
     this._barrier.client.addBlocker(key, promiseComplete, {
       fetchState: () => status
     });
 
-    return (async function() {
+    return (async () => {
       try {
         return (await promiseResult);
       } finally {
         this._barrier.client.removeBlocker(key, promiseComplete)
       }
-    }.bind(this))();
+    })();
   },
   close() {
     this._closeRequested = true;
 
     if (!this._dbConn) {
       return this._deferredClose.promise;
     }
 
@@ -553,17 +553,17 @@ ConnectionData.prototype = Object.freeze
 
     this._log.debug("Beginning transaction");
 
     let promise = this._transactionQueue.then(() => {
       if (this._closeRequested) {
         throw new Error("Transaction canceled due to a closed connection.");
       }
 
-      let transactionPromise = (async function() {
+      let transactionPromise = (async () => {
         // At this point we should never have an in progress transaction, since
         // they are enqueued.
         if (this._hasInProgressTransaction) {
           console.error("Unexpected transaction in progress when trying to start a new one.");
         }
         this._hasInProgressTransaction = true;
         try {
           // We catch errors in statement execution to detect nested transactions.
@@ -624,17 +624,17 @@ ConnectionData.prototype = Object.freeze
               throw ex;
             }
           }
 
           return result;
         } finally {
           this._hasInProgressTransaction = false;
         }
-      }.bind(this))();
+      })();
 
       // If a transaction yields on a never resolved promise, or is mistakenly
       // nested, it could hang the transactions queue forever.  Thus we timeout
       // the execution after a meaningful amount of time, to ensure in any case
       // we'll proceed after a while.
       let timeoutPromise = new Promise((resolve, reject) => {
         setTimeout(() => reject(new Error("Transaction timeout, most likely caused by unresolved pending work.")),
                    TRANSACTIONS_QUEUE_TIMEOUT_MS);
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js
+++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js
@@ -243,17 +243,17 @@ nsUnknownContentTypeDialog.prototype = {
         }
       }
       if (!parent) {
         Cu.reportError("No candidate parent windows were found for the save filepicker." +
                        "This should never happen.");
       }
     }
 
-    (async function() {
+    (async () => {
       if (!aForcePrompt) {
         // Check to see if the user wishes to auto save to the default download
         // folder without prompting. Note that preference might not be set.
         let autodownload = prefs.getBoolPref(PREF_BD_USEDOWNLOADDIR, false);
 
         if (autodownload) {
           // Retrieve the user's default download directory
           let preferredDir = await Downloads.getPreferredDownloadsDirectory();
@@ -357,17 +357,17 @@ nsUnknownContentTypeDialog.prototype = {
                 return;
               }
 
             }
           }
           aLauncher.saveDestinationAvailable(result);
         });
       });
-    }.bind(this))().then(null, Components.utils.reportError);
+    })().then(null, Components.utils.reportError);
   },
 
   getFinalLeafName: function (aLeafName, aFileExt)
   {
     // Remove any leading periods, since we don't want to save hidden files
     // automatically.
     aLeafName = aLeafName.replace(/^\.+/, "");
 
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -1349,17 +1349,17 @@ var AddonManagerInternal = {
    * @return Promise{null} Resolves when the background update check is complete
    *                       (the resulting addon installations may still be in progress).
    */
   backgroundUpdateCheck() {
     if (!gStarted)
       throw Components.Exception("AddonManager is not initialized",
                                  Cr.NS_ERROR_NOT_INITIALIZED);
 
-    let buPromise = (async function() {
+    let buPromise = (async () => {
       let hotfixID = this.hotfixID;
 
       let appUpdateEnabled = Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED) &&
                              Services.prefs.getBoolPref(PREF_APP_UPDATE_AUTO);
       let checkHotfix = hotfixID && appUpdateEnabled;
 
       logger.debug("Background update check beginning");
 
@@ -1508,17 +1508,17 @@ var AddonManagerInternal = {
         } catch (e) {
           logger.warn("Failed to update system addons", e);
         }
       }
 
       logger.debug("Background update check complete");
       Services.obs.notifyObservers(null,
                                    "addons-background-update-complete");
-    }.bind(this))();
+    })();
     // Fork the promise chain so we can log the error and let our caller see it too.
     buPromise.then(null, e => logger.warn("Error in background update", e));
     return buPromise;
   },
 
   /**
    * Adds a add-on to the list of detected changes for this startup. If
    * addStartupChange is called multiple times for the same add-on in the same
@@ -1739,24 +1739,24 @@ var AddonManagerInternal = {
    * Notifies all providers that the repository has updated its data for
    * installed add-ons.
    */
   updateAddonRepositoryData() {
     if (!gStarted)
       throw Components.Exception("AddonManager is not initialized",
                                  Cr.NS_ERROR_NOT_INITIALIZED);
 
-    return (async function() {
+    return (async () => {
       for (let provider of this.providers) {
         await promiseCallProvider(provider, "updateAddonRepositoryData");
       }
 
       // only tests should care about this
       Services.obs.notifyObservers(null, "TEST:addon-repository-data-updated");
-    }.bind(this))();
+    })();
   },
 
   /**
    * Asynchronously gets an AddonInstall for a URL.
    *
    * @param  aUrl
    *         The string represenation of the URL the add-on is located at
    * @param  aMimetype
@@ -1841,27 +1841,27 @@ var AddonManagerInternal = {
     if (!(aFile instanceof Ci.nsIFile))
       throw Components.Exception("aFile must be a nsIFile",
                                  Cr.NS_ERROR_INVALID_ARG);
 
     if (aMimetype && typeof aMimetype != "string")
       throw Components.Exception("aMimetype must be a string or null",
                                  Cr.NS_ERROR_INVALID_ARG);
 
-    return (async function() {
+    return (async () => {
       for (let provider of this.providers) {
         let install = await promiseCallProvider(
           provider, "getInstallForFile", aFile);
 
         if (install)
           return install;
       }
 
       return null;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Asynchronously gets all current AddonInstalls optionally limiting to a list
    * of types.
    *
    * @param  aTypes
    *         An optional array of types to retrieve. Each type is a string name
@@ -1871,29 +1871,29 @@ var AddonManagerInternal = {
     if (!gStarted)
       throw Components.Exception("AddonManager is not initialized",
                                  Cr.NS_ERROR_NOT_INITIALIZED);
 
     if (aTypes && !Array.isArray(aTypes))
       throw Components.Exception("aTypes must be an array or null",
                                  Cr.NS_ERROR_INVALID_ARG);
 
-    return (async function() {
+    return (async () => {
       let installs = [];
 
       for (let provider of this.providers) {
         let providerInstalls = await promiseCallProvider(
           provider, "getInstallsByTypes", aTypes);
 
         if (providerInstalls)
           installs.push(...providerInstalls);
       }
 
       return installs;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Asynchronously gets all current AddonInstalls.
    */
   getAllInstalls() {
     if (!gStarted)
       throw Components.Exception("AddonManager is not initialized",
@@ -2427,27 +2427,27 @@ var AddonManagerInternal = {
     if (!gStarted)
       throw Components.Exception("AddonManager is not initialized",
                                  Cr.NS_ERROR_NOT_INITIALIZED);
 
     if (!aGUID || typeof aGUID != "string")
       throw Components.Exception("aGUID must be a non-empty string",
                                  Cr.NS_ERROR_INVALID_ARG);
 
-    return (async function() {
+    return (async () => {
       for (let provider of this.providers) {
         let addon = await promiseCallProvider(
           provider, "getAddonBySyncGUID", aGUID);
 
         if (addon)
           return addon;
       }
 
       return null;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Asynchronously gets an array of add-ons.
    *
    * @param  aIDs
    *         The array of IDs to retrieve
    * @return {Promise}
@@ -2478,29 +2478,29 @@ var AddonManagerInternal = {
     if (!gStarted)
       throw Components.Exception("AddonManager is not initialized",
                                  Cr.NS_ERROR_NOT_INITIALIZED);
 
     if (aTypes && !Array.isArray(aTypes))
       throw Components.Exception("aTypes must be an array or null",
                                  Cr.NS_ERROR_INVALID_ARG);
 
-    return (async function() {
+    return (async () => {
       let addons = [];
 
       for (let provider of this.providers) {
         let providerAddons = await promiseCallProvider(
           provider, "getAddonsByTypes", aTypes);
 
         if (providerAddons)
           addons.push(...providerAddons);
       }
 
       return addons;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Asynchronously gets all installed add-ons.
    */
   getAllAddons() {
     if (!gStarted)
       throw Components.Exception("AddonManager is not initialized",
@@ -2520,29 +2520,29 @@ var AddonManagerInternal = {
     if (!gStarted)
       throw Components.Exception("AddonManager is not initialized",
                                  Cr.NS_ERROR_NOT_INITIALIZED);
 
     if (aTypes && !Array.isArray(aTypes))
       throw Components.Exception("aTypes must be an array or null",
                                  Cr.NS_ERROR_INVALID_ARG);
 
-    return (async function() {
+    return (async () => {
       let addons = [];
 
       for (let provider of this.providers) {
         let providerAddons = await promiseCallProvider(
           provider, "getAddonsWithOperationsByTypes", aTypes);
 
         if (providerAddons)
           addons.push(...providerAddons);
       }
 
       return addons;
-    }.bind(this))();
+    })();
   },
 
   /**
    * Adds a new AddonManagerListener if the listener is not already registered.
    *
    * @param  aListener
    *         The listener to add
    */
--- a/toolkit/mozapps/extensions/internal/AddonRepository.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonRepository.jsm
@@ -1543,17 +1543,17 @@ var AddonDatabase = {
 
   /**
    * Asynchronously opens a new connection to the database file.
    *
    * @return {Promise} a promise that resolves to the database.
    */
   openConnection() {
     if (!this.connectionPromise) {
-     this.connectionPromise = (async function() {
+     this.connectionPromise = (async () => {
        this.DB = BLANK_DB();
 
        let inputDB, schema;
 
        try {
          let data = await OS.File.read(this.jsonFile, { encoding: "utf-8"})
          inputDB = JSON.parse(data);
 
@@ -1604,17 +1604,17 @@ var AddonDatabase = {
        // We use _insertAddon manually instead of calling
        // insertAddons to avoid the write to disk which would
        // be a waste since this is the data that was just read.
        for (let addon of inputDB.addons) {
          this._insertAddon(addon);
        }
 
        return this.DB;
-     }.bind(this))();
+     })();
     }
 
     return this.connectionPromise;
   },
 
   /**
    * A lazy getter for the database connection.
    */
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
@@ -439,17 +439,17 @@ var AddonTestUtils = {
     let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
     let factory = registrar.getClassObject(CERTDB_CID, Ci.nsIFactory);
     registrar.unregisterFactory(CERTDB_CID, factory);
 
     // Get the real DB
     let realCertDB = factory.createInstance(null, Ci.nsIX509CertDB);
 
 
-    let verifyCert = async function(file, result, cert, callback) {
+    let verifyCert = async (file, result, cert, callback) => {
       if (result == Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED &&
           !this.useRealCertChecks && callback.wrappedJSObject) {
         // Bypassing XPConnect allows us to create a fake x509 certificate from JS
         callback = callback.wrappedJSObject;
 
         try {
           let manifestURI = this.getManifestURI(file);
 
@@ -463,17 +463,17 @@ var AddonTestUtils = {
         } finally {
           // Make sure to close the open zip file or it will be locked.
           if (file.isFile())
             Services.obs.notifyObservers(file, "flush-cache-entry", "cert-override");
         }
       }
 
       return [callback, result, cert];
-    }.bind(this);
+    };
 
 
     function FakeCertDB() {
       for (let property of Object.keys(realCertDB)) {
         if (property in this)
           continue;
 
         if (typeof realCertDB[property] == "function")
--- a/toolkit/mozapps/extensions/internal/GMPProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/GMPProvider.jsm
@@ -271,17 +271,17 @@ GMPWrapper.prototype = {
     }
 
     if (this._updateTask !== null) {
       this._log.trace("findUpdates() - " + this._plugin.id +
                       " - update task already running");
       return this._updateTask;
     }
 
-    this._updateTask = (async function() {
+    this._updateTask = (async () => {
       this._log.trace("findUpdates() - updateTask");
       try {
         let installManager = new GMPInstallManager();
         let res = await installManager.checkForAddons();
         let update = res.gmpAddons.find(addon => addon.id === this._plugin.id);
         if (update && update.isValid && !update.isInstalled) {
           this._log.trace("findUpdates() - found update for " +
                           this._plugin.id + ", installing");
@@ -294,17 +294,17 @@ GMPWrapper.prototype = {
       } catch (e) {
         this._log.error("findUpdates() - updateTask for " + this._plugin.id +
                         " threw", e);
         throw e;
       } finally {
         this._updateTask = null;
       }
       return true;
-    }.bind(this))();
+    })();
 
     return this._updateTask;
   },
 
   get pluginMimeTypes() { return []; },
   get pluginLibraries() {
     if (this.isInstalled) {
       let path = this.version;
@@ -577,34 +577,34 @@ var GMPProvider = {
       this._log.warn("startup - adding clearkey CDM failed", e);
     }
   },
 
   shutdown() {
     this._log.trace("shutdown");
     Services.prefs.removeObserver(GMPPrefs.KEY_LOG_BASE, configureLogging);
 
-    let shutdownTask = (async function() {
+    let shutdownTask = (async () => {
       this._log.trace("shutdown - shutdownTask");
       let shutdownSucceeded = true;
 
       for (let plugin of this._plugins.values()) {
         try {
           await plugin.wrapper.shutdown();
         } catch (e) {
           shutdownSucceeded = false;
         }
       }
 
       this._plugins = null;
 
       if (!shutdownSucceeded) {
         throw new Error("Shutdown failed");
       }
-    }.bind(this))();
+    })();
 
     return shutdownTask;
   },
 
   getAddonByID(aId, aCallback) {
     if (!this.isEnabled) {
       aCallback(null);
       return;
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -5646,17 +5646,17 @@ class AddonInstall {
    * manifest can be read.
    *
    * @param  aCallback
    *         A function to call when the manifest has been loaded
    * @throws if the add-on does not contain a valid install manifest or the
    *         XPI is incorrectly signed
    */
   loadManifest(file) {
-    return ((async function() {
+    return (async () => {
       let zipreader = Cc["@mozilla.org/libjar/zip-reader;1"].
           createInstance(Ci.nsIZipReader);
       try {
         zipreader.open(file);
       } catch (e) {
         zipreader.close();
         return Promise.reject([AddonManager.ERROR_CORRUPT_FILE, e]);
       }
@@ -5748,17 +5748,17 @@ class AddonInstall {
 
       this.addon._repositoryAddon = repoAddon;
       this.name = this.name || this.addon._repositoryAddon.name;
       this.addon.compatibilityOverrides = repoAddon ?
         repoAddon.compatibilityOverrides :
         null;
       this.addon.appDisabled = !isUsableAddon(this.addon);
       return undefined;
-    }).bind(this))();
+    })();
   }
 
   getIcon(desiredSize = 64) {
     if (!this.addon.icons || !this.file) {
       return null;
     }
 
     let {icon} = IconDetails.getPreferredIcon(this.addon.icons, null, desiredSize);
@@ -5771,17 +5771,17 @@ class AddonInstall {
   /**
    * This method should be called when the XPI is ready to be installed,
    * i.e., when a download finishes or when a local file has been verified.
    * It should only be called from install() when the install is in
    * STATE_DOWNLOADED (which actually means that the file is available
    * and has been verified).
    */
   checkPrompt() {
-    ((async function() {
+    (async () => {
       if (this.promptHandler) {
         let info = {
           existingAddon: this.existingAddon ? this.existingAddon.wrapper : null,
           addon: this.addon.wrapper,
           icon: this.getIcon(),
         };
 
         try {
@@ -5792,17 +5792,17 @@ class AddonInstall {
           XPIProvider.removeActiveInstall(this);
           AddonManagerPrivate.callInstallListeners("onInstallCancelled",
                                                    this.listeners, this.wrapper);
           return;
         }
       }
       this.state = AddonManager.STATE_PROMPTS_DONE;
       this.install();
-    }).bind(this))();
+    })();
   }
 
   /**
    * This method should be called when we have the XPI and any needed
    * permissions prompts have been completed.  If there are any upgrade
    * listeners, they are invoked and the install moves into STATE_POSTPONED.
    * Otherwise, the install moves into STATE_INSTALLING
    */
@@ -5858,17 +5858,17 @@ class AddonInstall {
 
     logger.debug("Starting install of " + this.addon.id + " from " + this.sourceURI.spec);
     AddonManagerPrivate.callAddonListeners("onInstalling",
                                            this.addon.wrapper,
                                            requiresRestart);
 
     let stagedAddon = this.installLocation.getStagingDir();
 
-    ((async function() {
+    (async () => {
       let installedUnpacked = 0;
 
       await this.installLocation.requestStagingDir();
 
       // remove any previously staged files
       await this.unstageInstall(stagedAddon);
 
       stagedAddon.append(this.addon.id);
@@ -5974,17 +5974,17 @@ class AddonInstall {
         }
         XPIProvider.setTelemetry(this.addon.id, "unpacked", installedUnpacked);
         recordAddonTelemetry(this.addon);
 
         // Notify providers that a new theme has been enabled.
         if (isTheme(this.addon.type) && this.addon.active)
           AddonManagerPrivate.notifyAddonChanged(this.addon.id, this.addon.type, requiresRestart);
       }
-    }).bind(this))().then(null, (e) => {
+    })().then(null, (e) => {
       logger.warn(`Failed to install ${this.file.path} from ${this.sourceURI.spec} to ${stagedAddon.path}`, e);
 
       if (stagedAddon.exists())
         recursiveRemove(stagedAddon);
       this.state = AddonManager.STATE_INSTALL_FAILED;
       this.error = AddonManager.ERROR_FILE_ACCESS;
       XPIProvider.removeActiveInstall(this);
       AddonManagerPrivate.callAddonListeners("onOperationCancelled",
@@ -5997,17 +5997,17 @@ class AddonInstall {
       return this.installLocation.releaseStagingDir();
     });
   }
 
   /**
    * Stages an upgrade for next application restart.
    */
   stageInstall(restartRequired, stagedAddon, isUpgrade) {
-    return ((async function() {
+    return (async () => {
       let stagedJSON = stagedAddon.clone();
       stagedJSON.leafName = this.addon.id + ".json";
 
       let installedUnpacked = 0;
 
       // First stage the file regardless of whether restarting is necessary
       if (this.addon.unpack || Preferences.get(PREF_XPI_UNPACK, false)) {
         logger.debug("Addon " + this.addon.id + " will be installed as " +
@@ -6033,48 +6033,48 @@ class AddonInstall {
         logger.debug("Staged install of " + this.addon.id + " from " + this.sourceURI.spec + " ready; waiting for restart.");
         if (isUpgrade) {
           delete this.existingAddon.pendingUpgrade;
           this.existingAddon.pendingUpgrade = this.addon;
         }
       }
 
       return installedUnpacked;
-    }).bind(this))();
+    })();
   }
 
   /**
    * Removes any previously staged upgrade.
    */
   unstageInstall(stagedAddon) {
-    return ((async function() {
+    return (async () => {
       let stagedJSON = stagedAddon.clone();
       let removedAddon = stagedAddon.clone();
 
       stagedJSON.append(this.addon.id + ".json");
 
       if (stagedJSON.exists()) {
         stagedJSON.remove(true);
       }
 
       removedAddon.append(this.addon.id);
       await removeAsync(removedAddon);
       removedAddon.leafName = this.addon.id + ".xpi";
       await removeAsync(removedAddon);
-    }).bind(this))();
+    })();
   }
 
   /**
     * Postone a pending update, until restart or until the add-on resumes.
     *
     * @param {Function} resumeFn - a function for the add-on to run
     *                                    when resuming.
     */
   postpone(resumeFn) {
-    return ((async function() {
+    return (async () => {
       this.state = AddonManager.STATE_POSTPONED;
 
       let stagingDir = this.installLocation.getStagingDir();
       let stagedAddon = stagingDir.clone();
 
       await this.installLocation.requestStagingDir();
       await this.unstageInstall(stagedAddon);
 
@@ -6105,29 +6105,29 @@ class AddonInstall {
             }
           },
         });
       }
       // Release the staging directory lock, but since the staging dir is populated
       // it will not be removed until resumed or installed by restart.
       // See also cleanStagingDir()
       this.installLocation.releaseStagingDir();
-    }).bind(this))();
+    })();
   }
 }
 
 class LocalAddonInstall extends AddonInstall {
   /**
    * Initialises this install to be an install from a local file.
    *
    * @returns Promise
    *          A Promise that resolves when the object is ready to use.
    */
   init() {
-    return ((async function() {
+    return (async () => {
       this.file = this.sourceURI.QueryInterface(Ci.nsIFileURL).file;
 
       if (!this.file.exists()) {
         logger.warn("XPI file " + this.file.path + " does not exist");
         this.state = AddonManager.STATE_DOWNLOAD_FAILED;
         this.error = AddonManager.ERROR_NETWORK_FAILURE;
         XPIProvider.removeActiveInstall(this);
         return;
@@ -6203,17 +6203,17 @@ class LocalAddonInstall extends AddonIns
           }, AddonManager.UPDATE_WHEN_ADDON_INSTALLED);
         });
       } else {
         AddonManagerPrivate.callInstallListeners("onNewInstall",
                                                  this.listeners,
                                                  this.wrapper);
 
       }
-    }).bind(this))();
+    })();
   }
 
   install() {
     if (this.state == AddonManager.STATE_DOWNLOAD_FAILED) {
       // For a local install, this state means that verification of the
       // file failed (e.g., the hash or signature or manifest contents
       // were invalid).  It doesn't make sense to retry anything in this
       // case but we have callers who don't know if their AddonInstall