diff --git a/.eslintignore b/.eslintignore index 26d524fc3134..44fe00ba15e9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -22,7 +22,6 @@ gfx/layers/** gfx/tests/browser/** gfx/tests/chrome/** gfx/tests/mochitest/** -gfx/tests/unit/** image/** layout/** memory/replace/dmd/test/** @@ -38,7 +37,6 @@ netwerk/test/mochitests/** netwerk/test/unit*/** netwerk/wifi/** parser/** -rdf/** tools/update-packaging/** uriloader/exthandler/** uriloader/exthandler/tests/mochitest/** @@ -57,7 +55,6 @@ mfbt/** mozglue/** nsprpub/** other-licenses/** -probes/** startupcache/** xpfe/** @@ -104,8 +101,6 @@ devtools/client/performance/components/test/test_jit_optimizations_01.html devtools/client/responsive.html/test/browser/touch.html devtools/client/shared/components/test/mochitest/*.html !devtools/client/shared/components/test/mochitest/test_stack-trace.html -devtools/client/shared/shim/test/test_*.html -devtools/client/shared/test/browser_toolbar_webconsole_errors_count.html devtools/client/storage/test/*.html !devtools/client/storage/test/storage-cookies.html !devtools/client/storage/test/storage-overflow.html @@ -176,7 +171,6 @@ devtools/server/tests/unit/xpcshell_debugging_script.js # dom/ exclusions dom/abort/** dom/animation/** -dom/archivereader/** dom/asmjscache/** dom/audiochannel/** dom/base/** @@ -190,7 +184,6 @@ dom/canvas/** dom/commandhandler/** dom/console/** dom/crypto/** -dom/devicestorage/** dom/encoding/** dom/events/** dom/fetch/** @@ -198,7 +191,6 @@ dom/file/** dom/filehandle/** dom/filesystem/** dom/flex/** -dom/flyweb/** dom/gamepad/** dom/geolocation/** dom/grid/** @@ -206,7 +198,6 @@ dom/html/** dom/imptests/** dom/interfaces/** dom/ipc/** -dom/json/** dom/jsurl/** dom/locales/** dom/manifest/** @@ -233,12 +224,9 @@ dom/promise/** dom/push/** dom/quota/** dom/res/** -dom/secureelement/** -dom/security/test/contentverifier/** dom/security/test/cors/** dom/security/test/csp/** dom/security/test/general/** -dom/security/test/hsts/** dom/security/test/mixedcontentblocker/** dom/security/test/sri/** dom/security/test/unit/** @@ -252,7 +240,6 @@ dom/tests/html/** dom/tests/js/** dom/tests/mochitest/** dom/tests/unit/** -dom/time/** dom/u2f/** dom/url/** dom/vr/** @@ -353,7 +340,6 @@ testing/mozbase/mozprofile/tests/files/prefs_with_comments.js testing/talos/talos/scripts/jszip.min.js testing/talos/talos/startup_test/sessionrestore/profile/sessionstore.js testing/talos/talos/startup_test/sessionrestore/profile-manywindows/sessionstore.js -testing/talos/talos/tests/canvasmark/** testing/talos/talos/tests/devtools/addon/content/pages/** testing/talos/talos/tests/dromaeo/** testing/talos/talos/tests/v8_7/** @@ -371,9 +357,6 @@ services/common/kinto-offline-client.js # toolkit/ exclusions -# Not part of the default build -toolkit/components/help/** - # Intentionally invalid JS toolkit/components/workerloader/tests/moduleF-syntax-error.js diff --git a/.hgtags b/.hgtags index fb0245d14024..590c28e16505 100644 --- a/.hgtags +++ b/.hgtags @@ -146,3 +146,4 @@ ccfd7b716a91241ddbc084cb7116ec561e56d5d1 FIREFOX_BETA_61_BASE 9b74b9f2939a7ae3a0ea6e711dc32ed5203e03ff FIREFOX_BETA_62_BASE 4f6e597104dabedfecfafa2ab63dc79fd7f8bc7a FIREFOX_NIGHTLY_62_END 190b827aaa2b5e6fb9af7a0defb238ccc35f8b9e FIREFOX_BETA_63_BASE +034c5ef24e98b0ce85fa849face079f568eb397c FIREFOX_NIGHTLY_63_END diff --git a/CLOBBER b/CLOBBER index 54dd1f2aa44c..d4cdfaff33de 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Bug 1346211 - Modifying ICU data file requires a clobber. +Merge day clobber \ No newline at end of file diff --git a/accessible/tests/browser/.eslintrc.js b/accessible/tests/browser/.eslintrc.js index b2189661238a..49dde63cd5b6 100644 --- a/accessible/tests/browser/.eslintrc.js +++ b/accessible/tests/browser/.eslintrc.js @@ -32,15 +32,12 @@ module.exports = { "new-cap": ["error", {"capIsNew": false}], "new-parens": "error", "no-bitwise": "off", - "no-catch-shadow": "error", - "no-comma-dangle": "off", "no-console": "off", "no-constant-condition": "off", "no-continue": "off", "no-div-regex": "off", "no-extend-native": "error", "no-extra-parens": "off", - "no-extra-strict": "off", "no-fallthrough": "error", "no-floating-decimal": "off", "no-inline-comments": "off", @@ -54,12 +51,10 @@ module.exports = { "no-process-env": "off", "no-process-exit": "off", "no-proto": "error", - "no-reserved-keys": "off", "no-restricted-modules": "off", "no-return-assign": "error", "no-script-url": "off", "no-shadow": "error", - "no-space-before-semi": "off", "no-sync": "off", "no-ternary": "off", "no-throw-literal": "error", @@ -76,9 +71,7 @@ module.exports = { "radix": "error", "semi-spacing": ["error", {"before": false, "after": true}], "sort-vars": "off", - "space-in-brackets": "off", "space-in-parens": ["error", "never"], - "space-unary-word-ops": "off", "strict": ["error", "global"], "valid-jsdoc": "off", "vars-on-top": "off", @@ -86,7 +79,6 @@ module.exports = { "wrap-regex": "off", "yoda": "error", "guard-for-in": "off", - "newline-after-var": "off", "no-alert": "off", "no-eq-null": "off", "no-func-assign": "off", @@ -98,7 +90,6 @@ module.exports = { "no-label-var": "off", "no-lone-blocks": "off", "no-loop-func": "off", - "no-negated-in-lhs": "off", "no-new": "off", "no-new-func": "off", "no-new-object": "off", @@ -108,7 +99,6 @@ module.exports = { "object-curly-spacing": "off", "no-unused-expressions": "off", "no-void": "off", - "no-wrap-func": "off", "operator-assignment": "off", "operator-linebreak": ["error", "after"] } diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index c3c6ce724dad..48fe6662141d 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -271,6 +271,12 @@ pref("browser.urlbar.doubleClickSelectsAll", true); pref("browser.urlbar.doubleClickSelectsAll", false); #endif +// Whether using `ctrl` when hitting return/enter in the URL bar +// (or clicking 'go') should prefix 'www.' and suffix +// browser.fixup.alternate.suffix to the URL bar value prior to +// navigating. +pref("browser.urlbar.ctrlCanonizesURLs", true); + // Control autoFill behavior pref("browser.urlbar.autoFill", true); pref("browser.urlbar.speculativeConnect.enabled", true); diff --git a/browser/app/winlauncher/LauncherProcessWin.cpp b/browser/app/winlauncher/LauncherProcessWin.cpp index ff5bc72f8cf1..a3c571412c47 100644 --- a/browser/app/winlauncher/LauncherProcessWin.cpp +++ b/browser/app/winlauncher/LauncherProcessWin.cpp @@ -219,7 +219,7 @@ LauncherMain(int argc, wchar_t* argv[]) } const Maybe isSafeMode = IsSafeModeRequested(argc, argv, - SafeModeFlag::None); + SafeModeFlag::NoKeyPressCheck); if (!isSafeMode) { ShowError(ERROR_INVALID_PARAMETER); return 1; diff --git a/browser/base/content/browser-context.inc b/browser/base/content/browser-context.inc index b5df23b0ee28..99133e49f64c 100644 --- a/browser/base/content/browser-context.inc +++ b/browser/base/content/browser-context.inc @@ -267,7 +267,7 @@ accesskey="&sendPageToDevice.accesskey;" hidden="true"> + onpopupshowing="(() => { gSync.populateSendTabToDevicesMenu(event.target, gBrowser.selectedTab); })()"/> { + gSync.populateSendTabToDevicesMenu(bodyNode, gBrowser.selectedTab, (clientId, name, clientType, lastModified) => { if (!name) { return document.createXULElement("toolbarseparator"); } diff --git a/browser/base/content/browser-sync.js b/browser/base/content/browser-sync.js index d8c92c36487b..60ac6fab2ee9 100644 --- a/browser/base/content/browser-sync.js +++ b/browser/base/content/browser-sync.js @@ -361,7 +361,7 @@ var gSync = { } }, - populateSendTabToDevicesMenu(devicesPopup, url, title, createDeviceNodeFn) { + populateSendTabToDevicesMenu(devicesPopup, aTab, createDeviceNodeFn) { if (!createDeviceNodeFn) { createDeviceNodeFn = (clientId, name, clientType, lastModified) => { let eltName = name ? "menuitem" : "menuseparator"; @@ -386,7 +386,7 @@ var gSync = { const state = UIState.get(); if (state.status == UIState.STATUS_SIGNED_IN && this.remoteClients.length > 0) { - this._appendSendTabDeviceList(fragment, createDeviceNodeFn, url, title); + this._appendSendTabDeviceList(fragment, createDeviceNodeFn, aTab); } else if (state.status == UIState.STATUS_SIGNED_IN) { this._appendSendTabSingleDevice(fragment, createDeviceNodeFn); } else if (state.status == UIState.STATUS_NOT_VERIFIED || @@ -402,14 +402,27 @@ var gSync = { // TODO: once our transition from the old-send tab world is complete, // this list should be built using the FxA device list instead of the client // collection. - _appendSendTabDeviceList(fragment, createDeviceNodeFn, url, title) { + _appendSendTabDeviceList(fragment, createDeviceNodeFn, tab) { + let tabsToSend = tab.multiselected ? gBrowser.selectedTabs : [tab]; + + function getTabUrl(t) { + return t.linkedBrowser.currentURI.spec; + } + function getTabTitle(t) { + return t.linkedBrowser.contentTitle; + } + const onSendAllCommand = (event) => { - this.sendTabToDevice(url, this.remoteClients, title); + for (let t of tabsToSend) { + this.sendTabToDevice(getTabUrl(t), this.remoteClients, getTabTitle(t)); + } }; const onTargetDeviceCommand = (event) => { const clientId = event.target.getAttribute("clientId"); const client = this.remoteClients.find(c => c.id == clientId); - this.sendTabToDevice(url, [client], title); + for (let t of tabsToSend) { + this.sendTabToDevice(getTabUrl(t), [client], getTabTitle(t)); + } }; function addTargetDevice(clientId, name, clientType, lastModified) { @@ -516,14 +529,31 @@ var gSync = { // "Send Tab to Device" menu item updateTabContextMenu(aPopupMenu, aTargetTab) { + // We may get here before initialisation. This situation + // can lead to a empty label for 'Send To Device' Menu. + this.init(); + if (!this.SYNC_ENABLED) { // These items are hidden in onSyncDisabled(). No need to do anything. return; } - const enabled = !this.syncConfiguredAndLoading && - this.isSendableURI(aTargetTab.linkedBrowser.currentURI.spec); + let hasASendableURI = false; + for (let tab of aTargetTab.multiselected ? gBrowser.selectedTabs : [aTargetTab]) { + if (this.isSendableURI(tab.linkedBrowser.currentURI.spec)) { + hasASendableURI = true; + break; + } + } + const enabled = !this.syncConfiguredAndLoading && hasASendableURI; - document.getElementById("context_sendTabToDevice").disabled = !enabled; + let sendTabsToDevice = document.getElementById("context_sendTabToDevice"); + sendTabsToDevice.disabled = !enabled; + + let tabCount = aTargetTab.multiselected ? gBrowser.multiSelectedTabsCount : 1; + sendTabsToDevice.label = PluralForm.get(tabCount, + gNavigatorBundle.getString("sendTabsToDevice.label")) + .replace("#1", tabCount.toLocaleString()); + sendTabsToDevice.accessKey = gNavigatorBundle.getString("sendTabsToDevice.accesskey"); }, // "Send Page to Device" and "Send Link to Device" menu items diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 4fbd988b85e7..406c98e6d017 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -5313,32 +5313,6 @@ var TabsProgressListener = { TelemetryStopwatch.cancel("FX_PAGE_LOAD_MS", aBrowser); } } - - // We used to listen for clicks in the browser here, but when that - // became unnecessary, removing the code below caused focus issues. - // This code should be removed. Tracked in bug 1337794. - let isRemoteBrowser = aBrowser.isRemoteBrowser; - // We check isRemoteBrowser here to avoid requesting the doc CPOW - let doc = isRemoteBrowser ? null : aWebProgress.DOMWindow.document; - - if (!isRemoteBrowser && - aStateFlags & Ci.nsIWebProgressListener.STATE_STOP && - Components.isSuccessCode(aStatus) && - doc.documentURI.startsWith("about:") && - !doc.documentURI.toLowerCase().startsWith("about:blank") && - !doc.documentURI.toLowerCase().startsWith("about:home") && - !doc.documentElement.hasAttribute("hasBrowserHandlers")) { - // STATE_STOP may be received twice for documents, thus store an - // attribute to ensure handling it just once. - doc.documentElement.setAttribute("hasBrowserHandlers", "true"); - aBrowser.addEventListener("pagehide", function onPageHide(event) { - if (event.target.defaultView.frameElement) - return; - aBrowser.removeEventListener("pagehide", onPageHide, true); - if (event.target.documentElement) - event.target.documentElement.removeAttribute("hasBrowserHandlers"); - }, true); - } }, onLocationChange(aBrowser, aWebProgress, aRequest, aLocationURI, aFlags) { diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index 7201f03355c2..b0981cd3a4c8 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -142,11 +142,10 @@ xmlns="http://www.w3.org/1999/xhtml" tbattr="tabbrowser-multiple" oncommand="gBrowser.replaceTabsWithWindow(TabContextMenu.contextTab);"/> - + + onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab);"/> diff --git a/browser/base/content/test/popups/browser_popup_frames.js b/browser/base/content/test/popups/browser_popup_frames.js index 08fee2a92dd6..fd348caff58f 100644 --- a/browser/base/content/test/popups/browser_popup_frames.js +++ b/browser/base/content/test/popups/browser_popup_frames.js @@ -27,9 +27,9 @@ add_task(async function test_opening_blocked_popups() { await ContentTask.spawn(tab.linkedBrowser, baseURL, async function(uri) { let iframe = content.document.createElement("iframe"); - iframe.src = uri; let pageHideHappened = ContentTaskUtils.waitForEvent(this, "pagehide", true); content.document.body.appendChild(iframe); + iframe.src = uri; await pageHideHappened; }); diff --git a/browser/base/content/test/tabs/browser.ini b/browser/base/content/test/tabs/browser.ini index 0c0cc2df4c63..daf5103fd784 100644 --- a/browser/base/content/test/tabs/browser.ini +++ b/browser/base/content/test/tabs/browser.ini @@ -63,6 +63,7 @@ skip-if = (verify && (os == 'win' || os == 'mac')) [browser_reload_deleted_file.js] skip-if = (debug && os == 'mac') || (debug && os == 'linux' && bits == 64) #Bug 1421183, disabled on Linux/OSX for leaked windows [browser_tabCloseProbes.js] +[browser_tabContextMenu_keyboard.js] [browser_tabReorder_overflow.js] [browser_tabReorder.js] [browser_tabSpinnerProbe.js] diff --git a/browser/base/content/test/tabs/browser_tabContextMenu_keyboard.js b/browser/base/content/test/tabs/browser_tabContextMenu_keyboard.js new file mode 100644 index 000000000000..873b570be66e --- /dev/null +++ b/browser/base/content/test/tabs/browser_tabContextMenu_keyboard.js @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +async function openContextMenu() { + let contextMenu = document.getElementById("tabContextMenu"); + let popupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown"); + EventUtils.synthesizeMouseAtCenter(gBrowser.selectedTab, {type: "contextmenu", button: 2}); + await popupShown; +} + +async function closeContextMenu() { + let contextMenu = document.getElementById("tabContextMenu"); + let popupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden"); + EventUtils.synthesizeKey("KEY_Escape"); + await popupHidden; +} + +add_task(async function test() { + // Ensure tabs are focusable. + await SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]}); + + // There should be one tab when we start the test. + let tab1 = gBrowser.selectedTab; + let tab2 = BrowserTestUtils.addTab(gBrowser); + tab1.focus(); + is(document.activeElement, tab1, "tab1 should be focused"); + + // Ensure that DownArrow doesn't switch to tab2 while the context menu is open. + await openContextMenu(); + EventUtils.synthesizeKey("KEY_ArrowDown"); + await closeContextMenu(); + is(gBrowser.selectedTab, tab1, "tab1 should still be active"); + if (AppConstants.platform == "macosx") { + // On Mac, focus doesn't return to the tab after dismissing the context menu. + // Since we're not testing that here, work around it by just focusing again. + tab1.focus(); + } + is(document.activeElement, tab1, "tab1 should be focused"); + + // Switch to tab2 by pressing DownArrow. + await BrowserTestUtils.switchTab(gBrowser, + () => EventUtils.synthesizeKey("KEY_ArrowDown")); + is(gBrowser.selectedTab, tab2, "should have switched to tab2"); + is(document.activeElement, tab2, "tab2 should now be focused"); + // Ensure that UpArrow doesn't switch to tab1 while the context menu is open. + await openContextMenu(); + EventUtils.synthesizeKey("KEY_ArrowUp"); + await closeContextMenu(); + is(gBrowser.selectedTab, tab2, "tab2 should still be active"); + + gBrowser.removeTab(tab2); +}); diff --git a/browser/base/content/test/urlbar/browser_canonizeURL.js b/browser/base/content/test/urlbar/browser_canonizeURL.js index 0b848e36cb9e..c301589d40b1 100644 --- a/browser/base/content/test/urlbar/browser_canonizeURL.js +++ b/browser/base/content/test/urlbar/browser_canonizeURL.js @@ -1,29 +1,34 @@ -add_task(async function() { +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml"; + +add_task(async function checkCtrlWorks() { let testcases = [ - ["example", "http://www.example.net/", { shiftKey: true }], + ["example", "http://www.example.com/", { ctrlKey: true }], // Check that a direct load is not overwritten by a previous canonization. ["http://example.com/test/", "http://example.com/test/", {}], - ["ex-ample", "http://www.ex-ample.net/", { shiftKey: true }], - [" example ", "http://www.example.net/", { shiftKey: true }], - [" example/foo ", "http://www.example.net/foo", { shiftKey: true }], - [" example/foo bar ", "http://www.example.net/foo%20bar", { shiftKey: true }], - ["example.net", "http://example.net/", { shiftKey: true }], - ["http://example", "http://example/", { shiftKey: true }], - ["example:8080", "http://example:8080/", { shiftKey: true }], - ["ex-ample.foo", "http://ex-ample.foo/", { shiftKey: true }], - ["example.foo/bar ", "http://example.foo/bar", { shiftKey: true }], - ["1.1.1.1", "http://1.1.1.1/", { shiftKey: true }], - ["ftp://example", "ftp://example/", { shiftKey: true }], - ["ftp.example.bar", "http://ftp.example.bar/", { shiftKey: true }], - ["ex ample", Services.search.defaultEngine.getSubmission("ex ample", null, "keyword").uri.spec, { shiftKey: true }], + + ["ex-ample", "http://www.ex-ample.com/", { ctrlKey: true }], + [" example ", "http://www.example.com/", { ctrlKey: true }], + [" example/foo ", "http://www.example.com/foo", { ctrlKey: true }], + [" example/foo bar ", "http://www.example.com/foo%20bar", { ctrlKey: true }], + ["example.net", "http://example.net/", { ctrlKey: true }], + ["http://example", "http://example/", { ctrlKey: true }], + ["example:8080", "http://example:8080/", { ctrlKey: true }], + ["ex-ample.foo", "http://ex-ample.foo/", { ctrlKey: true }], + ["example.foo/bar ", "http://example.foo/bar", { ctrlKey: true }], + ["1.1.1.1", "http://1.1.1.1/", { ctrlKey: true }], + ["ftp://example", "ftp://example/", { ctrlKey: true }], + ["ftp.example.bar", "http://ftp.example.bar/", { ctrlKey: true }], + ["ex ample", Services.search.defaultEngine.getSubmission("ex ample", null, "keyword").uri.spec, { ctrlKey: true }], ]; // Disable autoFill for this test, since it could mess up the results. - let autoFill = Preferences.get("browser.urlbar.autoFill"); - Preferences.set("browser.urlbar.autoFill", false); - registerCleanupFunction(() => { - Preferences.set("browser.urlbar.autoFill", autoFill); - }); + await SpecialPowers.pushPrefEnv({set: [ + ["browser.urlbar.autoFill", false], + ["browser.urlbar.ctrlCanonizesURLs", true], + ]}); for (let [inputValue, expectedURL, options] of testcases) { let promiseLoad = waitForDocLoadAndStopIt(expectedURL); @@ -40,3 +45,38 @@ add_task(async function() { await promiseLoad; } }); + +add_task(async function checkPrefTurnsOffCanonize() { + // Add a dummy search engine to avoid hitting the network. + let engine = await SearchTestUtils.promiseNewSearchEngine( + getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME); + let oldCurrentEngine = Services.search.currentEngine; + Services.search.currentEngine = engine; + registerCleanupFunction(() => { Services.search.currentEngine = oldCurrentEngine; }); + + let tabsToClose = []; + // Ensure we don't end up loading something in the current tab becuase it's empty: + if (isTabEmpty(gBrowser.selectedTab)) { + tabsToClose.push(await BrowserTestUtils.openNewForegroundTab({gBrowser, opening: "about:mozilla"})); + } + let initialTabURL = gBrowser.selectedBrowser.currentURI.spec; + let initialTab = gBrowser.selectedTab; + await SpecialPowers.pushPrefEnv({set: [["browser.urlbar.ctrlCanonizesURLs", false]]}); + + let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser); + + gURLBar.focus(); + gURLBar.selectionStart = gURLBar.selectionEnd = + gURLBar.inputField.value.length; + gURLBar.inputField.value = "exampl"; + EventUtils.sendString("e"); + EventUtils.synthesizeKey("KEY_Enter", AppConstants.platform == "macosx" ? + {metaKey: true} : {ctrlKey: true}); + + tabsToClose.push(await promiseTabOpened); + is(initialTab.linkedBrowser.currentURI.spec, initialTabURL, + "Original tab shouldn't have navigated"); + for (let t of tabsToClose) { + gBrowser.removeTab(t); + } +}); diff --git a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js index 895ffbbba57b..740f1fe84386 100644 --- a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js +++ b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js @@ -70,10 +70,7 @@ add_task(async function plainEnterOnSuggestion() { }); add_task(async function ctrlEnterOnSuggestion() { - await testPressEnterOnSuggestion("http://www.foofoo.com/", - AppConstants.platform === "macosx" ? - { metaKey: true } : - { ctrlKey: true }); + await testPressEnterOnSuggestion("http://www.foofoo.com/", { ctrlKey: true }); }); add_task(async function copySuggestionText() { diff --git a/browser/base/content/test/urlbar/browser_urlbar_canonize_on_autofill.js b/browser/base/content/test/urlbar/browser_urlbar_canonize_on_autofill.js index 5061ee35136a..a7168a8c858b 100644 --- a/browser/base/content/test/urlbar/browser_urlbar_canonize_on_autofill.js +++ b/browser/base/content/test/urlbar/browser_urlbar_canonize_on_autofill.js @@ -1,7 +1,7 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -/* This test ensures that pressing ctrl/shift+enter bypasses the autoFilled +/* This test ensures that pressing ctrl+enter bypasses the autoFilled * value, and only considers what the user typed (but not just enter). */ @@ -49,16 +49,6 @@ add_task(async function() { autofilled: "example.com/", modified: "www.exam.com", waitForUrl: "http://www.exam.com/", - keys: [["KEY_Enter", AppConstants.platform === "macosx" ? - {metaKey: true} : - {ctrlKey: true}]], - }); - - await test_autocomplete({ desc: "SHIFT+ENTER on the autofilled part should bypass autofill", - typed: "exam", - autofilled: "example.com/", - modified: "www.exam.net", - waitForUrl: "http://www.exam.net/", - keys: [["KEY_Enter", {shiftKey: true}]], + keys: [["KEY_Enter", {ctrlKey: true}]], }); }); diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml index a537e48901fb..53984e06dc6e 100644 --- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -85,6 +85,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. this._formattingEnabled = this._prefs.getBoolPref("formatting.enabled"); this._mayTrimURLs = this._prefs.getBoolPref("trimURLs"); this._adoptIntoActiveWindow = this._prefs.getBoolPref("switchTabs.adoptIntoActiveWindow"); + this._ctrlCanonizesURLs = this._prefs.getBoolPref("ctrlCanonizesURLs"); this.inputField.controllers.insertControllerAt(0, this._copyCutController); this.inputField.addEventListener("paste", this); this.inputField.addEventListener("mousedown", this); @@ -713,11 +714,16 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. let isMouseEvent = event instanceof MouseEvent; let reuseEmpty = !isMouseEvent; let where = undefined; - if (isMouseEvent) { - where = whereToOpenLink(event, false, false); + if (!isMouseEvent && event && event.altKey) { + // We support using 'alt' to open in a tab, because ctrl/shift + // might be used for canonizing URLs: + where = event.shiftKey ? "tabshifted" : "tab"; + } else if (!isMouseEvent && this._ctrlCanonizesURLs && event && event.ctrlKey) { + // If we're allowing canonization, and this is a key event with ctrl + // pressed, open in current tab to allow ctrl-enter to canonize URL. + where = "current"; } else { - let altEnter = event && event.altKey; - where = altEnter ? "tab" : "current"; + where = whereToOpenLink(event, false, false); } if (this.openInTab) { if (where == "current") { @@ -848,6 +854,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. } return; } + + // Once we get here, we got a switchtab action but the user + // bypassed it by pressing shift/meta/ctrl. Those modifiers + // might otherwise affect where we open - we always want to + // open in the current tab. + where = "current"; break; case "searchengine": if (selectedOneOff && selectedOneOff.engine) { @@ -1027,40 +1039,19 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. // Only add the suffix when the URL bar value isn't already "URL-like", // and only if we get a keyboard event, to match user expectations. if (!/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(aUrl) || - !(aTriggeringEvent instanceof KeyboardEvent)) { + !this._ctrlCanonizesURLs || + !(aTriggeringEvent instanceof KeyboardEvent) || + !aTriggeringEvent.ctrlKey) { return; } - let url = aUrl; - let accel = AppConstants.platform == "macosx" ? - aTriggeringEvent.metaKey : - aTriggeringEvent.ctrlKey; - let shift = aTriggeringEvent.shiftKey; - let suffix = ""; - - switch (true) { - case (accel && shift): - suffix = ".org/"; - break; - case (shift): - suffix = ".net/"; - break; - case (accel): - try { - suffix = Services.prefs.getCharPref("browser.fixup.alternate.suffix"); - if (suffix.charAt(suffix.length - 1) != "/") - suffix += "/"; - } catch (e) { - suffix = ".com/"; - } - break; + let suffix = Services.prefs.getCharPref("browser.fixup.alternate.suffix", ".com/"); + if (!suffix.endsWith("/")) { + suffix += "/"; } - if (!suffix) - return; - // trim leading/trailing spaces (bug 233205) - url = url.trim(); + let url = aUrl.trim(); // Tack www. and suffix on. If user has appended directories, insert // suffix before them (bug 279035). Be careful not to get two slashes. @@ -1331,6 +1322,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. case "formatting.enabled": this._formattingEnabled = this._prefs.getBoolPref(aData); break; + case "ctrlCanonizesURLs": + this._ctrlCanonizesURLs = this._prefs.getBoolPref(aData); + break; case "speculativeConnect.enabled": this.speculativeConnectEnabled = this._prefs.getBoolPref(aData); break; @@ -1657,9 +1651,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. } let canonizeValue = this.value; - if (event.shiftKey || (AppConstants.platform === "macosx" ? - event.metaKey : - event.ctrlKey)) { + if (event.ctrlKey) { let action = this._parseActionUrl(canonizeValue); if (action && "searchSuggestion" in action.params) { canonizeValue = action.params.searchSuggestion; diff --git a/browser/components/enterprisepolicies/content/aboutPolicies.js b/browser/components/enterprisepolicies/content/aboutPolicies.js index d6dbd8cd32c3..826699e8aea1 100644 --- a/browser/components/enterprisepolicies/content/aboutPolicies.js +++ b/browser/components/enterprisepolicies/content/aboutPolicies.js @@ -229,6 +229,12 @@ function generateDocumentation() { let new_cont = document.getElementById("documentationContent"); new_cont.setAttribute("id", "documentationContent"); + // map specific policies to a different string ID, to allow updates to + // existing descriptions + let string_mapping = { + "DisableSetDesktopBackground": "DisableSetAsDesktopBackground", + }; + for (let policyName in schema.properties) { let main_tbody = document.createElement("tbody"); main_tbody.classList.add("collapsible"); @@ -244,7 +250,8 @@ function generateDocumentation() { row.appendChild(col(policyName)); } let descriptionColumn = col(""); - descriptionColumn.setAttribute("data-l10n-id", `policy-${policyName}`); + let stringID = string_mapping[policyName] || policyName; + descriptionColumn.setAttribute("data-l10n-id", `policy-${stringID}`); row.appendChild(descriptionColumn); main_tbody.appendChild(row); let sec_tbody = document.createElement("tbody"); diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index d7b3f545a635..e694a0288f4e 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -1047,6 +1047,8 @@ BrowserGlue.prototype = { toolbar_field_border: "rgba(249, 249, 250, 0.2)", ntp_background: "#2A2A2E", ntp_text: "rgb(249, 249, 250)", + sidebar: "#19191a", + sidebar_text: "rgb(249, 249, 250)", author: vendorShortName, }, { useInDarkMode: true, diff --git a/browser/components/preferences/in-content/tests/browser_contentblocking.js b/browser/components/preferences/in-content/tests/browser_contentblocking.js index 8639dc73e972..9017a5c1ff29 100644 --- a/browser/components/preferences/in-content/tests/browser_contentblocking.js +++ b/browser/components/preferences/in-content/tests/browser_contentblocking.js @@ -60,12 +60,26 @@ add_task(async function testContentBlockingToggle() { add_task(async function testContentBlockingMainCategory() { SpecialPowers.pushPrefEnv({set: [ [CB_UI_PREF, true], + ]}); + + let prefs = [ [CB_PREF, true], [FB_PREF, true], [TP_PREF, false], [TP_PBM_PREF, true], [NCB_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER], - ]}); + ]; + + for (let pref of prefs) { + switch (typeof pref[1]) { + case "boolean": + SpecialPowers.setBoolPref(pref[0], pref[1]); + break; + case "number": + SpecialPowers.setIntPref(pref[0], pref[1]); + break; + } + } let checkboxes = [ "#contentBlockingFastBlockCheckbox", @@ -115,6 +129,10 @@ add_task(async function testContentBlockingMainCategory() { checkControlStateWorker(doc, alwaysEnabledControls, true); gBrowser.removeCurrentTab(); + + for (let pref of prefs) { + SpecialPowers.clearUserPref(pref[0]); + } }); // Tests that the content blocking "Restore Defaults" button does what it's supposed to. diff --git a/browser/config/version.txt b/browser/config/version.txt index f1d963ce19b6..351c72c7e70f 100644 --- a/browser/config/version.txt +++ b/browser/config/version.txt @@ -1 +1 @@ -63.0a1 +64.0a1 diff --git a/browser/config/version_display.txt b/browser/config/version_display.txt index f1d963ce19b6..351c72c7e70f 100644 --- a/browser/config/version_display.txt +++ b/browser/config/version_display.txt @@ -1 +1 @@ -63.0a1 +64.0a1 diff --git a/browser/locales/en-US/browser/policies/policies-descriptions.ftl b/browser/locales/en-US/browser/policies/policies-descriptions.ftl index e21d33652bf4..813240677264 100644 --- a/browser/locales/en-US/browser/policies/policies-descriptions.ftl +++ b/browser/locales/en-US/browser/policies/policies-descriptions.ftl @@ -60,26 +60,32 @@ policy-DisableSafeMode = Disable the feature to restart in Safe Mode. Note: the policy-DisableSecurityBypass = Prevent the user from bypassing certain security warnings. -policy-DisableSetDesktopBackground = Disable the menu command Set Image as Desktop Background. +policy-DisableSetAsDesktopBackground = Disable the menu command Set as Desktop Background for images. policy-DisableSystemAddonUpdate = Prevent the browser from installing and updating system add-ons. policy-DisableTelemetry = Turn off Telemetry. -policy-DisplayBookmarksToolbar = Display the Bookmark Toolbar by default. +policy-DisplayBookmarksToolbar = Display the Bookmarks Toolbar by default. policy-DisplayMenuBar = Display the Menu Bar by default. policy-DontCheckDefaultBrowser = Disable check for default browser on startup. +# “lock” means that the user won’t be able to change this setting policy-EnableTrackingProtection = Enable or disable Content Blocking and optionally lock it. +# A “locked” extension can’t be disabled or removed by the user. This policy +# takes 3 keys (“Install”, ”Uninstall”, ”Locked”), you can either keep them in +# English or translate them as verbs. See also: +# https://github.com/mozilla/policy-templates/blob/master/README.md#extensions-machine-only policy-Extensions = Install, uninstall or lock extensions. The Install option takes URLs or paths as parameters. The Uninstall and Locked options take extension IDs. policy-FlashPlugin = Allow or deny usage of the Flash plugin. policy-HardwareAcceleration = If false, turn off hardware acceleration. +# “lock” means that the user won’t be able to change this setting policy-Homepage = Set and optionally lock the homepage. policy-InstallAddonsPermission = Allow certain websites to install add-ons. @@ -90,7 +96,7 @@ policy-OfferToSaveLogins = Enforce the setting to allow { -brand-short-name } to policy-OverrideFirstRunPage = Override the first run page. Set this policy to blank if you want to disable the first run page. -policy-OverridePostUpdatePage = Override the post-update "What’s New" page. Set this policy to blank if you want to disable the post-update page. +policy-OverridePostUpdatePage = Override the post-update “What’s New” page. Set this policy to blank if you want to disable the post-update page. policy-Permissions = Configure permissions for camera, microphone, location and notifications. @@ -104,4 +110,6 @@ policy-SearchBar = Set the default location of the search bar. The user is still policy-SearchEngines = Configure search engine settings. This policy is only available on the Extended Support Release (ESR) version. +# “format” refers to the format used for the value of this policy. See also: +# https://github.com/mozilla/policy-templates/blob/master/README.md#websitefilter-machine-only policy-WebsiteFilter = Block websites from being visited. See documentation for more details on the format. diff --git a/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd b/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd index fa45ce582282..0adde4e1efdf 100644 --- a/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd +++ b/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd @@ -32,4 +32,4 @@ - + diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd index e581373a159a..ab5be96a261c 100644 --- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -61,8 +61,6 @@ can reach it easily. --> - - @@ -1088,7 +1086,6 @@ you can use these alternative items. Otherwise, their values should be empty. - - diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index 72b1e13875ea..0207ca1582fb 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -905,6 +905,19 @@ unmuteSelectedTabs.accesskey = b playTabs.label = Play Tabs playTabs.accesskey = y +# LOCALIZATION NOTE (sendTabsToDevice.label): +# Semi-colon list of plural forms. +# See: https://developer.mozilla.org/en/docs/Localization_and_Plurals +# #1 is the number of tabs sent to the device. +sendTabsToDevice.label = Send Tab to Device;Send #1 Tabs to Device +sendTabsToDevice.accesskey = n + +# LOCALIZATION NOTE (pageAction.sendTabsToDevice.label): +# Semi-colon list of plural forms. +# See: https://developer.mozilla.org/en/docs/Localization_and_Plurals +# #1 is the number of tabs sent to the device. +pageAction.sendTabsToDevice.label = Send Tab to Device;Send #1 Tabs to Device + # LOCALIZATION NOTE (certErrorDetails*.label): These are text strings that # appear in the about:certerror page, so that the user can copy and send them to # the server administrators for troubleshooting. diff --git a/browser/themes/osx/places/sidebar.css b/browser/themes/osx/places/sidebar.css index de3029c17b18..786ec6531cdc 100644 --- a/browser/themes/osx/places/sidebar.css +++ b/browser/themes/osx/places/sidebar.css @@ -26,12 +26,12 @@ margin: 0 10px; } -.sidebar-placesTreechildren::-moz-tree-row(selected) { +.sidebar-panel:not([lwt-sidebar]) .sidebar-placesTreechildren::-moz-tree-row(selected) { -moz-appearance: -moz-mac-source-list-selection; -moz-font-smoothing-background-color: -moz-mac-source-list-selection; } -.sidebar-placesTreechildren::-moz-tree-row(selected,focus) { +.sidebar-panel:not([lwt-sidebar-highlight]) .sidebar-placesTreechildren::-moz-tree-row(selected,focus) { -moz-appearance: -moz-mac-active-source-list-selection; -moz-font-smoothing-background-color: -moz-mac-active-source-list-selection; } diff --git a/browser/themes/shared/places/sidebar.inc.css b/browser/themes/shared/places/sidebar.inc.css index a0f5df724ca2..cba955e0eedc 100644 --- a/browser/themes/shared/places/sidebar.inc.css +++ b/browser/themes/shared/places/sidebar.inc.css @@ -19,7 +19,6 @@ } .sidebar-panel[lwt-sidebar-brighttext] .sidebar-placesTreechildren::-moz-tree-row(selected) { - -moz-appearance: none; background-color: rgba(249,249,250,.1); } @@ -30,7 +29,6 @@ } .sidebar-panel[lwt-sidebar-highlight] .sidebar-placesTreechildren::-moz-tree-row(selected,focus) { - -moz-appearance: none; background-color: var(--lwt-sidebar-highlight-background-color); } diff --git a/browser/themes/shared/sidebar.inc.css b/browser/themes/shared/sidebar.inc.css index 32b3be49864b..48be552cc7a9 100644 --- a/browser/themes/shared/sidebar.inc.css +++ b/browser/themes/shared/sidebar.inc.css @@ -26,7 +26,7 @@ -moz-appearance: none; border: 0 solid; border-inline-end-width: 1px; - border-inline-end-color: var(--sidebar-border-color); + border-color: var(--sidebar-border-color); min-width: 1px; width: 4px; background-image: none !important; diff --git a/chrome/test/unit/test_resolve_uris.js b/chrome/test/unit/test_resolve_uris.js index e1ee461e73d3..10aef2424fd7 100644 --- a/chrome/test/unit/test_resolve_uris.js +++ b/chrome/test/unit/test_resolve_uris.js @@ -82,7 +82,7 @@ function do_run_test() { } if (typeof run_test === "undefined") { - // eslint-disable-next-line no-native-reassign + // eslint-disable-next-line no-global-assign run_test = function() { do_run_test(); }; diff --git a/config/milestone.txt b/config/milestone.txt index bdc9bcf488b7..9f5ef7669eef 100644 --- a/config/milestone.txt +++ b/config/milestone.txt @@ -10,4 +10,4 @@ # hardcoded milestones in the tree from these two files. #-------------------------------------------------------- -63.0a1 +64.0a1 diff --git a/devtools/.eslintrc.js b/devtools/.eslintrc.js index 3c61df2b7031..98604f5e5bdc 100644 --- a/devtools/.eslintrc.js +++ b/devtools/.eslintrc.js @@ -253,6 +253,8 @@ module.exports = { // Allow using == instead of ===, in the interest of landing something since // the devtools codebase is split on convention here. "eqeqeq": "off", + // Disallow space between function identifier and application. + "func-call-spacing": "error", // Don't require function expressions to have a name. // This makes the code more verbose and hard to read. Our engine already // does a fantastic job assigning a name to the function, which includes @@ -288,9 +290,6 @@ module.exports = { "new-parens": "error", // Allow use of bitwise operators. "no-bitwise": "off", - // Disallow the catch clause parameter name being the same as a variable in - // the outer scope, to avoid confusion. - "no-catch-shadow": "error", // Allow using the console API. "no-console": "off", // Allow using constant expressions in conditions like while (true) @@ -341,8 +340,6 @@ module.exports = { "no-proto": "error", // Disallow multiple spaces in a regular expression literal. "no-regex-spaces": "off", - // Allow reserved words being used as object literal keys. - "no-reserved-keys": "off", // Don't restrict usage of specified node modules (not a node environment). "no-restricted-modules": "off", // Disallow use of assignment in return statement. It is preferable for a @@ -356,8 +353,6 @@ module.exports = { // random name. // Still, making this a warning can help people avoid being confused. "no-shadow": "error", - // Disallow space between function identifier and application. - "no-spaced-func": "error", // Allow use of synchronous methods (not a node environment). "no-sync": "off", // Allow the use of ternary operators. @@ -398,10 +393,6 @@ module.exports = { // Don't require to sort variables within the same declaration block. // Anyway, one-var is disabled. "sort-vars": "off", - // Disable the rule that checks if spaces inside {} and [] are there or not. - // Our code is split on conventions, and it'd be nice to have "error" rules - // instead, one for [] and one for {}. So, disabling until we write them. - "space-in-brackets": "off", // Disallow spaces inside parentheses. "space-in-parens": ["error", "never"], // Require spaces before/after unary operators (words on by default, @@ -433,8 +424,6 @@ module.exports = { "computed-property-spacing": "off", // Require for-in loops to have an if statement. "guard-for-in": "off", - // allow/disallow an empty newline after var statement - "newline-after-var": "off", // disallow the use of alert, confirm, and prompt "no-alert": "off", // disallow comparisons to null without a type-checking operator @@ -455,8 +444,6 @@ module.exports = { "no-lone-blocks": "off", // disallow creation of functions within loops "no-loop-func": "off", - // disallow negation of the left operand of an in expression - "no-negated-in-lhs": "off", // disallow use of new operator when not part of the assignment or // comparison "no-new": "off", @@ -480,8 +467,6 @@ module.exports = { "no-useless-concat": "off", // disallow use of void operator "no-void": "off", - // disallow wrapping of non-IIFE statements in parens - "no-wrap-func": "off", // require assignment operator shorthand where possible or prohibit it // entirely "operator-assignment": "off", diff --git a/devtools/.eslintrc.mochitests.js b/devtools/.eslintrc.mochitests.js index 3b93729cc0c3..7268ed6b705d 100644 --- a/devtools/.eslintrc.mochitests.js +++ b/devtools/.eslintrc.mochitests.js @@ -11,7 +11,6 @@ module.exports = { "synthesizeKeyFromKeyTag": true, "TargetFactory": true, "waitForTick": true, - "waitUntilState": true, }, "parserOptions": { diff --git a/devtools/client/aboutdebugging/aboutdebugging.css b/devtools/client/aboutdebugging/aboutdebugging.css index e65c3f71e561..e7db2894705c 100644 --- a/devtools/client/aboutdebugging/aboutdebugging.css +++ b/devtools/client/aboutdebugging/aboutdebugging.css @@ -227,7 +227,6 @@ button { height: 24px; background-image: url(chrome://devtools/skin/images/help.svg); background-repeat: no-repeat; - background-size: 24px; flex-shrink: 0; margin-inline-end: 8px; } diff --git a/devtools/client/accessibility/accessibility.css b/devtools/client/accessibility/accessibility.css index 8d09c24e6228..623249dc5d39 100644 --- a/devtools/client/accessibility/accessibility.css +++ b/devtools/client/accessibility/accessibility.css @@ -116,6 +116,7 @@ body { width: 16px; height: 16px; mask: url("chrome://devtools/skin/images/help.svg") no-repeat; + mask-size: contain; } .devtools-toolbar .help:focus { diff --git a/devtools/client/debugger/new/dist/debugger.css b/devtools/client/debugger/new/dist/debugger.css index a00e5f595274..e1d3a693c9f8 100644 --- a/devtools/client/debugger/new/dist/debugger.css +++ b/devtools/client/debugger/new/dist/debugger.css @@ -3766,6 +3766,7 @@ img.skipPausing { .command-bar img.shortcuts { mask: url("chrome://devtools/skin/images/help.svg") no-repeat; + mask-size: contain; } .command-bar .replay-inactive { diff --git a/devtools/client/inspector/computed/computed.js b/devtools/client/inspector/computed/computed.js index f9933022e906..4ea826f4fbe4 100644 --- a/devtools/client/inspector/computed/computed.js +++ b/devtools/client/inspector/computed/computed.js @@ -6,11 +6,10 @@ "use strict"; -const promise = require("promise"); -const flags = require("devtools/shared/flags"); const ToolDefinitions = require("devtools/client/definitions").Tools; const CssLogic = require("devtools/shared/inspector/css-logic"); const {ELEMENT_STYLE} = require("devtools/shared/specs/styles"); +const promise = require("promise"); const OutputParser = require("devtools/client/shared/output-parser"); const {PrefObserver} = require("devtools/client/shared/prefs"); const {createChild} = require("devtools/client/inspector/shared/utils"); @@ -184,20 +183,14 @@ function CssComputedView(inspector, document, pageStyle) { this.styleDocument.addEventListener("mousedown", this.focusWindow); this.element.addEventListener("click", this._onClick); this.element.addEventListener("contextmenu", this._onContextMenu); + this.element.addEventListener("mousemove", () => { + this.addHighlightersToView(); + }, { once: true }); this.searchField.addEventListener("input", this._onFilterStyles); this.searchClearButton.addEventListener("click", this._onClearSearch); this.includeBrowserStylesCheckbox.addEventListener("input", this._onIncludeBrowserStyles); - if (flags.testing) { - // In tests, we start listening immediately to avoid having to simulate a mousemove. - this.highlighters.addToView(this); - } else { - this.element.addEventListener("mousemove", () => { - this.highlighters.addToView(this); - }, { once: true }); - } - this.searchClearButton.hidden = true; // No results text. @@ -739,6 +732,14 @@ CssComputedView.prototype = { } }, + /** + * Adds the highlighters overlay to the computed view. This is called by the "mousemove" + * event handler and in shared-head.js when opening and selecting the computed view. + */ + addHighlightersToView() { + this.highlighters.addToView(this); + }, + /** * Destructor for CssComputedView. */ diff --git a/devtools/client/inspector/flexbox/flexbox.js b/devtools/client/inspector/flexbox/flexbox.js index 60ba8d5b2022..b5d669c89432 100644 --- a/devtools/client/inspector/flexbox/flexbox.js +++ b/devtools/client/inspector/flexbox/flexbox.js @@ -5,7 +5,6 @@ "use strict"; const { throttle } = require("devtools/client/inspector/shared/utils"); -const flags = require("devtools/shared/flags"); const { clearFlexbox, @@ -63,16 +62,10 @@ class FlexboxInspector { return; } - if (flags.testing) { - // In tests, we start listening immediately to avoid having to simulate a mousemove. + this.document.addEventListener("mousemove", () => { this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden); this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown); - } else { - this.document.addEventListener("mousemove", () => { - this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden); - this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown); - }, { once: true }); - } + }, { once: true }); this.inspector.sidebar.on("select", this.onSidebarSelect); @@ -311,77 +304,99 @@ class FlexboxInspector { async update(flexboxFront) { // Stop refreshing if the inspector or store is already destroyed or no node is // selected. - if (!this.inspector || - !this.store || - !this.inspector.selection.nodeFront || - !this.hasGetCurrentFlexbox) { + if (!this.inspector || !this.store || !this.inspector.selection.nodeFront) { return; } - try { - // Fetch the current flexbox if no flexbox front was passed into this update. - if (!flexboxFront) { - flexboxFront = await this.layoutInspector.getCurrentFlexbox( - this.inspector.selection.nodeFront); - } - - // Clear the flexbox panel if there is no flex container for the current node - // selection. - if (!flexboxFront) { - this.store.dispatch(clearFlexbox()); - return; - } - - // If the FlexboxFront doesn't yet have access to the NodeFront for its container, - // then get it from the walker. This happens when the walker hasn't seen this - // particular DOM Node in the tree yet or when we are connected to an older server. - let containerNodeFront = flexboxFront.containerNodeFront; - if (!containerNodeFront) { - containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID, - ["containerEl"]); - } - - // Fetch the flex items for the given flex container and the flex item NodeFronts. - const flexItems = []; - const flexItemFronts = await flexboxFront.getFlexItems(); - - for (const flexItemFront of flexItemFronts) { - let itemNodeFront = flexItemFront.nodeFront; - if (!itemNodeFront) { - itemNodeFront = await this.walker.getNodeFromActor(flexItemFront.actorID, - ["element"]); + // Fetch the current flexbox if no flexbox front was passed into this update. + if (!flexboxFront) { + try { + if (!this.hasGetCurrentFlexbox) { + return; } - flexItems.push({ - actorID: flexItemFront.actorID, - shown: false, - flexItemSizing: flexItemFront.flexItemSizing, - nodeFront: itemNodeFront, - properties: flexItemFront.properties, - }); + flexboxFront = await this.layoutInspector.getCurrentFlexbox( + this.inspector.selection.nodeFront); + } catch (e) { + // This call might fail if called asynchrously after the toolbox is finished + // closing. + return; + } + } + + // Clear the flexbox panel if there is no flex container for the current node + // selection. + if (!flexboxFront) { + try { + this.store.dispatch(clearFlexbox()); + } catch (e) { + // This call might fail if called asynchrously after the toolbox is finished + // closing. + } + return; + } + + let containerNodeFront = flexboxFront.containerNodeFront; + + // If the FlexboxFront doesn't yet have access to the NodeFront for its container, + // then get it from the walker. This happens when the walker hasn't seen this + // particular DOM Node in the tree yet or when we are connected to an older server. + if (!containerNodeFront) { + try { + containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID, + ["containerEl"]); + } catch (e) { + // This call might fail if called asynchrously after the toolbox is finished + // closing. + return; + } + } + + const highlighted = this._highlighters && + containerNodeFront == this.highlighters.flexboxHighlighterShown; + + // Fetch the flex items for the given flex container and the flex item NodeFronts. + const flexItems = []; + const flexItemFronts = await flexboxFront.getFlexItems(); + + for (const flexItemFront of flexItemFronts) { + let itemNodeFront = flexItemFront.nodeFront; + + if (!itemNodeFront) { + try { + itemNodeFront = await this.walker.getNodeFromActor(flexItemFront.actorID, + ["element"]); + } catch (e) { + // This call might fail if called asynchrously after the toolbox is finished + // closing. + return; + } } - const highlighted = this._highlighters && - containerNodeFront == this.highlighters.flexboxHighlighterShown; - const currentUrl = this.inspector.target.url; - // Get the hostname, if there is no hostname, fall back on protocol - // ex: `data:` uri, and `about:` pages - const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol; - const customColors = await this.getCustomFlexboxColors(); - const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR; - - this.store.dispatch(updateFlexbox({ - actorID: flexboxFront.actorID, - color, - flexItems, - highlighted, - nodeFront: containerNodeFront, - properties: flexboxFront.properties, - })); - } catch (e) { - // This call might fail if called asynchrously after the toolbox is finished - // closing. + flexItems.push({ + actorID: flexItemFront.actorID, + shown: false, + flexItemSizing: flexItemFront.flexItemSizing, + nodeFront: itemNodeFront, + properties: flexItemFront.properties, + }); } + + const currentUrl = this.inspector.target.url; + // Get the hostname, if there is no hostname, fall back on protocol + // ex: `data:` uri, and `about:` pages + const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol; + const customColors = await this.getCustomFlexboxColors(); + const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR; + + this.store.dispatch(updateFlexbox({ + actorID: flexboxFront.actorID, + color, + flexItems, + highlighted, + nodeFront: containerNodeFront, + properties: flexboxFront.properties, + })); } } diff --git a/devtools/client/inspector/fonts/fonts.js b/devtools/client/inspector/fonts/fonts.js index 73fbaa966183..e1df23d0b07c 100644 --- a/devtools/client/inspector/fonts/fonts.js +++ b/devtools/client/inspector/fonts/fonts.js @@ -85,7 +85,7 @@ class FontInspector { this.onNewNode = this.onNewNode.bind(this); this.onPreviewTextChange = debounce(this.onPreviewTextChange, 100, this); this.onPropertyChange = this.onPropertyChange.bind(this); - this.onRulePropertyUpdated = debounce(this.onRulePropertyUpdated, 100, this); + this.onRulePropertyUpdated = debounce(this.onRulePropertyUpdated, 300, this); this.onToggleFontHighlight = this.onToggleFontHighlight.bind(this); this.onThemeChanged = this.onThemeChanged.bind(this); this.update = this.update.bind(this); @@ -598,22 +598,23 @@ class FontInspector { * @param {String} value * CSS property value */ - syncChanges(name, value) { + async syncChanges(name, value) { const textProperty = this.getTextProperty(name, value); if (textProperty) { - // This method may be called after the connection to the page style actor is closed. - // For example, during teardown of automated tests. Here, we catch any failure that - // may occur because of that. We're not interested in handling the error. - textProperty.setValue(value).catch(error => { + try { + await textProperty.setValue(value, "", true); + this.ruleView.on("property-value-updated", this.onRulePropertyUpdated); + } catch (error) { + // Because setValue() does an asynchronous call to the server, there is a chance + // the font editor was destroyed while we were waiting. If that happened, just + // bail out silently. if (!this.document) { return; } throw error; - }); + } } - - this.ruleView.on("property-value-updated", this.onRulePropertyUpdated); } /** diff --git a/devtools/client/inspector/grids/grid-inspector.js b/devtools/client/inspector/grids/grid-inspector.js index a76ec8ca3091..bc426b96204a 100644 --- a/devtools/client/inspector/grids/grid-inspector.js +++ b/devtools/client/inspector/grids/grid-inspector.js @@ -6,7 +6,6 @@ const Services = require("Services"); const { throttle } = require("devtools/client/inspector/shared/utils"); -const flags = require("devtools/shared/flags"); const { updateGridColor, @@ -98,16 +97,10 @@ class GridInspector { return; } - if (flags.testing) { - // In tests, we start listening immediately to avoid having to simulate a mousemove. + this.document.addEventListener("mousemove", () => { this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden); this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown); - } else { - this.document.addEventListener("mousemove", () => { - this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden); - this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown); - }, { once: true }); - } + }, { once: true }); this.inspector.sidebar.on("select", this.onSidebarSelect); this.inspector.on("new-root", this.onNavigate); diff --git a/devtools/client/inspector/grids/test/.eslintrc.js b/devtools/client/inspector/grids/test/.eslintrc.js index ed1e234b39bc..b63e8411e3b7 100644 --- a/devtools/client/inspector/grids/test/.eslintrc.js +++ b/devtools/client/inspector/grids/test/.eslintrc.js @@ -3,4 +3,7 @@ module.exports = { // Extend from the shared list of defined globals for mochitests. "extends": "../../../../.eslintrc.mochitests.js", + "globals": { + "waitUntilState": true + } }; diff --git a/devtools/client/inspector/markup/test/.eslintrc.js b/devtools/client/inspector/markup/test/.eslintrc.js index ed1e234b39bc..698ae9181a0a 100644 --- a/devtools/client/inspector/markup/test/.eslintrc.js +++ b/devtools/client/inspector/markup/test/.eslintrc.js @@ -2,5 +2,5 @@ module.exports = { // Extend from the shared list of defined globals for mochitests. - "extends": "../../../../.eslintrc.mochitests.js", + "extends": "../../../../.eslintrc.mochitests.js" }; diff --git a/devtools/client/inspector/markup/test/browser.ini b/devtools/client/inspector/markup/test/browser.ini index 8fb39cdf965a..aa1b198c2ad8 100644 --- a/devtools/client/inspector/markup/test/browser.ini +++ b/devtools/client/inspector/markup/test/browser.ini @@ -73,7 +73,6 @@ support-files = !/devtools/client/inspector/test/head.js !/devtools/client/inspector/test/shared-head.js !/devtools/client/shared/test/shared-head.js - !/devtools/client/shared/test/shared-redux-head.js !/devtools/client/shared/test/telemetry-test-helpers.js !/devtools/client/shared/test/test-actor.js !/devtools/client/shared/test/test-actor-registry.js @@ -131,8 +130,6 @@ skip-if = true # Bug 1177550 [browser_markup_events_react_production_16.2.0_jsx.js] [browser_markup_events_source_map.js] [browser_markup_events-windowed-host.js] -[browser_markup_flex_display_badge.js] -[browser_markup_grid_display_badge.js] [browser_markup_links_01.js] [browser_markup_links_02.js] [browser_markup_links_03.js] diff --git a/devtools/client/inspector/markup/test/browser_markup_grid_display_badge.js b/devtools/client/inspector/markup/test/browser_markup_grid_display_badge.js deleted file mode 100644 index 353131e3b379..000000000000 --- a/devtools/client/inspector/markup/test/browser_markup_grid_display_badge.js +++ /dev/null @@ -1,60 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -// Tests that the grid display badge toggles on the grid highlighter. - -const TEST_URI = ` - -
-`; - -const HIGHLIGHTER_TYPE = "CssGridHighlighter"; - -add_task(async function() { - await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); - const { inspector } = await openLayoutView(); - const { highlighters, store } = inspector; - - info("Check the grid display badge is shown and not active."); - await selectNode("#grid", inspector); - const gridContainer = await getContainerForSelector("#grid", inspector); - const gridDisplayBadge = gridContainer.elt.querySelector(".markup-badge[data-display]"); - ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active."); - - info("Check the initial state of the grid highlighter."); - ok(!highlighters.highlighters[HIGHLIGHTER_TYPE], - "No CSS grid highlighter exists in the highlighters overlay."); - ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown."); - - info("Toggling ON the CSS grid highlighter from the grid display badge."); - const onHighlighterShown = highlighters.once("grid-highlighter-shown"); - let onCheckboxChange = waitUntilState(store, state => - state.grids.length === 1 && - state.grids[0].highlighted); - gridDisplayBadge.click(); - await onHighlighterShown; - await onCheckboxChange; - - info("Check the CSS grid highlighter is created and grid display badge state."); - ok(highlighters.highlighters[HIGHLIGHTER_TYPE], - "CSS grid highlighter is created in the highlighters overlay."); - ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown."); - ok(gridDisplayBadge.classList.contains("active"), "grid display badge is active."); - - info("Toggling OFF the CSS grid highlighter from the grid display badge."); - const onHighlighterHidden = highlighters.once("grid-highlighter-hidden"); - onCheckboxChange = waitUntilState(store, state => - state.grids.length == 1 && - !state.grids[0].highlighted); - gridDisplayBadge.click(); - await onHighlighterHidden; - await onCheckboxChange; - - ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active."); -}); diff --git a/devtools/client/inspector/markup/test/head.js b/devtools/client/inspector/markup/test/head.js index ab7f1c97ee8f..e21a77d033aa 100644 --- a/devtools/client/inspector/markup/test/head.js +++ b/devtools/client/inspector/markup/test/head.js @@ -1,3 +1,4 @@ + /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -10,11 +11,6 @@ Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js", this); -// Load the shared Redux helpers into this compartment. -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/devtools/client/shared/test/shared-redux-head.js", - this); - var {getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor"); var clipboard = require("devtools/shared/platform/clipboard"); diff --git a/devtools/client/inspector/rules/rules.js b/devtools/client/inspector/rules/rules.js index 6871850cb207..9424871708ab 100644 --- a/devtools/client/inspector/rules/rules.js +++ b/devtools/client/inspector/rules/rules.js @@ -8,7 +8,6 @@ const promise = require("promise"); const Services = require("Services"); -const flags = require("devtools/shared/flags"); const {l10n} = require("devtools/shared/inspector/css-logic"); const {ELEMENT_STYLE} = require("devtools/shared/specs/styles"); const OutputParser = require("devtools/client/shared/output-parser"); @@ -152,6 +151,9 @@ function CssRuleView(inspector, document, store, pageStyle) { this.shortcuts.on("CmdOrCtrl+F", event => this._onShortcut("CmdOrCtrl+F", event)); this.element.addEventListener("copy", this._onCopy); this.element.addEventListener("contextmenu", this._onContextMenu); + this.element.addEventListener("mousemove", () => { + this.addHighlightersToView(); + }, { once: true }); this.addRuleButton.addEventListener("click", this._onAddRule); this.searchField.addEventListener("input", this._onFilterStyles); this.searchClearButton.addEventListener("click", this._onClearSearch); @@ -161,15 +163,6 @@ function CssRuleView(inspector, document, store, pageStyle) { this.activeCheckbox.addEventListener("click", this._onTogglePseudoClass); this.focusCheckbox.addEventListener("click", this._onTogglePseudoClass); - if (flags.testing) { - // In tests, we start listening immediately to avoid having to simulate a mousemove. - this.highlighters.addToView(this); - } else { - this.element.addEventListener("mousemove", () => { - this.highlighters.addToView(this); - }, { once: true }); - } - this._handlePrefChange = this._handlePrefChange.bind(this); this._handleUAStylePrefChange = this._handleUAStylePrefChange.bind(this); this._handleDefaultColorUnitPrefChange = @@ -1644,6 +1637,14 @@ CssRuleView.prototype = { event.stopPropagation(); } }, + + /** + * Adds the highlighters overlay to the rule view. This is called by the "mousemove" + * event handler and in shared-head.js when opening and selecting the rule view. + */ + addHighlightersToView() { + this.highlighters.addToView(this); + }, }; /** diff --git a/devtools/client/inspector/test/shared-head.js b/devtools/client/inspector/test/shared-head.js index f0f1a63df668..911d753aee0a 100644 --- a/devtools/client/inspector/test/shared-head.js +++ b/devtools/client/inspector/test/shared-head.js @@ -91,6 +91,9 @@ function openRuleView() { // through an additional ".flush()" property. view.debounce = manualDebounce(); + // Adds the highlighters overlay in the rule view. + view.addHighlightersToView(); + return { toolbox: data.toolbox, inspector: data.inspector, @@ -110,6 +113,8 @@ function openRuleView() { function openComputedView() { return openInspectorSidebarTab("computedview").then(data => { const view = data.inspector.getPanel("computedview").computedView; + // Adds the highlighters overlay in the computed view. + view.addHighlightersToView(); return { toolbox: data.toolbox, @@ -160,7 +165,9 @@ function openLayoutView() { * @return {CssRuleView} the rule view */ function selectRuleView(inspector) { - return inspector.getPanel("ruleview").view; + const view = inspector.getPanel("ruleview").view; + view.addHighlightersToView(); + return view; } /** @@ -172,7 +179,9 @@ function selectRuleView(inspector) { */ function selectComputedView(inspector) { inspector.sidebar.select("computedview"); - return inspector.getPanel("computedview").computedView; + const view = inspector.getPanel("computedview").computedView; + view.addHighlightersToView(); + return view; } /** diff --git a/devtools/client/memory/utils.js b/devtools/client/memory/utils.js index ed94b4ad6044..d0135fb6b878 100644 --- a/devtools/client/memory/utils.js +++ b/devtools/client/memory/utils.js @@ -453,6 +453,7 @@ exports.openFilePicker = function({ title, filters, defaultName, mode }) { */ exports.formatNumber = function(number, showSign = false) { const rounded = Math.round(number); + // eslint-disable-next-line no-compare-neg-zero if (rounded === 0 || rounded === -0) { return "0"; } diff --git a/devtools/client/shared/components/MdnLink.css b/devtools/client/shared/components/MdnLink.css index e80583e65fdd..6f231f6518d4 100644 --- a/devtools/client/shared/components/MdnLink.css +++ b/devtools/client/shared/components/MdnLink.css @@ -6,6 +6,7 @@ .network-monitor .learn-more-link::before { background-image: url(chrome://devtools/skin/images/help.svg); + background-size: contain; } .network-monitor .tree-container .treeTable tr .learn-more-link { diff --git a/devtools/client/shared/redux/middleware/test/.eslintrc.js b/devtools/client/shared/redux/middleware/test/.eslintrc.js index f7f2df049299..0d12cd9a34b1 100644 --- a/devtools/client/shared/redux/middleware/test/.eslintrc.js +++ b/devtools/client/shared/redux/middleware/test/.eslintrc.js @@ -8,6 +8,7 @@ module.exports = { "run_next_test": true, "equal": true, "do_print": true, + "waitUntilState": true }, "rules": { // Stop giving errors for run_test diff --git a/devtools/client/themes/images/help.svg b/devtools/client/themes/images/help.svg index 737218ce1781..9dc7e80c1f8e 100644 --- a/devtools/client/themes/images/help.svg +++ b/devtools/client/themes/images/help.svg @@ -1,6 +1,7 @@ - - + + + diff --git a/dom/bindings/Errors.msg b/dom/bindings/Errors.msg index 2a882b59cedb..c165fa803eb7 100644 --- a/dom/bindings/Errors.msg +++ b/dom/bindings/Errors.msg @@ -111,3 +111,4 @@ MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR, 0, JSEXN_RANGEERR, "The MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR, 0, JSEXN_RANGEERR, "The end time for an AudioParam method must be non-negative.") MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_VALUE_ERROR, 0, JSEXN_RANGEERR, "The value passed to exponentialRampToValueAtTime must be positive.") MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_CONSTANT_ERROR, 0, JSEXN_RANGEERR, "The exponential constant passed to setTargetAtTime must be non-negative.") +MSG_DEF(MSG_VALUE_OUT_OF_RANGE, 1, JSEXN_RANGEERR, "The value for the {0} is outside the valid range.") \ No newline at end of file diff --git a/dom/indexedDB/test/helpers.js b/dom/indexedDB/test/helpers.js index d4607fc39de7..5d6994347ac7 100644 --- a/dom/indexedDB/test/helpers.js +++ b/dom/indexedDB/test/helpers.js @@ -17,7 +17,7 @@ var testGenerator = testSteps(); // is whether the property is read-only or not. var c = Object.getOwnPropertyDescriptor(this, "Components"); if ((!c || !c.value || c.writable) && typeof SpecialPowers === "object") { - // eslint-disable-next-line no-native-reassign + // eslint-disable-next-line no-global-assign Components = SpecialPowers.wrap(SpecialPowers.Components); } diff --git a/dom/media/webaudio/AudioBufferSourceNode.cpp b/dom/media/webaudio/AudioBufferSourceNode.cpp index 614bfe98fccb..67046dfe3422 100644 --- a/dom/media/webaudio/AudioBufferSourceNode.cpp +++ b/dom/media/webaudio/AudioBufferSourceNode.cpp @@ -699,9 +699,16 @@ void AudioBufferSourceNode::Start(double aWhen, double aOffset, const Optional& aDuration, ErrorResult& aRv) { - if (!WebAudioUtils::IsTimeValid(aWhen) || aOffset < 0 || - (aDuration.WasPassed() && !WebAudioUtils::IsTimeValid(aDuration.Value()))) { - aRv.Throw(NS_ERROR_RANGE_ERR); + if (!WebAudioUtils::IsTimeValid(aWhen)) { + aRv.ThrowRangeError(NS_LITERAL_STRING("start time")); + return; + } + if (aOffset < 0) { + aRv.ThrowRangeError(NS_LITERAL_STRING("offset")); + return; + } + if (aDuration.WasPassed() && !WebAudioUtils::IsTimeValid(aDuration.Value())) { + aRv.ThrowRangeError(NS_LITERAL_STRING("duration")); return; } @@ -802,7 +809,7 @@ void AudioBufferSourceNode::Stop(double aWhen, ErrorResult& aRv) { if (!WebAudioUtils::IsTimeValid(aWhen)) { - aRv.Throw(NS_ERROR_RANGE_ERR); + aRv.ThrowRangeError(NS_LITERAL_STRING("stop time")); return; } diff --git a/dom/media/webaudio/ConstantSourceNode.cpp b/dom/media/webaudio/ConstantSourceNode.cpp index 35272b19324d..0814fcb41e18 100644 --- a/dom/media/webaudio/ConstantSourceNode.cpp +++ b/dom/media/webaudio/ConstantSourceNode.cpp @@ -228,7 +228,7 @@ void ConstantSourceNode::Start(double aWhen, ErrorResult& aRv) { if (!WebAudioUtils::IsTimeValid(aWhen)) { - aRv.Throw(NS_ERROR_RANGE_ERR); + aRv.ThrowRangeError(NS_LITERAL_STRING("start time")); return; } @@ -252,7 +252,7 @@ void ConstantSourceNode::Stop(double aWhen, ErrorResult& aRv) { if (!WebAudioUtils::IsTimeValid(aWhen)) { - aRv.Throw(NS_ERROR_RANGE_ERR); + aRv.ThrowRangeError(NS_LITERAL_STRING("stop time")); return; } diff --git a/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js b/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js index c9aaaf1c5348..2059e3475178 100644 --- a/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js +++ b/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js @@ -36,7 +36,7 @@ function loadPrivilegedScriptTest() { handlers[type].forEach(handler => handler.apply(null, args)); }; var handlers = {}; - /* eslint-disable-next-line no-native-reassign */ + /* eslint-disable-next-line no-global-assign */ addMessageListener = function(message, handler) { if (handlers.hasOwnProperty(message)) { handlers[message].push(handler); @@ -44,7 +44,7 @@ function loadPrivilegedScriptTest() { handlers[message] = [handler]; } }; - /* eslint-disable-next-line no-native-reassign */ + /* eslint-disable-next-line no-global-assign */ removeMessageListener = function(message, handler) { if (!handler || !handlers.hasOwnProperty(message)) { return; diff --git a/dom/script/ScriptSettings.cpp b/dom/script/ScriptSettings.cpp index 6a8c3c871f3d..adc3645cdd1f 100644 --- a/dom/script/ScriptSettings.cpp +++ b/dom/script/ScriptSettings.cpp @@ -662,8 +662,11 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject, { MOZ_ASSERT(aGlobalObject); - if (aIsMainThread && gRunToCompletionListeners > 0) { - mDocShellEntryMonitor.emplace(cx(), aReason); + if (aIsMainThread) { + if (gRunToCompletionListeners > 0) { + mDocShellEntryMonitor.emplace(cx(), aReason); + } + mScriptActivity.emplace(true); } } @@ -815,11 +818,12 @@ AutoSafeJSContext::AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMP } AutoSlowOperation::AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL) - : AutoJSAPI() + : mIsMainThread(NS_IsMainThread()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - - Init(); + if (mIsMainThread) { + mScriptActivity.emplace(true); + } } void @@ -828,8 +832,10 @@ AutoSlowOperation::CheckForInterrupt() // For now we support only main thread! if (mIsMainThread) { // JS_CheckForInterrupt expects us to be in a realm. - JSAutoRealm ar(cx(), xpc::UnprivilegedJunkScope()); - JS_CheckForInterrupt(cx()); + AutoJSAPI jsapi; + if (jsapi.Init(xpc::UnprivilegedJunkScope())) { + JS_CheckForInterrupt(jsapi.cx()); + } } } diff --git a/dom/script/ScriptSettings.h b/dom/script/ScriptSettings.h index cce5607c3771..d69b7ed95967 100644 --- a/dom/script/ScriptSettings.h +++ b/dom/script/ScriptSettings.h @@ -12,6 +12,7 @@ #include "MainThreadUtils.h" #include "nsIGlobalObject.h" #include "nsIPrincipal.h" +#include "xpcpublic.h" #include "mozilla/Maybe.h" @@ -383,6 +384,7 @@ private: friend nsIPrincipal* GetWebIDLCallerPrincipal(); Maybe mDocShellEntryMonitor; + Maybe mScriptActivity; JS::AutoHideScriptedCaller mCallerOverride; #ifdef MOZ_GECKO_PROFILER AutoProfilerLabel mAutoProfilerLabel; @@ -455,17 +457,21 @@ private: * Use AutoSlowOperation when native side calls many JS callbacks in a row * and slow script dialog should be activated if too much time is spent going * through those callbacks. - * AutoSlowOperation puts a JSAutoRequest on the stack so that we don't continue - * to reset the watchdog and CheckForInterrupt can be then used to check whether - * JS execution should be interrupted. + * AutoSlowOperation puts an AutoScriptActivity on the stack so that we don't + * continue to reset the watchdog. CheckForInterrupt can then be used to check + * whether JS execution should be interrupted. + * This class (including CheckForInterrupt) is a no-op when used off the main + * thread. */ -class MOZ_RAII AutoSlowOperation : public dom::AutoJSAPI +class MOZ_RAII AutoSlowOperation { public: explicit AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM); void CheckForInterrupt(); private: MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER + bool mIsMainThread; + Maybe mScriptActivity; }; /** diff --git a/dom/tests/browser/perfmetrics/setinterval.html b/dom/tests/browser/perfmetrics/setinterval.html index bf309638e28e..4c3e7264ca30 100644 --- a/dom/tests/browser/perfmetrics/setinterval.html +++ b/dom/tests/browser/perfmetrics/setinterval.html @@ -10,10 +10,10 @@ clearInterval(interval); } - interval = setInterval(doSomething, 10); + interval = setInterval(doSomething, 1); -

A page with setInterval() calls

+

A page with a setInterval() call

diff --git a/dom/tests/browser/perfmetrics/settimeout.html b/dom/tests/browser/perfmetrics/settimeout.html index 24178500a8cd..01f632caf510 100644 --- a/dom/tests/browser/perfmetrics/settimeout.html +++ b/dom/tests/browser/perfmetrics/settimeout.html @@ -8,9 +8,10 @@ console.log("We are doing something here"); } + setTimeout(doSomething, 1); - -

A page with setInterval() calls

+ +

A page with a setTimeout() call

diff --git a/gfx/layers/client/ClientPaintedLayer.cpp b/gfx/layers/client/ClientPaintedLayer.cpp index f2841237d780..274c3ca40d71 100644 --- a/gfx/layers/client/ClientPaintedLayer.cpp +++ b/gfx/layers/client/ClientPaintedLayer.cpp @@ -11,6 +11,7 @@ #include "client/ClientLayerManager.h" // for ClientLayerManager, etc #include "gfxContext.h" // for gfxContext #include "gfx2DGlue.h" +#include "gfxEnv.h" // for gfxEnv #include "gfxRect.h" // for gfxRect #include "gfxPrefs.h" // for gfxPrefs #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc @@ -155,13 +156,15 @@ ClientPaintedLayer::RenderLayerWithReadback(ReadbackProcessor *aReadback) RefPtr ctx = gfxContext::CreatePreservingTransformOrNull(target); MOZ_ASSERT(ctx); // already checked the target above - ClientManager()->GetPaintedLayerCallback()(this, - ctx, - iter.mDrawRegion, - iter.mDrawRegion, - state.mClip, - state.mRegionToInvalidate, - ClientManager()->GetPaintedLayerCallbackData()); + if (!gfxEnv::SkipRasterization()) { + ClientManager()->GetPaintedLayerCallback()(this, + ctx, + iter.mDrawRegion, + iter.mDrawRegion, + state.mClip, + state.mRegionToInvalidate, + ClientManager()->GetPaintedLayerCallbackData()); + } ctx = nullptr; mContentClient->ReturnDrawTarget(target); diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index 5827405defeb..ee6ad9c52af8 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -24,6 +24,7 @@ #include "Units.h" // for ScreenIntRect #include "UnitTransforms.h" // for ViewAs #include "apz/src/AsyncPanZoomController.h" // for AsyncPanZoomController +#include "gfxEnv.h" // for gfxEnv #include "gfxPrefs.h" // for gfxPrefs #ifdef XP_MACOSX #include "gfxPlatformMac.h" @@ -477,6 +478,11 @@ LayerManagerComposite::EndTransaction(const TimeStamp& aTimeStamp, void LayerManagerComposite::UpdateAndRender() { + if (gfxEnv::SkipComposition()) { + mInvalidRegion.SetEmpty(); + return; + } + nsIntRegion invalid; // The results of our drawing always go directly into a pixel buffer, // so we don't need to pass any global transform here. diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index 0615d92d5a4f..984d926597fd 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -151,7 +151,6 @@ union SurfaceDescriptor { SurfaceDescriptorMacIOSurface; SurfaceDescriptorSharedGLTexture; SurfaceDescriptorGPUVideo; - SurfaceDescriptorShared; null_t; }; diff --git a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp index 8b26a2633959..e2b986600d91 100644 --- a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp +++ b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp @@ -10,6 +10,7 @@ #include "ImageLayerMLGPU.h" #include "CanvasLayerMLGPU.h" #include "GeckoProfiler.h" // for profiler_* +#include "gfxEnv.h" // for gfxEnv #include "MLGDevice.h" #include "RenderPassMLGPU.h" #include "RenderViewMLGPU.h" @@ -276,6 +277,10 @@ LayerManagerMLGPU::EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFla void LayerManagerMLGPU::Composite() { + if (gfxEnv::SkipComposition()) { + return; + } + AUTO_PROFILER_LABEL("LayerManagerMLGPU::Composite", GRAPHICS); // Don't composite if we're minimized/hidden, or if there is nothing to draw. diff --git a/gfx/thebes/gfxEnv.h b/gfx/thebes/gfxEnv.h index ee0628ab7ab2..7a02833e8cdf 100644 --- a/gfx/thebes/gfxEnv.h +++ b/gfx/thebes/gfxEnv.h @@ -101,6 +101,12 @@ public: // Offscreen GL context for main layer manager DECL_GFX_ENV("MOZ_LAYERS_PREFER_OFFSCREEN", LayersPreferOffscreen); + // Skip final window composition + DECL_GFX_ENV("MOZ_SKIPCOMPOSITION", SkipComposition); + + // Skip rasterizing painted layer contents + DECL_GFX_ENV("MOZ_SKIPRASTERIZATION", SkipRasterization); + // Stop the VR rendering DECL_GFX_ENV("NO_VR_RENDERING", NoVRRendering); diff --git a/intl/l10n/L10nRegistry.jsm b/intl/l10n/L10nRegistry.jsm index a3292a72f4fe..a429acaf5dbc 100644 --- a/intl/l10n/L10nRegistry.jsm +++ b/intl/l10n/L10nRegistry.jsm @@ -95,26 +95,18 @@ const L10nRegistry = { const sourcesOrder = Array.from(this.sources.keys()).reverse(); const pseudoNameFromPref = Services.prefs.getStringPref("intl.l10n.pseudo", ""); for (const locale of requestedLangs) { - for (const fetchPromises of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) { - const ctx = await Promise.all(fetchPromises).then( - dataSets => { - const ctx = new MessageContext(locale, { - ...MSG_CONTEXT_OPTIONS, - transform: PSEUDO_STRATEGIES[pseudoNameFromPref], - }); - for (const data of dataSets) { - if (data === null) { - return null; - } - ctx.addResource(data); - } - return ctx; - }, - () => null - ); - if (ctx !== null) { - yield ctx; + for await (const dataSets of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) { + const ctx = new MessageContext(locale, { + ...MSG_CONTEXT_OPTIONS, + transform: PSEUDO_STRATEGIES[pseudoNameFromPref], + }); + for (const data of dataSets) { + if (data === null) { + return; + } + ctx.addResource(data); } + yield ctx; } } }, @@ -190,7 +182,7 @@ const L10nRegistry = { * @param {Array} [resolvedOrder] * @returns {AsyncIterator} */ -function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) { +async function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) { const resolvedLength = resolvedOrder.length; const resourcesLength = resourceIds.length; @@ -200,18 +192,36 @@ function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resol for (const sourceName of sourcesOrder) { const order = resolvedOrder.concat(sourceName); - // We bail only if the hasFile returns a strict false here, - // because for FileSource it may also return undefined, which means - // that we simply don't know if the source contains the file and we'll - // have to perform the I/O to learn. - if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[resolvedOrder.length]) === false) { - continue; + // We want to bail out early if we know that any of + // the (res)x(source) combinations in the permutation + // are unavailable. + // The combination may have been `undefined` when we + // stepped into this branch, and now is resolved to + // `false`. + // + // If the combination resolved to `false` is the last + // in the resolvedOrder, we want to continue in this + // loop, but if it's somewhere in the middle, we can + // safely bail from the whole branch. + for (let [idx, sourceName] of order.entries()) { + if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[idx]) === false) { + if (idx === order.length - 1) { + continue; + } else { + return; + } + } } // If the number of resolved sources equals the number of resources, // create the right context and return it if it loads. if (resolvedLength + 1 === resourcesLength) { - yield generateResourceSet(locale, order, resourceIds); + let dataSet = await generateResourceSet(locale, order, resourceIds); + // Here we check again to see if the newly resolved + // resources returned `false` on any position. + if (!dataSet.includes(false)) { + yield dataSet; + } } else if (resolvedLength < resourcesLength) { // otherwise recursively load another generator that walks over the // partially resolved list of sources. @@ -346,10 +356,10 @@ const PSEUDO_STRATEGIES = { * @param {Array} resourceIds * @returns {Promise} */ -function generateResourceSet(locale, sourcesOrder, resourceIds) { - return resourceIds.map((resourceId, i) => { +async function generateResourceSet(locale, sourcesOrder, resourceIds) { + return Promise.all(resourceIds.map((resourceId, i) => { return L10nRegistry.sources.get(sourcesOrder[i]).fetchFile(locale, resourceId); - }); + })); } /** @@ -420,14 +430,14 @@ class FileSource { fetchFile(locale, path) { if (!this.locales.includes(locale)) { - return Promise.reject(`The source has no resources for locale "${locale}"`); + return false; } const fullPath = this.getPath(locale, path); if (this.cache.hasOwnProperty(fullPath)) { if (this.cache[fullPath] === false) { - return Promise.reject(`The source has no resources for path "${fullPath}"`); + return false; } // `true` means that the file is indexed, but hasn't // been fetched yet. @@ -435,7 +445,7 @@ class FileSource { return this.cache[fullPath]; } } else if (this.indexed) { - return Promise.reject(`The source has no resources for path "${fullPath}"`); + return false; } return this.cache[fullPath] = L10nRegistry.load(fullPath).then( data => { @@ -443,7 +453,7 @@ class FileSource { }, err => { this.cache[fullPath] = false; - return Promise.reject(err); + return false; } ); } diff --git a/intl/l10n/Localization.jsm b/intl/l10n/Localization.jsm index 8aa0722f20d8..1d453578134a 100644 --- a/intl/l10n/Localization.jsm +++ b/intl/l10n/Localization.jsm @@ -97,7 +97,7 @@ class CachedAsyncIterable extends CachedIterable { return { async next() { if (cached.length <= cur) { - cached.push(await cached.iterator.next()); + cached.push(cached.iterator.next()); } return cached[cur++]; } @@ -114,10 +114,10 @@ class CachedAsyncIterable extends CachedIterable { let idx = 0; while (idx++ < count) { const last = this[this.length - 1]; - if (last && last.done) { + if (last && await (last).done) { break; } - this.push(await this.iterator.next()); + this.push(this.iterator.next()); } // Return the last cached {value, done} object to allow the calling // code to decide if it needs to call touchNext again. @@ -322,7 +322,6 @@ class Localization { onChange() { this.ctxs = CachedAsyncIterable.from( this.generateMessages(this.resourceIds)); - this.ctxs.touchNext(2); } } diff --git a/intl/l10n/l10n.js b/intl/l10n/l10n.js index ad6c914b3219..1afb8f7ee00d 100644 --- a/intl/l10n/l10n.js +++ b/intl/l10n/l10n.js @@ -1,6 +1,7 @@ { const { DOMLocalization } = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {}); + const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); /** * Polyfill for document.ready polyfill. @@ -46,8 +47,9 @@ document.l10n = new DOMLocalization(resourceIds); - // Trigger the first two contexts to be loaded eagerly. - document.l10n.ctxs.touchNext(2); + const appLocales = Services.locale.getAppLocalesAsBCP47(); + const prefetchCount = appLocales.length > 1 ? 2 : 1; + document.l10n.ctxs.touchNext(prefetchCount); document.l10n.ready = documentReady().then(() => { document.l10n.registerObservers(); diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js index 9c76980df240..9a048f19fb9a 100644 --- a/js/src/builtin/Array.js +++ b/js/src/builtin/Array.js @@ -971,6 +971,7 @@ function ArraySpeciesCreate(originalArray, length) { assert(length >= 0, "length should be a non-negative number"); // Step 2. + // eslint-disable-next-line no-compare-neg-zero if (length === -0) length = 0; diff --git a/js/src/jit-test/lib/wasm-binary.js b/js/src/jit-test/lib/wasm-binary.js index 7f1f2b0bc540..6bbefa1b3ba9 100644 --- a/js/src/jit-test/lib/wasm-binary.js +++ b/js/src/jit-test/lib/wasm-binary.js @@ -24,7 +24,6 @@ const startId = 8; const elemId = 9; const codeId = 10; const dataId = 11; -const gcFeatureOptInId = 42; // User-defined section names const nameName = "name"; @@ -178,10 +177,6 @@ function moduleWithSections(sectionArray) { return toU8(bytes); } -function gcFeatureOptInSection(version) { - return { name: gcFeatureOptInId, body: [ version & 0x7F ] } -} - function sigSection(sigs) { var body = []; body.push(...varU32(sigs.length)); diff --git a/js/src/jit-test/tests/realms/bug1487238.js b/js/src/jit-test/tests/realms/bug1487238.js new file mode 100644 index 000000000000..dc0f9710a919 --- /dev/null +++ b/js/src/jit-test/tests/realms/bug1487238.js @@ -0,0 +1,3 @@ +// |jit-test| error: TypeError +var x = newGlobal({sameCompartmentAs: this}); +x instanceof x.Map.prototype.set; diff --git a/js/src/jit-test/tests/wasm/binary.js b/js/src/jit-test/tests/wasm/binary.js index f7fb5aac083a..d86714094699 100644 --- a/js/src/jit-test/tests/wasm/binary.js +++ b/js/src/jit-test/tests/wasm/binary.js @@ -47,9 +47,9 @@ assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(codeId))), CompileError, assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(dataId))), CompileError, sectionError("data")); // unknown sections are unconditionally rejected -assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37))), CompileError, unknownSection); -assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37, 0))), CompileError, unknownSection); -assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37, 1, 0))), CompileError, unknownSection); +assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42))), CompileError, unknownSection); +assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42, 0))), CompileError, unknownSection); +assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42, 1, 0))), CompileError, unknownSection); // user sections have special rules assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0))), CompileError, sectionError("custom")); // no length diff --git a/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js b/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js index dce81a3a50ec..14e9beb497a1 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js @@ -12,7 +12,6 @@ function Baguette(calories) { // Ensure the baseline compiler sync's before the postbarrier. (function() { wasmEvalText(`(module - (gc_feature_opt_in 1) (global (mut anyref) (ref.null anyref)) (func (export "f") get_global 0 @@ -24,7 +23,6 @@ function Baguette(calories) { })(); let exportsPlain = wasmEvalText(`(module - (gc_feature_opt_in 1) (global i32 (i32.const 42)) (global $g (mut anyref) (ref.null anyref)) (func (export "set") (param anyref) get_local 0 set_global $g) @@ -32,7 +30,6 @@ let exportsPlain = wasmEvalText(`(module )`).exports; let exportsObj = wasmEvalText(`(module - (gc_feature_opt_in 1) (global $g (export "g") (mut anyref) (ref.null anyref)) (func (export "set") (param anyref) get_local 0 set_global $g) (func (export "get") (result anyref) get_global $g) diff --git a/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js b/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js index 9c9f5f4b84d6..1b159a749c14 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js @@ -5,7 +5,6 @@ if (!wasmGcEnabled()) { const { startProfiling, endProfiling, assertEqPreciseStacks, isSingleStepProfilingEnabled } = WasmHelpers; let e = wasmEvalText(`(module - (gc_feature_opt_in 1) (global $g (mut anyref) (ref.null anyref)) (func (export "set") (param anyref) get_local 0 set_global $g) )`).exports; diff --git a/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js b/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js index d7fcce38683d..b1a689491881 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js @@ -4,7 +4,6 @@ if (!wasmGcEnabled()) { gczeal(14, 1); let { exports } = wasmEvalText(`(module - (gc_feature_opt_in 1) (global $anyref (import "glob" "anyref") anyref) (func (export "get") (result anyref) get_global $anyref) )`, { diff --git a/js/src/jit-test/tests/wasm/gc/anyref.js b/js/src/jit-test/tests/wasm/gc/anyref.js index d6dcb15772ff..3328144e905e 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref.js +++ b/js/src/jit-test/tests/wasm/gc/anyref.js @@ -14,14 +14,12 @@ function Baguette(calories) { const { validate, CompileError } = WebAssembly; assertErrorMessage(() => wasmEvalText(`(module - (gc_feature_opt_in 1) (func (result anyref) i32.const 42 ) )`), CompileError, mismatchError('i32', 'anyref')); assertErrorMessage(() => wasmEvalText(`(module - (gc_feature_opt_in 1) (func (result anyref) i32.const 0 ref.null anyref @@ -31,7 +29,6 @@ assertErrorMessage(() => wasmEvalText(`(module )`), CompileError, /select operand types/); assertErrorMessage(() => wasmEvalText(`(module - (gc_feature_opt_in 1) (func (result i32) ref.null anyref if @@ -44,16 +41,16 @@ assertErrorMessage(() => wasmEvalText(`(module // Basic compilation tests. let simpleTests = [ - "(module (gc_feature_opt_in 1) (func (drop (ref.null anyref))))", - "(module (gc_feature_opt_in 1) (func $test (local anyref)))", - "(module (gc_feature_opt_in 1) (func $test (param anyref)))", - "(module (gc_feature_opt_in 1) (func $test (result anyref) (ref.null anyref)))", - "(module (gc_feature_opt_in 1) (func $test (block anyref (unreachable)) unreachable))", - "(module (gc_feature_opt_in 1) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))", - `(module (gc_feature_opt_in 1) (import "a" "b" (param anyref)))`, - `(module (gc_feature_opt_in 1) (import "a" "b" (result anyref)))`, - `(module (gc_feature_opt_in 1) (global anyref (ref.null anyref)))`, - `(module (gc_feature_opt_in 1) (global (mut anyref) (ref.null anyref)))`, + "(module (func (drop (ref.null anyref))))", + "(module (func $test (local anyref)))", + "(module (func $test (param anyref)))", + "(module (func $test (result anyref) (ref.null anyref)))", + "(module (func $test (block anyref (unreachable)) unreachable))", + "(module (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))", + `(module (import "a" "b" (param anyref)))`, + `(module (import "a" "b" (result anyref)))`, + `(module (global anyref (ref.null anyref)))`, + `(module (global (mut anyref) (ref.null anyref)))`, ]; for (let src of simpleTests) { @@ -64,7 +61,6 @@ for (let src of simpleTests) { // Basic behavioral tests. let { exports } = wasmEvalText(`(module - (gc_feature_opt_in 1) (func (export "is_null") (result i32) ref.null anyref ref.is_null @@ -102,7 +98,6 @@ assertEq(exports.is_null_local(), 1); // Anyref param and result in wasm functions. exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (func (export "is_null") (result i32) (param $ref anyref) get_local $ref ref.is_null @@ -160,7 +155,6 @@ assertEq(ref.calories, baguette.calories); // Make sure grow-memory isn't blocked by the lack of gc. (function() { assertEq(wasmEvalText(`(module - (gc_feature_opt_in 1) (memory 0 64) (func (export "f") (param anyref) (result i32) i32.const 10 @@ -176,7 +170,6 @@ assertEq(ref.calories, baguette.calories); function assertJoin(body) { let val = { i: -1 }; assertEq(wasmEvalText(`(module - (gc_feature_opt_in 1) (func (export "test") (param $ref anyref) (param $i i32) (result anyref) ${body} ) @@ -243,7 +236,6 @@ assertJoin(`(block $out anyref (block $unreachable anyref (loop $top let x = { i: 42 }, y = { f: 53 }; exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (func (export "test") (param $lhs anyref) (param $rhs anyref) (param $i i32) (result anyref) get_local $lhs get_local $rhs @@ -298,7 +290,6 @@ let imports = { }; exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (import $ret "funcs" "ret" (result anyref)) (import $param "funcs" "param" (param anyref)) @@ -327,7 +318,6 @@ assertEq(exports.ret(), imports.myBaguette); // Check lazy stubs generation. exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (import $mirror "funcs" "mirror" (param anyref) (result anyref)) (import $augment "funcs" "augment" (param anyref) (result anyref)) @@ -411,15 +401,15 @@ assertEq(exports.count_g(), 1); // Anyref globals in wasm modules. -assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "anyref") anyref))`, { glob: { anyref: 42 } }), +assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "anyref") anyref))`, { glob: { anyref: 42 } }), WebAssembly.LinkError, /import object field 'anyref' is not a Object-or-null/); -assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "anyref") anyref))`, { glob: { anyref: new WebAssembly.Global({ value: 'i32' }, 42) } }), +assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "anyref") anyref))`, { glob: { anyref: new WebAssembly.Global({ value: 'i32' }, 42) } }), WebAssembly.LinkError, /imported global type mismatch/); -assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "i32") i32))`, { glob: { i32: {} } }), +assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "i32") i32))`, { glob: { i32: {} } }), WebAssembly.LinkError, /import object field 'i32' is not a Number/); @@ -433,7 +423,6 @@ imports = { }; exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (global $g_imp_imm_null (import "constants" "imm_null") anyref) (global $g_imp_imm_bread (import "constants" "imm_bread") anyref) diff --git a/js/src/jit-test/tests/wasm/gc/binary.js b/js/src/jit-test/tests/wasm/gc/binary.js index 334d8b3f19d0..222a8e799a96 100644 --- a/js/src/jit-test/tests/wasm/gc/binary.js +++ b/js/src/jit-test/tests/wasm/gc/binary.js @@ -8,10 +8,7 @@ const v2vSig = {args:[], ret:VoidCode}; const v2vSigSection = sigSection([v2vSig]); function checkInvalid(body, errorMessage) { - assertErrorMessage(() => new WebAssembly.Module( - moduleWithSections([gcFeatureOptInSection(1), v2vSigSection, declSection([0]), bodySection([body])])), - WebAssembly.CompileError, - errorMessage); + assertErrorMessage(() => new WebAssembly.Module(moduleWithSections([v2vSigSection, declSection([0]), bodySection([body])])), WebAssembly.CompileError, errorMessage); } const invalidRefNullBody = funcBody({locals:[], body:[ diff --git a/js/src/jit-test/tests/wasm/gc/debugger.js b/js/src/jit-test/tests/wasm/gc/debugger.js index 494068d40d4e..96e79c43c20a 100644 --- a/js/src/jit-test/tests/wasm/gc/debugger.js +++ b/js/src/jit-test/tests/wasm/gc/debugger.js @@ -5,7 +5,7 @@ if (!wasmGcEnabled() || !wasmDebuggingIsSupported()) { (function() { let g = newGlobal(); let dbg = new Debugger(g); - g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (gc_feature_opt_in 1) (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`); + g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`); })(); (function() { @@ -14,7 +14,6 @@ if (!wasmGcEnabled() || !wasmDebuggingIsSupported()) { let src = ` (module - (gc_feature_opt_in 1) (func (export "func") (result anyref) (param $ref anyref) get_local $ref ) diff --git a/js/src/jit-test/tests/wasm/gc/disabled.js b/js/src/jit-test/tests/wasm/gc/disabled.js index 14768ee16eb1..f720b515ee32 100644 --- a/js/src/jit-test/tests/wasm/gc/disabled.js +++ b/js/src/jit-test/tests/wasm/gc/disabled.js @@ -4,21 +4,21 @@ if (wasmGcEnabled()) { const { CompileError, validate } = WebAssembly; -const UNRECOGNIZED_OPCODE_OR_BAD_TYPE = /unrecognized opcode|reference types not enabled|invalid inline block type/; +const UNRECOGNIZED_OPCODE_OR_BAD_TYPE = /(unrecognized opcode|bad type|invalid inline block type)/; function assertValidateError(text) { assertEq(validate(wasmTextToBinary(text)), false); } let simpleTests = [ - "(module (gc_feature_opt_in 1) (func (drop (ref.null anyref))))", - "(module (gc_feature_opt_in 1) (func $test (local anyref)))", - "(module (gc_feature_opt_in 1) (func $test (param anyref)))", - "(module (gc_feature_opt_in 1) (func $test (result anyref) (ref.null anyref)))", - "(module (gc_feature_opt_in 1) (func $test (block anyref (unreachable)) unreachable))", - "(module (gc_feature_opt_in 1) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))", - `(module (gc_feature_opt_in 1) (import "a" "b" (param anyref)))`, - `(module (gc_feature_opt_in 1) (import "a" "b" (result anyref)))`, + "(module (func (drop (ref.null anyref))))", + "(module (func $test (local anyref)))", + "(module (func $test (param anyref)))", + "(module (func $test (result anyref) (ref.null anyref)))", + "(module (func $test (block anyref (unreachable)) unreachable))", + "(module (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))", + `(module (import "a" "b" (param anyref)))`, + `(module (import "a" "b" (result anyref)))`, ]; for (let src of simpleTests) { diff --git a/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js b/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js deleted file mode 100644 index 5cf5f3f0d4a0..000000000000 --- a/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js +++ /dev/null @@ -1,120 +0,0 @@ -if (!wasmGcEnabled()) { - quit(0); -} - -// Encoding. If the section is present it must be first. - -var bad_order = - new Uint8Array([0x00, 0x61, 0x73, 0x6d, - 0x01, 0x00, 0x00, 0x00, - - 0x01, // Type section - 0x01, // Section size - 0x00, // Zero types - - 0x2a, // GcFeatureOptIn section - 0x01, // Section size - 0x01]); // Version - -assertErrorMessage(() => new WebAssembly.Module(bad_order), - WebAssembly.CompileError, - /expected custom section/); - -// Version numbers. Version 1 is good, version 2 is bad. - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 2))`)), - WebAssembly.CompileError, - /unsupported version of the gc feature/); - -// Struct types are only available if we opt in. - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (type (struct (field i32))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (type (struct (field i32))))`)), - WebAssembly.CompileError, - /Structure types not enabled/); - -// Parameters of ref type are only available if we opt in. - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (type (func (param anyref))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (type (func (param anyref))))`)), - WebAssembly.CompileError, - /reference types not enabled/); - -// Ditto returns - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (type (func (result anyref))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (type (func (result anyref))))`)), - WebAssembly.CompileError, - /reference types not enabled/); - -// Ditto locals - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (func (result i32) - (local anyref) - (i32.const 0)))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (func (result i32) - (local anyref) - (i32.const 0)))`)), - WebAssembly.CompileError, - /reference types not enabled/); - -// Ditto globals - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (global (mut anyref) (ref.null anyref)))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (global (mut anyref) (ref.null anyref)))`)), - WebAssembly.CompileError, - /reference types not enabled/); - -// Ref instructions are only available if we opt in. -// -// When testing these we need to avoid struct types or parameters, locals, -// returns, or globals of ref type, or guards on those will preempt the guards -// on the instructions. - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (func (ref.null anyref)))`)), - WebAssembly.CompileError, - /unrecognized opcode/); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (func ref.is_null))`)), - WebAssembly.CompileError, - /unrecognized opcode/); diff --git a/js/src/jit-test/tests/wasm/gc/ref-global.js b/js/src/jit-test/tests/wasm/gc/ref-global.js index 0a64c9973bb3..9eb961c2c8f9 100644 --- a/js/src/jit-test/tests/wasm/gc/ref-global.js +++ b/js/src/jit-test/tests/wasm/gc/ref-global.js @@ -7,7 +7,6 @@ if (!wasmGcEnabled()) { let bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (type $point (struct (field $x f64) @@ -43,7 +42,6 @@ if (!wasmGcEnabled()) { let bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "g" (global (mut (ref $box)))))`); @@ -58,7 +56,6 @@ if (!wasmGcEnabled()) { let bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (global $boxg (export "box") (mut (ref $box)) (ref.null (ref $box))))`); diff --git a/js/src/jit-test/tests/wasm/gc/ref-restrict.js b/js/src/jit-test/tests/wasm/gc/ref-restrict.js index 9e1f5ce5025d..bb95ddef3897 100644 --- a/js/src/jit-test/tests/wasm/gc/ref-restrict.js +++ b/js/src/jit-test/tests/wasm/gc/ref-restrict.js @@ -52,7 +52,6 @@ function wasmCompile(text) { assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $x i32))) (func (export "f") (param (ref $box)) (unreachable)))`), WebAssembly.CompileError, @@ -60,7 +59,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (func (export "f") (param anyref) (unreachable)))`), "object"); @@ -68,7 +66,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $x i32))) (func (export "f") (result (ref $box)) (ref.null (ref $box))))`), WebAssembly.CompileError, @@ -76,7 +73,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (func (export "f") (result anyref) (ref.null anyref)))`), "object"); @@ -84,7 +80,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $x i32))) (import "m" "f" (param (ref $box))))`), WebAssembly.CompileError, @@ -92,7 +87,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "f" (param anyref)))`), "object"); @@ -100,7 +94,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $x i32))) (import "m" "f" (param i32) (result (ref $box))))`), WebAssembly.CompileError, @@ -108,7 +101,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "f" (param i32) (result anyref)))`), "object"); @@ -116,7 +108,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "g" (global (mut (ref $box)))))`), WebAssembly.CompileError, @@ -124,7 +115,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "g" (global (ref $box))))`), WebAssembly.CompileError, @@ -132,13 +122,11 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "g" (global (mut anyref))))`), "object"); assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "g" (global anyref)))`), "object"); @@ -146,7 +134,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (global $boxg (export "box") (mut (ref $box)) (ref.null (ref $box))))`), WebAssembly.CompileError, @@ -154,7 +141,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (global $boxg (export "box") (ref $box) (ref.null (ref $box))))`), WebAssembly.CompileError, @@ -162,13 +148,11 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (global $boxg (export "box") (mut anyref) (ref.null anyref)))`), "object"); assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (global $boxg (export "box") anyref (ref.null anyref)))`), "object"); @@ -176,7 +160,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (table (export "tbl") 1 anyfunc) (elem (i32.const 0) $f1) @@ -186,7 +169,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (table (export "tbl") 1 anyfunc) (elem (i32.const 0) $f1) @@ -196,7 +178,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (table (export "tbl") 1 anyfunc) (elem (i32.const 0) $f1) (func $f1 (param anyref) (unreachable)))`), @@ -204,7 +185,6 @@ assertEq(typeof wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (table (export "tbl") 1 anyfunc) (elem (i32.const 0) $f1) (func $f1 (result anyref) (ref.null anyref)))`), @@ -214,7 +194,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "tbl" (table 1 anyfunc)) (elem (i32.const 0) $f1) @@ -224,7 +203,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "tbl" (table 1 anyfunc)) (elem (i32.const 0) $f1) @@ -234,7 +212,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "tbl" (table 1 anyfunc)) (elem (i32.const 0) $f1) (func $f1 (param anyref) (unreachable)))`), @@ -242,7 +219,6 @@ assertEq(typeof wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "tbl" (table 1 anyfunc)) (elem (i32.const 0) $f1) (func $f1 (result anyref) (ref.null anyref)))`), @@ -252,7 +228,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (param (ref $box)))) (table (export "tbl") 1 anyfunc) @@ -263,7 +238,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (result (ref $box)))) (table (export "tbl") 1 anyfunc) @@ -274,7 +248,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (type $fn (func (param anyref))) (table (export "tbl") 1 anyfunc) (func (param i32) @@ -283,7 +256,6 @@ assertEq(typeof wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (type $fn (func (result anyref))) (table (export "tbl") 1 anyfunc) (func (param i32) (result anyref) @@ -294,7 +266,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (param (ref $box)))) (import "m" "tbl" (table 1 anyfunc)) @@ -305,7 +276,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (result (ref $box)))) (import "m" "tbl" (table 1 anyfunc)) @@ -316,7 +286,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (type $fn (func (param anyref))) (import "m" "tbl" (table 1 anyfunc)) (func (param i32) @@ -325,7 +294,6 @@ assertEq(typeof wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (type $fn (func (result anyref))) (import "m" "tbl" (table 1 anyfunc)) (func (param i32) (result anyref) @@ -337,7 +305,6 @@ assertEq(typeof wasmCompile( { let m = wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (param (ref $box)) (result i32))) (table 1 anyfunc) diff --git a/js/src/jit-test/tests/wasm/gc/ref.js b/js/src/jit-test/tests/wasm/gc/ref.js index 6638894b520c..1f087388ad69 100644 --- a/js/src/jit-test/tests/wasm/gc/ref.js +++ b/js/src/jit-test/tests/wasm/gc/ref.js @@ -1,6 +1,6 @@ if (!wasmGcEnabled()) { assertErrorMessage(() => wasmEvalText(`(module (func (param (ref 0)) (unreachable)))`), - WebAssembly.CompileError, /reference types not enabled/); + WebAssembly.CompileError, /bad type/); quit(0); } @@ -8,7 +8,6 @@ if (!wasmGcEnabled()) { var bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (type $cons (struct (field $car i32) (field $cdr (ref $cons)))) @@ -68,7 +67,6 @@ assertEq(WebAssembly.validate(bin), true); new WebAssembly.Module(wasmTextToBinary(` (module - (gc_feature_opt_in 1) (type $s (struct)) (func $null (param (ref $s)) (result i32) (ref.is_null (get_local 0)))) @@ -78,7 +76,6 @@ new WebAssembly.Module(wasmTextToBinary(` new WebAssembly.Module(wasmTextToBinary(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (func $f (param (ref $s)) (call $g (get_local 0))) (func $g (param anyref) (unreachable))) @@ -88,8 +85,7 @@ new WebAssembly.Module(wasmTextToBinary(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) - (func (param (ref $odd)) (unreachable))) + (func (param (ref $odd)) (unreachable))) `), SyntaxError, /Type label.*not found/); @@ -98,7 +94,6 @@ SyntaxError, /Type label.*not found/); wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field i32))) (func $f (param (ref $s)) (unreachable)) @@ -107,7 +102,6 @@ wasmEvalText(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field f32))) ;; Incompatible type (func $f (param (ref $s)) (unreachable)) @@ -117,7 +111,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field (mut i32)))) ;; Incompatible mutability (func $f (param (ref $s)) (unreachable)) @@ -130,7 +123,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field i32))) (func $f (param (ref $s)) (local (ref $t)) (set_local 1 (get_local 0)))) @@ -138,7 +130,6 @@ wasmEvalText(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field f32))) (func $f (param (ref $s)) (local (ref $t)) (set_local 1 (get_local 0)))) @@ -147,7 +138,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field (mut i32)))) (func $f (param (ref $s)) (unreachable)) @@ -160,7 +150,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field i32))) (func $f (param (ref $s)) (result (ref $t)) (get_local 0))) @@ -168,7 +157,6 @@ wasmEvalText(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field f32))) (func $f (param (ref $s)) (result (ref $t)) (get_local 0))) @@ -177,7 +165,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field (mut i32)))) (func $f (param (ref $s)) (result (ref $t)) (get_local 0))) @@ -188,7 +175,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $x (func (param i32))) (func $f (param (ref $x)) (unreachable))) `), @@ -196,7 +182,6 @@ SyntaxError, /Type label.*not found/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type (func (param i32))) (func $f (param (ref 0)) (unreachable))) `), @@ -206,7 +191,6 @@ WebAssembly.CompileError, /does not reference a struct type/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (func $f (param anyref) (call $g (get_local 0))) (func $g (param (ref $s)) (unreachable))) diff --git a/js/src/jit-test/tests/wasm/gc/structs.js b/js/src/jit-test/tests/wasm/gc/structs.js index 333fd1303612..a8e94518f3e6 100644 --- a/js/src/jit-test/tests/wasm/gc/structs.js +++ b/js/src/jit-test/tests/wasm/gc/structs.js @@ -1,14 +1,11 @@ if (!wasmGcEnabled()) { - assertErrorMessage(() => wasmEvalText(`(module - (gc_feature_opt_in 1) - (type $s (struct)))`), + assertErrorMessage(() => wasmEvalText(`(module (type $s (struct)))`), WebAssembly.CompileError, /Structure types not enabled/); quit(); } var bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (table 2 anyfunc) (elem (i32.const 0) $doit $doitagain) @@ -76,7 +73,6 @@ assertEq(ins.x2(8), Math.PI) wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32)))) `) @@ -84,7 +80,6 @@ wasmEvalText(` wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct))) `) @@ -92,7 +87,6 @@ wasmEvalText(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field $x i32))) (type $s (struct (field $y i32)))) `), @@ -102,35 +96,30 @@ SyntaxError, /duplicate type name/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s)) `), SyntaxError, /parsing wasm text/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (field $x i32))) `), SyntaxError, /bad type definition/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field $x i31)))) `), SyntaxError, /parsing wasm text/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (fjeld $x i32)))) `), SyntaxError, /parsing wasm text/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct abracadabra))) `), SyntaxError, /parsing wasm text/); @@ -139,7 +128,6 @@ SyntaxError, /parsing wasm text/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct)) (type $f (func (param i32) (result i32))) (func (type 0) (param i32) (result i32) (unreachable))) @@ -151,10 +139,6 @@ WebAssembly.CompileError, /signature index references non-signature/); var bad = new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, - 0x2a, // GcFeatureOptIn section - 0x01, // Section size - 0x01, // Version - 0x01, // Type section 0x03, // Section size 0x01, // One type diff --git a/js/src/jsdate.cpp b/js/src/jsdate.cpp index bc7851fa7626..7ad3b9b8b0d2 100644 --- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -123,6 +123,33 @@ static Atomic sReduceMicros * hashCode */ +namespace +{ + +class DateTimeHelper +{ + private: +#if ENABLE_INTL_API && !MOZ_SYSTEM_ICU + static double localTZA(double t, DateTimeInfo::TimeZoneOffset offset); +#else + static int equivalentYearForDST(int year); + static bool isRepresentableAsTime32(double t); + static double daylightSavingTA(double t); + static double adjustTime(double date); + static PRMJTime toPRMJTime(double localTime, double utcTime); +#endif + + public: + static double localTime(double t); + static double UTC(double t); + static JSString* timeZoneComment(JSContext* cx, double utcTime, double localTime); +#if !ENABLE_INTL_API || MOZ_SYSTEM_ICU + static size_t formatTime(char* buf, size_t buflen, const char* fmt, double utcTime, double localTime); +#endif +}; + +} + // ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557 // 5.2.5 Mathematical Operations static inline double @@ -440,8 +467,8 @@ JS::SetTimeResolutionUsec(uint32_t resolution, bool jitter) #if ENABLE_INTL_API && !MOZ_SYSTEM_ICU // ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557 // 20.3.1.7 LocalTZA ( t, isUTC ) -static double -LocalTZA(double t, DateTimeInfo::TimeZoneOffset offset) +double +DateTimeHelper::localTZA(double t, DateTimeInfo::TimeZoneOffset offset) { MOZ_ASSERT(IsFinite(t)); @@ -452,20 +479,20 @@ LocalTZA(double t, DateTimeInfo::TimeZoneOffset offset) // ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557 // 20.3.1.8 LocalTime ( t ) -static double -LocalTime(double t) +double +DateTimeHelper::localTime(double t) { if (!IsFinite(t)) return GenericNaN(); MOZ_ASSERT(StartOfTime <= t && t <= EndOfTime); - return t + LocalTZA(t, DateTimeInfo::TimeZoneOffset::UTC); + return t + localTZA(t, DateTimeInfo::TimeZoneOffset::UTC); } // ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557 // 20.3.1.9 UTC ( t ) -static double -UTC(double t) +double +DateTimeHelper::UTC(double t) { if (!IsFinite(t)) return GenericNaN(); @@ -473,7 +500,7 @@ UTC(double t) if (t < (StartOfTime - msPerDay) || t > (EndOfTime + msPerDay)) return GenericNaN(); - return t - LocalTZA(t, DateTimeInfo::TimeZoneOffset::Local); + return t - localTZA(t, DateTimeInfo::TimeZoneOffset::Local); } #else /* @@ -483,8 +510,8 @@ UTC(double t) * for determining DST; it hasn't been proven not to produce an * incorrect year for times near year boundaries. */ -static int -EquivalentYearForDST(int year) +int +DateTimeHelper::equivalentYearForDST(int year) { /* * Years and leap years on which Jan 1 is a Sunday, Monday, etc. @@ -517,15 +544,15 @@ EquivalentYearForDST(int year) // Return true if |t| is representable as a 32-bit time_t variable, that means // the year is in [1970, 2038). -static bool -IsRepresentableAsTime32(double t) +bool +DateTimeHelper::isRepresentableAsTime32(double t) { return 0.0 <= t && t < 2145916800000.0; } /* ES5 15.9.1.8. */ -static double -DaylightSavingTA(double t) +double +DateTimeHelper::daylightSavingTA(double t) { if (!IsFinite(t)) return GenericNaN(); @@ -534,8 +561,8 @@ DaylightSavingTA(double t) * If earlier than 1970 or after 2038, potentially beyond the ken of * many OSes, map it to an equivalent year before asking. */ - if (!IsRepresentableAsTime32(t)) { - int year = EquivalentYearForDST(int(YearFromTime(t))); + if (!isRepresentableAsTime32(t)) { + int year = equivalentYearForDST(int(YearFromTime(t))); double day = MakeDay(year, MonthFromTime(t), DateFromTime(t)); t = MakeDate(day, TimeWithinDay(t)); } @@ -545,24 +572,24 @@ DaylightSavingTA(double t) return static_cast(offsetMilliseconds); } -static double -AdjustTime(double date) +double +DateTimeHelper::adjustTime(double date) { double localTZA = DateTimeInfo::localTZA(); - double t = DaylightSavingTA(date) + localTZA; + double t = daylightSavingTA(date) + localTZA; t = (localTZA >= 0) ? fmod(t, msPerDay) : -fmod(msPerDay - t, msPerDay); return t; } /* ES5 15.9.1.9. */ -static double -LocalTime(double t) +double +DateTimeHelper::localTime(double t) { - return t + AdjustTime(t); + return t + adjustTime(t); } -static double -UTC(double t) +double +DateTimeHelper::UTC(double t) { // Following the ES2017 specification creates undesirable results at DST // transitions. For example when transitioning from PST to PDT, @@ -571,10 +598,22 @@ UTC(double t) // V8 and subtract one hour before computing the offset. // Spec bug: https://bugs.ecmascript.org/show_bug.cgi?id=4007 - return t - AdjustTime(t - DateTimeInfo::localTZA() - msPerHour); + return t - adjustTime(t - DateTimeInfo::localTZA() - msPerHour); } #endif /* ENABLE_INTL_API && !MOZ_SYSTEM_ICU */ +static double +LocalTime(double t) +{ + return DateTimeHelper::localTime(t); +} + +static double +UTC(double t) +{ + return DateTimeHelper::UTC(t); +} + /* ES5 15.9.1.10. */ static double HourFromTime(double t) @@ -2712,8 +2751,8 @@ date_toJSON(JSContext* cx, unsigned argc, Value* vp) } #if ENABLE_INTL_API && !MOZ_SYSTEM_ICU -static JSString* -TimeZoneComment(JSContext* cx, double utcTime, double localTime) +JSString* +DateTimeHelper::timeZoneComment(JSContext* cx, double utcTime, double localTime) { const char* locale = cx->runtime()->getDefaultLocale(); if (!locale) { @@ -2747,8 +2786,8 @@ TimeZoneComment(JSContext* cx, double utcTime, double localTime) } #else /* Interface to PRMJTime date struct. */ -static PRMJTime -ToPRMJTime(double localTime, double utcTime) +PRMJTime +DateTimeHelper::toPRMJTime(double localTime, double utcTime) { double year = YearFromTime(localTime); @@ -2762,33 +2801,33 @@ ToPRMJTime(double localTime, double utcTime) prtm.tm_wday = int8_t(WeekDay(localTime)); prtm.tm_year = year; prtm.tm_yday = int16_t(DayWithinYear(localTime, year)); - prtm.tm_isdst = (DaylightSavingTA(utcTime) != 0); + prtm.tm_isdst = (daylightSavingTA(utcTime) != 0); return prtm; } -static size_t -FormatTime(char* buf, size_t buflen, const char* fmt, double utcTime, double localTime) +size_t +DateTimeHelper::formatTime(char* buf, size_t buflen, const char* fmt, double utcTime, double localTime) { - PRMJTime prtm = ToPRMJTime(localTime, utcTime); + PRMJTime prtm = toPRMJTime(localTime, utcTime); // If an equivalent year was used to compute the date/time components, use // the same equivalent year to determine the time zone name and offset in // PRMJ_FormatTime(...). - int timeZoneYear = IsRepresentableAsTime32(utcTime) + int timeZoneYear = isRepresentableAsTime32(utcTime) ? prtm.tm_year - : EquivalentYearForDST(prtm.tm_year); + : equivalentYearForDST(prtm.tm_year); int offsetInSeconds = (int) floor((localTime - utcTime) / msPerSecond); return PRMJ_FormatTime(buf, buflen, fmt, &prtm, timeZoneYear, offsetInSeconds); } -static JSString* -TimeZoneComment(JSContext* cx, double utcTime, double localTime) +JSString* +DateTimeHelper::timeZoneComment(JSContext* cx, double utcTime, double localTime) { char tzbuf[100]; - size_t tzlen = FormatTime(tzbuf, sizeof tzbuf, " (%Z)", utcTime, localTime); + size_t tzlen = formatTime(tzbuf, sizeof tzbuf, " (%Z)", utcTime, localTime); if (tzlen != 0) { // Decide whether to use the resulting time zone string. // @@ -2816,6 +2855,12 @@ TimeZoneComment(JSContext* cx, double utcTime, double localTime) } #endif /* ENABLE_INTL_API && !MOZ_SYSTEM_ICU */ +static JSString* +TimeZoneComment(JSContext* cx, double utcTime, double localTime) +{ + return DateTimeHelper::timeZoneComment(cx, utcTime, localTime); +} + enum class FormatSpec { DateTime, Date, @@ -2924,7 +2969,7 @@ ToLocaleFormatHelper(JSContext* cx, HandleObject obj, const char* format, Mutabl double localTime = LocalTime(utcTime); /* Let PRMJTime format it. */ - size_t result_len = FormatTime(buf, sizeof buf, format, utcTime, localTime); + size_t result_len = DateTimeHelper::formatTime(buf, sizeof buf, format, utcTime, localTime); /* If it failed, default to toString. */ if (result_len == 0) diff --git a/js/src/vm/BytecodeUtil.cpp b/js/src/vm/BytecodeUtil.cpp index b7235a682d1a..d82c69e72fc3 100644 --- a/js/src/vm/BytecodeUtil.cpp +++ b/js/src/vm/BytecodeUtil.cpp @@ -2258,7 +2258,7 @@ DecompileExpressionFromStack(JSContext* cx, int spindex, int skipStackHits, Hand FrameIter frameIter(cx); - if (frameIter.done() || !frameIter.hasScript() || frameIter.compartment() != cx->compartment()) + if (frameIter.done() || !frameIter.hasScript() || frameIter.realm() != cx->realm()) return true; /* @@ -2348,7 +2348,7 @@ DecompileArgumentFromStack(JSContext* cx, int formalIndex, UniqueChars* res) if (frameIter.done() || !frameIter.hasScript() || frameIter.script()->selfHosted() || - frameIter.compartment() != cx->compartment()) + frameIter.realm() != cx->realm()) { return true; } diff --git a/js/src/wasm/WasmAST.h b/js/src/wasm/WasmAST.h index 119b2d467bc2..b30e0e0bc9ba 100644 --- a/js/src/wasm/WasmAST.h +++ b/js/src/wasm/WasmAST.h @@ -1233,9 +1233,6 @@ class AstModule : public AstNode NameVector funcImportNames_; AstResizableVector tables_; AstResizableVector memories_; -#ifdef ENABLE_WASM_GC - uint32_t gcFeatureOptIn_; -#endif ExportVector exports_; Maybe startFunc_; FuncVector funcs_; @@ -1254,9 +1251,6 @@ class AstModule : public AstNode funcImportNames_(lifo), tables_(lifo), memories_(lifo), -#ifdef ENABLE_WASM_GC - gcFeatureOptIn_(0), -#endif exports_(lifo), funcs_(lifo), dataSegments_(lifo), @@ -1273,15 +1267,6 @@ class AstModule : public AstNode const AstResizableVector& memories() const { return memories_; } -#ifdef ENABLE_WASM_GC - bool addGcFeatureOptIn(uint32_t version) { - gcFeatureOptIn_ = version; - return true; - } - uint32_t gcFeatureOptIn() const { - return gcFeatureOptIn_; - } -#endif bool addTable(AstName name, const Limits& table) { return tables_.append(AstResizable(table, false, name)); } diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp index ac38143eec95..350191905976 100644 --- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -9967,12 +9967,12 @@ BaseCompiler::emitBody() #ifdef ENABLE_WASM_GC case uint16_t(Op::RefNull): - if (env_.gcTypesEnabled() == HasGcTypes::False) + if (env_.gcTypesEnabled == HasGcTypes::False) return iter_.unrecognizedOpcode(&op); CHECK_NEXT(emitRefNull()); break; case uint16_t(Op::RefIsNull): - if (env_.gcTypesEnabled() == HasGcTypes::False) + if (env_.gcTypesEnabled == HasGcTypes::False) return iter_.unrecognizedOpcode(&op); CHECK_NEXT(emitConversion(emitRefIsNull, ValType::AnyRef, ValType::I32)); break; @@ -10375,7 +10375,7 @@ js::wasm::BaselineCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo ValTypeVector locals; if (!locals.appendAll(env.funcTypes[func.index]->args())) return false; - if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled(), &locals)) + if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled, &locals)) return false; // One-pass baseline compilation. diff --git a/js/src/wasm/WasmBinaryConstants.h b/js/src/wasm/WasmBinaryConstants.h index f84a8b2b7e77..8c9e03969e74 100644 --- a/js/src/wasm/WasmBinaryConstants.h +++ b/js/src/wasm/WasmBinaryConstants.h @@ -38,10 +38,7 @@ enum class SectionId Start = 8, Elem = 9, Code = 10, - Data = 11, -#ifdef ENABLE_WASM_GC - GcFeatureOptIn = 42 // Arbitrary, but fits in 7 bits -#endif + Data = 11 }; enum class TypeCode diff --git a/js/src/wasm/WasmCode.cpp b/js/src/wasm/WasmCode.cpp index 6064ba67d769..98040946e149 100644 --- a/js/src/wasm/WasmCode.cpp +++ b/js/src/wasm/WasmCode.cpp @@ -695,7 +695,7 @@ struct ProjectLazyFuncIndex static constexpr unsigned LAZY_STUB_LIFO_DEFAULT_CHUNK_SIZE = 8 * 1024; bool -LazyStubTier::createMany(HasGcTypes gcTypesConfigured, const Uint32Vector& funcExportIndices, +LazyStubTier::createMany(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, const CodeTier& codeTier, size_t* stubSegmentIndex) { MOZ_ASSERT(funcExportIndices.length()); @@ -719,7 +719,7 @@ LazyStubTier::createMany(HasGcTypes gcTypesConfigured, const Uint32Vector& funcE Maybe callee; callee.emplace(calleePtr, ImmPtr::NoCheckToken()); if (!GenerateEntryStubs(masm, funcExportIndex, fe, callee, /* asmjs */ false, - gcTypesConfigured, &codeRanges)) + gcTypesEnabled, &codeRanges)) { return false; } @@ -801,7 +801,7 @@ LazyStubTier::createOne(uint32_t funcExportIndex, const CodeTier& codeTier) return false; size_t stubSegmentIndex; - if (!createMany(codeTier.code().metadata().temporaryGcTypesConfigured, funcExportIndexes, codeTier, + if (!createMany(codeTier.code().metadata().temporaryHasGcTypes, funcExportIndexes, codeTier, &stubSegmentIndex)) { return false; @@ -828,14 +828,14 @@ LazyStubTier::createOne(uint32_t funcExportIndex, const CodeTier& codeTier) } bool -LazyStubTier::createTier2(HasGcTypes gcTypesConfigured, const Uint32Vector& funcExportIndices, +LazyStubTier::createTier2(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, const CodeTier& codeTier, Maybe* outStubSegmentIndex) { if (!funcExportIndices.length()) return true; size_t stubSegmentIndex; - if (!createMany(gcTypesConfigured, funcExportIndices, codeTier, &stubSegmentIndex)) + if (!createMany(gcTypesEnabled, funcExportIndices, codeTier, &stubSegmentIndex)) return false; outStubSegmentIndex->emplace(stubSegmentIndex); diff --git a/js/src/wasm/WasmCode.h b/js/src/wasm/WasmCode.h index 0c0120f4dd6f..89674a12ef75 100644 --- a/js/src/wasm/WasmCode.h +++ b/js/src/wasm/WasmCode.h @@ -409,7 +409,7 @@ struct MetadataCacheablePod { ModuleKind kind; MemoryUsage memoryUsage; - HasGcTypes temporaryGcTypesConfigured; + HasGcTypes temporaryHasGcTypes; uint32_t minMemoryLength; uint32_t globalDataLength; Maybe maxMemoryLength; @@ -420,7 +420,7 @@ struct MetadataCacheablePod explicit MetadataCacheablePod(ModuleKind kind) : kind(kind), memoryUsage(MemoryUsage::None), - temporaryGcTypesConfigured(HasGcTypes::False), + temporaryHasGcTypes(HasGcTypes::False), minMemoryLength(0), globalDataLength(0), filenameIsURL(false) @@ -617,7 +617,7 @@ class LazyStubTier // them in a single stub. Jit entries won't be used until // setJitEntries() is actually called, after the Code owner has committed // tier2. - bool createTier2(HasGcTypes gcTypesConfigured, const Uint32Vector& funcExportIndices, + bool createTier2(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, const CodeTier& codeTier, Maybe* stubSegmentIndex); void setJitEntries(const Maybe& stubSegmentIndex, const Code& code); diff --git a/js/src/wasm/WasmCompile.cpp b/js/src/wasm/WasmCompile.cpp index 467981933450..0b3bfc250af1 100644 --- a/js/src/wasm/WasmCompile.cpp +++ b/js/src/wasm/WasmCompile.cpp @@ -84,7 +84,7 @@ CompileArgs::CompileArgs(JSContext* cx, ScriptedCaller&& scriptedCaller) baselineEnabled = cx->options().wasmBaseline() || gcEnabled; ionEnabled = cx->options().wasmIon() && !gcEnabled; sharedMemoryEnabled = cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled(); - gcTypesConfigured = gcEnabled ? HasGcTypes::True : HasGcTypes::False; + gcTypesEnabled = gcEnabled ? HasGcTypes::True : HasGcTypes::False; testTiering = (cx->options().testWasmAwaitTier2() || JitOptions.wasmDelayTier2) && !gcEnabled; // Debug information such as source view or debug traps will require @@ -467,7 +467,7 @@ wasm::CompileBuffer(const CompileArgs& args, const ShareableBytes& bytecode, Uni DebugEnabled debug; InitialCompileFlags(args, d, &mode, &tier, &debug); - ModuleEnvironment env(mode, tier, debug, args.gcTypesConfigured, + ModuleEnvironment env(mode, tier, debug, args.gcTypesEnabled, args.sharedMemoryEnabled ? Shareable::True : Shareable::False); if (!DecodeModuleEnvironment(d, &env)) return nullptr; @@ -493,7 +493,7 @@ wasm::CompileTier2(const CompileArgs& args, Module& module, Atomic* cancel UniqueChars error; Decoder d(module.bytecode().bytes, 0, &error); - MOZ_ASSERT(args.gcTypesConfigured == HasGcTypes::False, "can't ion-compile with gc types yet"); + MOZ_ASSERT(args.gcTypesEnabled == HasGcTypes::False, "can't ion-compile with gc types yet"); ModuleEnvironment env(CompileMode::Tier2, Tier::Ion, DebugEnabled::False, HasGcTypes::False, args.sharedMemoryEnabled ? Shareable::True : Shareable::False); @@ -622,7 +622,7 @@ wasm::CompileStreaming(const CompileArgs& args, DebugEnabled debug; InitialCompileFlags(args, d, &mode, &tier, &debug); - env.emplace(mode, tier, debug, args.gcTypesConfigured, + env.emplace(mode, tier, debug, args.gcTypesEnabled, args.sharedMemoryEnabled ? Shareable::True : Shareable::False); if (!DecodeModuleEnvironment(d, env.ptr())) return nullptr; diff --git a/js/src/wasm/WasmCompile.h b/js/src/wasm/WasmCompile.h index 7c05c06e0ac2..bb6346f0878b 100644 --- a/js/src/wasm/WasmCompile.h +++ b/js/src/wasm/WasmCompile.h @@ -52,7 +52,7 @@ struct CompileArgs : ShareableBase bool debugEnabled; bool ionEnabled; bool sharedMemoryEnabled; - HasGcTypes gcTypesConfigured; + HasGcTypes gcTypesEnabled; bool testTiering; explicit CompileArgs(ScriptedCaller&& scriptedCaller) @@ -61,7 +61,7 @@ struct CompileArgs : ShareableBase debugEnabled(false), ionEnabled(false), sharedMemoryEnabled(false), - gcTypesConfigured(HasGcTypes::False), + gcTypesEnabled(HasGcTypes::False), testTiering(false) {} diff --git a/js/src/wasm/WasmGenerator.cpp b/js/src/wasm/WasmGenerator.cpp index ba382c129674..3b96177aa060 100644 --- a/js/src/wasm/WasmGenerator.cpp +++ b/js/src/wasm/WasmGenerator.cpp @@ -829,7 +829,7 @@ ModuleGenerator::finishMetadata(const ShareableBytes& bytecode) // Copy over data from the ModuleEnvironment. metadata_->memoryUsage = env_->memoryUsage; - metadata_->temporaryGcTypesConfigured = env_->gcTypesConfigured; + metadata_->temporaryHasGcTypes = env_->gcTypesEnabled; metadata_->minMemoryLength = env_->minMemoryLength; metadata_->maxMemoryLength = env_->maxMemoryLength; metadata_->startFuncIndex = env_->startFuncIndex; diff --git a/js/src/wasm/WasmIonCompile.cpp b/js/src/wasm/WasmIonCompile.cpp index 8bee71b6b009..9a40a9133dad 100644 --- a/js/src/wasm/WasmIonCompile.cpp +++ b/js/src/wasm/WasmIonCompile.cpp @@ -3503,7 +3503,7 @@ wasm::IonCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo, ValTypeVector locals; if (!locals.appendAll(env.funcTypes[func.index]->args())) return false; - if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled(), &locals)) + if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled, &locals)) return false; // Set up for Ion compilation. diff --git a/js/src/wasm/WasmModule.cpp b/js/src/wasm/WasmModule.cpp index c929abcd4bd4..b2f026b6bacc 100644 --- a/js/src/wasm/WasmModule.cpp +++ b/js/src/wasm/WasmModule.cpp @@ -120,11 +120,11 @@ Module::finishTier2(const LinkData& linkData, UniqueCodeTier tier2Arg, ModuleEnv return false; } - HasGcTypes gcTypesConfigured = code().metadata().temporaryGcTypesConfigured; + HasGcTypes gcTypesEnabled = code().metadata().temporaryHasGcTypes; const CodeTier& tier2 = code().codeTier(Tier::Ion); Maybe stub2Index; - if (!stubs2->createTier2(gcTypesConfigured, funcExportIndices, tier2, &stub2Index)) + if (!stubs2->createTier2(gcTypesEnabled, funcExportIndices, tier2, &stub2Index)) return false; // Now that we can't fail or otherwise abort tier2, make it live. diff --git a/js/src/wasm/WasmOpIter.h b/js/src/wasm/WasmOpIter.h index 23ab09e3ecd4..c91e70050878 100644 --- a/js/src/wasm/WasmOpIter.h +++ b/js/src/wasm/WasmOpIter.h @@ -632,7 +632,7 @@ OpIter::Unify(StackType observed, StackType expected, StackType* result) return true; } - if (env_.gcTypesEnabled() == HasGcTypes::True && observed.isRefOrAnyRef() && + if (env_.gcTypesEnabled == HasGcTypes::True && observed.isRefOrAnyRef() && expected.isRefOrAnyRef() && IsSubtypeOf(observed, expected)) { *result = expected; @@ -661,7 +661,7 @@ OpIter::Join(StackType one, StackType two, StackType* result) return true; } - if (env_.gcTypesEnabled() == HasGcTypes::True && one.isRefOrAnyRef() && two.isRefOrAnyRef()) { + if (env_.gcTypesEnabled == HasGcTypes::True && one.isRefOrAnyRef() && two.isRefOrAnyRef()) { if (IsSubtypeOf(two, one)) { *result = one; return true; @@ -901,12 +901,12 @@ OpIter::readBlockType(ExprType* type) known = true; break; case uint8_t(ExprType::Ref): - known = env_.gcTypesEnabled() == HasGcTypes::True && + known = env_.gcTypesEnabled == HasGcTypes::True && uncheckedRefTypeIndex < MaxTypes && uncheckedRefTypeIndex < env_.types.length(); break; case uint8_t(ExprType::AnyRef): - known = env_.gcTypesEnabled() == HasGcTypes::True; + known = env_.gcTypesEnabled == HasGcTypes::True; break; case uint8_t(ExprType::Limit): break; diff --git a/js/src/wasm/WasmStubs.cpp b/js/src/wasm/WasmStubs.cpp index 83ce430faa5c..bcac21b76430 100644 --- a/js/src/wasm/WasmStubs.cpp +++ b/js/src/wasm/WasmStubs.cpp @@ -297,7 +297,7 @@ CallFuncExport(MacroAssembler& masm, const FuncExport& fe, const Maybe& // must map from the ABI of ExportFuncPtr to the export's signature's ABI. static bool GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe, const Maybe& funcPtr, - HasGcTypes gcTypesConfigured, Offsets* offsets) + HasGcTypes gcTypesEnabled, Offsets* offsets) { AssertExpectedSP(masm); masm.haltingAlign(CodeAlignment); @@ -352,7 +352,7 @@ GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe, const Maybe& funcPtr, HasGcTypes gcTypesConfigured, Offsets* offsets) + const Maybe& funcPtr, HasGcTypes gcTypesEnabled, Offsets* offsets) { AssertExpectedSP(masm); @@ -732,7 +732,7 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& masm.loadWasmPinnedRegsFromTls(); #ifdef ENABLE_WASM_GC - if (gcTypesConfigured == HasGcTypes::True) { + if (gcTypesEnabled == HasGcTypes::True) { masm.storePtr(WasmTlsReg, Address(sp, savedTlsOffset)); SuppressGC(masm, 1, ScratchIonEntry); } @@ -745,7 +745,7 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& masm.assertStackAlignment(WasmStackAlignment); #ifdef ENABLE_WASM_GC - if (gcTypesConfigured == HasGcTypes::True) { + if (gcTypesEnabled == HasGcTypes::True) { masm.loadPtr(Address(sp, savedTlsOffset), WasmTlsReg); SuppressGC(masm, -1, WasmTlsReg); } @@ -1848,14 +1848,14 @@ GenerateDebugTrapStub(MacroAssembler& masm, Label* throwLabel, CallableOffsets* bool wasm::GenerateEntryStubs(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& fe, - const Maybe& callee, bool isAsmJS, HasGcTypes gcTypesConfigured, + const Maybe& callee, bool isAsmJS, HasGcTypes gcTypesEnabled, CodeRangeVector* codeRanges) { MOZ_ASSERT(!callee == fe.hasEagerStubs()); MOZ_ASSERT_IF(isAsmJS, fe.hasEagerStubs()); Offsets offsets; - if (!GenerateInterpEntry(masm, fe, callee, gcTypesConfigured, &offsets)) + if (!GenerateInterpEntry(masm, fe, callee, gcTypesEnabled, &offsets)) return false; if (!codeRanges->emplaceBack(CodeRange::InterpEntry, fe.funcIndex(), offsets)) return false; @@ -1863,7 +1863,7 @@ wasm::GenerateEntryStubs(MacroAssembler& masm, size_t funcExportIndex, const Fun if (isAsmJS || fe.funcType().temporarilyUnsupportedAnyRef()) return true; - if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, gcTypesConfigured, &offsets)) + if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, gcTypesEnabled, &offsets)) return false; if (!codeRanges->emplaceBack(CodeRange::JitEntry, fe.funcIndex(), offsets)) return false; @@ -1914,7 +1914,7 @@ wasm::GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& import if (!fe.hasEagerStubs()) continue; if (!GenerateEntryStubs(masm, i, fe, noAbsolute, env.isAsmJS(), - env.gcTypesConfigured, &code->codeRanges)) + env.gcTypesEnabled, &code->codeRanges)) { return false; } diff --git a/js/src/wasm/WasmStubs.h b/js/src/wasm/WasmStubs.h index 0990ae98b35d..20655577ec82 100644 --- a/js/src/wasm/WasmStubs.h +++ b/js/src/wasm/WasmStubs.h @@ -39,7 +39,7 @@ GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& imports, extern bool GenerateEntryStubs(jit::MacroAssembler& masm, size_t funcExportIndex, const FuncExport& funcExport, const Maybe& callee, - bool isAsmJS, HasGcTypes gcTypesConfigured, CodeRangeVector* codeRanges); + bool isAsmJS, HasGcTypes gcTypesEnabled, CodeRangeVector* codeRanges); // An argument that will end up on the stack according to the system ABI, to be // passed to GenerateDirectCallFromJit. Since the direct JIT call creates its diff --git a/js/src/wasm/WasmTextToBinary.cpp b/js/src/wasm/WasmTextToBinary.cpp index 6f78c29758bd..8d4b41c15a52 100644 --- a/js/src/wasm/WasmTextToBinary.cpp +++ b/js/src/wasm/WasmTextToBinary.cpp @@ -97,9 +97,6 @@ class WasmToken Field, Float, Func, -#ifdef ENABLE_WASM_GC - GcFeatureOptIn, -#endif GetGlobal, GetLocal, Global, @@ -375,9 +372,6 @@ class WasmToken case Field: case Float: case Func: -#ifdef ENABLE_WASM_GC - case GcFeatureOptIn: -#endif case Global: case Mutable: case Import: @@ -1176,8 +1170,6 @@ WasmTokenStream::next() break; case 'g': - if (consume(u"gc_feature_opt_in")) - return WasmToken(WasmToken::GcFeatureOptIn, begin, cur_); if (consume(u"get_global")) return WasmToken(WasmToken::GetGlobal, begin, cur_); if (consume(u"get_local")) @@ -3631,28 +3623,6 @@ ParseMemory(WasmParseContext& c, AstModule* module) return module->addMemory(name, memory); } -#ifdef ENABLE_WASM_GC -// Custom section for experimental work. The size of this section should always -// be 1 byte, and that byte is a nonzero varint7 carrying the version number -// being opted into. -static bool -ParseGcFeatureOptIn(WasmParseContext& c, AstModule* module) -{ - WasmToken token; - if (!c.ts.getIf(WasmToken::Index, &token)) { - c.ts.generateError(token, "GC feature version number required", c.error); - return false; - } - - if (token.index() == 0 || token.index() > 127) { - c.ts.generateError(token, "invalid GC feature version number", c.error); - return false; - } - - return module->addGcFeatureOptIn(token.index()); -} -#endif - static bool ParseStartFunc(WasmParseContext& c, WasmToken token, AstModule* module) { @@ -4090,13 +4060,6 @@ ParseModule(const char16_t* text, uintptr_t stackLimit, LifoAlloc& lifo, UniqueC return nullptr; break; } -#ifdef ENABLE_WASM_GC - case WasmToken::GcFeatureOptIn: { - if (!ParseGcFeatureOptIn(c, module)) - return nullptr; - break; - } -#endif case WasmToken::Global: { if (!ParseGlobal(c, module)) return nullptr; @@ -5405,26 +5368,6 @@ EncodeExpr(Encoder& e, AstExpr& expr) /*****************************************************************************/ // wasm AST binary serialization -#ifdef ENABLE_WASM_GC -static bool -EncodeGcFeatureOptInSection(Encoder& e, AstModule& module) -{ - uint32_t optInVersion = module.gcFeatureOptIn(); - if (!optInVersion) - return true; - - size_t offset; - if (!e.startSection(SectionId::GcFeatureOptIn, &offset)) - return false; - - if (!e.writeVarU32(optInVersion)) - return false; - - e.finishSection(offset); - return true; -} -#endif - static bool EncodeTypeSection(Encoder& e, AstModule& module) { @@ -5915,11 +5858,6 @@ EncodeModule(AstModule& module, Uint32Vector* offsets, Bytes* bytes) if (!e.writeFixedU32(EncodingVersion)) return false; -#ifdef ENABLE_WASM_GC - if (!EncodeGcFeatureOptInSection(e, module)) - return false; -#endif - if (!EncodeTypeSection(e, module)) return false; diff --git a/js/src/wasm/WasmValidate.cpp b/js/src/wasm/WasmValidate.cpp index 0b38661f496d..c42a1a6a71c1 100644 --- a/js/src/wasm/WasmValidate.cpp +++ b/js/src/wasm/WasmValidate.cpp @@ -397,12 +397,12 @@ DecodeValType(Decoder& d, ModuleKind kind, uint32_t numTypes, HasGcTypes gcTypes return true; case uint8_t(ValType::AnyRef): if (gcTypesEnabled == HasGcTypes::False) - return d.fail("reference types not enabled"); + break; *type = ValType(ValType::Code(uncheckedCode)); return true; case uint8_t(ValType::Ref): { if (gcTypesEnabled == HasGcTypes::False) - return d.fail("reference types not enabled"); + break; if (uncheckedRefTypeIndex >= numTypes) return d.fail("ref index out of range"); // We further validate ref types in the caller. @@ -863,14 +863,14 @@ DecodeFunctionBodyExprs(const ModuleEnvironment& env, const FuncType& funcType, } #ifdef ENABLE_WASM_GC case uint16_t(Op::RefNull): { - if (env.gcTypesEnabled() == HasGcTypes::False) + if (env.gcTypesEnabled == HasGcTypes::False) return iter.unrecognizedOpcode(&op); ValType unusedType; CHECK(iter.readRefNull(&unusedType)); break; } case uint16_t(Op::RefIsNull): { - if (env.gcTypesEnabled() == HasGcTypes::False) + if (env.gcTypesEnabled == HasGcTypes::False) return iter.unrecognizedOpcode(&op); CHECK(iter.readConversion(ValType::AnyRef, ValType::I32, ¬hing)); break; @@ -1070,7 +1070,7 @@ wasm::ValidateFunctionBody(const ModuleEnvironment& env, uint32_t funcIndex, uin const uint8_t* bodyBegin = d.currentPosition(); - if (!DecodeLocalEntries(d, ModuleKind::Wasm, env.types, env.gcTypesEnabled(), &locals)) + if (!DecodeLocalEntries(d, ModuleKind::Wasm, env.types, env.gcTypesEnabled, &locals)) return false; if (!DecodeFunctionBodyExprs(env, funcType, locals, bodyBegin + bodySize, &d)) @@ -1154,7 +1154,7 @@ DecodeFuncType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, u return false; for (uint32_t i = 0; i < numArgs; i++) { - if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled(), &args[i])) + if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled, &args[i])) return false; if (!ValidateRefType(d, typeState, args[i])) return false; @@ -1171,7 +1171,7 @@ DecodeFuncType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, u if (numRets == 1) { ValType type; - if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled(), &type)) + if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled, &type)) return false; if (!ValidateRefType(d, typeState, type)) return false; @@ -1191,7 +1191,7 @@ DecodeFuncType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, u static bool DecodeStructType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, uint32_t typeIndex) { - if (env->gcTypesEnabled() == HasGcTypes::False) + if (env->gcTypesEnabled == HasGcTypes::False) return d.fail("Structure types not enabled"); uint32_t numFields; @@ -1214,7 +1214,7 @@ DecodeStructType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, if ((flags & ~uint8_t(FieldFlags::AllowedMask)) != 0) return d.fail("garbage flag bits"); fields[i].isMutable = flags & uint8_t(FieldFlags::Mutable); - if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled(), &fields[i].type)) + if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled, &fields[i].type)) return false; if (!ValidateRefType(d, typeState, fields[i].type)) return false; @@ -1229,34 +1229,6 @@ DecodeStructType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, return true; } -#ifdef ENABLE_WASM_GC -static bool -DecodeGCFeatureOptInSection(Decoder& d, ModuleEnvironment* env) -{ - MaybeSectionRange range; - if (!d.startSection(SectionId::GcFeatureOptIn, env, &range, "type")) - return false; - if (!range) - return true; - - uint32_t version; - if (!d.readVarU32(&version)) - return d.fail("expected gc feature version"); - - // For documentation of what's in the various versions, see - // https://github.com/lars-t-hansen/moz-gc-experiments - // - // When we evolve the engine to handle v2, we will continue to recognize v1 - // here if v2 is fully backwards compatible with v1. - - if (version != 1) - return d.fail("unsupported version of the gc feature"); - - env->gcFeatureOptIn = HasGcTypes::True; - return d.finishSection(*range, "gcfeatureoptin"); -} -#endif - static bool DecodeTypeSection(Decoder& d, ModuleEnvironment* env) { @@ -1564,7 +1536,7 @@ DecodeImport(Decoder& d, ModuleEnvironment* env) case DefinitionKind::Global: { ValType type; bool isMutable; - if (!DecodeGlobalType(d, env->types, env->gcTypesEnabled(), &type, &isMutable)) + if (!DecodeGlobalType(d, env->types, env->gcTypesEnabled, &type, &isMutable)) return false; if (!GlobalIsJSCompatible(d, type, isMutable)) return false; @@ -1796,11 +1768,11 @@ DecodeGlobalSection(Decoder& d, ModuleEnvironment* env) for (uint32_t i = 0; i < numDefs; i++) { ValType type; bool isMutable; - if (!DecodeGlobalType(d, env->types, env->gcTypesEnabled(), &type, &isMutable)) + if (!DecodeGlobalType(d, env->types, env->gcTypesEnabled, &type, &isMutable)) return false; InitExpr initializer; - if (!DecodeInitializerExpression(d, env->gcTypesEnabled(), env->globals, type, + if (!DecodeInitializerExpression(d, env->gcTypesEnabled, env->globals, type, env->types.length(), &initializer)) { return false; @@ -1989,7 +1961,7 @@ DecodeElemSection(Decoder& d, ModuleEnvironment* env) return d.fail("table index out of range"); InitExpr offset; - if (!DecodeInitializerExpression(d, env->gcTypesEnabled(), env->globals, ValType::I32, + if (!DecodeInitializerExpression(d, env->gcTypesEnabled, env->globals, ValType::I32, env->types.length(), &offset)) { return false; @@ -2069,11 +2041,6 @@ wasm::DecodeModuleEnvironment(Decoder& d, ModuleEnvironment* env) if (!DecodePreamble(d)) return false; -#ifdef ENABLE_WASM_GC - if (!DecodeGCFeatureOptInSection(d, env)) - return false; -#endif - if (!DecodeTypeSection(d, env)) return false; @@ -2181,7 +2148,7 @@ DecodeDataSection(Decoder& d, ModuleEnvironment* env) return d.fail("data segment requires a memory section"); DataSegment seg; - if (!DecodeInitializerExpression(d, env->gcTypesEnabled(), env->globals, ValType::I32, + if (!DecodeInitializerExpression(d, env->gcTypesEnabled, env->globals, ValType::I32, env->types.length(), &seg.offset)) { return false; diff --git a/js/src/wasm/WasmValidate.h b/js/src/wasm/WasmValidate.h index dbab1135d7d5..0906e7cba75e 100644 --- a/js/src/wasm/WasmValidate.h +++ b/js/src/wasm/WasmValidate.h @@ -60,30 +60,11 @@ struct ModuleEnvironment const ModuleKind kind; const CompileMode mode; const Shareable sharedMemoryEnabled; - // `gcTypesConfigured` reflects the value of the flags --wasm-gc and - // javascript.options.wasm_gc. These flags will disappear eventually, thus - // allowing the removal of this variable and its replacement everywhere by - // the value HasGcTypes::True. - // - // For now, the value is used (a) in the value of gcTypesEnabled(), which - // controls whether ref types and struct types and associated instructions - // are accepted during validation, and (b) to control whether we emit code - // to suppress GC while wasm activations are on the stack. - const HasGcTypes gcTypesConfigured; + const HasGcTypes gcTypesEnabled; const Tier tier; // Module fields decoded from the module environment (or initialized while // validating an asm.js module) and immutable during compilation: -#ifdef ENABLE_WASM_GC - // `gcFeatureOptIn` reflects the presence in a module of a GcFeatureOptIn - // section. This variable will be removed eventually, allowing it to be - // replaced everywhere by the value HasGcTypes::True. - // - // The flag is used in the value of gcTypesEnabled(), which controls whether - // ref types and struct types and associated instructions are accepted - // during validation. - HasGcTypes gcFeatureOptIn; -#endif MemoryUsage memoryUsage; uint32_t minMemoryLength; Maybe maxMemoryLength; @@ -115,11 +96,8 @@ struct ModuleEnvironment kind(kind), mode(mode), sharedMemoryEnabled(sharedMemoryEnabled), - gcTypesConfigured(hasGcTypes), + gcTypesEnabled(hasGcTypes), tier(tier), -#ifdef ENABLE_WASM_GC - gcFeatureOptIn(HasGcTypes::False), -#endif memoryUsage(MemoryUsage::None), minMemoryLength(0) {} @@ -139,13 +117,6 @@ struct ModuleEnvironment size_t numFuncDefs() const { return funcTypes.length() - funcImportGlobalDataOffsets.length(); } -#ifdef ENABLE_WASM_GC - HasGcTypes gcTypesEnabled() const { - if (gcTypesConfigured == HasGcTypes::True) - return gcFeatureOptIn; - return HasGcTypes::False; - } -#endif bool usesMemory() const { return memoryUsage != MemoryUsage::None; } @@ -358,7 +329,6 @@ class Encoder // after the section length is the string id of the section. MOZ_MUST_USE bool startSection(SectionId id, size_t* offset) { - MOZ_ASSERT(uint32_t(id) < 128); return writeVarU32(uint32_t(id)) && writePatchableVarU32(offset); } diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index 47887d0c6926..cb82121f6997 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -551,28 +551,49 @@ XPCJSContext::GetWatchdogTimestamp(WatchdogTimestampCategory aCategory) mWatchdogManager->GetTimestamp(aCategory, lock); } -void -xpc::SimulateActivityCallback(bool aActive) -{ - XPCJSContext::ActivityCallback(XPCJSContext::Get(), aActive); -} - // static -void -XPCJSContext::ActivityCallback(void* arg, bool active) +bool +XPCJSContext::RecordScriptActivity(bool aActive) { + MOZ_ASSERT(NS_IsMainThread()); + + XPCJSContext* xpccx = XPCJSContext::Get(); + if (!xpccx) { + // mozilla::SpinEventLoopUntil may use AutoScriptActivity(false) after + // we destroyed the XPCJSContext. + MOZ_ASSERT(!aActive); + return false; + } + + bool oldValue = xpccx->SetHasScriptActivity(aActive); + if (aActive == oldValue) { + // Nothing to do. + return oldValue; + } + // Since the slow script dialog never activates if we are recording or // replaying, don't record/replay JS activity notifications. if (recordreplay::IsRecordingOrReplaying()) { - return; + return oldValue; } - if (!active) { + if (!aActive) { ProcessHangMonitor::ClearHang(); } + xpccx->mWatchdogManager->RecordContextActivity(xpccx, aActive); - XPCJSContext* self = static_cast(arg); - self->mWatchdogManager->RecordContextActivity(self, active); + return oldValue; +} + +AutoScriptActivity::AutoScriptActivity(bool aActive) + : mActive(aActive) + , mOldValue(XPCJSContext::RecordScriptActivity(aActive)) +{ +} + +AutoScriptActivity::~AutoScriptActivity() +{ + MOZ_ALWAYS_TRUE(mActive == XPCJSContext::RecordScriptActivity(mOldValue)); } // static @@ -890,8 +911,6 @@ XPCJSContext::~XPCJSContext() Preferences::UnregisterCallback(ReloadPrefsCallback, "fuzzing.enabled", this); #endif - js::SetActivityCallback(Context(), nullptr, nullptr); - // Clear any pending exception. It might be an XPCWrappedJS, and if we try // to destroy it later we will crash. SetPendingException(nullptr); @@ -926,6 +945,7 @@ XPCJSContext::XPCJSContext() mWatchdogManager(GetWatchdogManager()), mSlowScriptSecondHalf(false), mTimeoutAccumulated(false), + mHasScriptActivity(false), mPendingResult(NS_OK), mActive(CONTEXT_INACTIVE), mLastStateChange(PR_Now()) @@ -1140,7 +1160,6 @@ XPCJSContext::Initialize(XPCJSContext* aPrimaryContext) PROFILER_SET_JS_CONTEXT(cx); - js::SetActivityCallback(cx, ActivityCallback, this); JS_AddInterruptCallback(cx, InterruptCallback); if (!aPrimaryContext) { diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp index 9082b82a5e9c..4917acecf6e3 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -590,15 +590,21 @@ SetInterruptCallback(JSContext* cx, unsigned argc, Value* vp) } static bool -SimulateActivityCallback(JSContext* cx, unsigned argc, Value* vp) +SimulateNoScriptActivity(JSContext* cx, unsigned argc, Value* vp) { // Sanity-check args. JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - if (args.length() != 1 || !args[0].isBoolean()) { - JS_ReportErrorASCII(cx, "Wrong number of arguments"); + if (args.length() != 1 || !args[0].isInt32() || args[0].toInt32() < 0) { + JS_ReportErrorASCII(cx, "Expected a positive integer argument"); return false; } - xpc::SimulateActivityCallback(args[0].toBoolean()); + + // This mimics mozilla::SpinEventLoopUntil but instead of spinning the + // event loop we sleep, to make sure we don't run script. + xpc::AutoScriptActivity asa(false); + PR_Sleep(PR_SecondsToInterval(args[0].toInt32())); + + args.rval().setUndefined(); return true; } @@ -665,7 +671,7 @@ static const JSFunctionSpec glob_functions[] = { JS_FN("atob", xpc::Atob, 1,0), JS_FN("btoa", xpc::Btoa, 1,0), JS_FN("setInterruptCallback", SetInterruptCallback, 1,0), - JS_FN("simulateActivityCallback", SimulateActivityCallback, 1,0), + JS_FN("simulateNoScriptActivity", SimulateNoScriptActivity, 1,0), JS_FN("registerAppManifest", RegisterAppManifest, 1, 0), #ifdef ENABLE_TESTS JS_FN("registerXPCTestComponents", RegisterXPCTestComponents, 0, 0), diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 3051788c5c0f..13893e20b648 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -373,7 +373,14 @@ public: PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory); - static void ActivityCallback(void* arg, bool active); + static bool RecordScriptActivity(bool aActive); + + bool SetHasScriptActivity(bool aActive) { + bool oldValue = mHasScriptActivity; + mHasScriptActivity = aActive; + return oldValue; + } + static bool InterruptCallback(JSContext* cx); // Mapping of often used strings to jsid atoms that live 'forever'. @@ -461,6 +468,8 @@ private: mozilla::TimeDuration mSlowScriptActualWait; bool mTimeoutAccumulated; + bool mHasScriptActivity; + // mPendingResult is used to implement Components.returnCode. Only really // meaningful while calling through XPCWrappedJS. nsresult mPendingResult; diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index e67eafbf4c5b..9b501524b503 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -550,8 +550,14 @@ WindowGlobalOrNull(JSObject* aObj); nsGlobalWindowInner* CurrentWindowOrNull(JSContext* cx); -void -SimulateActivityCallback(bool aActive); +class MOZ_RAII AutoScriptActivity +{ + bool mActive; + bool mOldValue; + public: + explicit AutoScriptActivity(bool aActive); + ~AutoScriptActivity(); +}; // This function may be used off-main-thread, in which case it is benignly // racey. diff --git a/js/xpconnect/tests/unit/test_watchdog_hibernate.js b/js/xpconnect/tests/unit/test_watchdog_hibernate.js index 1207e6ff5c98..5d4726eda977 100644 --- a/js/xpconnect/tests/unit/test_watchdog_hibernate.js +++ b/js/xpconnect/tests/unit/test_watchdog_hibernate.js @@ -23,13 +23,11 @@ async function testBody() { // scheduling, we should never have more than 3 seconds of inactivity without // hibernating. To add some padding for automation, we mandate that hibernation // must begin between 2 and 5 seconds from now. - await new Promise(resolve => { - var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback(resolve, 10000, Ci.nsITimer.TYPE_ONE_SHOT); - simulateActivityCallback(false); - }); - simulateActivityCallback(true); + // Sleep for 10 seconds. Note: we don't use nsITimer here because then we may run + // arbitrary (idle) events involving script before it fires. + simulateNoScriptActivity(10); + busyWait(1000); // Give the watchdog time to wake up on the condvar. var stateChange = Cu.getWatchdogTimestamp("ContextStateChange"); startHibernation = Cu.getWatchdogTimestamp("WatchdogHibernateStart"); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index a97c113f86b9..87e9c46e712a 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -469,9 +469,14 @@ nsLayoutUtils::AreRetainedDisplayListsEnabled() { if (XRE_IsContentProcess()) { return gfxPrefs::LayoutRetainDisplayList(); - } else { + } + + if (XRE_IsE10sParentProcess()) { return gfxPrefs::LayoutRetainDisplayListChrome(); } + + // Retained display lists require e10s. + return false; } bool diff --git a/layout/base/tests/test_reftests_with_caret.html b/layout/base/tests/test_reftests_with_caret.html index d25f70333207..fce22359fef5 100644 --- a/layout/base/tests/test_reftests_with_caret.html +++ b/layout/base/tests/test_reftests_with_caret.html @@ -61,11 +61,14 @@ const MAX_ITERATIONS = 1000; function createIframe(url,next) { var iframe = document.createElement("iframe"); - iframe.src = url; iframe.remotePageLoaded = remotePageLoaded; var me = this; var currentIteration = 0; function iframeLoadCompleted() { + let loc = iframe.contentWindow.location; + if (loc && loc.href == "about:blank") { + return; + } var docEl = iframe.contentDocument.documentElement; if (docEl.className.includes("reftest-wait")) { if (currentIteration++ > MAX_ITERATIONS) { @@ -84,6 +87,8 @@ function createIframe(url,next) { } iframe.addEventListener("load", iframeLoadCompleted); window.document.body.appendChild(iframe); + iframe.clientHeight; // flush layout. + iframe.src = url; iframe.focus(); }; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index e3d26d0f888a..2890f09b447f 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -9443,6 +9443,44 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, #endif } + nsSize oldSize = mRect.Size(); + bool sizeChanged = ((aOldSize ? *aOldSize : oldSize) != aNewSize); + + // Our frame size may not have been computed and set yet, but code under + // functions such as ComputeEffectsRect (which we're about to call) use the + // values that are stored in our frame rect to compute their results. We + // need the results from those functions to be based on the frame size that + // we *will* have, so we temporarily set our frame size here before calling + // those functions. + // + // XXX Someone should document here why we revert the frame size before we + // return rather than just leaving it set. + // + // We pass false here to avoid invalidating display items for this temporary + // change. We sometimes reflow frames multiple times, with the final size being + // the same as the initial. The single call to SetSize after reflow is done + // will take care of invalidating display items if the size has actually + // changed. + SetSize(aNewSize, false); + + const bool applyOverflowClipping = + nsFrame::ShouldApplyOverflowClipping(this, disp); + + if (ChildrenHavePerspective(disp) && sizeChanged) { + RecomputePerspectiveChildrenOverflow(this); + + if (!applyOverflowClipping) { + aOverflowAreas.SetAllTo(bounds); + DebugOnly ok = ComputeCustomOverflow(aOverflowAreas); + + // ComputeCustomOverflow() should not return false, when + // FrameMaintainsOverflow() returns true. + MOZ_ASSERT(ok, "FrameMaintainsOverflow() != ComputeCustomOverflow()"); + + UnionChildOverflow(aOverflowAreas); + } + } + // This is now called FinishAndStoreOverflow() instead of // StoreOverflow() because frame-generic ways of adding overflow // can happen here, e.g. CSS2 outline and native theme. @@ -9467,7 +9505,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, NS_ASSERTION((disp->mOverflowY == NS_STYLE_OVERFLOW_CLIP) == (disp->mOverflowX == NS_STYLE_OVERFLOW_CLIP), "If one overflow is clip, the other should be too"); - if (nsFrame::ShouldApplyOverflowClipping(this, disp)) { + if (applyOverflowClipping) { // The contents are actually clipped to the padding area aOverflowAreas.SetAllTo(bounds); } @@ -9501,26 +9539,6 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, ComputeAndIncludeOutlineArea(this, aOverflowAreas, aNewSize); - nsSize oldSize = mRect.Size(); - bool sizeChanged = ((aOldSize ? *aOldSize : oldSize) != aNewSize); - - // Our frame size may not have been computed and set yet, but code under - // functions such as ComputeEffectsRect (which we're about to call) use the - // values that are stored in our frame rect to compute their results. We - // need the results from those functions to be based on the frame size that - // we *will* have, so we temporarily set our frame size here before calling - // those functions. - // - // XXX Someone should document here why we revert the frame size before we - // return rather than just leaving it set. - // - // We pass false here to avoid invalidating display items for this temporary - // change. We sometimes reflow frames multiple times, with the final size being - // the same as the initial. The single call to SetSize after reflow is done - // will take care of invalidating display items if the size has actually - // changed. - SetSize(aNewSize, false); - // Nothing in here should affect scrollable overflow. aOverflowAreas.VisualOverflow() = ComputeEffectsRect(this, aOverflowAreas.VisualOverflow(), aNewSize); @@ -9537,11 +9555,6 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, } /* If we're transformed, transform the overflow rect by the current transformation. */ - if (ChildrenHavePerspective(disp) && sizeChanged) { - nsRect newBounds(nsPoint(0, 0), aNewSize); - RecomputePerspectiveChildrenOverflow(this); - } - if (hasTransform) { SetProperty(nsIFrame::PreTransformOverflowAreasProperty(), new nsOverflowAreas(aOverflowAreas)); diff --git a/layout/reftests/forms/fieldset/reftest.list b/layout/reftests/forms/fieldset/reftest.list index 9399c5c054a9..65b64e6bc8b1 100644 --- a/layout/reftests/forms/fieldset/reftest.list +++ b/layout/reftests/forms/fieldset/reftest.list @@ -10,7 +10,7 @@ fuzzy-if(winWidget&&!layersGPUAccelerated,0-142,0-276) == positioned-container-1 == relpos-legend-2.html relpos-legend-2-ref.html == relpos-legend-3.html relpos-legend-3-ref.html == relpos-legend-4.html relpos-legend-4-ref.html -fuzzy-if(webrender,17-19,1217-2452) == sticky-legend-1.html sticky-legend-1-ref.html +== sticky-legend-1.html sticky-legend-1-ref.html fuzzy-if(skiaContent,0-1,0-40768) == abs-pos-child-sizing.html abs-pos-child-sizing-ref.html == overflow-hidden.html overflow-hidden-ref.html == legend-rtl.html legend-rtl-ref.html diff --git a/layout/reftests/forms/fieldset/sticky-legend-1-ref.html b/layout/reftests/forms/fieldset/sticky-legend-1-ref.html index 892fa4c29f14..6557d8125802 100644 --- a/layout/reftests/forms/fieldset/sticky-legend-1-ref.html +++ b/layout/reftests/forms/fieldset/sticky-legend-1-ref.html @@ -1,7 +1,7 @@ -
+
diff --git a/layout/reftests/forms/fieldset/sticky-legend-1.html b/layout/reftests/forms/fieldset/sticky-legend-1.html index 588ea521ff68..719c18eb8b78 100644 --- a/layout/reftests/forms/fieldset/sticky-legend-1.html +++ b/layout/reftests/forms/fieldset/sticky-legend-1.html @@ -1,7 +1,7 @@ -
+
diff --git a/layout/reftests/transform-3d/perspective-overflow-1-ref.html b/layout/reftests/transform-3d/perspective-overflow-1-ref.html new file mode 100644 index 000000000000..424a7993bb26 --- /dev/null +++ b/layout/reftests/transform-3d/perspective-overflow-1-ref.html @@ -0,0 +1,28 @@ + + + + +Testcase for bug 1483659 + + + +
+
+
+ + diff --git a/layout/reftests/transform-3d/perspective-overflow-1.html b/layout/reftests/transform-3d/perspective-overflow-1.html new file mode 100644 index 000000000000..178e3d2e2848 --- /dev/null +++ b/layout/reftests/transform-3d/perspective-overflow-1.html @@ -0,0 +1,36 @@ + + + + + +Testcase for bug 1483659 + + + +
+
+
+ + + diff --git a/layout/reftests/transform-3d/reftest.list b/layout/reftests/transform-3d/reftest.list index 00aed828126b..4e430f54a226 100644 --- a/layout/reftests/transform-3d/reftest.list +++ b/layout/reftests/transform-3d/reftest.list @@ -93,3 +93,4 @@ fuzzy-if(winWidget,0-150,0-120) fuzzy-if(webrender&&cocoaWidget,99-99,133-133) = == intermediate-1.html intermediate-1-ref.html == preserves3d-nested-filter-1.html preserves3d-nested-filter-1-ref.html != preserve3d-scale.html about:blank +== perspective-overflow-1.html perspective-overflow-1-ref.html diff --git a/mobile/android/.eslintrc.js b/mobile/android/.eslintrc.js index 5c3b1a73ae68..593bf7ac488a 100644 --- a/mobile/android/.eslintrc.js +++ b/mobile/android/.eslintrc.js @@ -10,7 +10,6 @@ module.exports = { // re-enable these over time. "consistent-return": "off", "no-empty": "off", - "no-native-reassign": "off", "no-nested-ternary": "off", "no-new-object": "off", "no-octal": "off", diff --git a/mobile/android/tests/browser/robocop/robocop_head.js b/mobile/android/tests/browser/robocop/robocop_head.js index 6d1cae4ad68d..67e987cebcdd 100644 --- a/mobile/android/tests/browser/robocop/robocop_head.js +++ b/mobile/android/tests/browser/robocop/robocop_head.js @@ -15,6 +15,7 @@ { let c = Object.getOwnPropertyDescriptor(this, "Components"); if ((!c || !c.value || c.writable) && typeof SpecialPowers === "object") + // eslint-disable-next-line no-global-assign Components = SpecialPowers.wrap(SpecialPowers.Components); } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 71419bacb826..761c2edc22ba 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3115,10 +3115,10 @@ pref("layout.display-list.dump-parent", false); // Toggle retaining display lists between paints #if !defined(ANDROID) pref("layout.display-list.retain", true); +pref("layout.display-list.retain.chrome", true); #else pref("layout.display-list.retain", false); #endif -pref("layout.display-list.retain.chrome", false); // Set the maximum amount of modified frames allowed before doing a full // display list rebuild. diff --git a/services/settings/remote-settings.js b/services/settings/remote-settings.js index 35dd0f38da12..cfebc2f552fe 100644 --- a/services/settings/remote-settings.js +++ b/services/settings/remote-settings.js @@ -163,12 +163,18 @@ async function fetchLatestChanges(url, lastEtag) { } catch (e) { payload = e.message; } + if (!payload.hasOwnProperty("data")) { // If the server is failing, the JSON response might not contain the - // expected data (e.g. error response - Bug 1259145) - throw new Error(`Server error ${response.status} ${response.statusText}: ${JSON.stringify(payload)}`); + // expected data. For example, real server errors (Bug 1259145) + // or dummy local server for tests (Bug 1481348) + const is404FromCustomServer = response.status == 404 && Services.prefs.prefHasUserValue(PREF_SETTINGS_SERVER); + if (!is404FromCustomServer) { + throw new Error(`Server error ${response.status} ${response.statusText}: ${JSON.stringify(payload)}`); + } + } else { + changes = payload.data; } - changes = payload.data; } // The server should always return ETag. But we've had situations where the CDN // was interfering. diff --git a/services/settings/test/unit/test_remote_settings_poll.js b/services/settings/test/unit/test_remote_settings_poll.js index caec2d539f72..ce3834816186 100644 --- a/services/settings/test/unit/test_remote_settings_poll.js +++ b/services/settings/test/unit/test_remote_settings_poll.js @@ -261,6 +261,19 @@ add_task(async function test_server_bad_json() { add_task(clear_state); +add_task(async function test_server_404_response() { + function simulateDummy404(request, response) { + response.setHeader("Content-Type", "application/json; charset=UTF-8"); + response.write(""); + response.setStatusLine(null, 404, "OK"); + } + server.registerPathHandler(CHANGES_PATH, simulateDummy404); + + await RemoteSettings.pollChanges(); // Does not fail when running from tests. +}); +add_task(clear_state); + + add_task(async function test_server_error() { const startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY); diff --git a/services/sync/modules/constants.js b/services/sync/modules/constants.js index 0d6cbc80529c..4a91fac9d315 100644 --- a/services/sync/modules/constants.js +++ b/services/sync/modules/constants.js @@ -8,7 +8,7 @@ for (let [key, val] of Object.entries({ // Don't manually modify this line, as it is automatically replaced on merge day // by the gecko_migration.py script. -WEAVE_VERSION: "1.65.0", +WEAVE_VERSION: "1.66.0", // Sync Server API version that the client supports. SYNC_API_VERSION: "1.5", diff --git a/services/sync/tps/extensions/tps/api.js b/services/sync/tps/extensions/tps/api.js new file mode 100644 index 000000000000..265275aa35c0 --- /dev/null +++ b/services/sync/tps/extensions/tps/api.js @@ -0,0 +1,74 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +ChromeUtils.import("resource://gre/modules/Services.jsm"); +ChromeUtils.import("resource://gre/modules/FileUtils.jsm"); +ChromeUtils.import("resource://gre/modules/Timer.jsm"); + +/* globals ExtensionAPI */ + +XPCOMUtils.defineLazyServiceGetter(this, "resProto", + "@mozilla.org/network/protocol;1?name=resource", + "nsISubstitutingProtocolHandler"); + +async function tpsStartup() { + try { + ChromeUtils.import("resource://tps/tps.jsm"); + ChromeUtils.import("resource://tps/quit.js", TPS); + + let testFile = Services.prefs.getStringPref("testing.tps.testFile", ""); + let testPhase = Services.prefs.getStringPref("testing.tps.testPhase", ""); + if (!testFile || !testPhase) { + // Note: this quits. + TPS.DumpError("TPS no longer takes arguments from the command line. " + + "instead you need to pass preferences `testing.tps.{testFile,testPhase}` " + + "and optionally `testing.tps.{logFile,ignoreUnusedEngines}`.\n"); + } + + let logFile = Services.prefs.getStringPref("testing.tps.logFile", ""); + let ignoreUnusedEngines = Services.prefs.getBoolPref("testing.tps.ignoreUnusedEngines", false); + let options = { ignoreUnusedEngines }; + let testFileUri = Services.io.newFileURI(new FileUtils.File(testFile)).spec; + + try { + await TPS.RunTestPhase(testFileUri, testPhase, logFile, options); + } catch (err) { + TPS.DumpError("TestPhase failed", err); + } + } catch (e) { + if (typeof TPS != "undefined") { + // Note: This calls quit() under the hood + TPS.DumpError("Test initialization failed", e); + } + // Try and quit right away, no reason to wait around for python + // to kill us if initialization failed. + Services.startup.quit(Ci.nsIAppStartup.eForceQuit); + } +} + +function onStartupFinished() { + return new Promise(resolve => { + const onStartupFinished = () => { + Services.obs.removeObserver(onStartupFinished, "browser-delayed-startup-finished"); + resolve(); + }; + Services.obs.addObserver(onStartupFinished, "browser-delayed-startup-finished"); + }); +} + +this.tps = class extends ExtensionAPI { + onStartup() { + resProto.setSubstitution("tps", + Services.io.newURI("resource/", null, this.extension.rootURI)); + /* Ignore the platform's online/offline status while running tests. */ + Services.io.manageOfflineStatus = false; + Services.io.offline = false; + tpsStartup(); + } + + onShutdown() { + resProto.setSubstitution("tps", null); + } +}; diff --git a/services/sync/tps/extensions/tps/bootstrap.js b/services/sync/tps/extensions/tps/bootstrap.js deleted file mode 100644 index 7f126d069f8a..000000000000 --- a/services/sync/tps/extensions/tps/bootstrap.js +++ /dev/null @@ -1,104 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); -ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/osfile.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "resProto", - "@mozilla.org/network/protocol;1?name=resource", - "nsISubstitutingProtocolHandler"); - -const Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); - -const CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1"; - -const CATEGORY_NAME = "command-line-handler"; -const CATEGORY_ENTRY = "m-tps"; - -function TPSCmdLine() {} - -TPSCmdLine.prototype = { - factory: XPCOMUtils._getFactory(TPSCmdLine), - classDescription: "TPSCmdLine", - classID: Components.ID("{4e5bd3f0-41d3-11df-9879-0800200c9a66}"), - contractID: "@mozilla.org/commandlinehandler/general-startup;1?type=tps", - - QueryInterface: ChromeUtils.generateQI([Ci.nsICommandLineHandler]), - - register() { - Cm.registerFactory(this.classID, this.classDescription, - this.contractID, this.factory); - - Services.catMan.addCategoryEntry(CATEGORY_NAME, CATEGORY_ENTRY, - this.contractID, false, true); - }, - - unregister() { - Services.catMan.deleteCategoryEntry(CATEGORY_NAME, CATEGORY_ENTRY, - this.contractID, false); - - Cm.unregisterFactory(this.classID, this.factory); - }, - - /* nsICmdLineHandler */ - commandLineArgument: "-tps", - prefNameForStartup: "general.startup.tps", - helpText: "Run TPS tests with the given test file.", - handlesArgs: true, - defaultArgs: "", - openWindowWithArgs: true, - - /* nsICommandLineHandler */ - handle: function handler_handle(cmdLine) { - let options = {}; - - let uristr = cmdLine.handleFlagWithParam("tps", false); - if (uristr == null) { - return; - } - let phase = cmdLine.handleFlagWithParam("tpsphase", false); - if (phase == null) { - throw Error("must specify --tpsphase with --tps"); - } - let logfile = cmdLine.handleFlagWithParam("tpslogfile", false); - if (logfile == null) { - logfile = ""; - } - - options.ignoreUnusedEngines = cmdLine.handleFlag("ignore-unused-engines", - false); - let uri = cmdLine.resolveURI(OS.Path.normalize(uristr)).spec; - - const onStartupFinished = () => { - Services.obs.removeObserver(onStartupFinished, "browser-delayed-startup-finished"); - /* Ignore the platform's online/offline status while running tests. */ - Services.io.manageOfflineStatus = false; - Services.io.offline = false; - ChromeUtils.import("resource://tps/tps.jsm"); - ChromeUtils.import("resource://tps/quit.js", TPS); - TPS.RunTestPhase(uri, phase, logfile, options).catch(err => TPS.DumpError("TestPhase failed", err)); - }; - Services.obs.addObserver(onStartupFinished, "browser-delayed-startup-finished"); - }, - - helpInfo: " --tps Run TPS tests with the given test file.\n" + - " --tpsphase Run the specified phase in the TPS test.\n" + - " --tpslogfile Logfile for TPS output.\n" + - " --ignore-unused-engines Don't load engines not used in tests.\n", -}; - -function startup(data, reason) { - TPSCmdLine.prototype.register(); - resProto.setSubstitution("tps", Services.io.newURI("resource/", null, data.resourceURI)); -} - -function shutdown(data, reason) { - resProto.setSubstitution("tps", null); - TPSCmdLine.prototype.unregister(); -} - -function install(data, reason) {} -function uninstall(data, reason) {} diff --git a/services/sync/tps/extensions/tps/install.rdf b/services/sync/tps/extensions/tps/install.rdf deleted file mode 100644 index f9f060af129d..000000000000 --- a/services/sync/tps/extensions/tps/install.rdf +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - tps@mozilla.org - 0.5 - true - - - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 24.0.* - * - - - - - TPS - Sync test extension - Jonathan Griffin - Henrik Skupin - https://developer.mozilla.org/en-US/docs/TPS - true - - diff --git a/services/sync/tps/extensions/tps/manifest.json b/services/sync/tps/extensions/tps/manifest.json new file mode 100644 index 000000000000..2de6e902c689 --- /dev/null +++ b/services/sync/tps/extensions/tps/manifest.json @@ -0,0 +1,23 @@ +{ + "manifest_version": 2, + "name": "TPS", + "version": "1.0", + + "applications": { + "gecko": { + "id": "tps@mozilla.org" + } + }, + + "experiment_apis": { + "tps": { + "schema": "schema.json", + "parent": { + "scopes": ["addon_parent"], + "script": "api.js", + "paths": [["tps"]], + "events": ["startup"] + } + } + } +} diff --git a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm index 0f58459a8586..aff0ec141ab9 100644 --- a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm +++ b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm @@ -64,7 +64,7 @@ var Authentication = { async _openVerificationPage(uri) { let mainWindow = Services.wm.getMostRecentWindow("navigator:browser"); - let newtab = mainWindow.getBrowser().addTab(uri); + let newtab = mainWindow.getBrowser().addWebTab(uri); let win = mainWindow.getBrowser().getBrowserForTab(newtab); await new Promise(resolve => { win.addEventListener("loadend", resolve, { once: true }); diff --git a/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm b/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm index 23feb3f8027d..60a022159b2b 100644 --- a/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm +++ b/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm @@ -10,8 +10,12 @@ var EXPORTED_SYMBOLS = ["Address", "CreditCard", "DumpAddresses", "DumpCreditCards"]; ChromeUtils.import("resource://tps/logger.jsm"); -ChromeUtils.import("resource://formautofill/FormAutofillStorage.jsm"); -ChromeUtils.import("resource://formautofill/MasterPassword.jsm"); + +ChromeUtils.defineModuleGetter(this, "formAutofillStorage", + "resource://formautofill/FormAutofillStorage.jsm"); + +ChromeUtils.defineModuleGetter(this, "MasterPassword", + "resource://formautofill/MasterPassword.jsm"); class FormAutofillBase { constructor(props, subStorageName, fields) { diff --git a/services/sync/tps/extensions/tps/schema.json b/services/sync/tps/extensions/tps/schema.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/services/sync/tps/extensions/tps/schema.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/taskcluster/ci/config.yml b/taskcluster/ci/config.yml index 200b9dca9531..a7eec9569f32 100755 --- a/taskcluster/ci/config.yml +++ b/taskcluster/ci/config.yml @@ -30,8 +30,8 @@ treeherder: 'Tsd-e10s': 'Talos performance tests with e10s, Stylo disabled' 'Tss-e10s': 'Talos performance tests with e10s, Stylo sequential' 'T-P-e10s': 'Talos performance tests with e10s and gecko profiling' - 'tt-c': 'Telemetry client marionette tests' - 'tt-c-e10s': 'Telemetry client marionette tests with e10s' + 'tt': 'Telemetry tests' + 'tt-e10s': 'Telemetry tests with e10s' 'SY-e10s': 'Are we slim yet tests by TaskCluster with e10s' 'SYsd-e10s': 'Are we slim yet tests by TaskCluster with e10s, Stylo disabled' 'SYss-e10s': 'Are we slim yet tests by TaskCluster with e10s, Stylo sequential' diff --git a/taskcluster/ci/release-bouncer-aliases/kind.yml b/taskcluster/ci/release-bouncer-aliases/kind.yml index 1ff834acbb58..1ae4e0ab9e79 100644 --- a/taskcluster/ci/release-bouncer-aliases/kind.yml +++ b/taskcluster/ci/release-bouncer-aliases/kind.yml @@ -81,16 +81,15 @@ jobs: firefox-latest: installer firefox-stub: stub-installer mozilla-esr60: - # convert to firefox-esr-latest when ESR52 stops - firefox-esr-next-latest-ssl: installer-ssl - firefox-esr-next-latest: installer + firefox-esr-latest-ssl: installer-ssl + firefox-esr-latest: installer birch: firefox-latest-ssl: installer-ssl firefox-latest: installer firefox-stub: stub-installer jamun: - firefox-esr-next-latest-ssl: installer-ssl - firefox-esr-next-latest: installer + firefox-esr-latest-ssl: installer-ssl + firefox-esr-latest: installer maple: firefox-beta-latest-ssl: installer-ssl firefox-beta-latest: installer diff --git a/taskcluster/ci/test/misc.yml b/taskcluster/ci/test/misc.yml index b1961e9c7699..7f9968ca7c36 100644 --- a/taskcluster/ci/test/misc.yml +++ b/taskcluster/ci/test/misc.yml @@ -83,7 +83,7 @@ robocop: telemetry-tests-client: description: "Telemetry tests client run" suite: telemetry-tests-client - treeherder-symbol: tt-c() + treeherder-symbol: tt(c) max-run-time: 5400 checkout: true tier: 3 diff --git a/taskcluster/docker/funsize-update-generator/Pipfile.lock b/taskcluster/docker/funsize-update-generator/Pipfile.lock index cb16c4ccd5ce..777107f2edf8 100644 --- a/taskcluster/docker/funsize-update-generator/Pipfile.lock +++ b/taskcluster/docker/funsize-update-generator/Pipfile.lock @@ -18,31 +18,31 @@ "default": { "aiohttp": { "hashes": [ - "sha256:01a2059a0505460828854d218cf090d80db277033b8e6906144ab9bd4677fc82", - "sha256:01bcaf83911c5a88f74629f116540a1b80391e6e496e6fb8708bb2987b60da63", - "sha256:199ea4a9c424904f04a86563a8e9e2759d49e3a0bf789496714253237f16015f", - "sha256:229975cb8ff6056c8ef581383a653e7110480d52c9f46eaf560113f8d5005510", - "sha256:2bb4224e3a3d7dd2ee18f6c42c1925c3200cd46fe18ec9f293b9bc88644c4878", - "sha256:2ddf47c31048efad5a566d82822194bbb680fc1be852915c2949eb69891b5d5a", - "sha256:3bc9c87845962f583d6929f837b02b80d2544920be65daf0d0a1306ad1a2089b", - "sha256:3f88a3428f40c788321cf5b8191f9dd9e002145545fa0cefc023b4b11e17aaa7", - "sha256:4785935328facee0878c29d46f02b12f1e8e8db1cd3d9ec9af666eb163418a64", - "sha256:48e8d1973ba62a952f19a7916e54a7155f4b14505507432fc0559d8b5b0e5cad", - "sha256:5cd8662ddd7c95e99010e30cc52e20a092939844e8e8a4f37abf1866231f1880", - "sha256:6880406a0c776fbff63c0d9eb8a2d96d8134b17fafeeea01180b58ab8ff0f6f5", - "sha256:6a8e447742fc45791ffea0b3ce308f1476a9f4707fb6525a2f23b43d4b26cfb3", - "sha256:81456c04c54288928da4e7e1893314c8e74d5e9f33163e39aa47c26c5e5c7911", - "sha256:9b15efa7411dcf3b59c1f4766eb16ba1aba4531a33e54d469ee22106eabce460", - "sha256:a6132db365def76145084041cede574a0c8ed53aa1a680a3027e41ee8f291bd4", - "sha256:ddee38858a9ef52ca33cb5dd1607d07d0fb99e2efe523ecb437b1758c49622a5", - "sha256:de703f333381864dce788dbfa1a49ef4551e8f082b607a943b94b239d97965cc", - "sha256:e08cacfede41291c05b4668c3178d303d078417c013bc3d5287b2b0d0e6a3aa7", - "sha256:e4c37c7ec1e1157ae4af73fd1d7f201accebf6ed2222120bc660fd002c45cbac", - "sha256:e4f9fc91d617d2e54bda97bc1db9814918691fe799e037ccf973fda434fd2c18", - "sha256:f6f73c812c1830a06de76ccbea10a4ebb1fd46230a80f280362e84578e4932a2" + "sha256:04087c38e45da5aa1a8b2345441b821bf270436f7954eba1a7e36cc55fed81f8", + "sha256:07f025ea9fbc904f46cde7ba1e16c4085687cf8b6cabb6b815a8b5962605a743", + "sha256:0fae84267df30e27b072da1a09835616e6872f7cc82cfc3eb260a52e9b6de340", + "sha256:17b105bfeefe7c1d122d5948f7fe20adb5eae83cbbf6c7b5a787176c883fc0ea", + "sha256:21ec794275615fcf9b0715266ce6709eb40045560c75431a1439fb1ed0fb0241", + "sha256:2421ca89978a037f0ed1cc77fc5678561cc416c2047aad2e1dd8259bce1192b3", + "sha256:26e996559c8f723c19a638f5c315716c258d9e2e2e5fa31ef76cc62a4d676c99", + "sha256:540c02599fb3f913121fe5767506f2ce36d0ff9bda6f0cf3f4fe978d68f9a8f8", + "sha256:5e452185e23f4a30208b057932b4ca5d528f4c4fdcc58028809e9f763fa52f36", + "sha256:613bc9d4513df36f76faf19f1010430c0cea45cc9db4af0df96d237e5fd42800", + "sha256:6f35399afb09427523f97d6a6a000fb6562e9ed2d3560c2fdfb9d874beb46ecf", + "sha256:72f9ba7f4767a5e75aeb68f0441ddd3856f7129cbd0d188420e770d17e3b100a", + "sha256:74dc560e074a8a56ef3722bd87fc06acc38eaccba6b35afc39345782eeb41a42", + "sha256:8de492b8c8d5acb60c30cf2275f36d0fb21d71e0a462bbed61f099a98264c635", + "sha256:97e3f198da96d5833200d814812ee03dbf1b2ba5a85ea4751e5da1360fe9a7cd", + "sha256:bb2af48882b6d351ffe17423d19a1a51f0850ead5b7e7237b663a4e880e8d5b7", + "sha256:d50047664a199eab5e596e4a18f09781fcdc1ad43b3203c5585dc65cf4c57592", + "sha256:d65a3942bce7717a1dc730927f583308e100a94375ed81fa06bcb02127e4c3ae", + "sha256:e59bcc461b6523b8c9105032f7664bd918f9c3be5f96462b814e6bf1c915c32e", + "sha256:f1958340035221643c0c27326fecf24e49265ba21c709e42163bc8b16cb2e0c7", + "sha256:f4cba665391bd31b3807277de3c73fd80cc17a0d280f11485fe9e58e228b6c5c", + "sha256:f54001b0504f808a88aa786749af6c52e6ca00b5b7350fbe84d6274e537e7485" ], "index": "pypi", - "version": "==3.4.0" + "version": "==3.4.2" }, "arrow": { "hashes": [ @@ -67,10 +67,10 @@ }, "attrs": { "hashes": [ - "sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265", - "sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b" + "sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69", + "sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb" ], - "version": "==18.1.0" + "version": "==18.2.0" }, "backports.lzma": { "hashes": [ @@ -328,11 +328,11 @@ }, "scriptworker": { "hashes": [ - "sha256:2b02449c521f1aefbf58ca80305b434205d48c0ff2dae5c0853fe74dc959e555", - "sha256:dd71c060d7e187eeba06d54577fa288c423a5a89bc788b30d779d39a666186ba" + "sha256:063b0442bdbde23afbd2828408c43cdc0f411c9250ea8571655ccba6d2f8d61c", + "sha256:a940358870f5423ba07051ec696a8347c6d5459ad6b2c5823d3fd44a8449d1c0" ], "index": "pypi", - "version": "==15.0.0" + "version": "==15.0.2" }, "sh": { "hashes": [ @@ -386,7 +386,7 @@ "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" ], - "markers": "python_version < '4' and python_version >= '2.6' and python_version != '3.2.*' and python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.0.*'", + "markers": "python_version != '3.2.*' and python_version != '3.1.*' and python_version >= '2.6' and python_version < '4' and python_version != '3.0.*' and python_version != '3.3.*'", "version": "==1.23" }, "virtualenv": { @@ -394,7 +394,7 @@ "sha256:2ce32cd126117ce2c539f0134eb89de91a8413a29baac49cbab3eb50e2026669", "sha256:ca07b4c0b54e14a91af9f34d0919790b016923d157afda5efdde55c96718f752" ], - "markers": "python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.2.*'", + "markers": "python_version != '3.1.*' and python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.2.*'", "version": "==16.0.0" }, "yarl": { @@ -409,6 +409,7 @@ "sha256:f17495e6fe3d377e3faac68121caef6f974fcb9e046bc075bcff40d8e5cc69a4", "sha256:f85900b9cca0c67767bb61b2b9bd53208aaa7373dae633dbe25d179b4bf38aa7" ], + "markers": "python_version >= '3.4.1'", "version": "==1.2.6" } }, diff --git a/testing/mozbase/mozdevice/mozdevice/adb.py b/testing/mozbase/mozdevice/mozdevice/adb.py index 3e164829fd65..2082ea0e075c 100644 --- a/testing/mozbase/mozdevice/mozdevice/adb.py +++ b/testing/mozbase/mozdevice/mozdevice/adb.py @@ -529,6 +529,9 @@ class ADBDevice(ADBCommand): """ __metaclass__ = ABCMeta + SOCKET_DIRECTON_REVERSE = "reverse" + SOCKET_DIRECTON_FORWARD = "forward" + def __init__(self, device=None, adb='adb', @@ -962,7 +965,7 @@ class ADBDevice(ADBCommand): device_serial=self._device_serial, timeout=timeout) - # Port forwarding methods + # Networking methods def _validate_port(self, port, is_local=True): """Validate a port forwarding specifier. Raises ValueError on failure. @@ -977,22 +980,24 @@ class ADBDevice(ADBCommand): parts = port.split(":", 1) if len(parts) != 2 or parts[0] not in prefixes: - raise ValueError("Invalid forward specifier %s" % port) + raise ValueError("Invalid port specifier %s" % port) - def forward(self, local, remote, allow_rebind=True, timeout=None): - """Forward a local port to a specific port on the device. + def _validate_direction(self, direction): + """Validate direction of the socket connection. Raises ValueError on failure. - Ports are specified in the form: - tcp: - localabstract: - localreserved: - localfilesystem: - dev: - jdwp: (remote only) + :param str direction: The socket direction specifier to validate + :raises: * ValueError + """ + if direction not in [self.SOCKET_DIRECTON_FORWARD, self.SOCKET_DIRECTON_REVERSE]: + raise ValueError('Invalid direction specifier {}'.format(direction)) - :param str local: Local port to forward - :param str remote: Remote port to which to forward - :param bool allow_rebind: Don't error if the local port is already forwarded + def create_socket_connection(self, direction, local, remote, allow_rebind=True, timeout=None): + """Sets up a socket connection in the specified direction. + + :param str direction: Direction of the socket connection + :param str local: Local port + :param str remote: Remote port + :param bool allow_rebind: Do not fail if port is already bound :param timeout: The maximum time in seconds for any spawned adb process to complete before throwing an ADBTimeoutError. If it is not specified, the value @@ -1002,34 +1007,46 @@ class ADBDevice(ADBCommand): * ADBTimeoutError * ADBError """ - + # validate socket direction, and local and remote port formatting. + self._validate_direction(direction) for port, is_local in [(local, True), (remote, False)]: self._validate_port(port, is_local=is_local) - cmd = ["forward", local, remote] + cmd = [direction, local, remote] + if not allow_rebind: cmd.insert(1, "--no-rebind") + + # execute commands to establish socket connection. self.command_output(cmd, timeout=timeout) - def list_forwards(self, timeout=None): - """Return a list of tuples specifying active forwards + def list_socket_connections(self, direction, timeout=None): + """Return a list of tuples specifying active socket connectionss. Return values are of the form (device, local, remote). + :param str direction: 'forward' to list forward socket connections + 'reverse' to list reverse socket connections :param timeout: The maximum time in seconds for any spawned adb process to complete before throwing an ADBTimeoutError. If it is not specified, the value set in the ADBDevice constructor is used. :type timeout: integer or None - :raises: * ADBTimeoutError + :raises: * ValueError + * ADBTimeoutError * ADBError """ - forwards = self.command_output(["forward", "--list"], timeout=timeout) - return [tuple(line.split(" ")) for line in forwards.splitlines() if line.strip()] + self._validate_direction(direction) - def remove_forwards(self, local=None, timeout=None): - """Remove existing port forwards. + cmd = [direction, "--list"] + output = self.command_output(cmd, timeout=timeout) + return [tuple(line.split(" ")) for line in output.splitlines() if line.strip()] + def remove_socket_connections(self, direction, local=None, timeout=None): + """Remove existing socket connections for a given direction. + + :param str direction: 'forward' to remove forward socket connection + 'reverse' to remove reverse socket connection :param local: local port specifier as for ADBDevice.forward. If local is not specified removes all forwards. :type local: str or None @@ -1042,7 +1059,10 @@ class ADBDevice(ADBCommand): * ADBTimeoutError * ADBError """ - cmd = ["forward"] + self._validate_direction(direction) + + cmd = [direction] + if local is None: cmd.extend(["--remove-all"]) else: @@ -1051,6 +1071,55 @@ class ADBDevice(ADBCommand): self.command_output(cmd, timeout=timeout) + # Legacy port forward methods + + def forward(self, local, remote, allow_rebind=True, timeout=None): + """Forward a local port to a specific port on the device. + + See `ADBDevice.create_socket_connection`. + """ + self.create_socket_connection(self.SOCKET_DIRECTON_FORWARD, + local, remote, allow_rebind, timeout) + + def list_forwards(self, timeout=None): + """Return a list of tuples specifying active forwards. + + See `ADBDevice.list_socket_connection`. + """ + return self.list_socket_connections(self.SOCKET_DIRECTON_FORWARD, timeout) + + def remove_forwards(self, local=None, timeout=None): + """Remove existing port forwards. + + See `ADBDevice.remove_socket_connection`. + """ + self.remove_socket_connections(self.SOCKET_DIRECTON_FORWARD, local, timeout) + + # Legacy port reverse methods + + def reverse(self, local, remote, allow_rebind=True, timeout=None): + """Sets up a reverse socket connection from device to host. + + See `ADBDevice.create_socket_connection`. + """ + self.create_socket_connection(self.SOCKET_DIRECTON_REVERSE, + local, remote, allow_rebind, timeout) + + def list_reverses(self, timeout=None): + """Returns a list of tuples showing active reverse socket connections. + + See `ADBDevice.list_socket_connection`. + """ + return self.list_socket_connections(self.SOCKET_DIRECTON_REVERSE, timeout) + + def remove_reverses(self, local=None, timeout=None): + """Remove existing reverse socket connections. + + See `ADBDevice.remove_socket_connection`. + """ + self.remove_socket_connections(self.SOCKET_DIRECTON_REVERSE, + local, timeout) + # Device Shell methods def shell(self, cmd, env=None, cwd=None, timeout=None, root=False, diff --git a/testing/mozbase/mozdevice/setup.py b/testing/mozbase/mozdevice/setup.py index e0e31c0b3064..2064c4c95b92 100644 --- a/testing/mozbase/mozdevice/setup.py +++ b/testing/mozbase/mozdevice/setup.py @@ -8,7 +8,7 @@ from __future__ import absolute_import from setuptools import setup PACKAGE_NAME = 'mozdevice' -PACKAGE_VERSION = '1.1.0' +PACKAGE_VERSION = '1.1.1' deps = ['mozfile >= 1.0', 'mozlog >= 3.0', diff --git a/testing/tps/tps/phase.py b/testing/tps/tps/phase.py index 397c90796297..85a9e23d2485 100644 --- a/testing/tps/tps/phase.py +++ b/testing/tps/tps/phase.py @@ -3,6 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import re +import os.path class TPSTestPhase(object): @@ -29,17 +30,21 @@ class TPSTestPhase(object): def run(self): # launch Firefox - args = [ '-tps', self.testpath, - '-tpsphase', self.phase, - '-tpslogfile', self.logfile ] - if self.ignore_unused_engines: - args.append('--ignore-unused-engines') + prefs = { + "testing.tps.testFile": os.path.abspath(self.testpath), + "testing.tps.testPhase": self.phase, + "testing.tps.logFile": self.logfile, + "testing.tps.ignoreUnusedEngines": self.ignore_unused_engines + } + + self.profile.set_preferences(prefs); + + self.log('\nLaunching Firefox for phase %s with prefs %s\n' % + (self.phase, str(prefs))) - self.log('\nLaunching Firefox for phase %s with args %s\n' % - (self.phase, str(args))) self.firefoxRunner.run(env=self.env, - args=args, + args=[], profile=self.profile) # parse the logfile and look for results from the current test phase diff --git a/testing/tps/tps/testrunner.py b/testing/tps/tps/testrunner.py index 12cad820038b..1640794e1bf5 100644 --- a/testing/tps/tps/testrunner.py +++ b/testing/tps/tps/testrunner.py @@ -235,7 +235,7 @@ class TPSTestRunner(object): # create the profile if necessary if not profilename in profiles: - profiles[profilename] = Profile(preferences = self.preferences, + profiles[profilename] = Profile(preferences = self.preferences.copy(), addons = self.extensions) # create the test phase @@ -262,6 +262,7 @@ class TPSTestRunner(object): break; for profilename in profiles: + print "### Cleanup Profile ", profilename cleanup_phase = TPSTestPhase( 'cleanup-' + profilename, profiles[profilename], testname, diff --git a/testing/web-platform/meta/css/CSS2/borders/__dir__.ini b/testing/web-platform/meta/css/CSS2/borders/__dir__.ini index 26f80a3ebe4d..d300f06aa8ff 100644 --- a/testing/web-platform/meta/css/CSS2/borders/__dir__.ini +++ b/testing/web-platform/meta/css/CSS2/borders/__dir__.ini @@ -1 +1,2 @@ -disabled: if not debug && (os == "linux") && (bits == 32): https://bugzilla.mozilla.org/show_bug.cgi?id=1445834 +disabled: + if not debug and (os == "linux") and (bits == 32): https://bugzilla.mozilla.org/show_bug.cgi?id=1445834 diff --git a/testing/web-platform/tests/streams/readable-streams/patched-global.js b/testing/web-platform/tests/streams/readable-streams/patched-global.js index e8117c480484..c75b21e8c385 100644 --- a/testing/web-platform/tests/streams/readable-streams/patched-global.js +++ b/testing/web-platform/tests/streams/readable-streams/patched-global.js @@ -47,7 +47,6 @@ test(t => { const oldReadableStream = self.ReadableStream; - /* eslint-disable no-native-reassign */ self.ReadableStream = function() { throw new Error('ReadableStream called on global object'); }; @@ -60,8 +59,6 @@ test(t => { assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream'); assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream'); - - /* eslint-enable no-native-reassign */ }, 'ReadableStream tee() should not call the global ReadableStream'); done(); diff --git a/testing/web-platform/tests/streams/transform-streams/patched-global.js b/testing/web-platform/tests/streams/transform-streams/patched-global.js index d27b9cdd119e..f5d32c08ea73 100644 --- a/testing/web-platform/tests/streams/transform-streams/patched-global.js +++ b/testing/web-platform/tests/streams/transform-streams/patched-global.js @@ -21,8 +21,6 @@ test(() => { }, 'TransformStream constructor should not call setters for highWaterMark or size'); test(t => { - /* eslint-disable no-native-reassign */ - const oldReadableStream = ReadableStream; const oldWritableStream = WritableStream; const getReader = ReadableStream.prototype.getReader; @@ -47,7 +45,6 @@ test(t => { 'getReader should work when called on ts.readable'); assert_not_equals(getWriter.call(ts.writable), undefined, 'getWriter should work when called on ts.writable'); - /* eslint-enable no-native-reassign */ }, 'TransformStream should use the original value of ReadableStream and WritableStream'); done(); diff --git a/toolkit/components/aboutmemory/tests/test_aboutmemory4.xul b/toolkit/components/aboutmemory/tests/test_aboutmemory4.xul index 8f470791e929..673c3f6b43c7 100644 --- a/toolkit/components/aboutmemory/tests/test_aboutmemory4.xul +++ b/toolkit/components/aboutmemory/tests/test_aboutmemory4.xul @@ -37,42 +37,45 @@ frame.height = 300; frame.src = "about:memory?file=" + makePathname(aFilename); document.documentElement.appendChild(frame); - frame.focus(); + frame.addEventListener("load", function onFrameLoad(e) { + frame.removeEventListener("load", onFrameLoad); + frame.focus(); - // Initialize the clipboard contents. - SpecialPowers.clipboardCopyString("initial clipboard value"); + // Initialize the clipboard contents. + SpecialPowers.clipboardCopyString("initial clipboard value"); - let numFailures = 0, maxFailures = 30; + let numFailures = 0, maxFailures = 30; - // Because the file load is async, we don't know when it will finish and - // the output will show up. So we poll. - function copyPasteAndCheck() { - // Copy and paste frame contents, and filter out non-deterministic - // differences. - synthesizeKey("A", {accelKey: true}); - synthesizeKey("C", {accelKey: true}); - let actual = SpecialPowers.getClipboardData("text/unicode"); - actual = actual.replace(/\(pid \d+\)/, "(pid NNN)"); + // Because the file load is async, we don't know when it will finish and + // the output will show up. So we poll. + function copyPasteAndCheck() { + // Copy and paste frame contents, and filter out non-deterministic + // differences. + synthesizeKey("A", {accelKey: true}); + synthesizeKey("C", {accelKey: true}); + let actual = SpecialPowers.getClipboardData("text/unicode"); + actual = actual.replace(/\(pid \d+\)/, "(pid NNN)"); - if (actual.trim() === aExpected.trim()) { - SimpleTest.ok(true, "Clipboard has the expected contents"); - aNext(); - } else { - numFailures++; - if (numFailures === maxFailures) { - ok(false, "pasted text doesn't match"); - dump("******EXPECTED******\n"); - dump(aExpected); - dump("*******ACTUAL*******\n"); - dump(actual); - dump("********************\n"); - SimpleTest.finish(); + if (actual.trim() === aExpected.trim()) { + SimpleTest.ok(true, "Clipboard has the expected contents"); + aNext(); } else { - setTimeout(copyPasteAndCheck, 100); + numFailures++; + if (numFailures === maxFailures) { + ok(false, "pasted text doesn't match"); + dump("******EXPECTED******\n"); + dump(aExpected); + dump("*******ACTUAL*******\n"); + dump(actual); + dump("********************\n"); + SimpleTest.finish(); + } else { + setTimeout(copyPasteAndCheck, 100); + } } } - } - copyPasteAndCheck(); + copyPasteAndCheck(); + }); } // Returns a function that chains together multiple test() calls. diff --git a/toolkit/components/extensions/.eslintrc.js b/toolkit/components/extensions/.eslintrc.js index 511d5d08e334..5d4f4e2a50de 100644 --- a/toolkit/components/extensions/.eslintrc.js +++ b/toolkit/components/extensions/.eslintrc.js @@ -159,10 +159,6 @@ module.exports = { // Allow use of bitwise operators. "no-bitwise": "off", - // Disallow the catch clause parameter name being the same as a variable in - // the outer scope, to avoid confusion. - "no-catch-shadow": "off", - // Disallow using the console API. "no-console": "error", @@ -217,9 +213,6 @@ module.exports = { // Disallow usage of __proto__ property. "no-proto": "error", - // Allow reserved words being used as object literal keys. - "no-reserved-keys": "off", - // Don't restrict usage of specified node modules (not a node environment). "no-restricted-modules": "off", diff --git a/toolkit/components/extensions/Schemas.jsm b/toolkit/components/extensions/Schemas.jsm index 7e6951167bdf..7fe2315d46c2 100644 --- a/toolkit/components/extensions/Schemas.jsm +++ b/toolkit/components/extensions/Schemas.jsm @@ -2396,7 +2396,7 @@ FunctionEntry = class FunctionEntry extends CallEntry { // // TODO Bug 1369722: we should be able to remove the eslint-disable-line that follows // once Bug 1369722 has been fixed. -Event = class Event extends CallEntry { // eslint-disable-line no-native-reassign +Event = class Event extends CallEntry { // eslint-disable-line no-global-assign static parseSchema(root, event, path) { let extraParameters = Array.from(event.extraParameters || [], param => ({ type: root.parseSchema(param, path, ["name", "optional", "default"]), diff --git a/toolkit/components/passwordmgr/test/pwmgr_common.js b/toolkit/components/passwordmgr/test/pwmgr_common.js index 973913b16063..238ba6563112 100644 --- a/toolkit/components/passwordmgr/test/pwmgr_common.js +++ b/toolkit/components/passwordmgr/test/pwmgr_common.js @@ -351,7 +351,7 @@ if (this.addMessageListener) { var SpecialPowers = { Cc, Ci, Cr, Cu }; var ok, is; // Ignore ok/is in commonInit since they aren't defined in a chrome script. - ok = is = () => {}; // eslint-disable-line no-native-reassign + ok = is = () => {}; ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); ChromeUtils.import("resource://gre/modules/LoginHelper.jsm"); diff --git a/toolkit/components/telemetry/TelemetryArchive.jsm b/toolkit/components/telemetry/app/TelemetryArchive.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryArchive.jsm rename to toolkit/components/telemetry/app/TelemetryArchive.jsm diff --git a/toolkit/components/telemetry/TelemetryController.jsm b/toolkit/components/telemetry/app/TelemetryController.jsm similarity index 99% rename from toolkit/components/telemetry/TelemetryController.jsm rename to toolkit/components/telemetry/app/TelemetryController.jsm index 2cca9957a7a4..f7fefe2f1e9b 100644 --- a/toolkit/components/telemetry/TelemetryController.jsm +++ b/toolkit/components/telemetry/app/TelemetryController.jsm @@ -59,10 +59,10 @@ XPCOMUtils.defineLazyModuleGetters(this, { TelemetrySession: "resource://gre/modules/TelemetrySession.jsm", TelemetrySend: "resource://gre/modules/TelemetrySend.jsm", TelemetryReportingPolicy: "resource://gre/modules/TelemetryReportingPolicy.jsm", - TelemetryModules: "resource://gre/modules/TelemetryModules.jsm", + TelemetryModules: "resource://gre/modules/ModulesPing.jsm", UpdatePing: "resource://gre/modules/UpdatePing.jsm", - TelemetryHealthPing: "resource://gre/modules/TelemetryHealthPing.jsm", - TelemetryEventPing: "resource://gre/modules/TelemetryEventPing.jsm", + TelemetryHealthPing: "resource://gre/modules/HealthPing.jsm", + TelemetryEventPing: "resource://gre/modules/EventPing.jsm", OS: "resource://gre/modules/osfile.jsm", }); diff --git a/toolkit/components/telemetry/TelemetryEnvironment.jsm b/toolkit/components/telemetry/app/TelemetryEnvironment.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryEnvironment.jsm rename to toolkit/components/telemetry/app/TelemetryEnvironment.jsm diff --git a/toolkit/components/telemetry/TelemetryReportingPolicy.jsm b/toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryReportingPolicy.jsm rename to toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm diff --git a/toolkit/components/telemetry/TelemetrySend.jsm b/toolkit/components/telemetry/app/TelemetrySend.jsm similarity index 99% rename from toolkit/components/telemetry/TelemetrySend.jsm rename to toolkit/components/telemetry/app/TelemetrySend.jsm index b319d416feb1..de1b1e85dcb4 100644 --- a/toolkit/components/telemetry/TelemetrySend.jsm +++ b/toolkit/components/telemetry/app/TelemetrySend.jsm @@ -35,7 +35,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "Telemetry", "@mozilla.org/base/telemetry;1", "nsITelemetry"); ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing", - "resource://gre/modules/TelemetryHealthPing.jsm"); + "resource://gre/modules/HealthPing.jsm"); const Utils = TelemetryUtils; diff --git a/toolkit/components/telemetry/TelemetryStopwatch.jsm b/toolkit/components/telemetry/app/TelemetryStopwatch.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryStopwatch.jsm rename to toolkit/components/telemetry/app/TelemetryStopwatch.jsm diff --git a/toolkit/components/telemetry/TelemetryStorage.jsm b/toolkit/components/telemetry/app/TelemetryStorage.jsm similarity index 99% rename from toolkit/components/telemetry/TelemetryStorage.jsm rename to toolkit/components/telemetry/app/TelemetryStorage.jsm index 765d645b9c0a..3c2251b83c6b 100644 --- a/toolkit/components/telemetry/TelemetryStorage.jsm +++ b/toolkit/components/telemetry/app/TelemetryStorage.jsm @@ -39,7 +39,7 @@ XPCOMUtils.defineLazyGetter(this, "gAbortedSessionFilePath", function() { ChromeUtils.defineModuleGetter(this, "CommonUtils", "resource://services-common/utils.js"); ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing", - "resource://gre/modules/TelemetryHealthPing.jsm"); + "resource://gre/modules/HealthPing.jsm"); // Maxmimum time, in milliseconds, archive pings should be retained. const MAX_ARCHIVED_PINGS_RETENTION_MS = 60 * 24 * 60 * 60 * 1000; // 60 days diff --git a/toolkit/components/telemetry/TelemetryTimestamps.jsm b/toolkit/components/telemetry/app/TelemetryTimestamps.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryTimestamps.jsm rename to toolkit/components/telemetry/app/TelemetryTimestamps.jsm diff --git a/toolkit/components/telemetry/TelemetryUtils.jsm b/toolkit/components/telemetry/app/TelemetryUtils.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryUtils.jsm rename to toolkit/components/telemetry/app/TelemetryUtils.jsm diff --git a/toolkit/components/telemetry/gen_event_data.py b/toolkit/components/telemetry/build_scripts/gen_event_data.py similarity index 97% rename from toolkit/components/telemetry/gen_event_data.py rename to toolkit/components/telemetry/build_scripts/gen_event_data.py index 85569245dc08..97dce90688f7 100644 --- a/toolkit/components/telemetry/gen_event_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_event_data.py @@ -7,10 +7,10 @@ from __future__ import print_function from collections import OrderedDict -from shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers import parse_events import json -import parse_events import sys import itertools @@ -22,7 +22,7 @@ banner = """/* This file is auto-generated, only for internal use in TelemetryEv file_header = """\ #ifndef mozilla_TelemetryEventData_h #define mozilla_TelemetryEventData_h -#include "EventInfo.h" +#include "core/EventInfo.h" namespace { """ diff --git a/toolkit/components/telemetry/gen_event_enum.py b/toolkit/components/telemetry/build_scripts/gen_event_enum.py similarity index 96% rename from toolkit/components/telemetry/gen_event_enum.py rename to toolkit/components/telemetry/build_scripts/gen_event_enum.py index 786bcae3af2a..7b1f7d2fb76a 100644 --- a/toolkit/components/telemetry/gen_event_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_event_enum.py @@ -7,10 +7,10 @@ # The events are defined in files provided as command-line arguments. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_events import sys -import parse_events banner = """/* This file is auto-generated, see gen_event_enum.py. */ """ diff --git a/toolkit/components/telemetry/gen_histogram_data.py b/toolkit/components/telemetry/build_scripts/gen_histogram_data.py similarity index 98% rename from toolkit/components/telemetry/gen_histogram_data.py rename to toolkit/components/telemetry/build_scripts/gen_histogram_data.py index 7af76cc72e87..76a9cfaa6525 100644 --- a/toolkit/components/telemetry/gen_histogram_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_histogram_data.py @@ -6,10 +6,10 @@ # in a file provided as a command-line argument. from __future__ import print_function -from shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers import parse_histograms import sys -import parse_histograms import buildconfig banner = """/* This file is auto-generated, see gen_histogram_data.py. */ diff --git a/toolkit/components/telemetry/gen_histogram_enum.py b/toolkit/components/telemetry/build_scripts/gen_histogram_enum.py similarity index 97% rename from toolkit/components/telemetry/gen_histogram_enum.py rename to toolkit/components/telemetry/build_scripts/gen_histogram_enum.py index 9a9fde03431f..75c4f7bcc3b7 100644 --- a/toolkit/components/telemetry/gen_histogram_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_histogram_enum.py @@ -13,9 +13,9 @@ # The histograms are defined in files provided as command-line arguments. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_histograms -import parse_histograms import itertools import sys import buildconfig diff --git a/toolkit/components/telemetry/gen_histogram_phf.py b/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py similarity index 94% rename from toolkit/components/telemetry/gen_histogram_phf.py rename to toolkit/components/telemetry/build_scripts/gen_histogram_phf.py index f291f10f56dc..8918967f5e5c 100644 --- a/toolkit/components/telemetry/gen_histogram_phf.py +++ b/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py @@ -3,12 +3,12 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError from perfecthash import PerfectHash PHFSIZE = 512 -import parse_histograms +from parsers import parse_histograms import sys import buildconfig diff --git a/toolkit/components/telemetry/gen_process_data.py b/toolkit/components/telemetry/build_scripts/gen_process_data.py similarity index 97% rename from toolkit/components/telemetry/gen_process_data.py rename to toolkit/components/telemetry/build_scripts/gen_process_data.py index 56842c640ea2..8bfe90fdf0c5 100644 --- a/toolkit/components/telemetry/gen_process_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_process_data.py @@ -6,7 +6,7 @@ # in a file provided as a command-line argument. from __future__ import print_function -from shared_telemetry_utils import ParserError, load_yaml_file +from parsers.shared_telemetry_utils import ParserError, load_yaml_file import sys import collections diff --git a/toolkit/components/telemetry/gen_process_enum.py b/toolkit/components/telemetry/build_scripts/gen_process_enum.py similarity index 96% rename from toolkit/components/telemetry/gen_process_enum.py rename to toolkit/components/telemetry/build_scripts/gen_process_enum.py index d771e381c0bf..c70326b2b003 100644 --- a/toolkit/components/telemetry/gen_process_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_process_enum.py @@ -6,7 +6,7 @@ # in a file provided as a command-line argument. from __future__ import print_function -from shared_telemetry_utils import ParserError, load_yaml_file +from parsers.shared_telemetry_utils import ParserError, load_yaml_file import sys import collections diff --git a/toolkit/components/telemetry/gen_scalar_data.py b/toolkit/components/telemetry/build_scripts/gen_scalar_data.py similarity index 96% rename from toolkit/components/telemetry/gen_scalar_data.py rename to toolkit/components/telemetry/build_scripts/gen_scalar_data.py index ca4b8b462c7d..e86b30ecfdc6 100644 --- a/toolkit/components/telemetry/gen_scalar_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_scalar_data.py @@ -7,10 +7,10 @@ from __future__ import print_function from collections import OrderedDict -from shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers import parse_scalars import json -import parse_scalars import sys # The banner/text at the top of the generated file. @@ -21,7 +21,7 @@ banner = """/* This file is auto-generated, only for internal use in TelemetrySc file_header = """\ #ifndef mozilla_TelemetryScalarData_h #define mozilla_TelemetryScalarData_h -#include "ScalarInfo.h" +#include "core/ScalarInfo.h" namespace { """ diff --git a/toolkit/components/telemetry/gen_scalar_enum.py b/toolkit/components/telemetry/build_scripts/gen_scalar_enum.py similarity index 94% rename from toolkit/components/telemetry/gen_scalar_enum.py rename to toolkit/components/telemetry/build_scripts/gen_scalar_enum.py index d84895a91595..4ae2ceeb6ba2 100644 --- a/toolkit/components/telemetry/gen_scalar_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_scalar_enum.py @@ -8,10 +8,10 @@ # The scalars are defined in files provided as command-line arguments. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_scalars import sys -import parse_scalars banner = """/* This file is auto-generated, see gen_scalar_enum.py. */ """ diff --git a/toolkit/components/telemetry/build_scripts/parsers/__init__.py b/toolkit/components/telemetry/build_scripts/parsers/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/toolkit/components/telemetry/parse_events.py b/toolkit/components/telemetry/build_scripts/parsers/parse_events.py similarity index 100% rename from toolkit/components/telemetry/parse_events.py rename to toolkit/components/telemetry/build_scripts/parsers/parse_events.py diff --git a/toolkit/components/telemetry/parse_histograms.py b/toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py similarity index 98% rename from toolkit/components/telemetry/parse_histograms.py rename to toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py index a552d75283cd..89987f7650c2 100755 --- a/toolkit/components/telemetry/parse_histograms.py +++ b/toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py @@ -96,8 +96,13 @@ whitelists = None def load_whitelist(): global whitelists try: - whitelist_path = os.path.join(os.path.abspath(os.path.realpath(os.path.dirname(__file__))), - 'histogram-whitelists.json') + parsers_path = os.path.realpath(os.path.dirname(__file__)) + # The parsers live in build_scripts/parsers in the Telemetry module, while + # the histogram-whitelists file lives in the root of the module. Account + # for that when looking for the whitelist. + # NOTE: if the parsers are moved, this logic will need to be updated. + telemetry_module_path = os.path.abspath(os.path.join(parsers_path, os.pardir, os.pardir)) + whitelist_path = os.path.join(telemetry_module_path, 'histogram-whitelists.json') with open(whitelist_path, 'r') as f: try: whitelists = json.load(f) diff --git a/toolkit/components/telemetry/parse_scalars.py b/toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py similarity index 100% rename from toolkit/components/telemetry/parse_scalars.py rename to toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py diff --git a/toolkit/components/telemetry/shared_telemetry_utils.py b/toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py similarity index 100% rename from toolkit/components/telemetry/shared_telemetry_utils.py rename to toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py diff --git a/toolkit/components/telemetry/EventInfo.h b/toolkit/components/telemetry/core/EventInfo.h similarity index 100% rename from toolkit/components/telemetry/EventInfo.h rename to toolkit/components/telemetry/core/EventInfo.h diff --git a/toolkit/components/telemetry/ScalarInfo.h b/toolkit/components/telemetry/core/ScalarInfo.h similarity index 100% rename from toolkit/components/telemetry/ScalarInfo.h rename to toolkit/components/telemetry/core/ScalarInfo.h diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/core/Telemetry.cpp similarity index 99% rename from toolkit/components/telemetry/Telemetry.cpp rename to toolkit/components/telemetry/core/Telemetry.cpp index eef1463533c1..19a45c26a4be 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/core/Telemetry.cpp @@ -24,7 +24,7 @@ #include "mozilla/Unused.h" #include "base/pickle.h" -#include "CombinedStacks.h" +#include "other/CombinedStacks.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" #include "nsThreadManager.h" @@ -52,11 +52,11 @@ #include "Telemetry.h" #include "TelemetryCommon.h" #include "TelemetryHistogram.h" -#include "TelemetryIOInterposeObserver.h" +#include "other/TelemetryIOInterposeObserver.h" #include "ipc/TelemetryIPCAccumulator.h" #include "TelemetryScalar.h" #include "TelemetryEvent.h" -#include "WebrtcTelemetry.h" +#include "other/WebrtcTelemetry.h" #include "nsTHashtable.h" #include "nsHashKeys.h" #include "nsBaseHashtable.h" @@ -91,7 +91,7 @@ #if defined(MOZ_GECKO_PROFILER) #include "shared-libraries.h" -#include "KeyedStackCapturer.h" +#include "other/KeyedStackCapturer.h" #endif // MOZ_GECKO_PROFILER #if defined(MOZ_TELEMETRY_GECKOVIEW) diff --git a/toolkit/components/telemetry/Telemetry.h b/toolkit/components/telemetry/core/Telemetry.h similarity index 100% rename from toolkit/components/telemetry/Telemetry.h rename to toolkit/components/telemetry/core/Telemetry.h diff --git a/toolkit/components/telemetry/TelemetryCommon.cpp b/toolkit/components/telemetry/core/TelemetryCommon.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryCommon.cpp rename to toolkit/components/telemetry/core/TelemetryCommon.cpp diff --git a/toolkit/components/telemetry/TelemetryCommon.h b/toolkit/components/telemetry/core/TelemetryCommon.h similarity index 100% rename from toolkit/components/telemetry/TelemetryCommon.h rename to toolkit/components/telemetry/core/TelemetryCommon.h diff --git a/toolkit/components/telemetry/TelemetryEvent.cpp b/toolkit/components/telemetry/core/TelemetryEvent.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryEvent.cpp rename to toolkit/components/telemetry/core/TelemetryEvent.cpp diff --git a/toolkit/components/telemetry/TelemetryEvent.h b/toolkit/components/telemetry/core/TelemetryEvent.h similarity index 100% rename from toolkit/components/telemetry/TelemetryEvent.h rename to toolkit/components/telemetry/core/TelemetryEvent.h diff --git a/toolkit/components/telemetry/TelemetryHistogram.cpp b/toolkit/components/telemetry/core/TelemetryHistogram.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryHistogram.cpp rename to toolkit/components/telemetry/core/TelemetryHistogram.cpp diff --git a/toolkit/components/telemetry/TelemetryHistogram.h b/toolkit/components/telemetry/core/TelemetryHistogram.h similarity index 100% rename from toolkit/components/telemetry/TelemetryHistogram.h rename to toolkit/components/telemetry/core/TelemetryHistogram.h diff --git a/toolkit/components/telemetry/TelemetryScalar.cpp b/toolkit/components/telemetry/core/TelemetryScalar.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryScalar.cpp rename to toolkit/components/telemetry/core/TelemetryScalar.cpp diff --git a/toolkit/components/telemetry/TelemetryScalar.h b/toolkit/components/telemetry/core/TelemetryScalar.h similarity index 100% rename from toolkit/components/telemetry/TelemetryScalar.h rename to toolkit/components/telemetry/core/TelemetryScalar.h diff --git a/toolkit/components/telemetry/ipc/TelemetryComms.h b/toolkit/components/telemetry/core/ipc/TelemetryComms.h similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryComms.h rename to toolkit/components/telemetry/core/ipc/TelemetryComms.h diff --git a/toolkit/components/telemetry/ipc/TelemetryIPC.cpp b/toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryIPC.cpp rename to toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp diff --git a/toolkit/components/telemetry/ipc/TelemetryIPC.h b/toolkit/components/telemetry/core/ipc/TelemetryIPC.h similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryIPC.h rename to toolkit/components/telemetry/core/ipc/TelemetryIPC.h diff --git a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp similarity index 99% rename from toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp rename to toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp index 4ca5bcd44640..71e0aa730032 100644 --- a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp +++ b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp @@ -16,8 +16,8 @@ #include "nsComponentManagerUtils.h" #include "nsITimer.h" #include "nsThreadUtils.h" -#include "TelemetryHistogram.h" -#include "TelemetryScalar.h" +#include "core/TelemetryHistogram.h" +#include "core/TelemetryScalar.h" using mozilla::StaticMutex; using mozilla::StaticMutexAutoLock; diff --git a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h rename to toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h diff --git a/toolkit/components/telemetry/nsITelemetry.idl b/toolkit/components/telemetry/core/nsITelemetry.idl similarity index 100% rename from toolkit/components/telemetry/nsITelemetry.idl rename to toolkit/components/telemetry/core/nsITelemetry.idl diff --git a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp index d9fe8145ec99..97d6250adbb2 100644 --- a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp +++ b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp @@ -29,8 +29,8 @@ #include "nsXULAppAPI.h" #include "prenv.h" #include "prio.h" -#include "TelemetryScalar.h" -#include "TelemetryHistogram.h" +#include "core/TelemetryScalar.h" +#include "core/TelemetryHistogram.h" #include "xpcpublic.h" using mozilla::GetErrorName; diff --git a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp index dcafc92fa473..7c2cd4ecece9 100644 --- a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp +++ b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp @@ -4,7 +4,7 @@ #include "TelemetryGeckoViewTesting.h" #include "TelemetryGeckoViewPersistence.h" -#include "TelemetryScalar.h" +#include "core/TelemetryScalar.h" namespace TelemetryGeckoViewTesting { // This is defined in TelemetryGeckoViewPersistence.cpp diff --git a/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp b/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp index 38c50ebbe6db..3c1e888439fe 100644 --- a/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp +++ b/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp @@ -15,10 +15,10 @@ #include "nsThreadUtils.h" #include "nsPrintfCString.h" #include "prenv.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryGeckoViewPersistence.h" -#include "TelemetryScalar.h" +#include "core/TelemetryScalar.h" #include "TelemetryTestHelpers.h" using namespace mozilla; diff --git a/toolkit/components/telemetry/gen-histogram-bucket-ranges.py b/toolkit/components/telemetry/gen-histogram-bucket-ranges.py deleted file mode 100644 index 7a2f1b697867..000000000000 --- a/toolkit/components/telemetry/gen-histogram-bucket-ranges.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Write out detailed histogram information, including the ranges of the -# buckets specified by each histogram. - -import sys -import parse_histograms -import json - -from collections import OrderedDict - - -def main(argv): - filenames = argv - - all_histograms = OrderedDict() - - for histogram in parse_histograms.from_files(filenames): - name = histogram.name() - parameters = OrderedDict() - table = { - 'boolean': '2', - 'flag': '3', - 'enumerated': '1', - 'linear': '1', - 'exponential': '0', - 'count': '4', - } - # Use __setitem__ because Python lambdas are so limited. - parse_histograms.table_dispatch(histogram.kind(), table, - lambda k: parameters.__setitem__('kind', k)) - if histogram.low() == 0: - parameters['min'] = 1 - else: - parameters['min'] = histogram.low() - - try: - buckets = histogram.ranges() - parameters['buckets'] = buckets - parameters['max'] = buckets[-1] - parameters['bucket_count'] = len(buckets) - except parse_histograms.DefinitionException: - continue - - all_histograms.update({name: parameters}) - - print json.dumps({'histograms': all_histograms}) - - -main(sys.argv[1:]) diff --git a/toolkit/components/telemetry/moz.build b/toolkit/components/telemetry/moz.build index 2bda9795ab40..489334d0a829 100644 --- a/toolkit/components/telemetry/moz.build +++ b/toolkit/components/telemetry/moz.build @@ -44,7 +44,7 @@ XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini'] BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini'] XPIDL_SOURCES += [ - 'nsITelemetry.idl', + 'core/nsITelemetry.idl', ] XPIDL_MODULE = 'telemetry' @@ -54,32 +54,32 @@ EXPORTS.mozilla += [ '!TelemetryHistogramEnums.h', '!TelemetryProcessEnums.h', '!TelemetryScalarEnums.h', - 'CombinedStacks.h', - 'ipc/TelemetryComms.h', - 'ipc/TelemetryIPC.h', - 'ProcessedStack.h', - 'Telemetry.h', + 'core/ipc/TelemetryComms.h', + 'core/ipc/TelemetryIPC.h', + 'core/Telemetry.h', + 'other/CombinedStacks.h', + 'other/ProcessedStack.h', ] SOURCES += [ - 'CombinedStacks.cpp', + 'core/ipc/TelemetryIPC.cpp', + 'core/ipc/TelemetryIPCAccumulator.cpp', + 'core/Telemetry.cpp', + 'core/TelemetryCommon.cpp', + 'core/TelemetryEvent.cpp', + 'core/TelemetryHistogram.cpp', + 'core/TelemetryScalar.cpp', 'geckoview/TelemetryGeckoViewPersistence.cpp', - 'ipc/TelemetryIPC.cpp', - 'ipc/TelemetryIPCAccumulator.cpp', - 'ProcessedStack.cpp', - 'Telemetry.cpp', - 'TelemetryCommon.cpp', - 'TelemetryEvent.cpp', - 'TelemetryHistogram.cpp', - 'TelemetryIOInterposeObserver.cpp', - 'TelemetryScalar.cpp', - 'WebrtcTelemetry.cpp', + 'other/CombinedStacks.cpp', + 'other/ProcessedStack.cpp', + 'other/TelemetryIOInterposeObserver.cpp', + 'other/WebrtcTelemetry.cpp', ] # KeyedStackCapturer entirely relies on profiler to be enabled. if CONFIG['MOZ_GECKO_PROFILER']: SOURCES += [ - 'KeyedStackCapturer.cpp' + 'other/KeyedStackCapturer.cpp' ] EXTRA_COMPONENTS += [ @@ -88,22 +88,22 @@ EXTRA_COMPONENTS += [ ] EXTRA_JS_MODULES += [ - 'GCTelemetry.jsm', - 'TelemetryArchive.jsm', - 'TelemetryController.jsm', - 'TelemetryEnvironment.jsm', - 'TelemetryEventPing.jsm', - 'TelemetryHealthPing.jsm', - 'TelemetryModules.jsm', - 'TelemetryReportingPolicy.jsm', - 'TelemetrySend.jsm', - 'TelemetrySession.jsm', - 'TelemetryStopwatch.jsm', - 'TelemetryStorage.jsm', - 'TelemetryTimestamps.jsm', - 'TelemetryUtils.jsm', - 'UITelemetry.jsm', - 'UpdatePing.jsm', + 'app/TelemetryArchive.jsm', + 'app/TelemetryController.jsm', + 'app/TelemetryEnvironment.jsm', + 'app/TelemetryReportingPolicy.jsm', + 'app/TelemetrySend.jsm', + 'app/TelemetryStopwatch.jsm', + 'app/TelemetryStorage.jsm', + 'app/TelemetryTimestamps.jsm', + 'app/TelemetryUtils.jsm', + 'other/GCTelemetry.jsm', + 'other/UITelemetry.jsm', + 'pings/EventPing.jsm', + 'pings/HealthPing.jsm', + 'pings/ModulesPing.jsm', + 'pings/TelemetrySession.jsm', + 'pings/UpdatePing.jsm', ] TESTING_JS_MODULES += [ @@ -136,15 +136,15 @@ histogram_files = [ ] data = GENERATED_FILES['TelemetryHistogramData.inc'] -data.script = 'gen_histogram_data.py' +data.script = 'build_scripts/gen_histogram_data.py' data.inputs = histogram_files enums = GENERATED_FILES['TelemetryHistogramEnums.h'] -enums.script = 'gen_histogram_enum.py' +enums.script = 'build_scripts/gen_histogram_enum.py' enums.inputs = histogram_files data = GENERATED_FILES['TelemetryHistogramNameMap.h'] -data.script = 'gen_histogram_phf.py' +data.script = 'build_scripts/gen_histogram_phf.py' data.inputs = histogram_files # Generate scalar files. @@ -153,17 +153,17 @@ scalar_files = [ ] scalar_data = GENERATED_FILES['TelemetryScalarData.h'] -scalar_data.script = 'gen_scalar_data.py' +scalar_data.script = 'build_scripts/gen_scalar_data.py' scalar_data.inputs = scalar_files scalar_enums = GENERATED_FILES['TelemetryScalarEnums.h'] -scalar_enums.script = 'gen_scalar_enum.py' +scalar_enums.script = 'build_scripts/gen_scalar_enum.py' scalar_enums.inputs = scalar_files # Generate the JSON scalar definitions. They will only be # used in artifact or "build faster" builds. scalar_json_data = GENERATED_FILES['ScalarArtifactDefinitions.json'] -scalar_json_data.script = 'gen_scalar_data.py:generate_JSON_definitions' +scalar_json_data.script = 'build_scripts/gen_scalar_data.py:generate_JSON_definitions' scalar_json_data.inputs = scalar_files # Move the scalars JSON file to the directory where the Firefox binary is. @@ -175,17 +175,17 @@ event_files = [ ] event_data = GENERATED_FILES['TelemetryEventData.h'] -event_data.script = 'gen_event_data.py' +event_data.script = 'build_scripts/gen_event_data.py' event_data.inputs = event_files event_enums = GENERATED_FILES['TelemetryEventEnums.h'] -event_enums.script = 'gen_event_enum.py' +event_enums.script = 'build_scripts/gen_event_enum.py' event_enums.inputs = event_files # Generate the JSON event definitions. They will only be # used in artifact or "build faster" builds. event_json_data = GENERATED_FILES['EventArtifactDefinitions.json'] -event_json_data.script = 'gen_event_data.py:generate_JSON_definitions' +event_json_data.script = 'build_scripts/gen_event_data.py:generate_JSON_definitions' event_json_data.inputs = event_files # Move the events JSON file to the directory where the Firefox binary is. @@ -197,11 +197,11 @@ processes_files = [ ] processes_enum = GENERATED_FILES['TelemetryProcessEnums.h'] -processes_enum.script = 'gen_process_enum.py' +processes_enum.script = 'build_scripts/gen_process_enum.py' processes_enum.inputs = processes_files processes_data = GENERATED_FILES['TelemetryProcessData.h'] -processes_data.script = 'gen_process_data.py' +processes_data.script = 'build_scripts/gen_process_data.py' processes_data.inputs = processes_files # Add support for GeckoView: please note that building GeckoView diff --git a/toolkit/components/telemetry/CombinedStacks.cpp b/toolkit/components/telemetry/other/CombinedStacks.cpp similarity index 100% rename from toolkit/components/telemetry/CombinedStacks.cpp rename to toolkit/components/telemetry/other/CombinedStacks.cpp diff --git a/toolkit/components/telemetry/CombinedStacks.h b/toolkit/components/telemetry/other/CombinedStacks.h similarity index 100% rename from toolkit/components/telemetry/CombinedStacks.h rename to toolkit/components/telemetry/other/CombinedStacks.h diff --git a/toolkit/components/telemetry/GCTelemetry.jsm b/toolkit/components/telemetry/other/GCTelemetry.jsm similarity index 100% rename from toolkit/components/telemetry/GCTelemetry.jsm rename to toolkit/components/telemetry/other/GCTelemetry.jsm diff --git a/toolkit/components/telemetry/KeyedStackCapturer.cpp b/toolkit/components/telemetry/other/KeyedStackCapturer.cpp similarity index 100% rename from toolkit/components/telemetry/KeyedStackCapturer.cpp rename to toolkit/components/telemetry/other/KeyedStackCapturer.cpp diff --git a/toolkit/components/telemetry/KeyedStackCapturer.h b/toolkit/components/telemetry/other/KeyedStackCapturer.h similarity index 98% rename from toolkit/components/telemetry/KeyedStackCapturer.h rename to toolkit/components/telemetry/other/KeyedStackCapturer.h index 6c3438265a6b..f6632b8fe29e 100644 --- a/toolkit/components/telemetry/KeyedStackCapturer.h +++ b/toolkit/components/telemetry/other/KeyedStackCapturer.h @@ -6,7 +6,7 @@ #ifndef KeyedStackCapturer_h__ #define KeyedStackCapturer_h__ -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "nsString.h" #include "nsClassHashtable.h" #include "mozilla/Mutex.h" diff --git a/toolkit/components/telemetry/ProcessedStack.cpp b/toolkit/components/telemetry/other/ProcessedStack.cpp similarity index 100% rename from toolkit/components/telemetry/ProcessedStack.cpp rename to toolkit/components/telemetry/other/ProcessedStack.cpp diff --git a/toolkit/components/telemetry/ProcessedStack.h b/toolkit/components/telemetry/other/ProcessedStack.h similarity index 100% rename from toolkit/components/telemetry/ProcessedStack.h rename to toolkit/components/telemetry/other/ProcessedStack.h diff --git a/toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp similarity index 99% rename from toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp rename to toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp index 411437fdb123..76ba444abc8c 100644 --- a/toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp +++ b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "TelemetryIOInterposeObserver.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" namespace mozilla { namespace Telemetry { diff --git a/toolkit/components/telemetry/TelemetryIOInterposeObserver.h b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h similarity index 99% rename from toolkit/components/telemetry/TelemetryIOInterposeObserver.h rename to toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h index f92881cfc224..efffe3ee19b9 100644 --- a/toolkit/components/telemetry/TelemetryIOInterposeObserver.h +++ b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h @@ -20,7 +20,7 @@ #include "nsBaseHashtable.h" #include "nsClassHashtable.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" #include "mozilla/IOInterposer.h" namespace mozilla { diff --git a/toolkit/components/telemetry/UITelemetry.jsm b/toolkit/components/telemetry/other/UITelemetry.jsm similarity index 100% rename from toolkit/components/telemetry/UITelemetry.jsm rename to toolkit/components/telemetry/other/UITelemetry.jsm diff --git a/toolkit/components/telemetry/WebrtcTelemetry.cpp b/toolkit/components/telemetry/other/WebrtcTelemetry.cpp similarity index 98% rename from toolkit/components/telemetry/WebrtcTelemetry.cpp rename to toolkit/components/telemetry/other/WebrtcTelemetry.cpp index 8c03f3a99fb0..0bc166ef7f24 100644 --- a/toolkit/components/telemetry/WebrtcTelemetry.cpp +++ b/toolkit/components/telemetry/other/WebrtcTelemetry.cpp @@ -5,8 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "Telemetry.h" -#include "TelemetryCommon.h" +#include "mozilla/Telemetry.h" #include "WebrtcTelemetry.h" #include "jsapi.h" #include "nsPrintfCString.h" diff --git a/toolkit/components/telemetry/WebrtcTelemetry.h b/toolkit/components/telemetry/other/WebrtcTelemetry.h similarity index 97% rename from toolkit/components/telemetry/WebrtcTelemetry.h rename to toolkit/components/telemetry/other/WebrtcTelemetry.h index ed87c71073ff..6f7f9e192a16 100644 --- a/toolkit/components/telemetry/WebrtcTelemetry.h +++ b/toolkit/components/telemetry/other/WebrtcTelemetry.h @@ -9,7 +9,7 @@ #include "nsBaseHashtable.h" #include "nsHashKeys.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" class WebrtcTelemetry { public: diff --git a/toolkit/components/telemetry/TelemetryEventPing.jsm b/toolkit/components/telemetry/pings/EventPing.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryEventPing.jsm rename to toolkit/components/telemetry/pings/EventPing.jsm diff --git a/toolkit/components/telemetry/TelemetryHealthPing.jsm b/toolkit/components/telemetry/pings/HealthPing.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryHealthPing.jsm rename to toolkit/components/telemetry/pings/HealthPing.jsm diff --git a/toolkit/components/telemetry/TelemetryModules.jsm b/toolkit/components/telemetry/pings/ModulesPing.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryModules.jsm rename to toolkit/components/telemetry/pings/ModulesPing.jsm diff --git a/toolkit/components/telemetry/TelemetrySession.jsm b/toolkit/components/telemetry/pings/TelemetrySession.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetrySession.jsm rename to toolkit/components/telemetry/pings/TelemetrySession.jsm diff --git a/toolkit/components/telemetry/UpdatePing.jsm b/toolkit/components/telemetry/pings/UpdatePing.jsm similarity index 100% rename from toolkit/components/telemetry/UpdatePing.jsm rename to toolkit/components/telemetry/pings/UpdatePing.jsm diff --git a/toolkit/components/telemetry/schemas/core.schema.json b/toolkit/components/telemetry/schemas/core.schema.json deleted file mode 100644 index 327cdc298904..000000000000 --- a/toolkit/components/telemetry/schemas/core.schema.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema" : "http://json-schema.org/draft-04/schema#", - "type" : "object", - "name" : "core", - "properties" : { - "arch" : { - "type" : "string" - }, - "clientId" : { - "type" : "string", - "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" - }, - "device" : { - "type" : "string" - }, - "experiments" : { - "type" : "array", - "items" : { - "type" : "string" - } - }, - "locale" : { - "type" : "string" - }, - "os" : { - "type" : "string" - }, - "osversion" : { - "type" : "string" - }, - "seq" : { - "type" : "integer", - "minimum": 0 - }, - "v" : { - "type" : "integer", - "enum" : [ 1 ] - } - }, - "required" : ["arch", "clientId", "device", "locale", "os", "osversion", "seq", "v"] -} diff --git a/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp b/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp index da4fe71c9775..bd1db74c1c92 100644 --- a/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp +++ b/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "mozilla/CycleCollectedJSContext.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" #include "mozilla/Unused.h" using namespace mozilla; diff --git a/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp b/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp index 27225beb13e8..fa75ea5ace43 100644 --- a/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp @@ -2,8 +2,8 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -#include "CombinedStacks.h" -#include "ProcessedStack.h" +#include "other/CombinedStacks.h" +#include "other/ProcessedStack.h" using namespace mozilla::Telemetry; using namespace TelemetryTestHelpers; diff --git a/toolkit/components/telemetry/tests/gtest/TestCounters.cpp b/toolkit/components/telemetry/tests/gtest/TestCounters.cpp index eefe4f6f090e..0df7879b17ce 100644 --- a/toolkit/components/telemetry/tests/gtest/TestCounters.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestCounters.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "js/Conversions.h" #include "nsITelemetry.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryTestHelpers.h" diff --git a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp index bfc53da43303..dee74f1ee609 100644 --- a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "js/Conversions.h" #include "nsITelemetry.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryTestHelpers.h" diff --git a/toolkit/components/telemetry/tests/gtest/TestScalars.cpp b/toolkit/components/telemetry/tests/gtest/TestScalars.cpp index f5cc7f523529..e8a808a77314 100644 --- a/toolkit/components/telemetry/tests/gtest/TestScalars.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestScalars.cpp @@ -10,10 +10,10 @@ #include "nsJSUtils.h" // nsAutoJSString #include "nsITelemetry.h" #include "nsThreadUtils.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "mozilla/TelemetryProcessEnums.h" #include "TelemetryFixture.h" -#include "TelemetryScalar.h" +#include "core/TelemetryScalar.h" #include "TelemetryTestHelpers.h" using namespace mozilla; diff --git a/toolkit/components/telemetry/tests/python/test_gen_event_data_json.py b/toolkit/components/telemetry/tests/python/test_gen_event_data_json.py index afc673786c80..a8ddd6f6df0f 100644 --- a/toolkit/components/telemetry/tests/python/test_gen_event_data_json.py +++ b/toolkit/components/telemetry/tests/python/test_gen_event_data_json.py @@ -13,6 +13,9 @@ from os import path TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) +# The generators live in "build_scripts", account for that. +# NOTE: if the generators are moved, this logic will need to be updated. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) import gen_event_data # noqa: E402 diff --git a/toolkit/components/telemetry/tests/python/test_gen_scalar_data_json.py b/toolkit/components/telemetry/tests/python/test_gen_scalar_data_json.py index 56178b5092cc..e52831daeab9 100644 --- a/toolkit/components/telemetry/tests/python/test_gen_scalar_data_json.py +++ b/toolkit/components/telemetry/tests/python/test_gen_scalar_data_json.py @@ -13,6 +13,8 @@ from os import path TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) +# The generators live in "build_scripts", account for that. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) import gen_scalar_data # noqa: E402 diff --git a/toolkit/components/telemetry/tests/python/test_histogramtools_non_strict.py b/toolkit/components/telemetry/tests/python/test_histogramtools_non_strict.py index 3951e29ba5e4..193d84659096 100644 --- a/toolkit/components/telemetry/tests/python/test_histogramtools_non_strict.py +++ b/toolkit/components/telemetry/tests/python/test_histogramtools_non_strict.py @@ -10,7 +10,10 @@ from os import path TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) -import parse_histograms # noqa: E402 +# The parsers live in a subdirectory of "build_scripts", account for that. +# NOTE: if the parsers are moved, this logic will need to be updated. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) +from parsers import parse_histograms # noqa: E402 def load_histogram(histograms): diff --git a/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py b/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py index d9a3fe63b0c9..2c557667339c 100644 --- a/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py +++ b/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py @@ -10,8 +10,11 @@ from test_histogramtools_non_strict import load_histogram TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) -from shared_telemetry_utils import ParserError -import parse_histograms +# The parsers live in a subdirectory of "build_scripts", account for that. +# NOTE: if the parsers are moved, this logic will need to be updated. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_histograms class TestParser(unittest.TestCase): diff --git a/toolkit/components/telemetry/tests/python/test_parse_scalars.py b/toolkit/components/telemetry/tests/python/test_parse_scalars.py index a6d47ac28447..ce3a22821d49 100644 --- a/toolkit/components/telemetry/tests/python/test_parse_scalars.py +++ b/toolkit/components/telemetry/tests/python/test_parse_scalars.py @@ -10,8 +10,11 @@ from os import path TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) -from shared_telemetry_utils import ParserError -import parse_scalars +# The parsers live in a subdirectory of "build_scripts", account for that. +# NOTE: if the parsers are moved, this logic will need to be updated. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_scalars def load_scalar(scalar): diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryEventPing.js b/toolkit/components/telemetry/tests/unit/test_EventPing.js similarity index 98% rename from toolkit/components/telemetry/tests/unit/test_TelemetryEventPing.js rename to toolkit/components/telemetry/tests/unit/test_EventPing.js index ae3f42d5c501..06fe61f9fa28 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryEventPing.js +++ b/toolkit/components/telemetry/tests/unit/test_EventPing.js @@ -12,7 +12,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryEventPing", - "resource://gre/modules/TelemetryEventPing.jsm"); + "resource://gre/modules/EventPing.jsm"); function checkPingStructure(type, payload, options) { Assert.equal(type, TelemetryEventPing.EVENT_PING_TYPE, "Should be an event ping."); @@ -26,7 +26,7 @@ function checkPingStructure(type, payload, options) { } function fakePolicy(set, clear, send) { - let mod = ChromeUtils.import("resource://gre/modules/TelemetryEventPing.jsm", {}); + let mod = ChromeUtils.import("resource://gre/modules/EventPing.jsm", {}); mod.Policy.setTimeout = set; mod.Policy.clearTimeout = clear; mod.Policy.sendPing = send; diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryEventPing_disabled.js b/toolkit/components/telemetry/tests/unit/test_EventPing_disabled.js similarity index 94% rename from toolkit/components/telemetry/tests/unit/test_TelemetryEventPing_disabled.js rename to toolkit/components/telemetry/tests/unit/test_EventPing_disabled.js index 7a08fd409f14..af86a1e64e92 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryEventPing_disabled.js +++ b/toolkit/components/telemetry/tests/unit/test_EventPing_disabled.js @@ -12,7 +12,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryEventPing", - "resource://gre/modules/TelemetryEventPing.jsm"); + "resource://gre/modules/EventPing.jsm"); const OPTIN = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN; diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js b/toolkit/components/telemetry/tests/unit/test_HealthPing.js similarity index 98% rename from toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js rename to toolkit/components/telemetry/tests/unit/test_HealthPing.js index 93a0724fd211..5293f11bd000 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js +++ b/toolkit/components/telemetry/tests/unit/test_HealthPing.js @@ -14,7 +14,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing", - "resource://gre/modules/TelemetryHealthPing.jsm"); + "resource://gre/modules/HealthPing.jsm"); function checkHealthPingStructure(ping, expectedFailuresDict) { let payload = ping.payload; @@ -26,7 +26,7 @@ function checkHealthPingStructure(ping, expectedFailuresDict) { } function fakeHealthSchedulerTimer(set, clear) { - let telemetryHealthPing = ChromeUtils.import("resource://gre/modules/TelemetryHealthPing.jsm", {}); + let telemetryHealthPing = ChromeUtils.import("resource://gre/modules/HealthPing.jsm", {}); telemetryHealthPing.Policy.setSchedulerTickTimeout = set; telemetryHealthPing.Policy.clearSchedulerTickTimeout = clear; } diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryModules.js b/toolkit/components/telemetry/tests/unit/test_ModulesPing.js similarity index 99% rename from toolkit/components/telemetry/tests/unit/test_TelemetryModules.js rename to toolkit/components/telemetry/tests/unit/test_ModulesPing.js index 111131f07856..f8f2a271d7ac 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryModules.js +++ b/toolkit/components/telemetry/tests/unit/test_ModulesPing.js @@ -3,7 +3,7 @@ "use strict"; -ChromeUtils.import("resource://gre/modules/TelemetryModules.jsm"); +ChromeUtils.import("resource://gre/modules/ModulesPing.jsm"); ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); ChromeUtils.import("resource://gre/modules/Preferences.jsm"); ChromeUtils.import("resource://gre/modules/ctypes.jsm"); diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js b/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js index bdf3e3b99f13..b6278104965f 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js @@ -20,7 +20,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing", - "resource://gre/modules/TelemetryHealthPing.jsm"); + "resource://gre/modules/HealthPing.jsm"); XPCOMUtils.defineLazyServiceGetter(Services, "cookies", "@mozilla.org/cookieService;1", "nsICookieService"); diff --git a/toolkit/components/telemetry/tests/unit/xpcshell.ini b/toolkit/components/telemetry/tests/unit/xpcshell.ini index 5e4fa9d2ab4a..fa19989ccd96 100644 --- a/toolkit/components/telemetry/tests/unit/xpcshell.ini +++ b/toolkit/components/telemetry/tests/unit/xpcshell.ini @@ -45,7 +45,7 @@ skip-if = os == "android" [test_TelemetryLateWrites.js] [test_TelemetryLockCount.js] [test_TelemetryController.js] -[test_TelemetryHealthPing.js] +[test_HealthPing.js] skip-if = (verify && (os == 'win')) tags = addons [test_TelemetryController_idle.js] @@ -82,11 +82,11 @@ skip-if = os == "android" # Disabled due to crashes (see bug 1331366) [test_TelemetryEvents_buildFaster.js] [test_ChildEvents.js] skip-if = os == "android" # Disabled due to crashes (see bug 1331366) -[test_TelemetryModules.js] +[test_ModulesPing.js] [test_PingSender.js] skip-if = (os == "android") || (os == "linux" && bits == 32) [test_TelemetryGC.js] [test_TelemetryAndroidEnvironment.js] [test_TelemetryUtils.js] -[test_TelemetryEventPing.js] -[test_TelemetryEventPing_disabled.js] +[test_EventPing.js] +[test_EventPing_disabled.js] diff --git a/toolkit/content/widgets/tabbox.xml b/toolkit/content/widgets/tabbox.xml index 72ad869b9e66..3367b6bd44ac 100644 --- a/toolkit/content/widgets/tabbox.xml +++ b/toolkit/content/widgets/tabbox.xml @@ -538,39 +538,39 @@ ]]> - + - + - + - + - + - + Dispatch(NS_NewRunnableFunction("CrashReporter::InvokeCallback", std::move(runnable)), - NS_DISPATCH_SYNC); + NS_DISPATCH_NORMAL); } else { runnable(); } diff --git a/toolkit/xre/SafeMode.h b/toolkit/xre/SafeMode.h index 2c4aa978473b..5ac652be2d92 100644 --- a/toolkit/xre/SafeMode.h +++ b/toolkit/xre/SafeMode.h @@ -25,7 +25,8 @@ namespace mozilla { enum class SafeModeFlag : uint32_t { None = 0, - Unset = (1 << 0) + Unset = (1 << 0), + NoKeyPressCheck = (1 << 1), }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SafeModeFlag) @@ -56,7 +57,8 @@ IsSafeModeRequested(int& aArgc, CharT* aArgv[], // order bit will be 1 if the key is pressed. By masking the returned short // with 0x8000 the result will be 0 if the key is not pressed and non-zero // otherwise. - if ((GetKeyState(VK_SHIFT) & 0x8000) && + if (!(aFlags & SafeModeFlag::NoKeyPressCheck) && + (GetKeyState(VK_SHIFT) & 0x8000) && !(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000) && !EnvHasValue("MOZ_DISABLE_SAFE_MODE_KEY")) { @@ -69,7 +71,8 @@ IsSafeModeRequested(int& aArgc, CharT* aArgv[], #endif // defined(XP_WIN) #if defined(XP_MACOSX) - if ((GetCurrentEventKeyModifiers() & optionKey) && + if (!(aFlags & SafeModeFlag::NoKeyPressCheck) && + (GetCurrentEventKeyModifiers() & optionKey) && !EnvHasValue("MOZ_DISABLE_SAFE_MODE_KEY")) { result = true; } diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js index 3471f39300cc..de27179d2b2f 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js @@ -1,11 +1,22 @@ "use strict"; +/** + * The configuration is based on eslint:recommended config. The details for all + * the ESLint rules, and which ones are in the recommended configuration can + * be found here: + * + * https://eslint.org/docs/rules/ + */ module.exports = { "env": { "browser": true, "es6": true }, + "extends": [ + "eslint:recommended" + ], + "globals": { "AddonManagerPermissions": false, "BroadcastChannel": false, @@ -135,6 +146,10 @@ module.exports = { // Functions must always return something or nothing "consistent-return": "error", + // XXX This rule line should be removed to enable it. See bug 1487642. + // Require super() calls in constructors + "constructor-super": "off", + // Require braces around blocks that start a new line // Note that this rule is likely to be overridden on a per-directory basis // very frequently. @@ -152,6 +167,10 @@ module.exports = { // Require function* name() "generator-star-spacing": ["error", {"after": true, "before": false}], + // XXX This rule line should be removed to enable it. See bug 1487642. + // Enforce return statements in getters + "getter-return": "off", + // Two space indent // "indent": ["error", 2, { "SwitchCase": 1 }], @@ -201,74 +220,46 @@ module.exports = { // Disallow use of arguments.caller or arguments.callee. "no-caller": "error", - // Disallow modifying variables of class declarations. - "no-class-assign": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow lexical declarations in case clauses + "no-case-declarations": "off", - // Disallow assignment operators in conditional statements - "no-cond-assign": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow the use of console + "no-console": "off", - // Disallow modifying variables that are declared using const. - "no-const-assign": "error", - - // Disallow control characters in regular expressions. - "no-control-regex": "error", - - // Disallow the use of debugger - "no-debugger": "error", - - // Disallow deleting variables - "no-delete-var": "error", - - // No duplicate arguments in function declarations - "no-dupe-args": "error", - - // Disallow duplicate class members. - "no-dupe-class-members": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow constant expressions in conditions + "no-constant-condition": "off", // No duplicate keys in object declarations "no-dupe-keys": "error", - // No duplicate cases in switch statements - "no-duplicate-case": "error", - // If an if block ends with a return no need for an else block "no-else-return": "error", // No empty statements "no-empty": ["error", {"allowEmptyCatch": true}], - // No empty character classes in regex - "no-empty-character-class": "error", - - // Disallow empty destructuring - "no-empty-pattern": "error", - // Disallow eval and setInteral/setTimeout with strings "no-eval": "error", - // No assigning to exception variable - "no-ex-assign": "error", - // Disallow unnecessary calls to .bind() "no-extra-bind": "error", - // No using !! where casting to boolean is already happening - "no-extra-boolean-cast": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow fallthrough of case statements + "no-fallthrough": "off", - // No double semicolon - "no-extra-semi": "error", - - // No overwriting defined functions - "no-func-assign": "error", + // Disallow assignments to native objects or read-only global variables + "no-global-assign": "error", // Disallow eval and setInteral/setTimeout with strings "no-implied-eval": "error", - // No invalid regular expressions - "no-invalid-regexp": "error", - - // No odd whitespace characters - "no-irregular-whitespace": "error", + // This has been superseded since we're using ES6. + // Disallow variable or function declarations in nested blocks + "no-inner-declarations": "off", // Disallow the use of the __iterator__ property "no-iterator": "error", @@ -282,9 +273,6 @@ module.exports = { // No single if block inside an else block "no-lonely-if": "error", - // no-tabs disallows tabs completely. - // "no-mixed-spaces-and-tabs": "error", - // No unnecessary spacing "no-multi-spaces": ["error", { exceptions: { "ArrayExpression": true, @@ -293,9 +281,6 @@ module.exports = { "VariableDeclarator": true } }], - // No reassigning native JS objects - "no-native-reassign": "error", - // Nested ternary statements are confusing "no-nested-ternary": "error", @@ -305,24 +290,9 @@ module.exports = { // Dissallow use of new wrappers "no-new-wrappers": "error", - // No Math() or JSON() - "no-obj-calls": "error", - - // No octal literals - "no-octal": "error", - - // No redeclaring variables - "no-redeclare": "error", - - // Disallow multiple spaces in regular expressions - "no-regex-spaces": "error", - // Disallows unnecessary `return await ...`. "no-return-await": "error", - // Disallow assignments where both sides are exactly the same - "no-self-assign": "error", - // No unnecessary comparisons "no-self-compare": "error", @@ -335,33 +305,15 @@ module.exports = { // No declaring variables that hide things like arguments "no-shadow-restricted-names": "error", - // Disallow sparse arrays - "no-sparse-arrays": "error", - // Disallow tabs. "no-tabs": "error", // No trailing whitespace "no-trailing-spaces": "error", - // No using undeclared variables - "no-undef": "error", - - // Error on newline where a semicolon is needed - "no-unexpected-multiline": "error", - // Disallow the use of Boolean literals in conditional expressions. "no-unneeded-ternary": "error", - // No unreachable statements - "no-unreachable": "error", - - // Disallow control flow statements in finally blocks - "no-unsafe-finally": "error", - - // No (!foo in bar) or (!object instanceof Class) - "no-unsafe-negation": "error", - // No unsanitized use of innerHTML=, document.write() etc. // cf. https://github.com/mozilla/eslint-plugin-no-unsanitized#rule-details "no-unsanitized/method": "error", @@ -383,6 +335,10 @@ module.exports = { // lines) "no-useless-concat": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow unnecessary escape characters + "no-useless-escape": "off", + // Disallow redundant return statements "no-useless-return": "error", @@ -402,6 +358,10 @@ module.exports = { "avoidEscape": true }], + // XXX Bug 1487642 - decide if we want to enable this or not. + // Require generator functions to contain yield + "require-yield": "off", + // No spacing inside rest or spread expressions "rest-spread-spacing": "error", @@ -435,11 +395,5 @@ module.exports = { // Requires or disallows a whitespace (space or tab) beginning a comment "spaced-comment": "error", - - // No comparisons to NaN - "use-isnan": "error", - - // Only check typeof against valid results - "valid-typeof": "error" } }; diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json index 3ec6e45eee4a..fd89bb068f93 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "0.15.4", + "version": "0.16.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package.json b/tools/lint/eslint/eslint-plugin-mozilla/package.json index e563af8ff31b..33edfb865091 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "0.15.4", + "version": "0.16.0", "description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.", "keywords": [ "eslint", diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index 32184d2d34c2..ba7198f87767 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -381,7 +381,9 @@ TISInputSourceWrapper::TranslateToString(UInt32 aKeyCode, UInt32 aModifiers, if (len == 0) { return true; } - NS_ENSURE_TRUE(EnsureStringLength(aStr, len), false); + if (!aStr.SetLength(len, fallible)) { + return false; + } NS_ASSERTION(sizeof(char16_t) == sizeof(UniChar), "size of char16_t and size of UniChar are different"); memcpy(aStr.BeginWriting(), chars, len * sizeof(char16_t)); diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp index 39b370520e60..fbb722277d09 100644 --- a/widget/gtk/WindowSurfaceWayland.cpp +++ b/widget/gtk/WindowSurfaceWayland.cpp @@ -524,7 +524,7 @@ WindowBackBuffer::Detach() } bool -WindowBackBuffer::SetImageDataFromBackBuffer( +WindowBackBuffer::SetImageDataFromBuffer( class WindowBackBuffer* aSourceBuffer) { if (!IsMatchingSize(aSourceBuffer)) { @@ -562,27 +562,39 @@ static const struct wl_callback_listener frame_listener = { WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow) : mWindow(aWindow) , mWaylandDisplay(WaylandDisplayGet(aWindow->GetWaylandDisplay())) - , mFrontBuffer(nullptr) - , mBackBuffer(nullptr) + , mWaylandBuffer(nullptr) + , mBackupBuffer(nullptr) , mFrameCallback(nullptr) , mFrameCallbackSurface(nullptr) , mDisplayThreadMessageLoop(MessageLoop::current()) - , mDirectWlBufferDraw(true) - , mDelayedCommit(false) - , mFullScreenDamage(false) + , mDelayedCommitHandle(nullptr) + , mDrawToWaylandBufferDirectly(true) + , mPendingCommit(false) + , mWaylandBufferFullScreenDamage(false) , mIsMainThread(NS_IsMainThread()) { } WindowSurfaceWayland::~WindowSurfaceWayland() { - delete mFrontBuffer; - delete mBackBuffer; + if (mPendingCommit) { + NS_WARNING("Deleted WindowSurfaceWayland with a pending commit!"); + } + + if (mDelayedCommitHandle) { + // Delete reference to this to prevent WaylandBufferDelayCommitHandler() + // operate on released this. mDelayedCommitHandle itself will + // be released at WaylandBufferDelayCommitHandler(). + *mDelayedCommitHandle = nullptr; + } if (mFrameCallback) { wl_callback_destroy(mFrameCallback); } + delete mWaylandBuffer; + delete mBackupBuffer; + if (!mIsMainThread) { // We can be destroyed from main thread even though we was created/used // in compositor thread. We have to unref/delete WaylandDisplay in compositor @@ -600,69 +612,77 @@ void WindowSurfaceWayland::UpdateScaleFactor() { wl_surface* waylandSurface = mWindow->GetWaylandSurface(); - if (waylandSurface) { - wl_surface_set_buffer_scale(waylandSurface, mWindow->GdkScaleFactor()); + MOZ_ASSERT(waylandSurface, + "Missing Wayland wl_surface during wl_buffer switch!"); + if (!waylandSurface) { + // TODO: Set the scale factor properly later if we're missing wl_surface + // on wl_buffer request (Bug 1487763). + return; } + + wl_proxy_set_queue((struct wl_proxy *)waylandSurface, + mWaylandDisplay->GetEventQueue()); + wl_surface_set_buffer_scale(waylandSurface, mWindow->GdkScaleFactor()); } WindowBackBuffer* -WindowSurfaceWayland::GetFrontBufferToDraw(int aWidth, int aHeight) +WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth, int aHeight) { - if (!mFrontBuffer) { - mFrontBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); - mBackBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); - return mFrontBuffer; + if (!mWaylandBuffer) { + mWaylandBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); + mBackupBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); + return mWaylandBuffer; } - if (!mFrontBuffer->IsAttached()) { - if (!mFrontBuffer->IsMatchingSize(aWidth, aHeight)) { - mFrontBuffer->Resize(aWidth, aHeight); + if (!mWaylandBuffer->IsAttached()) { + if (!mWaylandBuffer->IsMatchingSize(aWidth, aHeight)) { + mWaylandBuffer->Resize(aWidth, aHeight); // There's a chance that scale factor has been changed // when buffer size changed UpdateScaleFactor(); } - return mFrontBuffer; + return mWaylandBuffer; } // Front buffer is used by compositor, draw to back buffer - if (mBackBuffer->IsAttached()) { + if (mBackupBuffer->IsAttached()) { NS_WARNING("No drawing buffer available"); return nullptr; } - MOZ_ASSERT(!mDelayedCommit, + MOZ_ASSERT(!mPendingCommit, "Uncommitted buffer switch, screen artifacts ahead."); - WindowBackBuffer *tmp = mFrontBuffer; - mFrontBuffer = mBackBuffer; - mBackBuffer = tmp; + WindowBackBuffer *tmp = mWaylandBuffer; + mWaylandBuffer = mBackupBuffer; + mBackupBuffer = tmp; - if (mBackBuffer->IsMatchingSize(aWidth, aHeight)) { + if (mBackupBuffer->IsMatchingSize(aWidth, aHeight)) { // Former front buffer has the same size as a requested one. // Gecko may expect a content already drawn on screen so copy // existing data to the new buffer. - mFrontBuffer->SetImageDataFromBackBuffer(mBackBuffer); + mWaylandBuffer->SetImageDataFromBuffer(mBackupBuffer); // When buffer switches we need to damage whole screen // (https://bugzilla.redhat.com/show_bug.cgi?id=1418260) - mFullScreenDamage = true; + mWaylandBufferFullScreenDamage = true; } else { // Former buffer has different size from the new request. Only resize // the new buffer and leave gecko to render new whole content. - mFrontBuffer->Resize(aWidth, aHeight); + mWaylandBuffer->Resize(aWidth, aHeight); } - return mFrontBuffer; + return mWaylandBuffer; } already_AddRefed -WindowSurfaceWayland::LockFrontBuffer(int aWidth, int aHeight) +WindowSurfaceWayland::LockWaylandBuffer(int aWidth, int aHeight) { - WindowBackBuffer* buffer = GetFrontBufferToDraw(aWidth, aHeight); + WindowBackBuffer* buffer = GetWaylandBufferToDraw(aWidth, aHeight); if (buffer) { return buffer->Lock(); } - NS_WARNING("WindowSurfaceWayland::LockFrontBuffer(): No buffer available"); + NS_WARNING("WindowSurfaceWayland::LockWaylandBuffer(): No buffer available"); return nullptr; } @@ -690,8 +710,8 @@ WindowSurfaceWayland::LockImageSurface(const gfx::IntSize& aLockSize) A) Lock() is called to whole surface. In that case we don't need to clip/buffer the drawing and we can return wl_buffer directly for drawing. - - mFrontBuffer is available - that's an ideal situation. - - mFrontBuffer is locked by compositor - flip buffers and draw. + - mWaylandBuffer is available - that's an ideal situation. + - mWaylandBuffer is locked by compositor - flip buffers and draw. - if we can't flip buffers - go B) B) Lock() is requested for part(s) of screen. We need to provide temporary @@ -707,30 +727,30 @@ WindowSurfaceWayland::Lock(const LayoutDeviceIntRegion& aRegion) gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); // Are we asked for entire nsWindow to draw? - mDirectWlBufferDraw = (aRegion.GetNumRects() == 1 && - bounds.x == 0 && bounds.y == 0 && - lockSize.width == screenRect.width && - lockSize.height == screenRect.height); + mDrawToWaylandBufferDirectly = (aRegion.GetNumRects() == 1 && + bounds.x == 0 && bounds.y == 0 && + lockSize.width == screenRect.width && + lockSize.height == screenRect.height); - if (mDirectWlBufferDraw) { - RefPtr dt = LockFrontBuffer(screenRect.width, - screenRect.height); + if (mDrawToWaylandBufferDirectly) { + RefPtr dt = LockWaylandBuffer(screenRect.width, + screenRect.height); if (dt) { return dt.forget(); } // We don't have any front buffer available. Try indirect drawing // to mImageSurface which is mirrored to front buffer at commit. - mDirectWlBufferDraw = false; + mDrawToWaylandBufferDirectly = false; } return LockImageSurface(lockSize); } bool -WindowSurfaceWayland::CommitImageSurface(const LayoutDeviceIntRegion& aRegion) +WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion) { - MOZ_ASSERT(!mDirectWlBufferDraw); + MOZ_ASSERT(!mDrawToWaylandBufferDirectly); LayoutDeviceIntRect screenRect = mWindow->GetBounds(); gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); @@ -740,8 +760,8 @@ WindowSurfaceWayland::CommitImageSurface(const LayoutDeviceIntRegion& aRegion) return false; } - RefPtr dt = LockFrontBuffer(screenRect.width, - screenRect.height); + RefPtr dt = LockWaylandBuffer(screenRect.width, + screenRect.height); RefPtr surf = gfx::Factory::CreateSourceSurfaceForCairoSurface(mImageSurface->CairoSurface(), mImageSurface->GetSize(), @@ -769,32 +789,70 @@ WindowSurfaceWayland::CommitImageSurface(const LayoutDeviceIntRegion& aRegion) return true; } -void -WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) +static void +WaylandBufferDelayCommitHandler(WindowSurfaceWayland **aSurface) { - MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); + if (*aSurface) { + (*aSurface)->DelayedCommitHandler(); + } else { + // Referenced WindowSurfaceWayland is already deleted. + // Do nothing but just release the mDelayedCommitHandle allocated at + // WindowSurfaceWayland::CommitWaylandBuffer(). + free(aSurface); + } +} + +void +WindowSurfaceWayland::CommitWaylandBuffer() +{ + MOZ_ASSERT(mPendingCommit, "Committing empty surface!"); wl_surface* waylandSurface = mWindow->GetWaylandSurface(); if (!waylandSurface) { - // Target window is already destroyed - don't bother to render there. - NS_WARNING("WindowSurfaceWayland::Commit(): parent wl_surface is already hidden/deleted."); + // Target window is not created yet - delay the commit. This can happen only + // when the window is newly created and there's no active + // frame callback pending. + MOZ_ASSERT(!mFrameCallback || waylandSurface != mFrameCallbackSurface, + "Missing wayland surface at frame callback!"); + + // Do nothing if there's already mDelayedCommitHandle pending. + if (!mDelayedCommitHandle) { + mDelayedCommitHandle = static_cast( + moz_xmalloc(sizeof(*mDelayedCommitHandle))); + *mDelayedCommitHandle = this; + + MessageLoop::current()->PostDelayedTask( + NewRunnableFunction("WaylandBackBufferCommit", + &WaylandBufferDelayCommitHandler, + mDelayedCommitHandle), + EVENT_LOOP_DELAY); + } return; } wl_proxy_set_queue((struct wl_proxy *)waylandSurface, mWaylandDisplay->GetEventQueue()); - if (!mDirectWlBufferDraw) { - // We have new content at mImageSurface - copy data to mFrontBuffer first. - CommitImageSurface(aInvalidRegion); + // We have an active frame callback request so handle it. + if (mFrameCallback) { + if (waylandSurface == mFrameCallbackSurface) { + // We have an active frame callback pending from our recent surface. + // It means we should defer the commit to FrameCallbackHandler(). + return; + } + // If our stored wl_surface does not match the actual one it means the frame + // callback is no longer active and we should release it. + wl_callback_destroy(mFrameCallback); + mFrameCallback = nullptr; + mFrameCallbackSurface = nullptr; } - if (mFullScreenDamage) { + if (mWaylandBufferFullScreenDamage) { LayoutDeviceIntRect rect = mWindow->GetBounds(); wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height); - mFullScreenDamage = false; + mWaylandBufferFullScreenDamage = false; } else { gint scaleFactor = mWindow->GdkScaleFactor(); - for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) { + for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); iter.Next()) { const mozilla::LayoutDeviceIntRect &r = iter.Get(); // We need to remove the scale factor because the wl_surface_damage // also multiplies by current scale factor. @@ -803,62 +861,69 @@ WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) } } - // Frame callback is always connected to actual wl_surface. When the surface - // is unmapped/deleted the frame callback is never called. Unfortunatelly - // we don't know if the frame callback is not going to be called. - // But our mozcontainer code deletes wl_surface when the GdkWindow is hidden - // creates a new one when is visible. - if (mFrameCallback && mFrameCallbackSurface == waylandSurface) { - // Do nothing here - we have a valid wl_surface and the buffer will be - // commited to compositor in next frame callback event. - mDelayedCommit = true; - return; - } else { - if (mFrameCallback) { - // Delete frame callback connected to obsoleted wl_surface. - wl_callback_destroy(mFrameCallback); - } + // Clear all back buffer damage as we're committing + // all requested regions. + mWaylandBufferDamage.SetEmpty(); - mFrameCallback = wl_surface_frame(waylandSurface); - wl_callback_add_listener(mFrameCallback, &frame_listener, this); - mFrameCallbackSurface = waylandSurface; + mFrameCallback = wl_surface_frame(waylandSurface); + wl_callback_add_listener(mFrameCallback, &frame_listener, this); + mFrameCallbackSurface = waylandSurface; - // There's no pending frame callback so we can draw immediately - // and create frame callback for possible subsequent drawing. - mFrontBuffer->Attach(waylandSurface); - mDelayedCommit = false; + mWaylandBuffer->Attach(waylandSurface); + + // There's no pending commit, all changes are sent to compositor. + mPendingCommit = false; +} + +void +WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) +{ + MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); + + // We have new content at mImageSurface - copy data to mWaylandBuffer first. + if (!mDrawToWaylandBufferDirectly) { + CommitImageSurfaceToWaylandBuffer(aInvalidRegion); } + + // If we're not at fullscreen damage add drawing area from aInvalidRegion + if (!mWaylandBufferFullScreenDamage) { + mWaylandBufferDamage.OrWith(aInvalidRegion); + } + + // We're ready to commit. + mPendingCommit = true; + CommitWaylandBuffer(); } void WindowSurfaceWayland::FrameCallbackHandler() { MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); + MOZ_ASSERT(mFrameCallback != nullptr, + "FrameCallbackHandler() called without valid frame callback!"); + MOZ_ASSERT(mFrameCallbackSurface != nullptr, + "FrameCallbackHandler() called without valid wl_surface!"); - if (mFrameCallback) { - wl_callback_destroy(mFrameCallback); - mFrameCallback = nullptr; - mFrameCallbackSurface = nullptr; + wl_callback_destroy(mFrameCallback); + mFrameCallback = nullptr; + mFrameCallbackSurface = nullptr; + + if (mPendingCommit) { + CommitWaylandBuffer(); } +} - if (mDelayedCommit) { - wl_surface* waylandSurface = mWindow->GetWaylandSurface(); - if (!waylandSurface) { - // Target window is already destroyed - don't bother to render there. - NS_WARNING("WindowSurfaceWayland::FrameCallbackHandler(): parent wl_surface is already hidden/deleted."); - return; - } - wl_proxy_set_queue((struct wl_proxy *)waylandSurface, - mWaylandDisplay->GetEventQueue()); +void +WindowSurfaceWayland::DelayedCommitHandler() +{ + MOZ_ASSERT(mDelayedCommitHandle != nullptr, "Missing mDelayedCommitHandle!"); - // Send pending surface to compositor and register frame callback - // for possible subsequent drawing. - mFrameCallback = wl_surface_frame(waylandSurface); - wl_callback_add_listener(mFrameCallback, &frame_listener, this); - mFrameCallbackSurface = waylandSurface; + *mDelayedCommitHandle = nullptr; + free(mDelayedCommitHandle); + mDelayedCommitHandle = nullptr; - mFrontBuffer->Attach(waylandSurface); - mDelayedCommit = false; + if (mPendingCommit) { + CommitWaylandBuffer(); } } diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h index ff7c6711b615..d42e413ce241 100644 --- a/widget/gtk/WindowSurfaceWayland.h +++ b/widget/gtk/WindowSurfaceWayland.h @@ -74,7 +74,7 @@ public: bool IsAttached() { return mAttached; } bool Resize(int aWidth, int aHeight); - bool SetImageDataFromBackBuffer(class WindowBackBuffer* aSourceBuffer); + bool SetImageDataFromBuffer(class WindowBackBuffer* aSourceBuffer); bool IsMatchingSize(int aWidth, int aHeight) { @@ -111,27 +111,31 @@ public: already_AddRefed Lock(const LayoutDeviceIntRegion& aRegion) override; void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final; void FrameCallbackHandler(); + void DelayedCommitHandler(); private: - WindowBackBuffer* GetFrontBufferToDraw(int aWidth, int aHeight); + WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight); void UpdateScaleFactor(); - already_AddRefed LockFrontBuffer(int aWidth, int aHeight); + already_AddRefed LockWaylandBuffer(int aWidth, int aHeight); already_AddRefed LockImageSurface(const gfx::IntSize& aLockSize); - bool CommitImageSurface(const LayoutDeviceIntRegion& aRegion); + bool CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion); + void CommitWaylandBuffer(); // TODO: Do we need to hold a reference to nsWindow object? nsWindow* mWindow; nsWaylandDisplay* mWaylandDisplay; - WindowBackBuffer* mFrontBuffer; - WindowBackBuffer* mBackBuffer; + WindowBackBuffer* mWaylandBuffer; + LayoutDeviceIntRegion mWaylandBufferDamage; + WindowBackBuffer* mBackupBuffer; RefPtr mImageSurface; wl_callback* mFrameCallback; wl_surface* mFrameCallbackSurface; MessageLoop* mDisplayThreadMessageLoop; - bool mDirectWlBufferDraw; - bool mDelayedCommit; - bool mFullScreenDamage; + WindowSurfaceWayland** mDelayedCommitHandle; + bool mDrawToWaylandBufferDirectly; + bool mPendingCommit; + bool mWaylandBufferFullScreenDamage; bool mIsMainThread; }; diff --git a/xpcom/components/Module.h b/xpcom/components/Module.h index b073e83d27f8..fac3e6ca8d54 100644 --- a/xpcom/components/Module.h +++ b/xpcom/components/Module.h @@ -23,7 +23,7 @@ namespace mozilla { */ struct Module { - static const unsigned int kVersion = 63; + static const unsigned int kVersion = 64; struct CIDEntry; diff --git a/xpcom/io/Base64.cpp b/xpcom/io/Base64.cpp index 69c34d02d30b..ccfa82a24f45 100644 --- a/xpcom/io/Base64.cpp +++ b/xpcom/io/Base64.cpp @@ -697,9 +697,9 @@ Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, Base64URLEncodePaddingPolicy aPaddingPolicy, nsACString& aBase64) { + aBase64.Truncate(); // Don't encode empty strings. if (aBinaryLen == 0) { - aBase64.Truncate(); return NS_OK; } @@ -709,14 +709,15 @@ Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, } // Allocate a buffer large enough to hold the encoded string with padding. - // Add one byte for null termination. uint32_t base64Len = ((aBinaryLen + 2) / 3) * 4; - if (NS_WARN_IF(!aBase64.SetCapacity(base64Len + 1, fallible))) { - aBase64.Truncate(); - return NS_ERROR_FAILURE; + + nsresult rv; + auto handle = aBase64.BulkWrite(base64Len, 0, false, rv); + if (NS_FAILED(rv)) { + return rv; } - char* base64 = aBase64.BeginWriting(); + char* base64 = handle.Elements(); uint32_t index = 0; for (; index + 3 <= aBinaryLen; index += 3) { @@ -739,7 +740,7 @@ Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, *base64++ = kBase64URLAlphabet[((aBinary[index + 1] & 0xf) << 2)]; } - uint32_t length = base64 - aBase64.BeginWriting(); + uint32_t length = base64 - handle.Elements(); if (aPaddingPolicy == Base64URLEncodePaddingPolicy::Include) { if (length % 4 == 2) { *base64++ = '='; @@ -754,10 +755,7 @@ Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, "Invalid encode padding policy"); } - // Null terminate and truncate to the actual number of characters. - *base64 = '\0'; - aBase64.SetLength(length); - + handle.Finish(length, false); return NS_OK; } diff --git a/xpcom/string/nsReadableUtils.cpp b/xpcom/string/nsReadableUtils.cpp index ae9f19bdedaa..fe0d7b2cfa72 100644 --- a/xpcom/string/nsReadableUtils.cpp +++ b/xpcom/string/nsReadableUtils.cpp @@ -459,44 +459,6 @@ FindCharInReadable(char aChar, nsACString::const_iterator& aSearchStart, return false; } -uint32_t -CountCharInReadable(const nsAString& aStr, char16_t aChar) -{ - uint32_t count = 0; - nsAString::const_iterator begin, end; - - aStr.BeginReading(begin); - aStr.EndReading(end); - - while (begin != end) { - if (*begin == aChar) { - ++count; - } - ++begin; - } - - return count; -} - -uint32_t -CountCharInReadable(const nsACString& aStr, char aChar) -{ - uint32_t count = 0; - nsACString::const_iterator begin, end; - - aStr.BeginReading(begin); - aStr.EndReading(end); - - while (begin != end) { - if (*begin == aChar) { - ++count; - } - ++begin; - } - - return count; -} - bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring) { diff --git a/xpcom/string/nsReadableUtils.h b/xpcom/string/nsReadableUtils.h index 0523f2fcbbbf..45cb85d4faf0 100644 --- a/xpcom/string/nsReadableUtils.h +++ b/xpcom/string/nsReadableUtils.h @@ -782,14 +782,6 @@ bool FindCharInReadable(char16_t aChar, nsAString::const_iterator& aSearchStart, bool FindCharInReadable(char aChar, nsACString::const_iterator& aSearchStart, const nsACString::const_iterator& aSearchEnd); -/** -* Finds the number of occurences of |aChar| in the string |aStr| -*/ -uint32_t CountCharInReadable(const nsAString& aStr, - char16_t aChar); -uint32_t CountCharInReadable(const nsACString& aStr, - char aChar); - bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring); bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring, const nsStringComparator& aComparator); @@ -825,12 +817,4 @@ CompareUTF8toUTF16(const nsACString& aUTF8String, void AppendUCS4ToUTF16(const uint32_t aSource, nsAString& aDest); -template -inline bool -EnsureStringLength(T& aStr, uint32_t aLen) -{ - aStr.SetLength(aLen); - return (aStr.Length() == aLen); -} - #endif // !defined(nsReadableUtils_h___) diff --git a/xpcom/threads/nsThreadUtils.h b/xpcom/threads/nsThreadUtils.h index 765fffe4d14e..962122aa85c7 100644 --- a/xpcom/threads/nsThreadUtils.h +++ b/xpcom/threads/nsThreadUtils.h @@ -21,8 +21,10 @@ #include "nsString.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" +#include "xpcpublic.h" #include "mozilla/Atomics.h" #include "mozilla/Likely.h" +#include "mozilla/Maybe.h" #include "mozilla/Move.h" #include "mozilla/TimeStamp.h" #include "mozilla/Tuple.h" @@ -320,6 +322,14 @@ SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr) { nsIThread* thread = aThread ? aThread : NS_GetCurrentThread(); + // From a latency perspective, spinning the event loop is like leaving script + // and returning to the event loop. Tell the watchdog we stopped running + // script (until we return). + mozilla::Maybe asa; + if (NS_IsMainThread()) { + asa.emplace(false); + } + while (!aPredicate()) { bool didSomething = NS_ProcessNextEvent(thread, true);