diff --git a/.cron.yml b/.cron.yml index e610ea687b4b..62e960ade236 100644 --- a/.cron.yml +++ b/.cron.yml @@ -121,4 +121,5 @@ jobs: by-project: # No default branch mozilla-central: - - {hour: 10, minute: 0} + - {weekday: 'Monday', hour: 10, minute: 0} + - {weekday: 'Thursday', hour: 10, minute: 0} diff --git a/accessible/base/TextAttrs.cpp b/accessible/base/TextAttrs.cpp index 7655941c7f5b..52f14655838a 100644 --- a/accessible/base/TextAttrs.cpp +++ b/accessible/base/TextAttrs.cpp @@ -592,7 +592,7 @@ TextAttrsMgr::FontStyleTextAttr:: TextAttrsMgr::FontWeightTextAttr:: FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) : - TTextAttr(!aFrame) + TTextAttr(!aFrame) { mRootNativeValue = GetFontWeight(aRootFrame); mIsRootDefined = true; @@ -605,7 +605,7 @@ TextAttrsMgr::FontWeightTextAttr:: bool TextAttrsMgr::FontWeightTextAttr:: - GetValueFor(Accessible* aAccessible, int32_t* aValue) + GetValueFor(Accessible* aAccessible, FontWeight* aValue) { nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent()); if (elm) { @@ -620,15 +620,16 @@ TextAttrsMgr::FontWeightTextAttr:: void TextAttrsMgr::FontWeightTextAttr:: - ExposeValue(nsIPersistentProperties* aAttributes, const int32_t& aValue) + ExposeValue(nsIPersistentProperties* aAttributes, + const FontWeight& aValue) { nsAutoString formattedValue; - formattedValue.AppendInt(aValue); + formattedValue.AppendFloat(aValue.ToFloat()); nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::fontWeight, formattedValue); } -int32_t +FontWeight TextAttrsMgr::FontWeightTextAttr:: GetFontWeight(nsIFrame* aFrame) { @@ -645,8 +646,9 @@ TextAttrsMgr::FontWeightTextAttr:: // bold font, i.e. synthetic bolding is used. IsSyntheticBold method is only // needed on Mac, but it is "safe" to use on all platforms. (For non-Mac // platforms it always return false.) - if (font->IsSyntheticBold()) - return 700; + if (font->IsSyntheticBold()) { + return FontWeight::Bold(); + } // On Windows, font->GetStyle()->weight will give the same weight as // fontEntry->Weight(), the weight of the first font in the font group, diff --git a/accessible/base/TextAttrs.h b/accessible/base/TextAttrs.h index 3cc4ba356db7..e5dac1bab6ea 100644 --- a/accessible/base/TextAttrs.h +++ b/accessible/base/TextAttrs.h @@ -6,6 +6,7 @@ #ifndef nsTextAttrs_h_ #define nsTextAttrs_h_ +#include "mozilla/FontPropertyTypes.h" #include "nsCOMPtr.h" #include "nsColor.h" #include "nsString.h" @@ -354,7 +355,7 @@ protected: /** * Class is used for the work with "font-weight" text attribute. */ - class FontWeightTextAttr : public TTextAttr + class FontWeightTextAttr : public TTextAttr { public: FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame); @@ -363,13 +364,14 @@ protected: protected: // TTextAttr - virtual bool GetValueFor(Accessible* aAccessible, int32_t* aValue) + virtual bool GetValueFor(Accessible* aAccessible, + mozilla::FontWeight* aValue) override; virtual void ExposeValue(nsIPersistentProperties* aAttributes, - const int32_t& aValue) override; + const mozilla::FontWeight& aValue) override; private: - int32_t GetFontWeight(nsIFrame* aFrame); + mozilla::FontWeight GetFontWeight(nsIFrame* aFrame); }; /** diff --git a/devtools/client/debugger/new/test/mochitest/browser.ini b/devtools/client/debugger/new/test/mochitest/browser.ini index 79269fe2a3e8..cc1437ab295c 100644 --- a/devtools/client/debugger/new/test/mochitest/browser.ini +++ b/devtools/client/debugger/new/test/mochitest/browser.ini @@ -144,6 +144,7 @@ support-files = [browser_dbg-async-stepping.js] [browser_dbg-babel-breakpoint-console.js] [browser_dbg-babel-scopes.js] +skip-if = ccov # Bug 1441545 [browser_dbg-babel-stepping.js] [browser_dbg-babel-preview.js] skip-if = (os == "win" && ccov) # Bug 1448523 diff --git a/devtools/client/framework/test/browser.ini b/devtools/client/framework/test/browser.ini index a6f443b16214..b544bb7c487d 100644 --- a/devtools/client/framework/test/browser.ini +++ b/devtools/client/framework/test/browser.ini @@ -82,6 +82,7 @@ skip-if = os == 'win' || debug # Bug 1282269, 1448084 [browser_toolbox_keyboard_navigation.js] skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keyboard Access setting is set to All Control in System Keyboard Preferences [browser_toolbox_options.js] +[browser_toolbox_options_multiple_tabs.js] [browser_toolbox_options_disable_buttons.js] [browser_toolbox_options_disable_cache-01.js] [browser_toolbox_options_disable_cache-02.js] diff --git a/devtools/client/framework/test/browser_toolbox_options.js b/devtools/client/framework/test/browser_toolbox_options.js index 215d07ce51df..ad2b0c60adfb 100644 --- a/devtools/client/framework/test/browser_toolbox_options.js +++ b/devtools/client/framework/test/browser_toolbox_options.js @@ -332,11 +332,16 @@ async function testToggleWebExtensions() { "There should not be any checkbox for the unregistered WebExtensions"); } +function getToolNode(id) { + return panelWin.document.getElementById(id); +} + async function testToggleTools() { let toolNodes = panelWin.document.querySelectorAll( "#default-tools-box input[type=checkbox]:not([data-unsupported])," + "#additional-tools-box input[type=checkbox]:not([data-unsupported])"); - let enabledTools = [...toolNodes].filter(node => node.checked); + let toolNodeIds = [...toolNodes].map(node => node.id); + let enabledToolIds = [...toolNodes].filter(node => node.checked).map(node => node.id); let toggleableTools = gDevTools.getDefaultTools() .filter(tool => { @@ -358,39 +363,43 @@ async function testToggleTools() { } // Toggle each tool - for (let node of toolNodes) { - await toggleTool(node); + for (let id of toolNodeIds) { + await toggleTool(getToolNode(id)); } // Toggle again to reset tool enablement state - for (let node of toolNodes) { - await toggleTool(node); + for (let id of toolNodeIds) { + await toggleTool(getToolNode(id)); } // Test that a tool can still be added when no tabs are present: // Disable all tools - for (let node of enabledTools) { - await toggleTool(node); + for (let id of enabledToolIds) { + await toggleTool(getToolNode(id)); } // Re-enable the tools which are enabled by default - for (let node of enabledTools) { - await toggleTool(node); + for (let id of enabledToolIds) { + await toggleTool(getToolNode(id)); } // Toggle first, middle, and last tools to ensure that toolbox tabs are // inserted in order - let firstTool = toolNodes[0]; - let middleTool = toolNodes[(toolNodes.length / 2) | 0]; - let lastTool = toolNodes[toolNodes.length - 1]; + let firstToolId = toolNodeIds[0]; + let middleToolId = toolNodeIds[(toolNodeIds.length / 2) | 0]; + let lastToolId = toolNodeIds[toolNodeIds.length - 1]; - await toggleTool(firstTool); - await toggleTool(firstTool); - await toggleTool(middleTool); - await toggleTool(middleTool); - await toggleTool(lastTool); - await toggleTool(lastTool); + await toggleTool(getToolNode(firstToolId)); + await toggleTool(getToolNode(firstToolId)); + await toggleTool(getToolNode(middleToolId)); + await toggleTool(getToolNode(middleToolId)); + await toggleTool(getToolNode(lastToolId)); + await toggleTool(getToolNode(lastToolId)); } +/** + * Toggle tool node checkbox. Note: because toggling the checkbox will result in + * re-rendering of the tool list, we must re-query the checkboxes every time. + */ async function toggleTool(node) { let deferred = defer(); diff --git a/devtools/client/framework/test/browser_toolbox_options_multiple_tabs.js b/devtools/client/framework/test/browser_toolbox_options_multiple_tabs.js new file mode 100644 index 000000000000..49a399e060b9 --- /dev/null +++ b/devtools/client/framework/test/browser_toolbox_options_multiple_tabs.js @@ -0,0 +1,112 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const URL = "data:text/html;charset=utf8,test for dynamically registering " + + "and unregistering tools across multiple tabs"; + +let tab1, tab2, modifiedPref; + +add_task(async function() { + tab1 = await openToolboxOptionsInNewTab(); + tab2 = await openToolboxOptionsInNewTab(); + + await testToggleTools(); + await cleanup(); +}); + +async function openToolboxOptionsInNewTab() { + const tab = await addTab(URL); + const target = TargetFactory.forTab(tab); + const toolbox = await gDevTools.showToolbox(target); + const doc = toolbox.doc; + const panel = await toolbox.selectTool("options"); + const { id } = panel.panelDoc.querySelector( + "#default-tools-box input[type=checkbox]:not([data-unsupported]):not([checked])"); + + return { + tab, + toolbox, + doc, + panelWin: panel.panelWin, + // This is a getter becuse toolbox tools list gets re-setup every time there + // is a tool-registered or tool-undregistered event. + get checkbox() { + return panel.panelDoc.getElementById(id); + } + }; +} + +async function testToggleTools() { + is(tab1.checkbox.id, tab2.checkbox.id, "Default tool box should be in sync."); + + const toolId = tab1.checkbox.id; + const testTool = gDevTools.getDefaultTools().find(tool => tool.id === toolId); + // Store modified pref names so that they can be cleared on error. + modifiedPref = testTool.visibilityswitch; + + info(`Registering tool ${toolId} in the first tab.`); + await toggleTool(tab1, toolId); + + info(`Unregistering tool ${toolId} in the first tab.`); + await toggleTool(tab1, toolId); + + info(`Registering tool ${toolId} in the second tab.`); + await toggleTool(tab2, toolId); + + info(`Unregistering tool ${toolId} in the second tab.`); + await toggleTool(tab2, toolId); + + info(`Registering tool ${toolId} in the first tab.`); + await toggleTool(tab1, toolId); + + info(`Unregistering tool ${toolId} in the second tab.`); + await toggleTool(tab2, toolId); +} + +async function toggleTool({ doc, panelWin, checkbox, tab }, toolId) { + const prevChecked = checkbox.checked; + + (prevChecked ? checkRegistered : checkUnregistered)(toolId); + + const onToggleTool = gDevTools.once( + `tool-${prevChecked ? "unregistered" : "registered"}`); + EventUtils.sendMouseEvent({ type: "click" }, checkbox, panelWin); + const id = await onToggleTool; + + is(id, toolId, `Correct event for ${toolId} was fired`); + // await new Promise(resolve => setTimeout(resolve, 60000)); + (prevChecked ? checkUnregistered : checkRegistered)(toolId); +} + +async function checkUnregistered(toolId) { + ok(!tab1.doc.getElementById("toolbox-tab-" + toolId), + `Tab for unregistered tool ${toolId} is not present in first toolbox`); + ok(!tab1.checkbox.checked, + `Checkbox for unregistered tool ${toolId} is not checked in first toolbox`); + ok(!tab2.doc.getElementById("toolbox-tab-" + toolId), + `Tab for unregistered tool ${toolId} is not present in second toolbox`); + ok(!tab2.checkbox.checked, + `Checkbox for unregistered tool ${toolId} is not checked in second toolbox`); +} + +function checkRegistered(toolId) { + ok(tab1.doc.getElementById("toolbox-tab-" + toolId), + `Tab for registered tool ${toolId} is present in first toolbox`); + ok(tab1.checkbox.checked, + `Checkbox for registered tool ${toolId} is checked in first toolbox`); + ok(tab2.doc.getElementById("toolbox-tab-" + toolId), + `Tab for registered tool ${toolId} is present in second toolbox`); + ok(tab2.checkbox.checked, + `Checkbox for registered tool ${toolId} is checked in second toolbox`); +} + +async function cleanup() { + await tab1.toolbox.destroy(); + await tab2.toolbox.destroy(); + gBrowser.removeCurrentTab(); + gBrowser.removeCurrentTab(); + Services.prefs.clearUserPref(modifiedPref); + tab1 = tab2 = modifiedPref = null; +} diff --git a/devtools/client/framework/toolbox-options.js b/devtools/client/framework/toolbox-options.js index 5a4f78000e3d..c3cbabed24b6 100644 --- a/devtools/client/framework/toolbox-options.js +++ b/devtools/client/framework/toolbox-options.js @@ -61,11 +61,10 @@ function OptionsPanel(iframeWindow, toolbox) { this.toolbox = toolbox; this.isReady = false; + this.setupToolsList = this.setupToolsList.bind(this); this._prefChanged = this._prefChanged.bind(this); this._themeRegistered = this._themeRegistered.bind(this); this._themeUnregistered = this._themeUnregistered.bind(this); - this._webExtensionRegistered = this._webExtensionRegistered.bind(this); - this._webExtensionUnregistered = this._webExtensionUnregistered.bind(this); this._disableJSClicked = this._disableJSClicked.bind(this); this.disableJSNode = this.panelDoc.getElementById("devtools-disable-javascript"); @@ -106,8 +105,14 @@ OptionsPanel.prototype = { gDevTools.on("theme-registered", this._themeRegistered); gDevTools.on("theme-unregistered", this._themeUnregistered); - this.toolbox.on("webextension-registered", this._webExtensionRegistered); - this.toolbox.on("webextension-unregistered", this._webExtensionUnregistered); + // Refresh the tools list when a new tool or webextension has been + // registered to the toolbox. + this.toolbox.on("tool-registered", this.setupToolsList); + this.toolbox.on("webextension-registered", this.setupToolsList); + // Refresh the tools list when a new tool or webextension has been + // unregistered from the toolbox. + this.toolbox.on("tool-unregistered", this.setupToolsList); + this.toolbox.on("webextension-unregistered", this.setupToolsList); }, _removeListeners: function() { @@ -116,8 +121,10 @@ OptionsPanel.prototype = { Services.prefs.removeObserver("devtools.source-map.client-service.enabled", this._prefChanged); - this.toolbox.off("webextension-registered", this._webExtensionRegistered); - this.toolbox.off("webextension-unregistered", this._webExtensionUnregistered); + this.toolbox.off("tool-registered", this.setupToolsList); + this.toolbox.off("tool-unregistered", this.setupToolsList); + this.toolbox.off("webextension-registered", this.setupToolsList); + this.toolbox.off("webextension-unregistered", this.setupToolsList); gDevTools.off("theme-registered", this._themeRegistered); gDevTools.off("theme-unregistered", this._themeUnregistered); @@ -148,18 +155,6 @@ OptionsPanel.prototype = { } }, - _webExtensionRegistered: function(extensionUUID) { - // Refresh the tools list when a new webextension has been registered - // to the toolbox. - this.setupToolsList(); - }, - - _webExtensionUnregistered: function(extensionUUID) { - // Refresh the tools list when a new webextension has been unregistered - // from the toolbox. - this.setupToolsList(); - }, - async setupToolbarButtonsList() { // Ensure the toolbox is open, and the buttons are all set up. await this.toolbox.isOpen; diff --git a/dom/file/ipc/IPCBlobInputStream.cpp b/dom/file/ipc/IPCBlobInputStream.cpp index d408281b9737..a6c4e75e8fc9 100644 --- a/dom/file/ipc/IPCBlobInputStream.cpp +++ b/dom/file/ipc/IPCBlobInputStream.cpp @@ -380,8 +380,20 @@ IPCBlobInputStream::AsyncWait(nsIInputStreamCallback* aCallback, // We have the remote inputStream, let's check if we can execute the callback. case eRunning: { - MutexAutoLock lock(mMutex); - return MaybeExecuteInputStreamCallback(aCallback, aEventTarget, lock); + { + MutexAutoLock lock(mMutex); + mInputStreamCallback = aCallback; + mInputStreamCallbackEventTarget = aEventTarget; + } + + nsresult rv = EnsureAsyncRemoteStream(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + MOZ_ASSERT(mAsyncRemoteStream); + return mAsyncRemoteStream->AsyncWait(aCallback ? this : nullptr, + 0, 0, aEventTarget); } // Stream is closed. @@ -435,64 +447,28 @@ IPCBlobInputStream::StreamReady(already_AddRefed aInputStream) this); } + nsCOMPtr inputStreamCallback = this; + nsCOMPtr inputStreamCallbackEventTarget; { MutexAutoLock lock(mMutex); - - nsCOMPtr inputStreamCallback; - inputStreamCallback.swap(mInputStreamCallback); - - nsCOMPtr inputStreamCallbackEventTarget; - inputStreamCallbackEventTarget.swap(mInputStreamCallbackEventTarget); - - if (inputStreamCallback) { - MaybeExecuteInputStreamCallback(inputStreamCallback, - inputStreamCallbackEventTarget, - lock); + inputStreamCallbackEventTarget = mInputStreamCallbackEventTarget; + if (!mInputStreamCallback) { + inputStreamCallback = nullptr; } } -} -nsresult -IPCBlobInputStream::MaybeExecuteInputStreamCallback(nsIInputStreamCallback* aCallback, - nsIEventTarget* aCallbackEventTarget, - const MutexAutoLock& aProofOfLock) -{ - MOZ_ASSERT(mState == eRunning); - MOZ_ASSERT(mRemoteStream || mAsyncRemoteStream); - - // If the callback has been already set, we return an error. - if (mInputStreamCallback && aCallback) { - return NS_ERROR_FAILURE; - } - - bool hadCallback = !!mInputStreamCallback; - - mInputStreamCallback = aCallback; - mInputStreamCallbackEventTarget = aCallbackEventTarget; - - nsCOMPtr callback = this; - - if (!mInputStreamCallback) { - if (!hadCallback) { - // Nothing was pending. - return NS_OK; + if (inputStreamCallback) { + nsresult rv = EnsureAsyncRemoteStream(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; } - // Let's set a null callback in order to abort the current operation. - callback = nullptr; + MOZ_ASSERT(mAsyncRemoteStream); + + rv = mAsyncRemoteStream->AsyncWait(inputStreamCallback, 0, 0, + inputStreamCallbackEventTarget); + Unused << NS_WARN_IF(NS_FAILED(rv)); } - - // We don't need to be locked anymore. - MutexAutoUnlock unlock(mMutex); - - nsresult rv = EnsureAsyncRemoteStream(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - MOZ_ASSERT(mAsyncRemoteStream); - - return mAsyncRemoteStream->AsyncWait(callback, 0, 0, aCallbackEventTarget); } void diff --git a/dom/file/ipc/IPCBlobInputStream.h b/dom/file/ipc/IPCBlobInputStream.h index 081a96d76a87..61c2fd10bb66 100644 --- a/dom/file/ipc/IPCBlobInputStream.h +++ b/dom/file/ipc/IPCBlobInputStream.h @@ -44,11 +44,6 @@ public: private: ~IPCBlobInputStream(); - nsresult - MaybeExecuteInputStreamCallback(nsIInputStreamCallback* aCallback, - nsIEventTarget* aEventTarget, - const MutexAutoLock& aProofOfLock); - nsresult EnsureAsyncRemoteStream(); diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 962ac1ef378d..f06409670f51 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -117,7 +117,7 @@ struct FontListEntry { nsString familyName; nsString faceName; nsCString filepath; - uint16_t weight; + float weight; int16_t stretch; uint8_t italic; uint8_t index; diff --git a/dom/mathml/nsMathMLElement.cpp b/dom/mathml/nsMathMLElement.cpp index 01200ff9a833..0500bc05f420 100644 --- a/dom/mathml/nsMathMLElement.cpp +++ b/dom/mathml/nsMathMLElement.cpp @@ -8,6 +8,7 @@ #include "nsMathMLElement.h" #include "base/compiler_specific.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/FontPropertyTypes.h" #include "nsGkAtoms.h" #include "nsITableCellLayout.h" // for MAX_COLSPAN / MAX_ROWSPAN #include "nsCRT.h" @@ -726,10 +727,10 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes, str.CompressWhitespace(); if (str.EqualsASCII("normal")) { aData->SetKeywordValue(eCSSProperty_font_weight, - NS_FONT_WEIGHT_NORMAL); + FontWeight::Normal().ToFloat()); } else if (str.EqualsASCII("bold")) { aData->SetKeywordValue(eCSSProperty_font_weight, - NS_FONT_WEIGHT_BOLD); + FontWeight::Bold().ToFloat()); } } } diff --git a/dom/media/MediaData.h b/dom/media/MediaData.h index 31bdf729cbc3..68dbcb3d1d02 100644 --- a/dom/media/MediaData.h +++ b/dom/media/MediaData.h @@ -645,11 +645,11 @@ public: // Set size of buffer, allocating memory as required. // If size is increased, new buffer area is filled with 0. - bool SetSize(size_t aSize); + MOZ_MUST_USE bool SetSize(size_t aSize); // Add aData at the beginning of buffer. - bool Prepend(const uint8_t* aData, size_t aSize); + MOZ_MUST_USE bool Prepend(const uint8_t* aData, size_t aSize); // Replace current content with aData. - bool Replace(const uint8_t* aData, size_t aSize); + MOZ_MUST_USE bool Replace(const uint8_t* aData, size_t aSize); // Clear the memory buffer. Will set target mData and mSize to 0. void Clear(); // Remove aSize bytes from the front of the sample. @@ -658,7 +658,7 @@ public: private: friend class MediaRawData; explicit MediaRawDataWriter(MediaRawData* aMediaRawData); - bool EnsureSize(size_t aSize); + MOZ_MUST_USE bool EnsureSize(size_t aSize); MediaRawData* mTarget; }; diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index fe4005890873..73052aee8894 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -3054,6 +3054,22 @@ ScriptLoader::NumberOfProcessors() return mNumberOfProcessors; } +static bool +IsInternalURIScheme(nsIURI* uri) +{ + bool isWebExt; + if (NS_SUCCEEDED(uri->SchemeIs("moz-extension", &isWebExt)) && isWebExt) { + return true; + } + + bool isResource; + if (NS_SUCCEEDED(uri->SchemeIs("resource", &isResource)) && isResource) { + return true; + } + + return false; +} + nsresult ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest, nsIIncrementalStreamLoader* aLoader, @@ -3142,10 +3158,9 @@ ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest, rv = channel->GetOriginalURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); - // Fixup moz-extension URIs, because the channel URI points to file:, - // which won't be allowed to load. - bool isWebExt = false; - if (uri && NS_SUCCEEDED(uri->SchemeIs("moz-extension", &isWebExt)) && isWebExt) { + // Fixup moz-extension: and resource: URIs, because the channel URI will + // point to file:, which won't be allowed to load. + if (uri && IsInternalURIScheme(uri)) { request->mBaseURL = uri; } else { channel->GetURI(getter_AddRefs(request->mBaseURL)); diff --git a/dom/security/test/general/file_same_site_cookies_redirect.sjs b/dom/security/test/general/file_same_site_cookies_redirect.sjs new file mode 100644 index 000000000000..2337df4824fd --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_redirect.sjs @@ -0,0 +1,61 @@ +// Custom *.sjs file specifically for the needs of Bug 1453814 + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="); + +const FRAME = ` + + + + Bug 1453814 - Do not allow same-site cookies for cross origin redirect + + + + + `; + +const SAME_ORIGIN = "http://mochi.test:8888/" +const CROSS_ORIGIN = "http://example.com/"; +const PATH = "tests/dom/security/test/general/file_same_site_cookies_redirect.sjs"; + +function handleRequest(request, response) +{ + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.queryString === "setSameSiteCookie") { + response.setHeader("Set-Cookie", "myKey=strictSameSiteCookie; samesite=strict", true); + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + if (request.queryString === "sameToCrossRedirect") { + let URL = CROSS_ORIGIN + PATH + "?loadFrame"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", URL, false); + return; + } + + if (request.queryString === "crossToSameRedirect") { + let URL = SAME_ORIGIN + PATH + "?loadFrame"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", URL, false); + return; + } + + if (request.queryString === "loadFrame") { + response.write(FRAME); + return; + } + + // we should never get here, but just in case return something unexpected + response.write("D'oh"); +} diff --git a/dom/security/test/general/mochitest.ini b/dom/security/test/general/mochitest.ini index 4d1afac02af7..64dd20138177 100644 --- a/dom/security/test/general/mochitest.ini +++ b/dom/security/test/general/mochitest.ini @@ -12,6 +12,7 @@ support-files = file_same_site_cookies_toplevel_nav.sjs file_same_site_cookies_cross_origin_context.sjs file_same_site_cookies_from_script.sjs + file_same_site_cookies_redirect.sjs [test_contentpolicytype_targeted_link_iframe.html] [test_nosniff.html] @@ -29,3 +30,4 @@ skip-if = toolkit == 'android' [test_same_site_cookies_toplevel_nav.html] [test_same_site_cookies_cross_origin_context.html] [test_same_site_cookies_from_script.html] +[test_same_site_cookies_redirect.html] diff --git a/dom/security/test/general/test_same_site_cookies_redirect.html b/dom/security/test/general/test_same_site_cookies_redirect.html new file mode 100644 index 000000000000..4fdc8936a39e --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_redirect.html @@ -0,0 +1,83 @@ + + + + Bug 1453814 - Do not allow same-site cookies for cross origin redirect + + + + + + + + + + diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 1aaa6b7a14e1..2f5f933b4a67 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -294,6 +294,9 @@ LoadContextOptions(const char* aPrefName, void* /* aClosure */) .setWasm(GetWorkerPref(NS_LITERAL_CSTRING("wasm"))) .setWasmBaseline(GetWorkerPref(NS_LITERAL_CSTRING("wasm_baselinejit"))) .setWasmIon(GetWorkerPref(NS_LITERAL_CSTRING("wasm_ionjit"))) +#ifdef ENABLE_WASM_GC + .setWasmGc(GetWorkerPref(NS_LITERAL_CSTRING("wasm_gc"))) +#endif .setThrowOnAsmJSValidationFailure(GetWorkerPref( NS_LITERAL_CSTRING("throw_on_asmjs_validation_failure"))) .setBaseline(GetWorkerPref(NS_LITERAL_CSTRING("baselinejit"))) diff --git a/dom/workers/moz.build b/dom/workers/moz.build index 1f23ef4f5f59..ccaaf27a6da1 100644 --- a/dom/workers/moz.build +++ b/dom/workers/moz.build @@ -98,3 +98,6 @@ BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] if CONFIG['CC_TYPE'] in ('clang', 'gcc'): CXXFLAGS += ['-Wno-error=shadow'] + +if CONFIG['NIGHTLY_BUILD']: + DEFINES['ENABLE_WASM_GC'] = True diff --git a/gfx/2d/NativeFontResourceDWrite.cpp b/gfx/2d/NativeFontResourceDWrite.cpp index 03a6debd233b..c89d7efcda0b 100644 --- a/gfx/2d/NativeFontResourceDWrite.cpp +++ b/gfx/2d/NativeFontResourceDWrite.cpp @@ -12,6 +12,7 @@ #include "Logging.h" #include "mozilla/RefPtr.h" #include "mozilla/StaticMutex.h" +#include "nsTArray.h" namespace mozilla { namespace gfx { @@ -84,6 +85,8 @@ private: class DWriteFontFileStream final : public IDWriteFontFileStream { public: + explicit DWriteFontFileStream(uint64_t aFontFileKey); + /** * Used by the FontFileLoader to create a new font stream, * this font stream is created from data in memory. The memory @@ -92,7 +95,7 @@ public: * * @param aData Font data */ - DWriteFontFileStream(uint8_t *aData, uint32_t aSize, uint64_t aFontFileKey); + bool Initialize(uint8_t *aData, uint32_t aSize); // IUnknown interface IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) @@ -135,7 +138,7 @@ public: virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime); private: - std::vector mData; + nsTArray mData; Atomic mRefCnt; uint64_t mFontFileKey; @@ -166,13 +169,10 @@ DWriteFontFileLoader::CreateStreamFromKey(const void *fontFileReferenceKey, return S_OK; } -DWriteFontFileStream::DWriteFontFileStream(uint8_t *aData, uint32_t aSize, - uint64_t aFontFileKey) +DWriteFontFileStream::DWriteFontFileStream(uint64_t aFontFileKey) : mRefCnt(0) , mFontFileKey(aFontFileKey) { - mData.resize(aSize); - memcpy(&mData.front(), aData, aSize); } DWriteFontFileStream::~DWriteFontFileStream() @@ -181,10 +181,20 @@ DWriteFontFileStream::~DWriteFontFileStream() sFontFileStreams.erase(mFontFileKey); } +bool +DWriteFontFileStream::Initialize(uint8_t *aData, uint32_t aSize) +{ + if (!mData.SetLength(aSize, fallible)) { + return false; + } + memcpy(mData.Elements(), aData, aSize); + return true; +} + HRESULT STDMETHODCALLTYPE DWriteFontFileStream::GetFileSize(UINT64 *fileSize) { - *fileSize = mData.size(); + *fileSize = mData.Length(); return S_OK; } @@ -201,7 +211,7 @@ DWriteFontFileStream::ReadFileFragment(const void **fragmentStart, void **fragmentContext) { // We are required to do bounds checking. - if (fileOffset + fragmentSize > mData.size()) { + if (fileOffset + fragmentSize > mData.Length()) { return E_FAIL; } @@ -232,8 +242,12 @@ NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength, sFontFileStreamsMutex.Lock(); uint64_t fontFileKey = sNextFontFileKey++; - RefPtr ffsRef = - new DWriteFontFileStream(aFontData, aDataLength, fontFileKey); + RefPtr ffsRef = new DWriteFontFileStream(fontFileKey); + if (!ffsRef->Initialize(aFontData, aDataLength)) { + sFontFileStreamsMutex.Unlock(); + gfxWarning() << "Failed to create DWriteFontFileStream."; + return nullptr; + } sFontFileStreams[fontFileKey] = ffsRef; sFontFileStreamsMutex.Unlock(); diff --git a/gfx/2d/NativeFontResourceFontconfig.cpp b/gfx/2d/NativeFontResourceFontconfig.cpp index 3dc1bc9263ad..e0665480e203 100644 --- a/gfx/2d/NativeFontResourceFontconfig.cpp +++ b/gfx/2d/NativeFontResourceFontconfig.cpp @@ -32,7 +32,10 @@ NativeFontResourceFontconfig::Create(uint8_t *aFontData, uint32_t aDataLength, F if (!aFontData || !aDataLength) { return nullptr; } - UniquePtr fontData(new uint8_t[aDataLength]); + UniquePtr fontData(new (fallible) uint8_t[aDataLength]); + if (!fontData) { + return nullptr; + } memcpy(fontData.get(), aFontData, aDataLength); FT_Face face = Factory::NewFTFaceFromData(aFTLibrary, fontData.get(), aDataLength, 0); diff --git a/gfx/2d/ScaledFontDWrite.cpp b/gfx/2d/ScaledFontDWrite.cpp index a63cf747fef5..8dfb01dca0e8 100644 --- a/gfx/2d/ScaledFontDWrite.cpp +++ b/gfx/2d/ScaledFontDWrite.cpp @@ -137,7 +137,7 @@ ScaledFontDWrite::ScaledFontDWrite(IDWriteFontFace *aFontFace, , mContrast(aContrast) { if (aStyle) { - mStyle = SkFontStyle(aStyle->weight, + mStyle = SkFontStyle(aStyle->weight.ToIntRounded(), DWriteFontStretchFromStretch(aStyle->stretch), aStyle->style == NS_FONT_STYLE_NORMAL ? SkFontStyle::kUpright_Slant : SkFontStyle::kItalic_Slant); diff --git a/gfx/layers/SourceSurfaceSharedData.h b/gfx/layers/SourceSurfaceSharedData.h index 549ea205b9d5..5ce1302be4da 100644 --- a/gfx/layers/SourceSurfaceSharedData.h +++ b/gfx/layers/SourceSurfaceSharedData.h @@ -82,17 +82,6 @@ public: void Unmap() override { } - bool AddConsumer() - { - return ++mConsumers == 1; - } - - bool RemoveConsumer() - { - MOZ_ASSERT(mConsumers > 0); - return --mConsumers == 0; - } - private: size_t GetDataLength() const { @@ -105,7 +94,6 @@ private: } int32_t mStride; - uint32_t mConsumers; IntSize mSize; RefPtr mBuf; SurfaceFormat mFormat; diff --git a/gfx/layers/ipc/SharedSurfacesParent.cpp b/gfx/layers/ipc/SharedSurfacesParent.cpp index e2f2ba8dcc08..6bc512bffedc 100644 --- a/gfx/layers/ipc/SharedSurfacesParent.cpp +++ b/gfx/layers/ipc/SharedSurfacesParent.cpp @@ -54,44 +54,22 @@ SharedSurfacesParent::Get(const wr::ExternalImageId& aId) return surface.forget(); } -/* static */ already_AddRefed -SharedSurfacesParent::Acquire(const wr::ExternalImageId& aId) -{ - MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); - if (!sInstance) { - return nullptr; - } - - RefPtr surface; - sInstance->mSurfaces.Get(wr::AsUint64(aId), getter_AddRefs(surface)); - - if (surface) { - DebugOnly rv = surface->AddConsumer(); - MOZ_ASSERT(!rv); - } - return surface.forget(); -} - -/* static */ bool -SharedSurfacesParent::Release(const wr::ExternalImageId& aId) +/* static */ void +SharedSurfacesParent::Remove(const wr::ExternalImageId& aId) { //MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); if (!sInstance) { - return false; + return; } uint64_t id = wr::AsUint64(aId); RefPtr surface; sInstance->mSurfaces.Get(wr::AsUint64(aId), getter_AddRefs(surface)); if (!surface) { - return false; + return; } - if (surface->RemoveConsumer()) { - sInstance->mSurfaces.Remove(id); - } - - return true; + sInstance->mSurfaces.Remove(id); } /* static */ void @@ -193,13 +171,5 @@ SharedSurfacesParent::Add(const wr::ExternalImageId& aId, sInstance->mSurfaces.Put(id, surface.forget()); } -/* static */ void -SharedSurfacesParent::Remove(const wr::ExternalImageId& aId) -{ - //MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); - DebugOnly rv = Release(aId); - MOZ_ASSERT(rv); -} - } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/SharedSurfacesParent.h b/gfx/layers/ipc/SharedSurfacesParent.h index 2b619f00fa9b..eaa3e2aa57f0 100644 --- a/gfx/layers/ipc/SharedSurfacesParent.h +++ b/gfx/layers/ipc/SharedSurfacesParent.h @@ -35,16 +35,9 @@ public: static void Initialize(); static void Shutdown(); - // Get without increasing the consumer count. static already_AddRefed Get(const wr::ExternalImageId& aId); - // Get but also increase the consumer count. Must call Release after finished. - static already_AddRefed - Acquire(const wr::ExternalImageId& aId); - - static bool Release(const wr::ExternalImageId& aId); - static void Add(const wr::ExternalImageId& aId, const SurfaceDescriptorShared& aDesc, base::ProcessId aPid); diff --git a/gfx/src/FontPropertyTypes.h b/gfx/src/FontPropertyTypes.h new file mode 100644 index 000000000000..2a1ef1e213f5 --- /dev/null +++ b/gfx/src/FontPropertyTypes.h @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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/. */ + +/* font specific types shared by both thebes and layout */ + +#ifndef GFX_FONT_PROPERTY_TYPES_H +#define GFX_FONT_PROPERTY_TYPES_H + +#include + +/* + * This file is separate from gfxFont.h so that layout can include it + * without bringing in gfxFont.h and everything it includes. + */ + +namespace mozilla { + +/** + * A type that will in future encode a value as fixed point. + */ +class FontFixedPointValue +{ +public: + // Ugh. We need a default constructor to allow this type to be used in the + // union in nsCSSValue. Furthermore we need the default and copy + // constructors to be "trivial" (i.e. the compiler implemented defaults that + // do no initialization). + // Annoyingly it seems we can't make the default implementations constexpr + // (at least in clang). We'd like to do that to allow Thin() et. al. below + // to also be constexpr. :/ + FontFixedPointValue() = default; + FontFixedPointValue(const FontFixedPointValue& aOther) = default; + + // Not currently encoded, but it will be in future + explicit FontFixedPointValue(int16_t aValue) + : mEncoded(aValue) + {} + + explicit FontFixedPointValue(int32_t aValue) + : mEncoded(aValue) + {} + + explicit FontFixedPointValue(float aValue) + : mEncoded(int16_t(aValue)) + {} + + float ToFloat() const { + return float(mEncoded); + } + + int16_t ToIntRounded() const { + return mEncoded; + } + + bool operator==(const FontFixedPointValue& aOther) const { + return mEncoded == aOther.mEncoded; + } + + bool operator!=(const FontFixedPointValue& aOther) const { + return mEncoded != aOther.mEncoded; + } + + bool operator<(const FontFixedPointValue& aOther) const { + return mEncoded < aOther.mEncoded; + } + + bool operator<=(const FontFixedPointValue& aOther) const { + return mEncoded <= aOther.mEncoded; + } + + bool operator>=(const FontFixedPointValue& aOther) const { + return mEncoded >= aOther.mEncoded; + } + + bool operator>(const FontFixedPointValue& aOther) const { + return mEncoded > aOther.mEncoded; + } + + int16_t ForHash() const { + return mEncoded; + } + +protected: + int16_t mEncoded; +}; + +class FontWeight : public FontFixedPointValue +{ +public: + // Ugh, to get union in nsCSSValue compiling + FontWeight() = default; + FontWeight(const FontWeight& aOther) = default; + + // Not currently encoded, but it will be in future + explicit FontWeight(int16_t aValue) + : FontFixedPointValue(aValue) + {} + + explicit FontWeight(int32_t aValue) + : FontFixedPointValue(aValue) + {} + + explicit FontWeight(float aValue) + : FontFixedPointValue(int16_t(aValue)) + {} + + bool operator==(const FontWeight& aOther) const + { + return mEncoded == aOther.mEncoded; + } + + /// The "distance" between two font weights + float operator-(const FontWeight& aOther) const { + return this->ToFloat() - aOther.ToFloat(); + } + + static FontWeight Thin() { + return FontWeight{100}; + } + static FontWeight Normal() { + return FontWeight{400}; + } + static FontWeight Bold() { + return FontWeight{700}; + } +}; + +} // namespace mozilla + +#endif // GFX_FONT_PROPERTY_TYPES_H + diff --git a/gfx/src/moz.build b/gfx/src/moz.build index 893b185529fe..131af5c5cd5b 100644 --- a/gfx/src/moz.build +++ b/gfx/src/moz.build @@ -45,6 +45,7 @@ EXPORTS += [ EXPORTS.mozilla += [ 'AppUnits.h', 'ArrayView.h', + 'FontPropertyTypes.h', ] EXPORTS.mozilla.gfx += [ diff --git a/gfx/src/nsFont.h b/gfx/src/nsFont.h index 9a86b55d2a87..56b26b820c02 100644 --- a/gfx/src/nsFont.h +++ b/gfx/src/nsFont.h @@ -13,6 +13,7 @@ #include "gfxFontConstants.h" // for NS_FONT_KERNING_AUTO, etc #include "gfxFontFeatures.h" #include "gfxFontVariations.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/RefPtr.h" // for RefPtr #include "nsColor.h" // for nsColor and NS_RGBA #include "nsCoord.h" // for nscoord @@ -44,6 +45,7 @@ const uint8_t kGenericFont_fantasy = 0x20; // Font structure. struct nsFont { + typedef mozilla::FontWeight FontWeight; // list of font families, either named or generic mozilla::FontFamilyList fontlist; @@ -79,7 +81,7 @@ struct nsFont { nscolor fontSmoothingBackgroundColor = NS_RGBA(0,0,0,0); // The weight of the font; see gfxFontConstants.h. - uint16_t weight = NS_FONT_WEIGHT_NORMAL; + FontWeight weight = FontWeight::Normal(); // The stretch of the font (the sum of various NS_FONT_STRETCH_* // constants; see gfxFontConstants.h). diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index 18a57463185a..9600d064fdda 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/ArrayUtils.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/MemoryReporting.h" #include "mozilla/intl/OSPreferences.h" @@ -219,12 +220,12 @@ gfxDWriteFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) if (LOG_FONTLIST_ENABLED()) { LOG_FONTLIST(("(fontlist) added (%s) to family (%s)" - " with style: %s weight: %d stretch: %d psname: %s fullname: %s", + " with style: %s weight: %g stretch: %d psname: %s fullname: %s", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(Name()).get(), (fe->IsItalic()) ? "italic" : (fe->IsOblique() ? "oblique" : "normal"), - fe->Weight(), fe->Stretch(), + fe->Weight().ToFloat(), fe->Stretch(), NS_ConvertUTF16toUTF8(psname).get(), NS_ConvertUTF16toUTF8(fullname).get())); } @@ -956,7 +957,7 @@ gfxDWriteFontList::GetDefaultFontForPlatform(const gfxFontStyle *aStyle) gfxFontEntry * gfxDWriteFontList::LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) { @@ -980,7 +981,7 @@ gfxDWriteFontList::LookupLocalFont(const nsAString& aFontName, gfxFontEntry * gfxDWriteFontList::MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, @@ -1151,12 +1152,12 @@ gfxDWriteFontList::InitFontListForPlatform() if (LOG_FONTLIST_ENABLED()) { gfxFontEntry *fe = faces[i]; LOG_FONTLIST(("(fontlist) moved (%s) to family (%s)" - " with style: %s weight: %d stretch: %d", + " with style: %s weight: %g stretch: %d", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(gillSansMTFamily->Name()).get(), (fe->IsItalic()) ? "italic" : (fe->IsOblique() ? "oblique" : "normal"), - fe->Weight(), fe->Stretch())); + fe->Weight().ToFloat(), fe->Stretch())); } } diff --git a/gfx/thebes/gfxDWriteFontList.h b/gfx/thebes/gfxDWriteFontList.h index bee3c4c7f1fb..de431ef0d8cf 100644 --- a/gfx/thebes/gfxDWriteFontList.h +++ b/gfx/thebes/gfxDWriteFontList.h @@ -6,6 +6,7 @@ #ifndef GFX_DWRITEFONTLIST_H #define GFX_DWRITEFONTLIST_H +#include "mozilla/FontPropertyTypes.h" #include "mozilla/MemoryReporting.h" #include "gfxDWriteCommon.h" #include "dwrite_3.h" @@ -46,6 +47,8 @@ class gfxDWriteFontEntry; class gfxDWriteFontFamily : public gfxFontFamily { public: + typedef mozilla::FontWeight FontWeight; + /** * Constructs a new DWriteFont Family. * @@ -119,7 +122,7 @@ public: weight = std::max(100, weight); weight = std::min(900, weight); - mWeight = weight; + mWeight = FontWeight(weight); mIsCJK = UNINITIALIZED_VALUE; } @@ -137,7 +140,7 @@ public: */ gfxDWriteFontEntry(const nsAString& aFaceName, IDWriteFont *aFont, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr), @@ -164,7 +167,7 @@ public: gfxDWriteFontEntry(const nsAString& aFaceName, IDWriteFontFile *aFontFile, IDWriteFontFileStream *aFontFileStream, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) : gfxFontEntry(aFaceName), mFont(nullptr), @@ -401,12 +404,12 @@ public: gfxFontFamily* CreateFontFamily(const nsAString& aName) const override; virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle); virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp index ef5dfbbd5da7..d3a453ff3116 100644 --- a/gfx/thebes/gfxDWriteFonts.cpp +++ b/gfx/thebes/gfxDWriteFonts.cpp @@ -11,6 +11,7 @@ #include "gfxTextRun.h" #include "harfbuzz/hb.h" +#include "mozilla/FontPropertyTypes.h" using namespace mozilla; using namespace mozilla::gfx; @@ -135,7 +136,7 @@ bool gfxDWriteFont::GetFakeMetricsForArialBlack(DWRITE_FONT_METRICS *aFontMetrics) { gfxFontStyle style(mStyle); - style.weight = 700; + style.weight = FontWeight(700); bool needsBold; gfxFontEntry* fe = @@ -156,7 +157,7 @@ void gfxDWriteFont::ComputeMetrics(AntialiasOption anAAOption) { DWRITE_FONT_METRICS fontMetrics; - if (!(mFontEntry->Weight() == 900 && + if (!(mFontEntry->Weight() == FontWeight(900) && !mFontEntry->IsUserFont() && mFontEntry->Name().EqualsLiteral("Arial Black") && GetFakeMetricsForArialBlack(&fontMetrics))) diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp index fbf9e2b102c5..2756a12008a4 100644 --- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -5,6 +5,7 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/Base64.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/MemoryReporting.h" #include "mozilla/dom/ContentChild.h" @@ -256,7 +257,7 @@ FT2FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold /* static */ FT2FontEntry* FT2FontEntry::CreateFontEntry(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, @@ -327,7 +328,9 @@ FT2FontEntry::CreateFontEntry(const FontListEntry& aFLE) FT2FontEntry *fe = new FT2FontEntry(aFLE.faceName()); fe->mFilename = aFLE.filepath(); fe->mFTFontIndex = aFLE.index(); - fe->mWeight = aFLE.weight(); + // The weight transported across IPC is a float, so we need to explicitly + // convert it back to a FontWeight. + fe->mWeight = FontWeight(aFLE.weight()); fe->mStretch = aFLE.stretch(); fe->mStyle = (aFLE.italic() ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL); return fe; @@ -340,7 +343,7 @@ FTFaceIsItalic(FT_Face aFace) return !!(aFace->style_flags & FT_STYLE_FLAG_ITALIC); } -static uint16_t +static FontWeight FTFaceGetWeight(FT_Face aFace) { TT_OS2 *os2 = static_cast(FT_Get_Sfnt_Table(aFace, ft_sfnt_os2)); @@ -368,7 +371,7 @@ FTFaceGetWeight(FT_Face aFace) NS_ASSERTION(result >= 100 && result <= 900, "Invalid weight in font!"); - return result; + return FontWeight(result); } // Used to create the font entry for installed faces on the device, @@ -660,10 +663,13 @@ FT2FontFamily::AddFacesToFontList(InfallibleTArray* aFontList) if (!fe) { continue; } - + + // We convert the weight to a float purely for transport across IPC. + // Ideally we'd avoid doing that. aFontList->AppendElement(FontListEntry(Name(), fe->Name(), fe->mFilename, - fe->Weight(), fe->Stretch(), + fe->Weight().ToFloat(), + fe->Stretch(), fe->mStyle, fe->mFTFontIndex)); } @@ -985,7 +991,7 @@ AppendToFaceList(nsCString& aFaceList, aFaceList.Append(','); aFaceList.Append(aFontEntry->IsItalic() ? '1' : '0'); aFaceList.Append(','); - aFaceList.AppendInt(aFontEntry->Weight()); + aFaceList.AppendFloat(aFontEntry->Weight().ToFloat()); aFaceList.Append(','); aFaceList.AppendInt(aFontEntry->Stretch()); aFaceList.Append(','); @@ -1144,11 +1150,11 @@ gfxFT2FontList::AddFaceToList(const nsCString& aEntryName, uint32_t aIndex, AppendToFaceList(aFaceList, name, fe); if (LOG_ENABLED()) { LOG(("(fontinit) added (%s) to family (%s)" - " with style: %s weight: %d stretch: %d", + " with style: %s weight: %g stretch: %d", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(family->Name()).get(), fe->IsItalic() ? "italic" : "normal", - fe->Weight(), fe->Stretch())); + fe->Weight().ToFloat(), fe->Stretch())); } } } @@ -1458,7 +1464,7 @@ gfxFT2FontList::InitFontListForPlatform() gfxFontEntry* gfxFT2FontList::LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) { @@ -1540,7 +1546,7 @@ gfxFT2FontList::GetDefaultFontForPlatform(const gfxFontStyle* aStyle) gfxFontEntry* gfxFT2FontList::MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxFT2FontList.h b/gfx/thebes/gfxFT2FontList.h index 1d5aae1b9b7e..4c9c2ffaa579 100644 --- a/gfx/thebes/gfxFT2FontList.h +++ b/gfx/thebes/gfxFT2FontList.h @@ -43,7 +43,7 @@ public: // create a font entry for a downloaded font static FT2FontEntry* CreateFontEntry(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, @@ -122,12 +122,12 @@ public: virtual ~gfxFT2FontList(); virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) override; virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp index 2936d36c0340..7caf5a904dca 100644 --- a/gfx/thebes/gfxFcPlatformFontList.cpp +++ b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -160,40 +160,40 @@ GetFaceNames(FcPattern* aFont, const nsAString& aFamilyName, } } -static uint16_t +static FontWeight MapFcWeight(int aFcWeight) { if (aFcWeight <= (FC_WEIGHT_THIN + FC_WEIGHT_EXTRALIGHT) / 2) { - return 100; + return FontWeight(100); } if (aFcWeight <= (FC_WEIGHT_EXTRALIGHT + FC_WEIGHT_LIGHT) / 2) { - return 200; + return FontWeight(200); } if (aFcWeight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_BOOK) / 2) { - return 300; + return FontWeight(300); } if (aFcWeight <= (FC_WEIGHT_REGULAR + FC_WEIGHT_MEDIUM) / 2) { // This includes FC_WEIGHT_BOOK - return 400; + return FontWeight(400); } if (aFcWeight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2) { - return 500; + return FontWeight(500); } if (aFcWeight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2) { - return 600; + return FontWeight(600); } if (aFcWeight <= (FC_WEIGHT_BOLD + FC_WEIGHT_EXTRABOLD) / 2) { - return 700; + return FontWeight(700); } if (aFcWeight <= (FC_WEIGHT_EXTRABOLD + FC_WEIGHT_BLACK) / 2) { - return 800; + return FontWeight(800); } if (aFcWeight <= FC_WEIGHT_BLACK) { - return 900; + return FontWeight(900); } // including FC_WEIGHT_EXTRABLACK - return 901; + return FontWeight(901); } static int16_t @@ -311,7 +311,7 @@ CreateFaceForPattern(FcPattern* aPattern) } gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t *aData, @@ -334,7 +334,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName, gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName, FcPattern* aFontPattern, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) : gfxFontEntry(aFaceName), mFontPattern(aFontPattern), @@ -1202,13 +1202,13 @@ gfxFontconfigFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) if (LOG_FONTLIST_ENABLED()) { LOG_FONTLIST(("(fontlist) added (%s) to family (%s)" - " with style: %s weight: %d stretch: %d" + " with style: %s weight: %g stretch: %d" " psname: %s fullname: %s", NS_ConvertUTF16toUTF8(fontEntry->Name()).get(), NS_ConvertUTF16toUTF8(Name()).get(), (fontEntry->IsItalic()) ? "italic" : (fontEntry->IsOblique() ? "oblique" : "normal"), - fontEntry->Weight(), fontEntry->Stretch(), + fontEntry->Weight().ToFloat(), fontEntry->Stretch(), NS_ConvertUTF16toUTF8(psname).get(), NS_ConvertUTF16toUTF8(fullname).get())); } @@ -1857,7 +1857,7 @@ gfxFcPlatformFontList::GetDefaultFontForPlatform(const gfxFontStyle* aStyle) gfxFontEntry* gfxFcPlatformFontList::LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) { @@ -1876,7 +1876,7 @@ gfxFcPlatformFontList::LookupLocalFont(const nsAString& aFontName, gfxFontEntry* gfxFcPlatformFontList::MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxFcPlatformFontList.h b/gfx/thebes/gfxFcPlatformFontList.h index 55e735fac59e..fb0c49d2a8d2 100644 --- a/gfx/thebes/gfxFcPlatformFontList.h +++ b/gfx/thebes/gfxFcPlatformFontList.h @@ -10,6 +10,7 @@ #include "gfxFontEntry.h" #include "gfxFT2FontBase.h" #include "gfxPlatformFontList.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/mozalloc.h" #include "nsAutoRef.h" #include "nsClassHashtable.h" @@ -93,7 +94,7 @@ public: // used for data fonts where the fontentry takes ownership // of the font data and the FT_Face explicit gfxFontconfigFontEntry(const nsAString& aFaceName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t *aData, @@ -103,7 +104,7 @@ public: // used for @font-face local system fonts with explicit patterns explicit gfxFontconfigFontEntry(const nsAString& aFaceName, FcPattern* aFontPattern, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle); @@ -287,11 +288,13 @@ public: InfallibleTArray* retValue); gfxFontEntry* - LookupLocalFont(const nsAString& aFontName, uint16_t aWeight, + LookupLocalFont(const nsAString& aFontName, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) override; gfxFontEntry* - MakePlatformFont(const nsAString& aFontName, uint16_t aWeight, + MakePlatformFont(const nsAString& aFontName, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index a981e09f5a0c..b797bc00b5f7 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -7,6 +7,7 @@ #include "mozilla/BinarySearch.h" #include "mozilla/DebugOnly.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/gfx/2D.h" #include "mozilla/MathAlgorithms.h" #include "mozilla/SVGContextPaint.h" @@ -3521,7 +3522,7 @@ gfxFont::GetSmallCapsFont() style.size *= SMALL_CAPS_SCALE_FACTOR; style.variantCaps = NS_FONT_VARIANT_CAPS_NORMAL; gfxFontEntry* fe = GetFontEntry(); - bool needsBold = style.weight >= 600 && !fe->IsBold(); + bool needsBold = style.weight >= FontWeight(600) && !fe->IsBold(); return fe->FindOrMakeFont(&style, needsBold, mUnicodeRangeMap); } @@ -3531,7 +3532,7 @@ gfxFont::GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel) gfxFontStyle style(*GetStyle()); style.AdjustForSubSuperscript(aAppUnitsPerDevPixel); gfxFontEntry* fe = GetFontEntry(); - bool needsBold = style.weight >= 600 && !fe->IsBold(); + bool needsBold = style.weight >= FontWeight(600) && !fe->IsBold(); return fe->FindOrMakeFont(&style, needsBold, mUnicodeRangeMap); } @@ -4110,7 +4111,8 @@ gfxFontStyle::gfxFontStyle() : size(DEFAULT_PIXEL_FONT_SIZE), sizeAdjust(-1.0f), baselineOffset(0.0f), languageOverride(NO_FONT_LANGUAGE_OVERRIDE), fontSmoothingBackgroundColor(NS_RGBA(0, 0, 0, 0)), - weight(NS_FONT_WEIGHT_NORMAL), stretch(NS_FONT_STRETCH_NORMAL), + weight(FontWeight::Normal()), + stretch(NS_FONT_STRETCH_NORMAL), style(NS_FONT_STYLE_NORMAL), variantCaps(NS_FONT_VARIANT_CAPS_NORMAL), variantSubSuper(NS_FONT_VARIANT_POSITION_NORMAL), @@ -4121,7 +4123,9 @@ gfxFontStyle::gfxFontStyle() : { } -gfxFontStyle::gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch, +gfxFontStyle::gfxFontStyle(uint8_t aStyle, + FontWeight aWeight, + int16_t aStretch, gfxFloat aSize, nsAtom *aLanguage, bool aExplicitLanguage, float aSizeAdjust, bool aSystemFont, @@ -4133,7 +4137,8 @@ gfxFontStyle::gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch, size(aSize), sizeAdjust(aSizeAdjust), baselineOffset(0.0f), languageOverride(aLanguageOverride), fontSmoothingBackgroundColor(NS_RGBA(0, 0, 0, 0)), - weight(aWeight), stretch(aStretch), + weight(aWeight), + stretch(aStretch), style(aStyle), variantCaps(NS_FONT_VARIANT_CAPS_NORMAL), variantSubSuper(NS_FONT_VARIANT_POSITION_NORMAL), @@ -4147,10 +4152,12 @@ gfxFontStyle::gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch, MOZ_ASSERT(!mozilla::IsNaN(size)); MOZ_ASSERT(!mozilla::IsNaN(sizeAdjust)); - if (weight > 900) - weight = 900; - if (weight < 100) - weight = 100; + if (weight > FontWeight(900)) { + weight = FontWeight(900); + } + if (weight < FontWeight(100)) { + weight = FontWeight(100); + } if (size >= FONT_MAX_SIZE) { size = FONT_MAX_SIZE; diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 4889b8d890e5..b72563254c68 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -25,6 +25,7 @@ #include "nsIObserver.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Attributes.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/TypedEnumBits.h" #include "MainThreadUtils.h" #include @@ -75,8 +76,10 @@ class SVGContextPaint; } // namespace mozilla struct gfxFontStyle { + typedef mozilla::FontWeight FontWeight; + gfxFontStyle(); - gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch, + gfxFontStyle(uint8_t aStyle, FontWeight aWeight, int16_t aStretch, gfxFloat aSize, nsAtom *aLanguage, bool aExplicitLanguage, float aSizeAdjust, bool aSystemFont, bool aPrinterFont, @@ -137,7 +140,7 @@ struct gfxFontStyle { nscolor fontSmoothingBackgroundColor; // The weight of the font: 100, 200, ... 900. - uint16_t weight; + FontWeight weight; // The stretch of the font (the sum of various NS_FONT_STRETCH_* // constants; see gfxFontConstants.h). @@ -184,8 +187,8 @@ struct gfxFontStyle { } PLDHashNumber Hash() const { - return ((style + (systemFont << 7) + - (weight << 8)) + uint32_t(size*1000) + int32_t(sizeAdjust*1000)) ^ + return (style + (systemFont << 7) + (weight.ForHash() << 8) + + uint32_t(size*1000) + int32_t(sizeAdjust*1000)) ^ nsRefPtrHashKey::HashKey(language); } diff --git a/gfx/thebes/gfxFontEntry.cpp b/gfx/thebes/gfxFontEntry.cpp index cc7c76f73e35..7931d64e9e3c 100644 --- a/gfx/thebes/gfxFontEntry.cpp +++ b/gfx/thebes/gfxFontEntry.cpp @@ -3,12 +3,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "gfxFontEntry.h" + #include "mozilla/DebugOnly.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/MathAlgorithms.h" #include "mozilla/Logging.h" -#include "gfxFontEntry.h" #include "gfxTextRun.h" #include "gfxPlatform.h" #include "nsGkAtoms.h" @@ -1234,24 +1236,25 @@ StretchDistance(int16_t aFontStretch, int16_t aTargetStretch) // weight distance ==> [0,1598] static inline uint32_t -WeightDistance(uint32_t aFontWeight, uint32_t aTargetWeight) +WeightDistance(FontWeight aFontWeight, FontWeight aTargetWeight) { // Compute a measure of the "distance" between the requested // weight and the given fontEntry - int32_t distance = 0, addedDistance = 0; + float distance = 0.0f, addedDistance = 0.0f; if (aTargetWeight != aFontWeight) { - if (aTargetWeight > 500) { + if (aTargetWeight > FontWeight(500)) { distance = aFontWeight - aTargetWeight; - } else if (aTargetWeight < 400) { + } else if (aTargetWeight < FontWeight(400)) { distance = aTargetWeight - aFontWeight; } else { // special case - target is between 400 and 500 // font weights between 400 and 500 are close - if (aFontWeight >= 400 && aFontWeight <= 500) { + if (aFontWeight >= FontWeight(400) && + aFontWeight <= FontWeight(500)) { if (aFontWeight < aTargetWeight) { - distance = 500 - aFontWeight; + distance = FontWeight(500) - aFontWeight; } else { distance = aFontWeight - aTargetWeight; } @@ -1263,7 +1266,7 @@ WeightDistance(uint32_t aFontWeight, uint32_t aTargetWeight) addedDistance = 100; } } - if (distance < 0) { + if (distance < 0.0f) { distance = -distance + REVERSE_WEIGHT_DISTANCE; } distance += addedDistance; @@ -1307,7 +1310,7 @@ gfxFontFamily::FindAllFontsForStyle(const gfxFontStyle& aFontStyle, aNeedsSyntheticBold = false; - bool wantBold = aFontStyle.weight >= 600; + bool wantBold = aFontStyle.weight >= FontWeight(600); gfxFontEntry *fe = nullptr; // If the family has only one face, we simply return it; no further @@ -1406,7 +1409,7 @@ gfxFontFamily::FindAllFontsForStyle(const gfxFontStyle& aFontStyle, if (matched) { aFontEntryList.AppendElement(matched); - if (!matched->IsBold() && aFontStyle.weight >= 600 && + if (!matched->IsBold() && aFontStyle.weight >= FontWeight(600) && aFontStyle.allowSyntheticWeight) { aNeedsSyntheticBold = true; } @@ -1442,7 +1445,7 @@ gfxFontFamily::CheckForSimpleFamily() return; } uint8_t faceIndex = (fe->IsItalic() ? kItalicMask : 0) | - (fe->Weight() >= 600 ? kBoldMask : 0); + (fe->Weight() >= FontWeight(600) ? kBoldMask : 0); if (faces[faceIndex]) { return; // two faces resolve to the same slot; family isn't "simple" } @@ -1501,7 +1504,7 @@ CalcStyleMatch(gfxFontEntry *aFontEntry, const gfxFontStyle *aStyle) } // measure of closeness of weight to the desired value - rank += 9 - Abs((aFontEntry->Weight() - aStyle->weight) / 100); + rank += 9 - Abs((aFontEntry->Weight() - aStyle->weight) / 100.0f); } else { // if no font to match, prefer non-bold, non-italic fonts if (aFontEntry->IsUpright()) { diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h index 728480e3a152..23da86f0ff50 100644 --- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -20,6 +20,7 @@ #include "nsUnicodeScriptCodes.h" #include "nsDataHashtable.h" #include "harfbuzz/hb.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/gfx/2D.h" #include "mozilla/UniquePtr.h" #include "mozilla/WeakPtr.h" @@ -109,6 +110,7 @@ struct gfxFontFeatureInfo { class gfxFontEntry { public: + typedef mozilla::FontWeight FontWeight; typedef mozilla::gfx::DrawTarget DrawTarget; typedef mozilla::unicode::Script Script; @@ -139,7 +141,7 @@ public: // returns Name() if nothing better is available. virtual nsString RealFaceName(); - uint16_t Weight() const { return mWeight; } + FontWeight Weight() const { return mWeight; } int16_t Stretch() const { return mStretch; } bool IsUserFont() const { return mIsDataUserFont || mIsLocalUserFont; } @@ -148,7 +150,7 @@ public: bool IsItalic() const { return mStyle == NS_FONT_STYLE_ITALIC; } bool IsOblique() const { return mStyle == NS_FONT_STYLE_OBLIQUE; } bool IsUpright() const { return mStyle == NS_FONT_STYLE_NORMAL; } - bool IsBold() const { return mWeight >= 600; } // bold == weights 600 and above + bool IsBold() const { return mWeight >= FontWeight(600); } // bold == weights 600 and above bool IgnoreGDEF() const { return mIgnoreGDEF; } bool IgnoreGSUB() const { return mIgnoreGSUB; } @@ -161,7 +163,7 @@ public: bool IsNormalStyle() const { return IsUpright() && - Weight() == NS_FONT_WEIGHT_NORMAL && + Weight() == FontWeight::Normal() && Stretch() == NS_FONT_STRETCH_NORMAL; } @@ -402,7 +404,7 @@ public: uint32_t mDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32]; uint32_t mNonDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32]; - uint16_t mWeight; + FontWeight mWeight; int16_t mStretch; RefPtr mCharacterMap; diff --git a/gfx/thebes/gfxGDIFont.cpp b/gfx/thebes/gfxGDIFont.cpp index 7b0c9c506f9f..520d194e094c 100644 --- a/gfx/thebes/gfxGDIFont.cpp +++ b/gfx/thebes/gfxGDIFont.cpp @@ -445,20 +445,20 @@ gfxGDIFont::FillLogFont(LOGFONTW& aLogFont, gfxFloat aSize) { GDIFontEntry *fe = static_cast(GetFontEntry()); - uint16_t weight; + FontWeight weight; if (fe->IsUserFont()) { if (fe->IsLocalUserFont()) { // for local user fonts, don't change the original weight // in the entry's logfont, because that could alter the // choice of actual face used (bug 724231) - weight = 0; + weight = FontWeight(0); } else { // avoid GDI synthetic bold which occurs when weight // specified is >= font data weight + 200 - weight = mNeedsBold ? 700 : 200; + weight = mNeedsBold ? FontWeight(700) : FontWeight(200); } } else { - weight = mNeedsBold ? 700 : fe->Weight(); + weight = mNeedsBold ? FontWeight(700) : fe->Weight(); } fe->FillLogFont(&aLogFont, weight, aSize); diff --git a/gfx/thebes/gfxGDIFontList.cpp b/gfx/thebes/gfxGDIFontList.cpp index a378ef6933fd..22a363e1f981 100644 --- a/gfx/thebes/gfxGDIFontList.cpp +++ b/gfx/thebes/gfxGDIFontList.cpp @@ -115,7 +115,8 @@ FontTypeToOutPrecision(uint8_t fontType) GDIFontEntry::GDIFontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType, - uint8_t aStyle, uint16_t aWeight, + uint8_t aStyle, + FontWeight aWeight, int16_t aStretch, gfxUserFontData *aUserFontData) : gfxFontEntry(aFaceName), @@ -255,7 +256,8 @@ GDIFontEntry::LookupUnscaledFont(HFONT aFont) void GDIFontEntry::FillLogFont(LOGFONTW *aLogFont, - uint16_t aWeight, gfxFloat aSize) + FontWeight aWeight, + gfxFloat aSize) { memcpy(aLogFont, &mLogFont, sizeof(LOGFONTW)); @@ -270,8 +272,8 @@ GDIFontEntry::FillLogFont(LOGFONTW *aLogFont, // for installed families with no bold face, and for downloaded fonts // (but NOT for local user fonts, because it could cause a different, // glyph-incompatible face to be used) - if (aWeight) { - aLogFont->lfWeight = aWeight; + if (aWeight.ToFloat() != 0.0f) { + aLogFont->lfWeight = LONG(aWeight.ToFloat()); } // for non-local() user fonts, we never want to apply italics here; @@ -303,7 +305,7 @@ GDIFontEntry::TestCharacterMap(uint32_t aCh) if (!IsUpright()) { fakeStyle.style = NS_FONT_STYLE_ITALIC; } - fakeStyle.weight = mWeight * 100; + fakeStyle.weight = mWeight; RefPtr tempFont = FindOrMakeFont(&fakeStyle, false); if (!tempFont || !tempFont->Valid()) @@ -382,7 +384,7 @@ GDIFontEntry::InitLogFont(const nsAString& aName, // it may give us a regular one based on weight. Windows should // do fake italic for us in that case. mLogFont.lfItalic = !IsUpright(); - mLogFont.lfWeight = mWeight; + mLogFont.lfWeight = int(mWeight.ToFloat()); int len = std::min(aName.Length(), LF_FACESIZE - 1); memcpy(&mLogFont.lfFaceName, aName.BeginReading(), len * sizeof(char16_t)); @@ -393,7 +395,8 @@ GDIFontEntry* GDIFontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, uint8_t aStyle, - uint16_t aWeight, int16_t aStretch, + FontWeight aWeight, + int16_t aStretch, gfxUserFontData* aUserFontData) { // jtdfix - need to set charset, unicode ranges, pitch/family @@ -464,7 +467,7 @@ GDIFontFamily::FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe, for (uint32_t i = 0; i < ff->mAvailableFonts.Length(); ++i) { fe = static_cast(ff->mAvailableFonts[i].get()); // check if we already know about this face - if (fe->mWeight == logFont.lfWeight && + if (fe->mWeight == FontWeight(int32_t(logFont.lfWeight)) && fe->IsItalic() == (logFont.lfItalic == 0xFF)) { // update the charset bit here since this could be different // XXX Can we still do this now that we store mCharset @@ -481,7 +484,7 @@ GDIFontFamily::FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe, NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL); fe = GDIFontEntry::CreateFontEntry(nsDependentString(lpelfe->elfFullName), feType, italicStyle, - (uint16_t) (logFont.lfWeight), 0, + FontWeight(int32_t(logFont.lfWeight)), 0, nullptr); if (!fe) return 1; @@ -707,7 +710,7 @@ gfxGDIFontList::EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe, gfxFontEntry* gfxGDIFontList::LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) { @@ -734,7 +737,7 @@ gfxGDIFontList::LookupLocalFont(const nsAString& aFontName, fe->mIsLocalUserFont = true; // make the new font entry match the userfont entry style characteristics - fe->mWeight = (aWeight == 0 ? 400 : aWeight); + fe->mWeight = (aWeight == FontWeight(0) ? FontWeight(400) : aWeight); fe->mStyle = aStyle; return fe; @@ -799,7 +802,7 @@ FixupSymbolEncodedFont(uint8_t* aFontData, uint32_t aLength) gfxFontEntry* gfxGDIFontList::MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, @@ -864,7 +867,7 @@ gfxGDIFontList::MakePlatformFont(const nsAString& aFontName, // make a new font entry using the unique name WinUserFontData *winUserFontData = new WinUserFontData(fontRef); - uint16_t w = (aWeight == 0 ? 400 : aWeight); + FontWeight w = (aWeight == FontWeight(0) ? FontWeight(400) : aWeight); GDIFontEntry *fe = GDIFontEntry::CreateFontEntry(uniqueName, gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/, diff --git a/gfx/thebes/gfxGDIFontList.h b/gfx/thebes/gfxGDIFontList.h index c197d473dfb2..53b97308359a 100644 --- a/gfx/thebes/gfxGDIFontList.h +++ b/gfx/thebes/gfxGDIFontList.h @@ -6,6 +6,7 @@ #ifndef GFX_GDIFONTLIST_H #define GFX_GDIFONTLIST_H +#include "mozilla/FontPropertyTypes.h" #include "mozilla/MemoryReporting.h" #include "gfxWindowsPlatform.h" #include "gfxPlatformFontList.h" @@ -107,11 +108,15 @@ enum gfxWindowsFontType { class GDIFontEntry : public gfxFontEntry { public: + typedef mozilla::FontWeight FontWeight; + LPLOGFONTW GetLogFont() { return &mLogFont; } nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override; - void FillLogFont(LOGFONTW *aLogFont, uint16_t aWeight, gfxFloat aSize); + void FillLogFont(LOGFONTW *aLogFont, + FontWeight aWeight, + gfxFloat aSize); static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics, DWORD fontType) @@ -164,12 +169,13 @@ public: static GDIFontEntry* CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, uint8_t aStyle, - uint16_t aWeight, int16_t aStretch, + FontWeight aWeight, + int16_t aStretch, gfxUserFontData* aUserFontData); // create a font entry for a font referenced by its fullname static GDIFontEntry* LoadLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle); @@ -182,7 +188,7 @@ protected: friend class gfxGDIFont; GDIFontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType, - uint8_t aStyle, uint16_t aWeight, int16_t aStretch, + uint8_t aStyle, FontWeight aWeight, int16_t aStretch, gfxUserFontData *aUserFontData); void InitLogFont(const nsAString& aName, gfxWindowsFontType aFontType); @@ -314,6 +320,8 @@ private: class gfxGDIFontList : public gfxPlatformFontList { public: + typedef mozilla::FontWeight FontWeight; + static gfxGDIFontList* PlatformFontList() { return static_cast(sPlatformFontList); } @@ -330,12 +338,12 @@ public: gfxFloat aDevToCssSize = 1.0) override; virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle); virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxMacPlatformFontList.h b/gfx/thebes/gfxMacPlatformFontList.h index f821cf6b4c8a..838821fd2e2a 100644 --- a/gfx/thebes/gfxMacPlatformFontList.h +++ b/gfx/thebes/gfxMacPlatformFontList.h @@ -8,6 +8,7 @@ #include +#include "mozilla/FontPropertyTypes.h" #include "mozilla/MemoryReporting.h" #include "nsDataHashtable.h" #include "nsRefPtrHashtable.h" @@ -30,13 +31,13 @@ class MacOSFontEntry : public gfxFontEntry public: friend class gfxMacPlatformFontList; - MacOSFontEntry(const nsAString& aPostscriptName, int32_t aWeight, + MacOSFontEntry(const nsAString& aPostscriptName, FontWeight aWeight, bool aIsStandardFace = false, double aSizeHint = 0.0); // for use with data fonts MacOSFontEntry(const nsAString& aPostscriptName, CGFontRef aFontRef, - uint16_t aWeight, uint16_t aStretch, uint8_t aStyle, + FontWeight aWeight, uint16_t aStretch, uint8_t aStyle, bool aIsDataUserFont, bool aIsLocal); virtual ~MacOSFontEntry() { @@ -130,12 +131,12 @@ public: bool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName) override; gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) override; gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxMacPlatformFontList.mm b/gfx/thebes/gfxMacPlatformFontList.mm index b9e8a17b8a47..0231bf5d3aae 100644 --- a/gfx/thebes/gfxMacPlatformFontList.mm +++ b/gfx/thebes/gfxMacPlatformFontList.mm @@ -65,6 +65,7 @@ #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentParent.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Preferences.h" #include "mozilla/Sprintf.h" @@ -363,7 +364,7 @@ MacOSFontEntry::IsCFF() } MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, - int32_t aWeight, + FontWeight aWeight, bool aIsStandardFace, double aSizeHint) : gfxFontEntry(aPostscriptName, aIsStandardFace), @@ -387,7 +388,8 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, CGFontRef aFontRef, - uint16_t aWeight, uint16_t aStretch, + FontWeight aWeight, + uint16_t aStretch, uint8_t aStyle, bool aIsDataUserFont, bool aIsLocalUserFont) @@ -902,7 +904,8 @@ gfxMacFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) // create a font entry MacOSFontEntry *fontEntry = - new MacOSFontEntry(postscriptFontName, cssWeight, isStandardFace, mSizeHint); + new MacOSFontEntry(postscriptFontName, FontWeight(cssWeight), + isStandardFace, mSizeHint); if (!fontEntry) { break; } @@ -1530,7 +1533,7 @@ gfxMacPlatformFontList::AppleWeightToCSSWeight(int32_t aAppleWeight) gfxFontEntry* gfxMacPlatformFontList::LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) { @@ -1545,8 +1548,8 @@ gfxMacPlatformFontList::LookupLocalFont(const nsAString& aFontName, return nullptr; } - NS_ASSERTION(aWeight >= 100 && aWeight <= 900, - "bogus font weight value!"); + MOZ_ASSERT(aWeight >= FontWeight(100) && aWeight <= FontWeight(900), + "bogus font weight value!"); newFontEntry = new MacOSFontEntry(aFontName, fontRef, aWeight, aStretch, aStyle, @@ -1563,7 +1566,7 @@ static void ReleaseData(void *info, const void *data, size_t size) gfxFontEntry* gfxMacPlatformFontList::MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, @@ -1571,7 +1574,8 @@ gfxMacPlatformFontList::MakePlatformFont(const nsAString& aFontName, { NS_ASSERTION(aFontData, "MakePlatformFont called with null data"); - NS_ASSERTION(aWeight >= 100 && aWeight <= 900, "bogus font weight value!"); + MOZ_ASSERT(aWeight >= FontWeight(100) && aWeight <= FontWeight(900), + "bogus font weight value!"); // create the font entry nsAutoString uniqueName; @@ -1701,7 +1705,7 @@ gfxMacPlatformFontList::LookupSystemFont(LookAndFeel::FontID aSystemFontID, aFontStyle.style = (traits & NSFontItalicTrait) ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL; aFontStyle.weight = - (traits & NSFontBoldTrait) ? NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL; + (traits & NSFontBoldTrait) ? FontWeight::Bold() : FontWeight::Normal(); aFontStyle.stretch = (traits & NSFontExpandedTrait) ? NS_FONT_STRETCH_EXPANDED : (traits & NSFontCondensedTrait) ? diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 174c7d773bab..abe2bb655768 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -3,6 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "mozilla/FontPropertyTypes.h" #include "mozilla/layers/CompositorManagerChild.h" #include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/ImageBridgeChild.h" @@ -1757,7 +1758,7 @@ gfxPlatform::IsFontFormatSupported(uint32_t aFormatFlags) gfxFontEntry* gfxPlatform::LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) { @@ -1769,7 +1770,7 @@ gfxPlatform::LookupLocalFont(const nsAString& aFontName, gfxFontEntry* gfxPlatform::MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index a13b3b42891e..b3cb4f32fe65 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -6,6 +6,7 @@ #ifndef GFX_PLATFORM_H #define GFX_PLATFORM_H +#include "mozilla/FontPropertyTypes.h" #include "mozilla/Logging.h" #include "mozilla/gfx/Types.h" #include "nsTArray.h" @@ -158,6 +159,7 @@ class gfxPlatform { friend class SRGBOverrideObserver; public: + typedef mozilla::FontWeight FontWeight; typedef mozilla::gfx::Color Color; typedef mozilla::gfx::DataSourceSurface DataSourceSurface; typedef mozilla::gfx::DrawTarget DrawTarget; @@ -391,7 +393,7 @@ public: * who must either AddRef() or delete. */ virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle); @@ -404,7 +406,7 @@ public: * who must either AddRef() or delete. */ virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h index 8d099f1bd8c1..d7d3bdf63788 100644 --- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -19,6 +19,7 @@ #include "nsIMemoryReporter.h" #include "mozilla/Attributes.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Mutex.h" #include "mozilla/RangedArray.h" @@ -97,6 +98,7 @@ class gfxPlatformFontList : public gfxFontInfoLoader friend class InitOtherFamilyNamesRunnable; public: + typedef mozilla::FontWeight FontWeight; typedef mozilla::unicode::Script Script; static gfxPlatformFontList* PlatformFontList() { @@ -186,14 +188,14 @@ public: // look up a font by name on the host platform virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) = 0; // create a new platform font from downloaded data (@font-face) // this method is responsible to ensure aFontData is free()'d virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp index 45274277e90c..a6f2569651db 100644 --- a/gfx/thebes/gfxPlatformGtk.cpp +++ b/gfx/thebes/gfxPlatformGtk.cpp @@ -26,6 +26,7 @@ #include "base/task.h" #include "base/thread.h" #include "base/message_loop.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/gfx/Logging.h" #include "mozilla/gfx/2D.h" @@ -274,7 +275,7 @@ gfxPlatformGtk::CreateFontGroup(const FontFamilyList& aFontFamilyList, gfxFontEntry* gfxPlatformGtk::LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) { @@ -285,7 +286,7 @@ gfxPlatformGtk::LookupLocalFont(const nsAString& aFontName, gfxFontEntry* gfxPlatformGtk::MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxPlatformGtk.h b/gfx/thebes/gfxPlatformGtk.h index 390e7b22f645..2055574365cd 100644 --- a/gfx/thebes/gfxPlatformGtk.h +++ b/gfx/thebes/gfxPlatformGtk.h @@ -66,7 +66,7 @@ public: * support @font-face src local() ) */ virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle) override; @@ -75,7 +75,7 @@ public: * */ virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - uint16_t aWeight, + FontWeight aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index ad41d704d375..a33b5600c56f 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -1768,9 +1768,9 @@ gfxTextRun::Dump(FILE* aOutput) { NS_ConvertUTF16toUTF8 fontName(font->GetName()); nsAutoCString lang; style->language->ToUTF8String(lang); - fprintf(aOutput, "%d: %s %f/%d/%d/%s", glyphRuns[i].mCharacterOffset, + fprintf(aOutput, "%d: %s %f/%g/%d/%s", glyphRuns[i].mCharacterOffset, fontName.get(), style->size, - style->weight, style->style, lang.get()); + style->weight.ToFloat(), style->style, lang.get()); } fputc(']', aOutput); } @@ -2416,7 +2416,7 @@ gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, nsAutoCString str((const char*)aString, aLength); MOZ_LOG(log, LogLevel::Warning,\ ("(%s) fontgroup: [%s] default: %s lang: %s script: %d " - "len %d weight: %d width: %d style: %s size: %6.2f %zu-byte " + "len %d weight: %g width: %d style: %s size: %6.2f %zu-byte " "TEXTRUN [%s] ENDTEXTRUN\n", (mStyle.systemFont ? "textrunui" : "textrun"), NS_ConvertUTF16toUTF8(families).get(), @@ -2425,7 +2425,7 @@ gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, (mFamilyList.GetDefaultFontType() == eFamily_sans_serif ? "sans-serif" : "none")), lang.get(), static_cast(Script::LATIN), aLength, - uint32_t(mStyle.weight), uint32_t(mStyle.stretch), + mStyle.weight.ToFloat(), uint32_t(mStyle.stretch), (mStyle.style & NS_FONT_STYLE_ITALIC ? "italic" : (mStyle.style & NS_FONT_STYLE_OBLIQUE ? "oblique" : "normal")), @@ -2464,7 +2464,7 @@ gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, uint32_t runLen = runLimit - runStart; MOZ_LOG(log, LogLevel::Warning,\ ("(%s) fontgroup: [%s] default: %s lang: %s script: %d " - "len %d weight: %d width: %d style: %s size: %6.2f " + "len %d weight: %g width: %d style: %s size: %6.2f " "%zu-byte TEXTRUN [%s] ENDTEXTRUN\n", (mStyle.systemFont ? "textrunui" : "textrun"), NS_ConvertUTF16toUTF8(families).get(), @@ -2473,7 +2473,7 @@ gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, (mFamilyList.GetDefaultFontType() == eFamily_sans_serif ? "sans-serif" : "none")), lang.get(), static_cast(runScript), runLen, - uint32_t(mStyle.weight), uint32_t(mStyle.stretch), + mStyle.weight.ToFloat(), uint32_t(mStyle.stretch), (mStyle.style & NS_FONT_STYLE_ITALIC ? "italic" : (mStyle.style & NS_FONT_STYLE_OBLIQUE ? "oblique" : "normal")), @@ -2818,7 +2818,7 @@ gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh) return nullptr; } - bool needsBold = mStyle.weight >= 600 && !fe->IsBold() && + bool needsBold = mStyle.weight >= FontWeight(600) && !fe->IsBold() && mStyle.allowSyntheticWeight; return fe->FindOrMakeFont(&mStyle, needsBold); } @@ -3444,7 +3444,7 @@ gfxFontGroup::WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh, gfxPlatformFontList::PlatformFontList()-> SystemFindFontForChar(aCh, aNextCh, aRunScript, &mStyle); if (fe) { - bool wantBold = mStyle.weight >= 600; + bool wantBold = mStyle.weight >= FontWeight(600); return fe->FindOrMakeFont(&mStyle, wantBold && !fe->IsBold()); } diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index 298ce0d9c63f..c31e44cb5253 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -10,6 +10,7 @@ #include "gfxPrefs.h" #include "nsIProtocolHandler.h" #include "gfxFontConstants.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" #include "mozilla/Telemetry.h" @@ -104,7 +105,7 @@ private: gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet* aFontSet, const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -120,8 +121,8 @@ gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet* aFontSet, mLoader(nullptr), mFontSet(aFontSet) { - MOZ_ASSERT(aWeight != 0, - "aWeight must not be 0; use NS_FONT_WEIGHT_NORMAL instead"); + MOZ_ASSERT(aWeight != FontWeight(0), + "aWeight must not be 0; use FontWeight::Normal() instead"); mIsUserFontContainer = true; mSrcList = aFontFaceSrcList; mSrcIndex = 0; @@ -144,7 +145,7 @@ gfxUserFontEntry::~gfxUserFontEntry() bool gfxUserFontEntry::Matches(const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -935,7 +936,7 @@ already_AddRefed gfxUserFontSet::FindOrCreateUserFontEntry( const nsAString& aFamilyName, const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -975,7 +976,7 @@ gfxUserFontSet::FindOrCreateUserFontEntry( already_AddRefed gfxUserFontSet::CreateUserFontEntry( const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -996,7 +997,7 @@ gfxUserFontEntry* gfxUserFontSet::FindExistingUserFontEntry( gfxUserFontFamily* aFamily, const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -1005,8 +1006,8 @@ gfxUserFontSet::FindExistingUserFontEntry( gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) { - MOZ_ASSERT(aWeight != 0, - "aWeight must not be 0; use NS_FONT_WEIGHT_NORMAL instead"); + MOZ_ASSERT(aWeight != FontWeight(0), + "aWeight must not be 0; use FontWeight::Normal() instead"); nsTArray>& fontList = aFamily->GetFontList(); @@ -1039,12 +1040,12 @@ gfxUserFontSet::AddUserFontEntry(const nsAString& aFamilyName, family->AddFontEntry(aUserFontEntry); if (LOG_ENABLED()) { - LOG(("userfonts (%p) added to \"%s\" (%p) style: %s weight: %d " + LOG(("userfonts (%p) added to \"%s\" (%p) style: %s weight: %g " "stretch: %d display: %d", this, NS_ConvertUTF16toUTF8(aFamilyName).get(), aUserFontEntry, (aUserFontEntry->IsItalic() ? "italic" : (aUserFontEntry->IsOblique() ? "oblique" : "normal")), - aUserFontEntry->Weight(), aUserFontEntry->Stretch(), + aUserFontEntry->Weight().ToFloat(), aUserFontEntry->Stretch(), aUserFontEntry->GetFontDisplay())); } } diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h index ef28c0b07b4c..23d607ab7b08 100644 --- a/gfx/thebes/gfxUserFontSet.h +++ b/gfx/thebes/gfxUserFontSet.h @@ -16,6 +16,7 @@ #include "nsIPrincipal.h" #include "nsIScriptError.h" #include "nsURIHashKey.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/net/ReferrerPolicy.h" #include "gfxFontConstants.h" @@ -184,6 +185,7 @@ class gfxUserFontSet { friend class gfxOTSContext; public: + typedef mozilla::FontWeight FontWeight; NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxUserFontSet) @@ -229,7 +231,7 @@ public: // TODO: support for unicode ranges not yet implemented virtual already_AddRefed CreateUserFontEntry( const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -243,7 +245,7 @@ public: already_AddRefed FindOrCreateUserFontEntry( const nsAString& aFamilyName, const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -404,8 +406,8 @@ public: HashFeatures(aKey->mFontEntry->mFeatureSettings), HashVariations(aKey->mFontEntry->mVariationSettings), mozilla::HashString(aKey->mFontEntry->mFamilyName), + aKey->mFontEntry->mWeight.ForHash(), (aKey->mFontEntry->mStyle | - (aKey->mFontEntry->mWeight << 2) | (aKey->mFontEntry->mStretch << 11) ) ^ aKey->mFontEntry->mLanguageOverride); } @@ -497,7 +499,7 @@ protected: gfxUserFontEntry* FindExistingUserFontEntry( gfxUserFontFamily* aFamily, const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -537,6 +539,8 @@ class gfxUserFontEntry : public gfxFontEntry { friend class gfxOTSContext; public: + typedef mozilla::FontWeight FontWeight; + enum UserFontLoadState { STATUS_NOT_LOADED = 0, STATUS_LOAD_PENDING, @@ -547,7 +551,7 @@ public: gfxUserFontEntry(gfxUserFontSet* aFontSet, const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -560,7 +564,7 @@ public: // Return whether the entry matches the given list of attributes bool Matches(const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, diff --git a/gfx/webrender_bindings/RenderThread.cpp b/gfx/webrender_bindings/RenderThread.cpp index 7bbf8365101f..8a3115dc8e02 100644 --- a/gfx/webrender_bindings/RenderThread.cpp +++ b/gfx/webrender_bindings/RenderThread.cpp @@ -100,6 +100,9 @@ RenderThread::ShutDownTask(layers::SynchronousTask* aTask) { layers::AutoCompleteTask complete(aTask); MOZ_ASSERT(IsInRenderThread()); + + MutexAutoLock lock(mRenderTextureMapLock); + mRenderTextures.Clear(); } // static diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 59a21723aaaf..2978d01734fb 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -456,10 +456,9 @@ fn get_proc_address(glcontext_ptr: *mut c_void, let symbol_name = CString::new(name).unwrap(); let symbol = unsafe { get_proc_address_from_glcontext(glcontext_ptr, symbol_name.as_ptr()) }; - // For now panic, not sure we should be though or if we can recover if symbol.is_null() { // XXX Bug 1322949 Make whitelist for extensions - println!("Could not find symbol {:?} by glcontext", symbol_name); + warn!("Could not find symbol {:?} by glcontext", symbol_name); } symbol as *const _ @@ -564,7 +563,7 @@ pub extern "C" fn wr_renderer_render(renderer: &mut Renderer, Ok(_) => true, Err(errors) => { for e in errors { - println!(" Failed to render: {:?}", e); + warn!(" Failed to render: {:?}", e); let msg = CString::new(format!("wr_renderer_render: {:?}", e)).unwrap(); unsafe { gfx_critical_note(msg.as_ptr()); @@ -836,7 +835,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId, let version = gl.get_string(gl::VERSION); - println!("WebRender - OpenGL version new {}", version); + info!("WebRender - OpenGL version new {}", version); let workers = unsafe { Arc::clone(&(*thread_pool).0) @@ -879,7 +878,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId, let (renderer, sender) = match Renderer::new(gl, notifier, opts) { Ok((renderer, sender)) => (renderer, sender), Err(e) => { - println!(" Failed to create a Renderer: {:?}", e); + warn!(" Failed to create a Renderer: {:?}", e); let msg = CString::new(format!("wr_window_new: {:?}", e)).unwrap(); unsafe { gfx_critical_note(msg.as_ptr()); @@ -1323,7 +1322,7 @@ pub extern "C" fn wr_api_capture( file.write(revision).unwrap(); } Err(e) => { - println!("Unable to create path '{:?}' for capture: {:?}", path, e); + warn!("Unable to create path '{:?}' for capture: {:?}", path, e); return } } diff --git a/gfx/webrender_bindings/src/lib.rs b/gfx/webrender_bindings/src/lib.rs index 5ffa18e37da3..426d28b21da7 100644 --- a/gfx/webrender_bindings/src/lib.rs +++ b/gfx/webrender_bindings/src/lib.rs @@ -10,6 +10,8 @@ extern crate app_units; extern crate gleam; extern crate rayon; extern crate thread_profiler; + +#[macro_use] extern crate log; #[cfg(target_os = "windows")] diff --git a/image/AnimationFrameBuffer.cpp b/image/AnimationFrameBuffer.cpp index 31ce5b103e50..5d8b672f6665 100644 --- a/image/AnimationFrameBuffer.cpp +++ b/image/AnimationFrameBuffer.cpp @@ -17,6 +17,7 @@ AnimationFrameBuffer::AnimationFrameBuffer() , mInsertIndex(0) , mGetIndex(0) , mSizeKnown(false) + , mRedecodeError(false) { } void @@ -71,7 +72,16 @@ AnimationFrameBuffer::Insert(RawAccessFrameRef&& aFrame) // and we did not keep all of the frames. Replace whatever is there // (probably an empty frame) with the new frame. MOZ_ASSERT(MayDiscard()); - MOZ_ASSERT(mInsertIndex < mFrames.Length()); + + // The first decode produced fewer frames than the redecodes, presumably + // because it hit an out-of-memory error which later attempts avoided. Just + // stop the animation because we can't tell the image that we have more + // frames now. + if (mInsertIndex >= mFrames.Length()) { + mRedecodeError = true; + mPending = 0; + return false; + } if (mInsertIndex > 0) { MOZ_ASSERT(!mFrames[mInsertIndex]); @@ -127,9 +137,23 @@ AnimationFrameBuffer::Insert(RawAccessFrameRef&& aFrame) bool AnimationFrameBuffer::MarkComplete() { + // We may have stopped decoding at a different point in the animation than we + // did previously. That means the decoder likely hit a new error, e.g. OOM. + // This will prevent us from advancing as well, because we are missing the + // required frames to blend. + // + // XXX(aosmond): In an ideal world, we would be generating full frames, and + // the consumer of our data doesn't care about our internal state. It simply + // knows about the first frame, the current frame, and how long to display the + // current frame. + if (NS_WARN_IF(mInsertIndex != mFrames.Length())) { + MOZ_ASSERT(mSizeKnown); + mRedecodeError = true; + mPending = 0; + } + // We reached the end of the animation, the next frame we get, if we get // another, will be the first frame again. - MOZ_ASSERT(mInsertIndex == mFrames.Length()); mInsertIndex = 0; // Since we only request advancing when we want to resume at a certain point @@ -231,7 +255,7 @@ AnimationFrameBuffer::AdvanceInternal() } } - if (!mSizeKnown || MayDiscard()) { + if (!mRedecodeError && (!mSizeKnown || MayDiscard())) { // Calculate how many frames we have requested ahead of the current frame. size_t buffered = mPending; if (mGetIndex > mInsertIndex) { @@ -276,13 +300,6 @@ AnimationFrameBuffer::Reset() return false; } - // If we are over the threshold, then we know we will have missing frames in - // our buffer. The easiest thing to do is to drop everything but the first - // frame and go back to the initial state. - bool restartDecoder = mPending == 0; - mInsertIndex = 0; - mPending = 2 * mBatch; - // Discard all frames besides the first, because the decoder always expects // that when it re-inserts a frame, it is not present. (It doesn't re-insert // the first frame.) @@ -290,6 +307,16 @@ AnimationFrameBuffer::Reset() RawAccessFrameRef discard = Move(mFrames[i]); } + mInsertIndex = 0; + + // If we hit an error after redecoding, we never want to restart decoding. + if (mRedecodeError) { + MOZ_ASSERT(mPending == 0); + return false; + } + + bool restartDecoder = mPending == 0; + mPending = 2 * mBatch; return restartDecoder; } diff --git a/image/AnimationFrameBuffer.h b/image/AnimationFrameBuffer.h index 0ad94aebe57f..aa23327e9186 100644 --- a/image/AnimationFrameBuffer.h +++ b/image/AnimationFrameBuffer.h @@ -129,6 +129,12 @@ public: */ bool SizeKnown() const { return mSizeKnown; } + /** + * @returns True if encountered an error during redecode which should cause + * the caller to stop inserting frames. + */ + bool HasRedecodeError() const { return mRedecodeError; } + /** * @returns The current frame index we have advanced to. */ @@ -187,6 +193,9 @@ private: // True if the total number of frames is known. bool mSizeKnown; + + // True if we encountered an error while redecoding. + bool mRedecodeError; }; } // namespace image diff --git a/image/AnimationSurfaceProvider.cpp b/image/AnimationSurfaceProvider.cpp index 4ff055e57534..4eeac1d852f2 100644 --- a/image/AnimationSurfaceProvider.cpp +++ b/image/AnimationSurfaceProvider.cpp @@ -224,13 +224,14 @@ AnimationSurfaceProvider::Run() FinishDecoding(); // Even if it is the last frame, we may not have enough frames buffered - // ahead of the current. - if (continueDecoding) { - MOZ_ASSERT(mDecoder); - continue; + // ahead of the current. If we are shutting down, we want to ensure we + // release the thread as soon as possible. The animation may advance even + // during shutdown, which keeps us decoding, and thus blocking the decode + // pool during teardown. + if (!mDecoder || !continueDecoding || + DecodePool::Singleton()->IsShuttingDown()) { + return; } - - return; } // Notify for the progress we've made so far. @@ -245,9 +246,13 @@ AnimationSurfaceProvider::Run() } // There's new output available - a new frame! Grab it. If we don't need any - // more for the moment we can break out of the loop. + // more for the moment we can break out of the loop. If we are shutting + // down, we want to ensure we release the thread as soon as possible. The + // animation may advance even during shutdown, which keeps us decoding, and + // thus blocking the decode pool during teardown. MOZ_ASSERT(result == LexerResult(Yield::OUTPUT_AVAILABLE)); - if (!CheckForNewFrameAtYield()) { + if (!CheckForNewFrameAtYield() || + DecodePool::Singleton()->IsShuttingDown()) { return; } } @@ -294,10 +299,7 @@ AnimationSurfaceProvider::CheckForNewFrameAtYield() AnnounceSurfaceAvailable(); } - // If we are shutting down, we want to ensure we release the thread as soon - // as possible. The animation may advance even during shutdown, which keeps - // us decoding, and thus blocking the decode pool during teardown. - return continueDecoding && !DecodePool::Singleton()->IsShuttingDown(); + return continueDecoding; } bool @@ -347,10 +349,7 @@ AnimationSurfaceProvider::CheckForNewFrameAtTerminalState() AnnounceSurfaceAvailable(); } - // If we are shutting down, we want to ensure we release the thread as soon - // as possible. The animation may advance even during shutdown, which keeps - // us decoding, and thus blocking the decode pool during teardown. - return continueDecoding && !DecodePool::Singleton()->IsShuttingDown(); + return continueDecoding; } void @@ -378,15 +377,15 @@ AnimationSurfaceProvider::FinishDecoding() NotifyDecodeComplete(WrapNotNull(mImage), WrapNotNull(mDecoder)); } - // Destroy our decoder; we don't need it anymore. - bool mayDiscard; + // Determine if we need to recreate the decoder, in case we are discarding + // frames and need to loop back to the beginning. + bool recreateDecoder; { MutexAutoLock lock(mFramesMutex); - mayDiscard = mFrames.MayDiscard(); + recreateDecoder = !mFrames.HasRedecodeError() && mFrames.MayDiscard(); } - if (mayDiscard) { - // Recreate the decoder so we can regenerate the frames again. + if (recreateDecoder) { mDecoder = DecoderFactory::CloneAnimationDecoder(mDecoder); MOZ_ASSERT(mDecoder); } else { diff --git a/image/test/gtest/TestAnimationFrameBuffer.cpp b/image/test/gtest/TestAnimationFrameBuffer.cpp index 55743ebdb1e7..e8fc495cc6da 100644 --- a/image/test/gtest/TestAnimationFrameBuffer.cpp +++ b/image/test/gtest/TestAnimationFrameBuffer.cpp @@ -143,6 +143,7 @@ TEST_F(ImageAnimationFrameBuffer, FinishUnderBatchAndThreshold) EXPECT_FALSE(keepDecoding); EXPECT_TRUE(buffer.SizeKnown()); EXPECT_EQ(size_t(0), buffer.PendingDecode()); + EXPECT_FALSE(buffer.HasRedecodeError()); } EXPECT_FALSE(buffer.MayDiscard()); @@ -220,6 +221,7 @@ TEST_F(ImageAnimationFrameBuffer, FinishMultipleBatchesUnderThreshold) EXPECT_TRUE(buffer.SizeKnown()); EXPECT_EQ(size_t(0), buffer.PendingDecode()); EXPECT_EQ(size_t(5), frames.Length()); + EXPECT_FALSE(buffer.HasRedecodeError()); // Finish progressing through the animation. for ( ; i < frames.Length(); ++i) { @@ -330,6 +332,7 @@ TEST_F(ImageAnimationFrameBuffer, MayDiscard) EXPECT_TRUE(buffer.SizeKnown()); EXPECT_EQ(size_t(2), buffer.PendingDecode()); EXPECT_EQ(size_t(10), frames.Length()); + EXPECT_FALSE(buffer.HasRedecodeError()); // Use remaining pending room. It shouldn't add new frames, only replace. do { @@ -513,3 +516,159 @@ TEST_F(ImageAnimationFrameBuffer, StartAfterBeginningAndReset) EXPECT_EQ(size_t(0), buffer.PendingAdvance()); } +TEST_F(ImageAnimationFrameBuffer, RedecodeMoreFrames) +{ + const size_t kThreshold = 5; + const size_t kBatch = 2; + AnimationFrameBuffer buffer; + buffer.Initialize(kThreshold, kBatch, 0); + const auto& frames = buffer.Frames(); + + // Add frames until we exceed the threshold. + bool keepDecoding; + bool restartDecoder; + size_t i = 0; + do { + keepDecoding = buffer.Insert(CreateEmptyFrame()); + EXPECT_TRUE(keepDecoding); + if (i > 0) { + restartDecoder = buffer.AdvanceTo(i); + EXPECT_FALSE(restartDecoder); + } + ++i; + } while (!buffer.MayDiscard()); + + // Should have threshold + 1 frames, and still not complete. + EXPECT_EQ(size_t(6), frames.Length()); + EXPECT_FALSE(buffer.SizeKnown()); + + // Now we lock in at 6 frames. + keepDecoding = buffer.MarkComplete(); + EXPECT_TRUE(keepDecoding); + EXPECT_TRUE(buffer.SizeKnown()); + EXPECT_FALSE(buffer.HasRedecodeError()); + + // Reinsert 6 frames first. + i = 0; + do { + keepDecoding = buffer.Insert(CreateEmptyFrame()); + EXPECT_TRUE(keepDecoding); + restartDecoder = buffer.AdvanceTo(i); + EXPECT_FALSE(restartDecoder); + ++i; + } while (i < 6); + + // We should now encounter an error and shutdown further decodes. + keepDecoding = buffer.Insert(CreateEmptyFrame()); + EXPECT_FALSE(keepDecoding); + EXPECT_EQ(size_t(0), buffer.PendingDecode()); + EXPECT_TRUE(buffer.HasRedecodeError()); +} + +TEST_F(ImageAnimationFrameBuffer, RedecodeFewerFrames) +{ + const size_t kThreshold = 5; + const size_t kBatch = 2; + AnimationFrameBuffer buffer; + buffer.Initialize(kThreshold, kBatch, 0); + const auto& frames = buffer.Frames(); + + // Add frames until we exceed the threshold. + bool keepDecoding; + bool restartDecoder; + size_t i = 0; + do { + keepDecoding = buffer.Insert(CreateEmptyFrame()); + EXPECT_TRUE(keepDecoding); + if (i > 0) { + restartDecoder = buffer.AdvanceTo(i); + EXPECT_FALSE(restartDecoder); + } + ++i; + } while (!buffer.MayDiscard()); + + // Should have threshold + 1 frames, and still not complete. + EXPECT_EQ(size_t(6), frames.Length()); + EXPECT_FALSE(buffer.SizeKnown()); + + // Now we lock in at 6 frames. + keepDecoding = buffer.MarkComplete(); + EXPECT_TRUE(keepDecoding); + EXPECT_TRUE(buffer.SizeKnown()); + EXPECT_FALSE(buffer.HasRedecodeError()); + + // Reinsert 5 frames before marking complete. + i = 0; + do { + keepDecoding = buffer.Insert(CreateEmptyFrame()); + EXPECT_TRUE(keepDecoding); + restartDecoder = buffer.AdvanceTo(i); + EXPECT_FALSE(restartDecoder); + ++i; + } while (i < 5); + + // We should now encounter an error and shutdown further decodes. + keepDecoding = buffer.MarkComplete(); + EXPECT_FALSE(keepDecoding); + EXPECT_EQ(size_t(0), buffer.PendingDecode()); + EXPECT_TRUE(buffer.HasRedecodeError()); +} + +TEST_F(ImageAnimationFrameBuffer, RedecodeFewerFramesAndBehindAdvancing) +{ + const size_t kThreshold = 5; + const size_t kBatch = 2; + AnimationFrameBuffer buffer; + buffer.Initialize(kThreshold, kBatch, 0); + const auto& frames = buffer.Frames(); + + // Add frames until we exceed the threshold. + bool keepDecoding; + bool restartDecoder; + size_t i = 0; + do { + keepDecoding = buffer.Insert(CreateEmptyFrame()); + EXPECT_TRUE(keepDecoding); + if (i > 0) { + restartDecoder = buffer.AdvanceTo(i); + EXPECT_FALSE(restartDecoder); + } + ++i; + } while (!buffer.MayDiscard()); + + // Should have threshold + 1 frames, and still not complete. + EXPECT_EQ(size_t(6), frames.Length()); + EXPECT_FALSE(buffer.SizeKnown()); + + // Now we lock in at 6 frames. + keepDecoding = buffer.MarkComplete(); + EXPECT_TRUE(keepDecoding); + EXPECT_TRUE(buffer.SizeKnown()); + EXPECT_FALSE(buffer.HasRedecodeError()); + + // Reinsert frames without advancing until we exhaust our pending space. This + // should be less than the current buffer length by definition. + i = 0; + do { + keepDecoding = buffer.Insert(CreateEmptyFrame()); + ++i; + } while (keepDecoding); + + EXPECT_EQ(size_t(2), i); + + // We should now encounter an error and shutdown further decodes. + keepDecoding = buffer.MarkComplete(); + EXPECT_FALSE(keepDecoding); + EXPECT_EQ(size_t(0), buffer.PendingDecode()); + EXPECT_TRUE(buffer.HasRedecodeError()); + + // We should however be able to continue advancing to the last decoded frame + // without it requesting the decoder to restart. + i = 0; + do { + restartDecoder = buffer.AdvanceTo(i); + EXPECT_FALSE(restartDecoder); + ++i; + } while (i < 2); +} + diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index ad9afc1190ab..fc7988285b9f 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -587,6 +587,19 @@ WasmSaturatingTruncationSupported(JSContext* cx, unsigned argc, Value* vp) return true; } +static bool +WasmGcEnabled(JSContext* cx, unsigned argc, Value* vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); +#ifdef ENABLE_WASM_GC + bool isSupported = cx->options().wasmBaseline() && cx->options().wasmGc(); +#else + bool isSupported = false; +#endif + args.rval().setBoolean(isSupported); + return true; +} + static bool WasmCompileMode(JSContext* cx, unsigned argc, Value* vp) { @@ -5503,6 +5516,10 @@ gc::ZealModeHelpText), " Returns a boolean indicating whether a given module has finished compiled code for tier2. \n" "This will return true early if compilation isn't two-tiered. "), + JS_FN_HELP("wasmGcEnabled", WasmGcEnabled, 1, 0, +"wasmGcEnabled(bool)", +" Returns a boolean indicating whether the WebAssembly GC support is enabled."), + JS_FN_HELP("isLazyFunction", IsLazyFunction, 1, 0, "isLazyFunction(fun)", " True if fun is a lazy JSFunction."), diff --git a/js/src/jit-test/tests/wasm/gc/anyref.js b/js/src/jit-test/tests/wasm/gc/anyref.js new file mode 100644 index 000000000000..d06b2154755a --- /dev/null +++ b/js/src/jit-test/tests/wasm/gc/anyref.js @@ -0,0 +1,383 @@ +// Ensure that if gc types aren't enabled, test cases properly fail. + +if (!wasmGcEnabled()) { + quit(0); +} + +// Dummy constructor. +function Baguette(calories) { + this.calories = calories; +} + +// Type checking. + +const { validate, CompileError } = WebAssembly; + +assertErrorMessage(() => wasmEvalText(`(module + (func (result anyref) + i32.const 42 + ) +)`), CompileError, mismatchError('i32', 'anyref')); + +assertErrorMessage(() => wasmEvalText(`(module + (func (result anyref) + i32.const 0 + ref.null anyref + i32.const 42 + select + ) +)`), CompileError, /select operand types/); + +assertErrorMessage(() => wasmEvalText(`(module + (func (result i32) + ref.null anyref + if + i32.const 42 + end + ) +)`), CompileError, mismatchError('anyref', 'i32')); + + +// Basic compilation tests. + +let simpleTests = [ + "(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) { + wasmEvalText(src, {a:{b(){}}}); + assertEq(validate(wasmTextToBinary(src)), true); +} + +// Basic behavioral tests. + +let { exports } = wasmEvalText(`(module + (func (export "is_null") (result i32) + ref.null anyref + ref.is_null + ) + + (func $sum (result i32) (param i32) + get_local 0 + i32.const 42 + i32.add + ) + + (func (export "is_null_spill") (result i32) + ref.null anyref + i32.const 58 + call $sum + drop + ref.is_null + ) + + (func (export "is_null_local") (result i32) (local anyref) + ref.null anyref + set_local 0 + i32.const 58 + call $sum + drop + get_local 0 + ref.is_null + ) +)`); + +assertEq(exports.is_null(), 1); +assertEq(exports.is_null_spill(), 1); +assertEq(exports.is_null_local(), 1); + +// Anyref param and result in wasm functions. + +exports = wasmEvalText(`(module + (func (export "is_null") (result i32) (param $ref anyref) + get_local $ref + ref.is_null + ) + + (func (export "ref_or_null") (result anyref) (param $ref anyref) (param $selector i32) + get_local $ref + ref.null anyref + get_local $selector + select + ) + + (func $recursive (export "nested") (result anyref) (param $ref anyref) (param $i i32) + ;; i == 10 => ret $ref + get_local $i + i32.const 10 + i32.eq + if + get_local $ref + return + end + + get_local $ref + + get_local $i + i32.const 1 + i32.add + + call $recursive + ) +)`).exports; + +assertErrorMessage(() => exports.is_null(undefined), TypeError, "can't convert undefined to object"); +assertEq(exports.is_null(null), 1); +assertEq(exports.is_null({}), 0); +assertEq(exports.is_null("hi"), 0); +assertEq(exports.is_null(3), 0); +assertEq(exports.is_null(3.5), 0); +assertEq(exports.is_null(true), 0); +assertEq(exports.is_null(Symbol("croissant")), 0); +assertEq(exports.is_null(new Baguette(100)), 0); + +let baguette = new Baguette(42); +assertEq(exports.ref_or_null(null, 0), null); +assertEq(exports.ref_or_null(baguette, 0), null); + +let ref = exports.ref_or_null(baguette, 1); +assertEq(ref, baguette); +assertEq(ref.calories, baguette.calories); + +ref = exports.nested(baguette, 0); +assertEq(ref, baguette); +assertEq(ref.calories, baguette.calories); + +// More interesting use cases about control flow joins. + +function assertJoin(body) { + let val = { i: -1 }; + assertEq(wasmEvalText(`(module + (func (export "test") (param $ref anyref) (param $i i32) (result anyref) + ${body} + ) + )`).exports.test(val), val); + assertEq(val.i, -1); +} + +assertJoin("(block anyref get_local $ref)"); +assertJoin("(block $out anyref get_local $ref br $out)"); +assertJoin("(loop anyref get_local $ref)"); + +assertJoin(`(block $out anyref (loop $top anyref + get_local $i + i32.const 1 + i32.add + tee_local $i + i32.const 10 + i32.eq + if + get_local $ref + return + end + br $top)) +`); + +assertJoin(`(block $out (loop $top + get_local $i + i32.const 1 + i32.add + tee_local $i + i32.const 10 + i32.le_s + if + br $top + else + get_local $ref + return + end + )) unreachable +`); + +assertJoin(`(block $out anyref (loop $top + get_local $ref + get_local $i + i32.const 1 + i32.add + tee_local $i + i32.const 10 + i32.eq + br_if $out + br $top + ) unreachable) +`); + +assertJoin(`(block $out anyref (block $unreachable anyref (loop $top + get_local $ref + get_local $i + i32.const 1 + i32.add + tee_local $i + br_table $unreachable $out + ) unreachable)) +`); + +let x = { i: 42 }, y = { f: 53 }; +exports = wasmEvalText(`(module + (func (export "test") (param $lhs anyref) (param $rhs anyref) (param $i i32) (result anyref) + get_local $lhs + get_local $rhs + get_local $i + select + ) +)`).exports; + +let result = exports.test(x, y, 0); +assertEq(result, y); +assertEq(result.i, undefined); +assertEq(result.f, 53); +assertEq(x.i, 42); + +result = exports.test(x, y, 1); +assertEq(result, x); +assertEq(result.i, 42); +assertEq(result.f, undefined); +assertEq(y.f, 53); + +// Anyref in params/result of imported functions. + +let firstBaguette = new Baguette(13), + secondBaguette = new Baguette(37); + +let imports = { + i: 0, + myBaguette: null, + funcs: { + param(x) { + if (this.i === 0) { + assertEq(x, firstBaguette); + assertEq(x.calories, 13); + assertEq(secondBaguette !== null, true); + } else if (this.i === 1 || this.i === 2) { + assertEq(x, secondBaguette); + assertEq(x.calories, 37); + assertEq(firstBaguette !== null, true); + } else if (this.i === 3) { + assertEq(x, null); + } else { + firstBaguette = null; + secondBaguette = null; + gc(); // evil mode + } + this.i++; + }, + ret() { + return imports.myBaguette; + } + } +}; + +exports = wasmEvalText(`(module + (import $ret "funcs" "ret" (result anyref)) + (import $param "funcs" "param" (param anyref)) + + (func (export "param") (param $x anyref) (param $y anyref) + get_local $y + get_local $x + call $param + call $param + ) + + (func (export "ret") (result anyref) + call $ret + ) +)`, imports).exports; + +exports.param(firstBaguette, secondBaguette); +exports.param(secondBaguette, null); +exports.param(firstBaguette, secondBaguette); + +imports.myBaguette = null; +assertEq(exports.ret(), null); + +imports.myBaguette = new Baguette(1337); +assertEq(exports.ret(), imports.myBaguette); + +// Check lazy stubs generation. + +exports = wasmEvalText(`(module + (import $mirror "funcs" "mirror" (param anyref) (result anyref)) + (import $augment "funcs" "augment" (param anyref) (result anyref)) + + (global $count_f (mut i32) (i32.const 0)) + (global $count_g (mut i32) (i32.const 0)) + + (func $f (param $param anyref) (result anyref) + i32.const 1 + get_global $count_f + i32.add + set_global $count_f + + get_local $param + call $augment + ) + + (func $g (param $param anyref) (result anyref) + i32.const 1 + get_global $count_g + i32.add + set_global $count_g + + get_local $param + call $mirror + ) + + (table (export "table") 10 anyfunc) + (elem (i32.const 0) $f $g $mirror $augment) + (type $table_type (func (param anyref) (result anyref))) + + (func (export "call_indirect") (param $i i32) (param $ref anyref) (result anyref) + get_local $ref + get_local $i + call_indirect $table_type + ) + + (func (export "count_f") (result i32) get_global $count_f) + (func (export "count_g") (result i32) get_global $count_g) +)`, { + funcs: { + mirror(x) { + return x; + }, + augment(x) { + x.i++; + x.newProp = "hello"; + return x; + } + } +}).exports; + +x = { i: 19 }; +assertEq(exports.table.get(0)(x), x); +assertEq(x.i, 20); +assertEq(x.newProp, "hello"); +assertEq(exports.count_f(), 1); +assertEq(exports.count_g(), 0); + +x = { i: 21 }; +assertEq(exports.table.get(1)(x), x); +assertEq(x.i, 21); +assertEq(typeof x.newProp, "undefined"); +assertEq(exports.count_f(), 1); +assertEq(exports.count_g(), 1); + +x = { i: 22 }; +assertEq(exports.table.get(2)(x), x); +assertEq(x.i, 22); +assertEq(typeof x.newProp, "undefined"); +assertEq(exports.count_f(), 1); +assertEq(exports.count_g(), 1); + +x = { i: 23 }; +assertEq(exports.table.get(3)(x), x); +assertEq(x.i, 24); +assertEq(x.newProp, "hello"); +assertEq(exports.count_f(), 1); +assertEq(exports.count_g(), 1); diff --git a/js/src/jit-test/tests/wasm/gc/directives.txt b/js/src/jit-test/tests/wasm/gc/directives.txt new file mode 100644 index 000000000000..8b0167509cf9 --- /dev/null +++ b/js/src/jit-test/tests/wasm/gc/directives.txt @@ -0,0 +1 @@ +|jit-test| test-also=--wasm-gc; include:wasm.js diff --git a/js/src/jit-test/tests/wasm/gc/disabled.js b/js/src/jit-test/tests/wasm/gc/disabled.js new file mode 100644 index 000000000000..f720b515ee32 --- /dev/null +++ b/js/src/jit-test/tests/wasm/gc/disabled.js @@ -0,0 +1,28 @@ +if (wasmGcEnabled()) { + quit(); +} + +const { CompileError, validate } = WebAssembly; + +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 (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) { + print(src) + assertErrorMessage(() => wasmEvalText(src), CompileError, UNRECOGNIZED_OPCODE_OR_BAD_TYPE); + assertValidateError(src); +} diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h index 81d0138e7c62..fca7ca012366 100644 --- a/js/src/jit/IonTypes.h +++ b/js/src/jit/IonTypes.h @@ -568,6 +568,8 @@ MIRTypeToSize(MIRType type) return 4; case MIRType::Double: return 8; + case MIRType::Pointer: + return sizeof(uintptr_t); default: MOZ_CRASH("MIRTypeToSize - unhandled case"); } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 96e8f7fc9e7e..8a92381a0307 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -935,6 +935,9 @@ class JS_PUBLIC_API(ContextOptions) { wasm_(true), wasmBaseline_(true), wasmIon_(true), +#ifdef ENABLE_WASM_GC + wasmGc_(false), +#endif testWasmAwaitTier2_(false), throwOnAsmJSValidationFailure_(false), nativeRegExp_(true), @@ -1032,6 +1035,14 @@ class JS_PUBLIC_API(ContextOptions) { return *this; } +#ifdef ENABLE_WASM_GC + bool wasmGc() const { return wasmGc_; } + ContextOptions& setWasmGc(bool flag) { + wasmGc_ = flag; + return *this; + } +#endif + bool throwOnAsmJSValidationFailure() const { return throwOnAsmJSValidationFailure_; } ContextOptions& setThrowOnAsmJSValidationFailure(bool flag) { throwOnAsmJSValidationFailure_ = flag; @@ -1117,6 +1128,9 @@ class JS_PUBLIC_API(ContextOptions) { setWasm(false); setWasmBaseline(false); setWasmIon(false); +#ifdef ENABLE_WASM_GC + setWasmGc(false); +#endif setNativeRegExp(false); } @@ -1127,6 +1141,9 @@ class JS_PUBLIC_API(ContextOptions) { bool wasm_ : 1; bool wasmBaseline_ : 1; bool wasmIon_ : 1; +#ifdef ENABLE_WASM_GC + bool wasmGc_ : 1; +#endif bool testWasmAwaitTier2_ : 1; bool throwOnAsmJSValidationFailure_ : 1; bool nativeRegExp_ : 1; diff --git a/js/src/moz.build b/js/src/moz.build index 0bed1b0e01c3..34a9afd74037 100755 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -695,6 +695,7 @@ if CONFIG['NIGHTLY_BUILD']: DEFINES['ENABLE_WASM_SATURATING_TRUNC_OPS'] = True DEFINES['ENABLE_WASM_SIGNEXTEND_OPS'] = True DEFINES['ENABLE_WASM_THREAD_OPS'] = True + DEFINES['ENABLE_WASM_GC'] = True # An experiment we want to run on Nightly and early Beta: Can we change the JS # representation of an exported global from the global's value to an instance diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 1e93ac29df52..11f1281e54fc 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -482,6 +482,9 @@ static bool enableNativeRegExp = false; static bool enableSharedMemory = SHARED_MEMORY_DEFAULT; static bool enableWasmBaseline = false; static bool enableWasmIon = false; +#ifdef ENABLE_WASM_GC +static bool enableWasmGc = false; +#endif static bool enableTestWasmAwaitTier2 = false; static bool enableAsyncStacks = false; static bool enableStreams = false; @@ -8295,6 +8298,9 @@ SetContextOptions(JSContext* cx, const OptionParser& op) enableNativeRegExp = !op.getBoolOption("no-native-regexp"); enableWasmBaseline = !op.getBoolOption("no-wasm-baseline"); enableWasmIon = !op.getBoolOption("no-wasm-ion"); +#ifdef ENABLE_WASM_GC + enableWasmGc = op.getBoolOption("wasm-gc"); +#endif enableTestWasmAwaitTier2 = op.getBoolOption("test-wasm-await-tier2"); enableAsyncStacks = !op.getBoolOption("no-async-stacks"); enableStreams = op.getBoolOption("enable-streams"); @@ -8306,6 +8312,9 @@ SetContextOptions(JSContext* cx, const OptionParser& op) .setWasm(enableWasm) .setWasmBaseline(enableWasmBaseline) .setWasmIon(enableWasmIon) +#ifdef ENABLE_WASM_GC + .setWasmGc(enableWasmGc) +#endif .setTestWasmAwaitTier2(enableTestWasmAwaitTier2) .setNativeRegExp(enableNativeRegExp) .setAsyncStack(enableAsyncStacks) @@ -8608,6 +8617,9 @@ SetWorkerContextOptions(JSContext* cx) .setWasm(enableWasm) .setWasmBaseline(enableWasmBaseline) .setWasmIon(enableWasmIon) +#ifdef ENABLE_WASM_GC + .setWasmGc(enableWasmGc) +#endif .setTestWasmAwaitTier2(enableTestWasmAwaitTier2) .setNativeRegExp(enableNativeRegExp) .setStreams(enableStreams) @@ -8851,6 +8863,9 @@ main(int argc, char** argv, char** envp) || !op.addBoolOption('\0', "no-wasm-ion", "Disable wasm ion compiler") || !op.addBoolOption('\0', "test-wasm-await-tier2", "Forcibly activate tiering and block " "instantiation on completion of tier2") +#ifdef ENABLE_WASM_GC + || !op.addBoolOption('\0', "wasm-gc", "Enable wasm GC features") +#endif || !op.addBoolOption('\0', "no-native-regexp", "Disable native regexp compilation") || !op.addBoolOption('\0', "no-unboxed-objects", "Disable creating unboxed plain objects") || !op.addBoolOption('\0', "enable-streams", "Enable WHATWG Streams") diff --git a/js/src/shell/moz.build b/js/src/shell/moz.build index ca7bd77e1e8c..dd3f6dd8e69d 100644 --- a/js/src/shell/moz.build +++ b/js/src/shell/moz.build @@ -20,6 +20,9 @@ UNIFIED_SOURCES += [ DEFINES['EXPORT_JS_API'] = True DEFINES['ENABLE_WASM_GLOBAL'] = True +if CONFIG['NIGHTLY_BUILD']: + DEFINES['ENABLE_WASM_GC'] = True + # Also set in ../moz.build DEFINES['ENABLE_SHARED_ARRAY_BUFFER'] = True diff --git a/js/src/threading/ProtectedData.h b/js/src/threading/ProtectedData.h index 816bedb9ef17..9b8910613097 100644 --- a/js/src/threading/ProtectedData.h +++ b/js/src/threading/ProtectedData.h @@ -116,6 +116,10 @@ class ProtectedData T& refNoCheck() { return value; } const T& refNoCheck() const { return value; } + static size_t offsetOfValue() { + return offsetof(ThisType, value); + } + private: T value; #ifdef JS_HAS_PROTECTED_DATA_CHECKS diff --git a/js/src/vm/JSFunction.h b/js/src/vm/JSFunction.h index 87b2b7a65623..104280c2ec70 100644 --- a/js/src/vm/JSFunction.h +++ b/js/src/vm/JSFunction.h @@ -95,6 +95,7 @@ class JSFunction : public js::NativeObject NATIVE_CLASS_CTOR = NATIVE_FUN | CONSTRUCTOR | CLASSCONSTRUCTOR_KIND, ASMJS_CTOR = ASMJS_KIND | NATIVE_CTOR, ASMJS_LAMBDA_CTOR = ASMJS_KIND | NATIVE_CTOR | LAMBDA, + ASMJS_NATIVE = ASMJS_KIND | NATIVE_FUN, WASM_FUN = NATIVE_FUN | WASM_OPTIMIZED, INTERPRETED_METHOD = INTERPRETED | METHOD_KIND, INTERPRETED_METHOD_GENERATOR_OR_ASYNC = INTERPRETED | METHOD_KIND, diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp index 1b6159e4611d..0af6d48a72c9 100644 --- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -1759,7 +1759,7 @@ class MOZ_STACK_CLASS ModuleValidator arrayViews_(cx), atomicsPresent_(false), simdPresent_(false), - env_(CompileMode::Once, Tier::Ion, DebugEnabled::False, + env_(CompileMode::Once, Tier::Ion, DebugEnabled::False, HasGcTypes::False, cx->compartment()->creationOptions().getSharedMemoryAndAtomicsEnabled() ? Shareable::True : Shareable::False, @@ -7724,6 +7724,9 @@ ValidateGlobalVariable(JSContext* cx, const AsmJSGlobal& global, HandleValue imp *val = Val(simdConstant.asInt32x4()); return true; } + case ValType::AnyRef: { + MOZ_CRASH("not available in asm.js"); + } } } } diff --git a/js/src/wasm/WasmAST.h b/js/src/wasm/WasmAST.h index 50c27eb60740..90aac8fc5924 100644 --- a/js/src/wasm/WasmAST.h +++ b/js/src/wasm/WasmAST.h @@ -209,6 +209,7 @@ enum class AstExprKind Load, Nop, Pop, + RefNull, Return, SetGlobal, SetLocal, @@ -1163,6 +1164,19 @@ class AstExtraConversionOperator final : public AstExpr }; #endif +class AstRefNull final : public AstExpr +{ + ValType refType_; + public: + static const AstExprKind Kind = AstExprKind::RefNull; + explicit AstRefNull(ValType refType) + : AstExpr(Kind, ExprType::Limit), refType_(refType) + {} + ValType refType() const { + return refType_; + } +}; + // This is an artificial AST node which can fill operand slots in an AST // constructed from parsing or decoding stack-machine code that doesn't have // an inherent AST structure. diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp index e8514ed861a7..9fb5a6c1301f 100644 --- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -296,6 +296,15 @@ struct RegI64 : public Register64 static RegI64 Invalid() { return RegI64(Register64::Invalid()); } }; +struct RegPtr : public Register +{ + RegPtr() : Register(Register::Invalid()) {} + explicit RegPtr(Register reg) : Register(reg) {} + bool isValid() const { return *this != Invalid(); } + bool isInvalid() const { return !isValid(); } + static RegPtr Invalid() { return RegPtr(Register::Invalid()); } +}; + struct RegF32 : public FloatRegister { RegF32() : FloatRegister() {} @@ -316,10 +325,21 @@ struct RegF64 : public FloatRegister struct AnyReg { + union { + RegI32 i32_; + RegI64 i64_; + RegPtr ref_; + RegF32 f32_; + RegF64 f64_; + }; + + enum { I32, I64, REF, F32, F64 } tag; + explicit AnyReg(RegI32 r) { tag = I32; i32_ = r; } explicit AnyReg(RegI64 r) { tag = I64; i64_ = r; } explicit AnyReg(RegF32 r) { tag = F32; f32_ = r; } explicit AnyReg(RegF64 r) { tag = F64; f64_ = r; } + explicit AnyReg(RegPtr r) { tag = REF; ref_ = r; } RegI32 i32() const { MOZ_ASSERT(tag == I32); @@ -337,6 +357,11 @@ struct AnyReg MOZ_ASSERT(tag == F64); return f64_; } + RegPtr ref() const { + MOZ_ASSERT(tag == REF); + return ref_; + } + AnyRegister any() const { switch (tag) { case F32: return AnyRegister(f32_); @@ -352,20 +377,14 @@ struct AnyReg // only on 64-bit platforms. MOZ_CRASH("AnyReg::any() on 32-bit platform"); #endif + case REF: + MOZ_CRASH("AnyReg::any() not implemented for ref types"); default: MOZ_CRASH(); } // Work around GCC 5 analysis/warning bug. MOZ_CRASH("AnyReg::any(): impossible case"); } - - union { - RegI32 i32_; - RegI64 i64_; - RegF32 f32_; - RegF64 f64_; - }; - enum { I32, I64, F32, F64 } tag; }; // Platform-specific registers. @@ -691,6 +710,10 @@ class BaseRegAlloc #endif } + bool isAvailablePtr(RegPtr r) { + return isAvailableGPR(r); + } + bool isAvailableF32(RegF32 r) { return isAvailableFPU(r); } @@ -726,6 +749,18 @@ class BaseRegAlloc allocInt64(specific); } + MOZ_MUST_USE RegPtr needPtr() { + if (!hasGPR()) + bc.sync(); + return RegPtr(allocGPR()); + } + + void needPtr(RegPtr specific) { + if (!isAvailablePtr(specific)) + bc.sync(); + allocGPR(specific); + } + MOZ_MUST_USE RegF32 needF32() { if (!hasFPU()) bc.sync(); @@ -758,6 +793,10 @@ class BaseRegAlloc freeInt64(r); } + void freePtr(RegPtr r) { + freeGPR(r); + } + void freeF64(RegF64 r) { freeFPU(r); } @@ -817,6 +856,10 @@ class BaseRegAlloc void addKnownF64(RegF64 r) { knownFPU_.add(r); } + + void addKnownRef(RegPtr r) { + knownGPR_.add(r); + } }; #endif }; @@ -888,23 +931,28 @@ class ScratchF32 : public ScratchFloat32Scope #endif #ifdef RABALDR_SCRATCH_I32 -class ScratchI32 : public BaseScratchRegister +template +class ScratchGPR : public BaseScratchRegister { public: - explicit ScratchI32(BaseRegAlloc& ra) + explicit ScratchGPR(BaseRegAlloc& ra) : BaseScratchRegister(ra, BaseRegAlloc::ScratchKind::I32) {} - operator RegI32() const { return RegI32(RabaldrScratchI32); } + operator RegType() const { return RegType(RabaldrScratchI32); } }; #else -class ScratchI32 : public ScratchRegisterScope +template +class ScratchGPR : public ScratchRegisterScope { public: - explicit ScratchI32(MacroAssembler& m) : ScratchRegisterScope(m) {} - operator RegI32() const { return RegI32(Register(*this)); } + explicit ScratchGPR(MacroAssembler& m) : ScratchRegisterScope(m) {} + operator RegType() const { return RegType(Register(*this)); } }; #endif +using ScratchI32 = ScratchGPR; +using ScratchPtr = ScratchGPR; + #if defined(JS_CODEGEN_X86) // ScratchEBX is a mnemonic device: For some atomic ops we really need EBX, // no other register will do. And we would normally have to allocate that @@ -985,6 +1033,7 @@ BaseLocalIter::settle() case MIRType::Int64: case MIRType::Double: case MIRType::Float32: + case MIRType::Pointer: if (argsIter_->argInRegister()) frameOffset_ = pushLocal(MIRTypeToSize(mirType_)); else @@ -1003,6 +1052,7 @@ BaseLocalIter::settle() case ValType::I64: case ValType::F32: case ValType::F64: + case ValType::AnyRef: mirType_ = ToMIRType(locals_[index_]); frameOffset_ = pushLocal(MIRTypeToSize(mirType_)); break; @@ -1242,7 +1292,7 @@ class BaseStackFrame masm.load64(Address(sp_, localOffset(src)), dest); } - void loadLocalPtr(const Local& src, Register dest) { + void loadLocalPtr(const Local& src, RegPtr dest) { masm.loadPtr(Address(sp_, localOffset(src)), dest); } @@ -1551,7 +1601,7 @@ class BaseStackFrame // Disambiguation: this loads a "Ptr" value from the stack, it does not load // the "StackPtr". - void loadStackPtr(int32_t offset, Register dest) { + void loadStackPtr(int32_t offset, RegPtr dest) { masm.loadPtr(Address(sp_, stackOffset(offset)), dest); } @@ -1862,6 +1912,7 @@ class BaseCompiler final : public BaseCompilerInterface RegI32 joinRegI32_; RegI64 joinRegI64_; + RegPtr joinRegPtr_; RegF32 joinRegF32_; RegF64 joinRegF64_; @@ -1924,16 +1975,19 @@ class BaseCompiler final : public BaseCompilerInterface bool isAvailableI32(RegI32 r) { return ra.isAvailableI32(r); } bool isAvailableI64(RegI64 r) { return ra.isAvailableI64(r); } + bool isAvailableRef(RegPtr r) { return ra.isAvailablePtr(r); } bool isAvailableF32(RegF32 r) { return ra.isAvailableF32(r); } bool isAvailableF64(RegF64 r) { return ra.isAvailableF64(r); } MOZ_MUST_USE RegI32 needI32() { return ra.needI32(); } MOZ_MUST_USE RegI64 needI64() { return ra.needI64(); } + MOZ_MUST_USE RegPtr needRef() { return ra.needPtr(); } MOZ_MUST_USE RegF32 needF32() { return ra.needF32(); } MOZ_MUST_USE RegF64 needF64() { return ra.needF64(); } void needI32(RegI32 specific) { ra.needI32(specific); } void needI64(RegI64 specific) { ra.needI64(specific); } + void needRef(RegPtr specific) { ra.needPtr(specific); } void needF32(RegF32 specific) { ra.needF32(specific); } void needF64(RegF64 specific) { ra.needF64(specific); } @@ -1943,6 +1997,7 @@ class BaseCompiler final : public BaseCompilerInterface void freeI32(RegI32 r) { ra.freeI32(r); } void freeI64(RegI64 r) { ra.freeI64(r); } + void freeRef(RegPtr r) { ra.freePtr(r); } void freeF32(RegF32 r) { ra.freeF32(r); } void freeF64(RegF64 r) { ra.freeF64(r); } @@ -2018,6 +2073,10 @@ class BaseCompiler final : public BaseCompilerInterface #endif } + RegI32 narrowPtr(RegPtr r) { + return RegI32(r); + } + RegI32 lowPart(RegI64 r) { #ifdef JS_PUNBOX64 return RegI32(r.reg); @@ -2050,6 +2109,11 @@ class BaseCompiler final : public BaseCompilerInterface masm.move64(src, dest); } + void moveRef(RegPtr src, RegPtr dest) { + if (src != dest) + masm.movePtr(src, dest); + } + void moveF64(RegF64 src, RegF64 dest) { if (src != dest) masm.moveDouble(src, dest); @@ -2065,6 +2129,8 @@ class BaseCompiler final : public BaseCompilerInterface needI32(joinRegI32_); else if (type == ExprType::I64) needI64(joinRegI64_); + else if (type == ExprType::AnyRef) + needRef(joinRegPtr_); } void maybeUnreserveJoinRegI(ExprType type) { @@ -2072,6 +2138,8 @@ class BaseCompiler final : public BaseCompilerInterface freeI32(joinRegI32_); else if (type == ExprType::I64) freeI64(joinRegI64_); + else if (type == ExprType::AnyRef) + freeRef(joinRegPtr_); } void maybeReserveJoinReg(ExprType type) { @@ -2088,6 +2156,9 @@ class BaseCompiler final : public BaseCompilerInterface case ExprType::F64: needF64(joinRegF64_); break; + case ExprType::AnyRef: + needRef(joinRegPtr_); + break; default: break; } @@ -2107,6 +2178,9 @@ class BaseCompiler final : public BaseCompilerInterface case ExprType::F64: freeF64(joinRegF64_); break; + case ExprType::AnyRef: + freeRef(joinRegPtr_); + break; default: break; } @@ -2127,6 +2201,10 @@ class BaseCompiler final : public BaseCompilerInterface struct Stk { + private: + Stk() : kind_(Unknown), i64val_(0) {} + + public: enum Kind { // The Mem opcodes are all clustered at the beginning to @@ -2135,6 +2213,7 @@ class BaseCompiler final : public BaseCompilerInterface MemI64, // 64-bit integer stack value ("offs") MemF32, // 32-bit floating stack value ("offs") MemF64, // 64-bit floating stack value ("offs") + MemRef, // reftype (pointer wide) stack value ("offs") // The Local opcodes follow the Mem opcodes for a similar // quick test within hasLocal(). @@ -2142,47 +2221,61 @@ class BaseCompiler final : public BaseCompilerInterface LocalI64, // Local int64 var ("slot") LocalF32, // Local float32 var ("slot") LocalF64, // Local double var ("slot") + LocalRef, // Local reftype (pointer wide) var ("slot") RegisterI32, // 32-bit integer register ("i32reg") RegisterI64, // 64-bit integer register ("i64reg") RegisterF32, // 32-bit floating register ("f32reg") RegisterF64, // 64-bit floating register ("f64reg") + RegisterRef, // reftype (pointer wide) register ("refReg") ConstI32, // 32-bit integer constant ("i32val") ConstI64, // 64-bit integer constant ("i64val") ConstF32, // 32-bit floating constant ("f32val") ConstF64, // 64-bit floating constant ("f64val") + ConstRef, // reftype (pointer wide) constant ("refval") + + Unknown, }; Kind kind_; - static const Kind MemLast = MemF64; - static const Kind LocalLast = LocalF64; + static const Kind MemLast = MemRef; + static const Kind LocalLast = LocalRef; union { RegI32 i32reg_; RegI64 i64reg_; + RegPtr refReg_; RegF32 f32reg_; RegF64 f64reg_; int32_t i32val_; int64_t i64val_; + intptr_t refval_; float f32val_; double f64val_; uint32_t slot_; uint32_t offs_; }; - explicit Stk(RegI32 r) : kind_(RegisterI32), i32reg_(r) {} - explicit Stk(RegI64 r) : kind_(RegisterI64), i64reg_(r) {} - explicit Stk(RegF32 r) : kind_(RegisterF32), f32reg_(r) {} - explicit Stk(RegF64 r) : kind_(RegisterF64), f64reg_(r) {} - explicit Stk(int32_t v) : kind_(ConstI32), i32val_(v) {} - explicit Stk(int64_t v) : kind_(ConstI64), i64val_(v) {} - explicit Stk(float v) : kind_(ConstF32), f32val_(v) {} - explicit Stk(double v) : kind_(ConstF64), f64val_(v) {} + explicit Stk(RegI32 r) : kind_(RegisterI32), i32reg_(r) {} + explicit Stk(RegI64 r) : kind_(RegisterI64), i64reg_(r) {} + explicit Stk(RegPtr r) : kind_(RegisterRef), refReg_(r) {} + explicit Stk(RegF32 r) : kind_(RegisterF32), f32reg_(r) {} + explicit Stk(RegF64 r) : kind_(RegisterF64), f64reg_(r) {} + explicit Stk(int32_t v) : kind_(ConstI32), i32val_(v) {} + explicit Stk(int64_t v) : kind_(ConstI64), i64val_(v) {} + explicit Stk(float v) : kind_(ConstF32), f32val_(v) {} + explicit Stk(double v) : kind_(ConstF64), f64val_(v) {} explicit Stk(Kind k, uint32_t v) : kind_(k), slot_(v) { MOZ_ASSERT(k > MemLast && k <= LocalLast); } + static Stk StkRef(intptr_t v) { + Stk s; + s.kind_ = ConstRef; + s.refval_ = v; + return s; + } void setOffs(Kind k, uint32_t v) { MOZ_ASSERT(k <= MemLast); kind_ = k; offs_ = v; } @@ -2191,11 +2284,13 @@ class BaseCompiler final : public BaseCompilerInterface RegI32 i32reg() const { MOZ_ASSERT(kind_ == RegisterI32); return i32reg_; } RegI64 i64reg() const { MOZ_ASSERT(kind_ == RegisterI64); return i64reg_; } + RegPtr refReg() const { MOZ_ASSERT(kind_ == RegisterRef); return refReg_; } RegF32 f32reg() const { MOZ_ASSERT(kind_ == RegisterF32); return f32reg_; } RegF64 f64reg() const { MOZ_ASSERT(kind_ == RegisterF64); return f64reg_; } int32_t i32val() const { MOZ_ASSERT(kind_ == ConstI32); return i32val_; } int64_t i64val() const { MOZ_ASSERT(kind_ == ConstI64); return i64val_; } + intptr_t refval() const { MOZ_ASSERT(kind_ == ConstRef); return refval_; } // For these two, use an out-param instead of simply returning, to // use the normal stack and not the x87 FP stack (which has effect on @@ -2215,6 +2310,10 @@ class BaseCompiler final : public BaseCompilerInterface stk_.infallibleEmplaceBack(Stk(Forward(args)...)); } + void pushConstRef(intptr_t v) { + stk_.infallibleEmplaceBack(Stk::StkRef(v)); + } + void loadConstI32(const Stk& src, RegI32 dest) { moveImm32(src.i32val(), dest); } @@ -2247,6 +2346,22 @@ class BaseCompiler final : public BaseCompilerInterface moveI64(src.i64reg(), dest); } + void loadConstRef(const Stk& src, RegPtr dest) { + moveImmRef(src.refval(), dest); + } + + void loadMemRef(const Stk& src, RegPtr dest) { + fr.loadStackPtr(src.offs(), dest); + } + + void loadLocalRef(const Stk& src, RegPtr dest) { + fr.loadLocalPtr(localFromSlot(src.slot(), MIRType::Pointer), dest); + } + + void loadRegisterRef(const Stk& src, RegPtr dest) { + moveRef(src.refReg(), dest); + } + void loadConstF64(const Stk& src, RegF64 dest) { double d; src.f64val(&d); @@ -2399,6 +2514,25 @@ class BaseCompiler final : public BaseCompilerInterface } } + void loadRef(const Stk& src, RegPtr dest) { + switch (src.kind()) { + case Stk::ConstRef: + loadConstRef(src, dest); + break; + case Stk::MemRef: + loadMemRef(src, dest); + break; + case Stk::LocalRef: + loadLocalRef(src, dest); + break; + case Stk::RegisterRef: + loadRegisterRef(src, dest); + break; + default: + MOZ_CRASH("Compiler bug: expected ref on stack"); + } + } + // Flush all local and register value stack elements to memory. // // TODO / OPTIMIZE: As this is fairly expensive and causes worse @@ -2501,6 +2635,19 @@ class BaseCompiler final : public BaseCompilerInterface v.setOffs(Stk::MemF32, offs); break; } + case Stk::LocalRef: { + ScratchPtr scratch(*this); + loadLocalRef(v, scratch); + uint32_t offs = fr.pushPtr(scratch); + v.setOffs(Stk::MemRef, offs); + break; + } + case Stk::RegisterRef: { + uint32_t offs = fr.pushPtr(v.refReg()); + freeRef(v.refReg()); + v.setOffs(Stk::MemRef, offs); + break; + } default: { break; } @@ -2544,6 +2691,11 @@ class BaseCompiler final : public BaseCompilerInterface push(r); } + void pushRef(RegPtr r) { + MOZ_ASSERT(!isAvailableRef(r)); + push(r); + } + void pushF64(RegF64 r) { MOZ_ASSERT(!isAvailableF64(r)); push(r); @@ -2564,6 +2716,10 @@ class BaseCompiler final : public BaseCompilerInterface push(v); } + void pushRef(intptr_t v) { + pushConstRef(v); + } + void pushF64(double v) { push(v); } @@ -2584,6 +2740,10 @@ class BaseCompiler final : public BaseCompilerInterface push(Stk::LocalI64, slot); } + void pushLocalRef(uint32_t slot) { + push(Stk::LocalRef, slot); + } + void pushLocalF64(uint32_t slot) { push(Stk::LocalF64, slot); } @@ -2698,6 +2858,54 @@ class BaseCompiler final : public BaseCompilerInterface return specific; } + // Call only from other popRef() variants. + // v must be the stack top. May pop the CPU stack. + + void popRef(const Stk& v, RegPtr dest) { + MOZ_ASSERT(&v == &stk_.back()); + switch (v.kind()) { + case Stk::ConstRef: + loadConstRef(v, dest); + break; + case Stk::LocalRef: + loadLocalRef(v, dest); + break; + case Stk::MemRef: + fr.popPtr(dest); + break; + case Stk::RegisterRef: + loadRegisterRef(v, dest); + break; + default: + MOZ_CRASH("Compiler bug: expected ref on stack"); + } + } + + RegPtr popRef(RegPtr specific) { + Stk& v = stk_.back(); + + if (!(v.kind() == Stk::RegisterRef && v.refReg() == specific)) { + needRef(specific); + popRef(v, specific); + if (v.kind() == Stk::RegisterRef) + freeRef(v.refReg()); + } + + stk_.popBack(); + return specific; + } + + MOZ_MUST_USE RegPtr popRef() { + Stk& v = stk_.back(); + RegPtr r; + if (v.kind() == Stk::RegisterRef) + r = v.refReg(); + else + popRef(v, (r = needRef())); + stk_.popBack(); + return r; + } + // Call only from other popF64() variants. // v must be the stack top. May pop the CPU stack. @@ -2914,6 +3122,12 @@ class BaseCompiler final : public BaseCompilerInterface k == Stk::LocalF32); return Some(AnyReg(popF32(joinRegF32_))); } + case ExprType::AnyRef: { + DebugOnly k(stk_.back().kind()); + MOZ_ASSERT(k == Stk::RegisterRef || k == Stk::ConstRef || k == Stk::MemRef || + k == Stk::LocalRef); + return Some(AnyReg(popRef(joinRegPtr_))); + } default: { MOZ_CRASH("Compiler bug: unexpected expression type"); } @@ -2944,6 +3158,10 @@ class BaseCompiler final : public BaseCompilerInterface MOZ_ASSERT(isAvailableF64(joinRegF64_)); needF64(joinRegF64_); return Some(AnyReg(joinRegF64_)); + case ExprType::AnyRef: + MOZ_ASSERT(isAvailableRef(joinRegPtr_)); + needRef(joinRegPtr_); + return Some(AnyReg(joinRegPtr_)); case ExprType::Void: return Nothing(); default: @@ -2967,6 +3185,9 @@ class BaseCompiler final : public BaseCompilerInterface case AnyReg::F32: pushF32(r->f32()); break; + case AnyReg::REF: + pushRef(r->ref()); + break; } } @@ -2986,6 +3207,9 @@ class BaseCompiler final : public BaseCompilerInterface case AnyReg::F32: freeF32(r->f32()); break; + case AnyReg::REF: + freeRef(r->ref()); + break; } } @@ -2998,6 +3222,7 @@ class BaseCompiler final : public BaseCompilerInterface for (uint32_t i = stk_.length() - 1; numval > 0; numval--, i--) { Stk& v = stk_[i]; switch (v.kind()) { + case Stk::MemRef: size += BaseStackFrame::StackSizeOfPtr; break; case Stk::MemI32: size += BaseStackFrame::StackSizeOfPtr; break; case Stk::MemI64: size += BaseStackFrame::StackSizeOfInt64; break; case Stk::MemF64: size += BaseStackFrame::StackSizeOfDouble; break; @@ -3024,6 +3249,9 @@ class BaseCompiler final : public BaseCompilerInterface case Stk::RegisterF32: freeF32(v.f32reg()); break; + case Stk::RegisterRef: + freeRef(v.refReg()); + break; default: break; } @@ -3070,6 +3298,9 @@ class BaseCompiler final : public BaseCompilerInterface case Stk::RegisterF64: check.addKnownF64(item.f64reg()); break; + case Stk::RegisterRef: + check.addKnownRef(item.refReg()); + break; default: break; } @@ -3159,6 +3390,9 @@ class BaseCompiler final : public BaseCompilerInterface case MIRType::Int64: fr.storeLocalI64(RegI64(i->gpr64()), l); break; + case MIRType::Pointer: + fr.storeLocalPtr(RegPtr(i->gpr()), l); + break; case MIRType::Double: fr.storeLocalF64(RegF64(i->fpu()), l); break; @@ -3488,6 +3722,17 @@ class BaseCompiler final : public BaseCompilerInterface } break; } + case ValType::AnyRef: { + ABIArg argLoc = call->abi.next(MIRType::Pointer); + if (argLoc.kind() == ABIArg::Stack) { + ScratchPtr scratch(*this); + loadRef(arg, scratch); + masm.storePtr(scratch, Address(masm.getStackPointer(), argLoc.offsetFromArgBase())); + } else { + loadRef(arg, RegPtr(argLoc.gpr())); + } + break; + } default: MOZ_CRASH("Function argument type"); } @@ -3561,6 +3806,10 @@ class BaseCompiler final : public BaseCompilerInterface masm.move64(Imm64(v), dest); } + void moveImmRef(intptr_t v, RegPtr dest) { + masm.movePtr(ImmWord(v), dest); + } + void moveImmF32(float f, RegF32 dest) { masm.loadConstantFloat32(f, dest); } @@ -3691,6 +3940,13 @@ class BaseCompiler final : public BaseCompilerInterface return r; } + RegPtr captureReturnedRef() { + RegPtr r = RegPtr(ReturnReg); + MOZ_ASSERT(isAvailableRef(r)); + needRef(r); + return r; + } + void returnCleanup(bool popStack) { if (popStack) fr.popStackBeforeBranch(controlOutermost().stackHeight); @@ -5275,6 +5531,11 @@ class BaseCompiler final : public BaseCompilerInterface *r0 = popF64(); } + void pop2xRef(RegPtr* r0, RegPtr* r1) { + *r1 = popRef(); + *r0 = popRef(); + } + RegI32 popI64ToI32() { RegI64 r = popI64(); return narrowI64(r); @@ -5614,6 +5875,9 @@ class BaseCompiler final : public BaseCompilerInterface MOZ_MUST_USE bool emitGrowMemory(); MOZ_MUST_USE bool emitCurrentMemory(); + MOZ_MUST_USE bool emitRefNull(); + void emitRefIsNull(); + MOZ_MUST_USE bool emitAtomicCmpXchg(ValType type, Scalar::Type viewType); MOZ_MUST_USE bool emitAtomicLoad(ValType type, Scalar::Type viewType); MOZ_MUST_USE bool emitAtomicRMW(ValType type, Scalar::Type viewType, AtomicOp op); @@ -6851,10 +7115,9 @@ BaseCompiler::sniffConditionalControlCmp(Cond compareOp, ValType operandType) OpBytes op; iter_.peekOp(&op); switch (op.b0) { - case uint16_t(Op::Select): - MOZ_FALLTHROUGH; case uint16_t(Op::BrIf): case uint16_t(Op::If): + case uint16_t(Op::Select): setLatentCompare(compareOp, operandType); return true; default: @@ -7436,6 +7699,12 @@ BaseCompiler::doReturn(ExprType type, bool popStack) freeF32(rv); break; } + case ExprType::AnyRef: { + RegPtr rv = popRef(RegPtr(ReturnReg)); + returnCleanup(popStack); + freeRef(rv); + break; + } default: { MOZ_CRASH("Function return type"); } @@ -7500,6 +7769,11 @@ BaseCompiler::pushReturned(const FunctionCall& call, ExprType type) pushF64(rv); break; } + case ExprType::AnyRef: { + RegPtr rv = captureReturnedRef(); + pushRef(rv); + break; + } default: MOZ_CRASH("Function return type"); } @@ -7827,6 +8101,9 @@ BaseCompiler::emitGetLocal() case ValType::F32: pushLocalF32(slot); break; + case ValType::AnyRef: + pushLocalRef(slot); + break; default: MOZ_CRASH("Local variable type"); } @@ -7883,6 +8160,16 @@ BaseCompiler::emitSetOrTeeLocal(uint32_t slot) pushF32(rv); break; } + case ValType::AnyRef: { + RegPtr rv = popRef(); + syncLocal(slot); + fr.storeLocalPtr(rv, localFromSlot(slot, MIRType::Pointer)); + if (isSetLocal) + freeRef(rv); + else + pushRef(rv); + break; + } default: MOZ_CRASH("Local variable type"); } @@ -8403,6 +8690,16 @@ BaseCompiler::emitSelect() pushF64(r); break; } + case ValType::AnyRef: { + RegPtr r, rs; + pop2xRef(&r, &rs); + emitBranchPerform(&b); + moveRef(rs, r); + masm.bind(&done); + freeRef(rs); + pushRef(r); + break; + } default: { MOZ_CRASH("select type"); } @@ -8557,6 +8854,29 @@ BaseCompiler::emitCurrentMemory() return true; } +bool +BaseCompiler::emitRefNull() +{ + if (!iter_.readRefNull()) + return false; + + if (deadCode_) + return true; + + pushRef(NULLREF_VALUE); + return true; +} + +void +BaseCompiler::emitRefIsNull() +{ + RegPtr r = popRef(); + RegI32 rd = narrowPtr(r); + + masm.cmpPtrSet(Assembler::Equal, r, ImmWord(NULLREF_VALUE), rd); + pushI32(rd); +} + bool BaseCompiler::emitAtomicCmpXchg(ValType type, Scalar::Type viewType) { @@ -9424,6 +9744,19 @@ BaseCompiler::emitBody() case uint16_t(Op::CurrentMemory): CHECK_NEXT(emitCurrentMemory()); +#ifdef ENABLE_WASM_GC + case uint16_t(Op::RefNull): + if (env_.gcTypesEnabled == HasGcTypes::False) + return iter_.unrecognizedOpcode(&op); + CHECK_NEXT(emitRefNull()); + break; + case uint16_t(Op::RefIsNull): + if (env_.gcTypesEnabled == HasGcTypes::False) + return iter_.unrecognizedOpcode(&op); + CHECK_NEXT(emitConversion(emitRefIsNull, ValType::AnyRef, ValType::I32)); + break; +#endif + // Numeric operations case uint16_t(Op::NumericPrefix): { #ifdef ENABLE_WASM_SATURATING_TRUNC_OPS @@ -9702,6 +10035,7 @@ BaseCompiler::BaseCompiler(const ModuleEnvironment& env, fr(*masm), joinRegI32_(RegI32(ReturnReg)), joinRegI64_(RegI64(ReturnReg64)), + joinRegPtr_(RegPtr(ReturnReg)), joinRegF32_(RegF32(ReturnFloat32Reg)), joinRegF64_(RegF64(ReturnDoubleReg)) { @@ -9809,7 +10143,7 @@ js::wasm::BaselineCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo ValTypeVector locals; if (!locals.appendAll(env.funcSigs[func.index]->args())) return false; - if (!DecodeLocalEntries(d, env.kind, &locals)) + if (!DecodeLocalEntries(d, env.kind, env.gcTypesEnabled, &locals)) return false; // One-pass baseline compilation. diff --git a/js/src/wasm/WasmBinaryConstants.h b/js/src/wasm/WasmBinaryConstants.h index 76147c12f457..2b5b08169e4a 100644 --- a/js/src/wasm/WasmBinaryConstants.h +++ b/js/src/wasm/WasmBinaryConstants.h @@ -62,6 +62,9 @@ enum class TypeCode // A function pointer with any signature AnyFunc = 0x70, // SLEB128(-0x10) + // A reference to any type. + AnyRef = 0x6f, + // Type constructor for function types Func = 0x60, // SLEB128(-0x20) @@ -78,6 +81,8 @@ enum class ValType F32 = uint8_t(TypeCode::F32), F64 = uint8_t(TypeCode::F64), + AnyRef = uint8_t(TypeCode::AnyRef), + // ------------------------------------------------------------------------ // The rest of these types are currently only emitted internally when // compiling asm.js and are rejected by wasm validation. @@ -93,6 +98,10 @@ enum class ValType typedef Vector ValTypeVector; +// The representation of a null reference value throughout the compiler. + +static const intptr_t NULLREF_VALUE = intptr_t((void*)nullptr); + enum class DefinitionKind { Function = 0x00, @@ -323,6 +332,10 @@ enum class Op I64Extend32S = 0xc4, #endif + // GC ops + RefNull = 0xd0, + RefIsNull = 0xd1, + FirstPrefix = 0xfc, NumericPrefix = 0xfc, ThreadPrefix = 0xfe, diff --git a/js/src/wasm/WasmBinaryIterator.cpp b/js/src/wasm/WasmBinaryIterator.cpp index 6e4764547855..7ada51160995 100644 --- a/js/src/wasm/WasmBinaryIterator.cpp +++ b/js/src/wasm/WasmBinaryIterator.cpp @@ -177,6 +177,7 @@ wasm::Classify(OpBytes op) case Op::F64ConvertUI64: case Op::F64ReinterpretI64: case Op::F64PromoteF32: + case Op::RefIsNull: #ifdef ENABLE_WASM_SIGNEXTEND_OPS case Op::I32Extend8S: case Op::I32Extend16S: @@ -240,6 +241,8 @@ wasm::Classify(OpBytes op) return OpKind::CurrentMemory; case Op::GrowMemory: return OpKind::GrowMemory; + case Op::RefNull: + return OpKind::RefNull; case Op::NumericPrefix: { #ifdef ENABLE_WASM_SATURATING_TRUNC_OPS switch (NumericOp(op.b1)) { diff --git a/js/src/wasm/WasmBinaryIterator.h b/js/src/wasm/WasmBinaryIterator.h index a06b6bde7d32..c6b4e0398e97 100644 --- a/js/src/wasm/WasmBinaryIterator.h +++ b/js/src/wasm/WasmBinaryIterator.h @@ -41,20 +41,22 @@ enum class LabelKind : uint8_t // represents the type of a value produced by an unconditional branch. enum class StackType { - I32 = uint8_t(ValType::I32), - I64 = uint8_t(ValType::I64), - F32 = uint8_t(ValType::F32), - F64 = uint8_t(ValType::F64), + I32 = uint8_t(ValType::I32), + I64 = uint8_t(ValType::I64), + F32 = uint8_t(ValType::F32), + F64 = uint8_t(ValType::F64), - I8x16 = uint8_t(ValType::I8x16), - I16x8 = uint8_t(ValType::I16x8), - I32x4 = uint8_t(ValType::I32x4), - F32x4 = uint8_t(ValType::F32x4), - B8x16 = uint8_t(ValType::B8x16), - B16x8 = uint8_t(ValType::B16x8), - B32x4 = uint8_t(ValType::B32x4), + I8x16 = uint8_t(ValType::I8x16), + I16x8 = uint8_t(ValType::I16x8), + I32x4 = uint8_t(ValType::I32x4), + F32x4 = uint8_t(ValType::F32x4), + B8x16 = uint8_t(ValType::B8x16), + B16x8 = uint8_t(ValType::B16x8), + B32x4 = uint8_t(ValType::B32x4), - Any = uint8_t(TypeCode::Limit) + AnyRef = uint8_t(ValType::AnyRef), + + Any = uint8_t(TypeCode::Limit), }; static inline StackType @@ -71,7 +73,49 @@ NonAnyToValType(StackType type) } static inline bool -Unify(StackType one, StackType two, StackType* result) +IsRefType(StackType st) +{ + return IsRefType(NonAnyToValType(st)); +} + +static inline bool +IsSubtypeOf(StackType one, StackType two) +{ + MOZ_ASSERT(IsRefType(one)); + MOZ_ASSERT(IsRefType(two)); + return one == two || two == StackType::AnyRef; +} + +static inline bool +Unify(HasGcTypes gcTypesEnabled, StackType observed, StackType expected, StackType* result) +{ + if (MOZ_LIKELY(observed == expected)) { + *result = observed; + return true; + } + + if (observed == StackType::Any) { + *result = expected; + return true; + } + + if (expected == StackType::Any) { + *result = observed; + return true; + } + + if (gcTypesEnabled == HasGcTypes::True && IsRefType(observed) && IsRefType(expected) && + IsSubtypeOf(observed, expected)) + { + *result = expected; + return true; + } + + return false; +} + +static inline bool +Join(HasGcTypes gcTypesEnabled, StackType one, StackType two, StackType* result) { if (MOZ_LIKELY(one == two)) { *result = one; @@ -88,6 +132,22 @@ Unify(StackType one, StackType two, StackType* result) return true; } + if (gcTypesEnabled == HasGcTypes::True && IsRefType(one) && IsRefType(two)) { + if (IsSubtypeOf(two, one)) { + *result = one; + return true; + } + + if (IsSubtypeOf(one, two)) { + *result = two; + return true; + } + + // No subtyping relations between the two types. + *result = StackType::AnyRef; + return true; + } + return false; } @@ -113,7 +173,6 @@ enum class OpKind { BrIf, BrTable, Nop, - Nullary, Unary, Binary, Comparison, @@ -159,6 +218,7 @@ enum class OpKind { SimdBooleanReduction, SimdShiftByScalar, SimdComparison, + RefNull, }; // Return the OpKind for a given Op. This is used for sanity-checking that @@ -534,6 +594,7 @@ class MOZ_STACK_CLASS OpIter : private Policy MOZ_MUST_USE bool readB8x16Const(I8x16* i8x16); MOZ_MUST_USE bool readB16x8Const(I16x8* i16x8); MOZ_MUST_USE bool readB32x4Const(I32x4* i32x4); + MOZ_MUST_USE bool readRefNull(); MOZ_MUST_USE bool readCall(uint32_t* calleeIndex, ValueVector* argValues); MOZ_MUST_USE bool readCallIndirect(uint32_t* sigIndex, Value* callee, ValueVector* argValues); MOZ_MUST_USE bool readOldCallDirect(uint32_t numFuncImports, uint32_t* funcIndex, @@ -731,7 +792,7 @@ OpIter::popWithType(StackType expectedType, Value* value) TypeAndValue tv = valueStack_.popCopy(); StackType _; - if (MOZ_UNLIKELY(!Unify(tv.type(), expectedType, &_))) + if (MOZ_UNLIKELY(!Unify(env_.gcTypesEnabled, tv.type(), expectedType, &_))) return typeMismatch(tv.type(), expectedType); *value = tv.value(); @@ -783,8 +844,11 @@ OpIter::topWithType(ValType expectedType, Value* value) TypeAndValue& tv = valueStack_.back(); - if (MOZ_UNLIKELY(!Unify(tv.type(), ToStackType(expectedType), &tv.typeRef()))) + if (MOZ_UNLIKELY(!Unify(env_.gcTypesEnabled, tv.type(), ToStackType(expectedType), + &tv.typeRef()))) + { return typeMismatch(tv.type(), ToStackType(expectedType)); + } *value = tv.value(); return true; @@ -846,6 +910,7 @@ OpIter::readBlockType(ExprType* type) if (!d_.readBlockType(&unchecked)) return fail("unable to read block signature"); + bool known = false; switch (unchecked) { case uint8_t(ExprType::Void): case uint8_t(ExprType::I32): @@ -859,11 +924,18 @@ OpIter::readBlockType(ExprType* type) case uint8_t(ExprType::B8x16): case uint8_t(ExprType::B16x8): case uint8_t(ExprType::B32x4): + known = true; + break; + case uint8_t(ExprType::AnyRef): + known = env_.gcTypesEnabled == HasGcTypes::True; + break; + case uint8_t(ExprType::Limit): break; - default: - return fail("invalid inline block type"); } + if (!known) + return fail("invalid inline block type"); + *type = ExprType(unchecked); return true; } @@ -1382,7 +1454,7 @@ OpIter::readSelect(StackType* type, Value* trueValue, Value* falseValue, if (!popAnyType(&trueType, trueValue)) return false; - if (!Unify(falseType, trueType, type)) + if (!Join(env_.gcTypesEnabled, falseType, trueType, type)) return fail("select operand types must match"); infalliblePush(*type); @@ -1595,6 +1667,17 @@ OpIter::readB32x4Const(I32x4* i32x4) push(ValType::B32x4); } +template +inline bool +OpIter::readRefNull() +{ + MOZ_ASSERT(Classify(op_) == OpKind::RefNull); + uint8_t valType; + if (!d_.readValType(&valType) || ValType(valType) != ValType::AnyRef) + return fail("unknown nullref type"); + return push(StackType::AnyRef); +} + template inline bool OpIter::popCallArgs(const ValTypeVector& expectedTypes, ValueVector* values) diff --git a/js/src/wasm/WasmBinaryToAST.cpp b/js/src/wasm/WasmBinaryToAST.cpp index ea3b46e2646f..55622e9e6b67 100644 --- a/js/src/wasm/WasmBinaryToAST.cpp +++ b/js/src/wasm/WasmBinaryToAST.cpp @@ -102,7 +102,7 @@ class AstDecodeContext lifo(lifo), d(d), generateNames(generateNames), - env_(CompileMode::Once, Tier::Ion, DebugEnabled::False, + env_(CompileMode::Once, Tier::Ion, DebugEnabled::False, HasGcTypes::False, cx->compartment()->creationOptions().getSharedMemoryAndAtomicsEnabled() ? Shareable::True : Shareable::False), @@ -1824,7 +1824,7 @@ AstDecodeFunctionBody(AstDecodeContext &c, uint32_t funcIndex, AstFunc** func) if (!locals.appendAll(sig->args())) return false; - if (!DecodeLocalEntries(c.d, ModuleKind::Wasm, &locals)) + if (!DecodeLocalEntries(c.d, ModuleKind::Wasm, c.env().gcTypesEnabled, &locals)) return false; AstDecodeOpIter iter(c.env(), c.d); diff --git a/js/src/wasm/WasmBuiltins.cpp b/js/src/wasm/WasmBuiltins.cpp index 846830d311d6..3ae6c83e5d5b 100644 --- a/js/src/wasm/WasmBuiltins.cpp +++ b/js/src/wasm/WasmBuiltins.cpp @@ -536,6 +536,9 @@ AddressOf(SymbolicAddress imm, ABIFunctionType* abiType) case SymbolicAddress::CallImport_F64: *abiType = Args_General4; return FuncCast(Instance::callImport_f64, *abiType); + case SymbolicAddress::CallImport_Ref: + *abiType = Args_General4; + return FuncCast(Instance::callImport_ref, *abiType); case SymbolicAddress::CoerceInPlace_ToInt32: *abiType = Args_General1; return FuncCast(CoerceInPlace_ToInt32, *abiType); @@ -690,6 +693,7 @@ wasm::NeedsBuiltinThunk(SymbolicAddress sym) case SymbolicAddress::CallImport_I32: case SymbolicAddress::CallImport_I64: case SymbolicAddress::CallImport_F64: + case SymbolicAddress::CallImport_Ref: case SymbolicAddress::CoerceInPlace_ToInt32: // GenerateImportJitExit case SymbolicAddress::CoerceInPlace_ToNumber: #if defined(JS_CODEGEN_MIPS32) diff --git a/js/src/wasm/WasmCode.cpp b/js/src/wasm/WasmCode.cpp index 88564c7e1f66..b1dd00a3cda0 100644 --- a/js/src/wasm/WasmCode.cpp +++ b/js/src/wasm/WasmCode.cpp @@ -609,22 +609,25 @@ LazyStubSegment::addStubs(size_t codeLength, const Uint32Vector& funcExportIndic return false; size_t i = 0; - for (DebugOnly funcExportIndex : funcExportIndices) { + for (uint32_t funcExportIndex : funcExportIndices) { const CodeRange& interpRange = codeRanges[i]; MOZ_ASSERT(interpRange.isInterpEntry()); MOZ_ASSERT(interpRange.funcIndex() == funcExports[funcExportIndex].funcIndex()); codeRanges_.infallibleAppend(interpRange); codeRanges_.back().offsetBy(offsetInSegment); + i++; - const CodeRange& jitRange = codeRanges[i + 1]; + if (funcExports[funcExportIndex].sig().temporarilyUnsupportedAnyRef()) + continue; + + const CodeRange& jitRange = codeRanges[i]; MOZ_ASSERT(jitRange.isJitEntry()); MOZ_ASSERT(jitRange.funcIndex() == interpRange.funcIndex()); codeRanges_.infallibleAppend(jitRange); codeRanges_.back().offsetBy(offsetInSegment); - - i += 2; + i++; } return true; @@ -658,8 +661,8 @@ struct ProjectLazyFuncIndex static constexpr unsigned LAZY_STUB_LIFO_DEFAULT_CHUNK_SIZE = 8 * 1024; bool -LazyStubTier::createMany(const Uint32Vector& funcExportIndices, const CodeTier& codeTier, - size_t* stubSegmentIndex) +LazyStubTier::createMany(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, + const CodeTier& codeTier, size_t* stubSegmentIndex) { MOZ_ASSERT(funcExportIndices.length()); @@ -673,16 +676,21 @@ LazyStubTier::createMany(const Uint32Vector& funcExportIndices, const CodeTier& uint8_t* moduleSegmentBase = codeTier.segment().base(); CodeRangeVector codeRanges; + DebugOnly numExpectedRanges = 0; for (uint32_t funcExportIndex : funcExportIndices) { const FuncExport& fe = funcExports[funcExportIndex]; + numExpectedRanges += fe.sig().temporarilyUnsupportedAnyRef() ? 1 : 2; void* calleePtr = moduleSegmentBase + moduleRanges[fe.interpCodeRangeIndex()].funcNormalEntry(); Maybe callee; callee.emplace(calleePtr, ImmPtr::NoCheckToken()); - if (!GenerateEntryStubs(masm, funcExportIndex, fe, callee, /* asmjs*/ false, &codeRanges)) + if (!GenerateEntryStubs(masm, funcExportIndex, fe, callee, /* asmjs */ false, + gcTypesEnabled, &codeRanges)) + { return false; + } } - MOZ_ASSERT(codeRanges.length() == 2 * funcExportIndices.length(), "two entries per function"); + MOZ_ASSERT(codeRanges.length() == numExpectedRanges, "incorrect number of entries per function"); masm.finish(); @@ -743,7 +751,9 @@ LazyStubTier::createMany(const Uint32Vector& funcExportIndices, const CodeTier& fe.funcIndex(), &exportIndex)); MOZ_ALWAYS_TRUE(exports_.insert(exports_.begin() + exportIndex, Move(lazyExport))); - interpRangeIndex += 2; + // Functions with anyref in their sig have only one entry (interp). + // All other functions get an extra jit entry. + interpRangeIndex += fe.sig().temporarilyUnsupportedAnyRef() ? 1 : 2; } return true; @@ -757,12 +767,22 @@ LazyStubTier::createOne(uint32_t funcExportIndex, const CodeTier& codeTier) return false; size_t stubSegmentIndex; - if (!createMany(funcExportIndexes, codeTier, &stubSegmentIndex)) + if (!createMany(codeTier.code().metadata().temporaryHasGcTypes, funcExportIndexes, codeTier, + &stubSegmentIndex)) + { return false; + } const UniqueLazyStubSegment& segment = stubSegments_[stubSegmentIndex]; const CodeRangeVector& codeRanges = segment->codeRanges(); + // Functions that have anyref in their sig don't get a jit entry. + if (codeTier.metadata().funcExports[funcExportIndex].sig().temporarilyUnsupportedAnyRef()) { + MOZ_ASSERT(codeRanges.length() >= 1); + MOZ_ASSERT(codeRanges.back().isInterpEntry()); + return true; + } + MOZ_ASSERT(codeRanges.length() >= 2); MOZ_ASSERT(codeRanges[codeRanges.length() - 2].isInterpEntry()); @@ -774,14 +794,14 @@ LazyStubTier::createOne(uint32_t funcExportIndex, const CodeTier& codeTier) } bool -LazyStubTier::createTier2(const Uint32Vector& funcExportIndices, const CodeTier& codeTier, - Maybe* outStubSegmentIndex) +LazyStubTier::createTier2(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, + const CodeTier& codeTier, Maybe* outStubSegmentIndex) { if (!funcExportIndices.length()) return true; size_t stubSegmentIndex; - if (!createMany(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 e434887cbfb1..a1341c695cc2 100644 --- a/js/src/wasm/WasmCode.h +++ b/js/src/wasm/WasmCode.h @@ -400,6 +400,7 @@ struct MetadataCacheablePod { ModuleKind kind; MemoryUsage memoryUsage; + HasGcTypes temporaryHasGcTypes; uint32_t minMemoryLength; uint32_t globalDataLength; Maybe maxMemoryLength; @@ -408,6 +409,7 @@ struct MetadataCacheablePod explicit MetadataCacheablePod(ModuleKind kind) : kind(kind), memoryUsage(MemoryUsage::None), + temporaryHasGcTypes(HasGcTypes::False), minMemoryLength(0), globalDataLength(0) {} @@ -572,8 +574,8 @@ class LazyStubTier LazyFuncExportVector exports_; size_t lastStubSegmentIndex_; - bool createMany(const Uint32Vector& funcExportIndices, const CodeTier& codeTier, - size_t* stubSegmentIndex); + bool createMany(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, + const CodeTier& codeTier, size_t* stubSegmentIndex); public: LazyStubTier() : lastStubSegmentIndex_(0) {} @@ -593,8 +595,8 @@ 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(const Uint32Vector& funcExportIndices, const CodeTier& codeTier, - Maybe* stubSegmentIndex); + bool createTier2(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, + const CodeTier& codeTier, Maybe* stubSegmentIndex); void setJitEntries(const Maybe& stubSegmentIndex, const Code& code); void addSizeOfMisc(MallocSizeOf mallocSizeOf, size_t* code, size_t* data) const; diff --git a/js/src/wasm/WasmCompile.cpp b/js/src/wasm/WasmCompile.cpp index ff8b59945b11..812e81ba3c5e 100644 --- a/js/src/wasm/WasmCompile.cpp +++ b/js/src/wasm/WasmCompile.cpp @@ -87,10 +87,17 @@ DecodeCodeSection(const ModuleEnvironment& env, DecoderT& d, ModuleGenerator& mg bool CompileArgs::initFromContext(JSContext* cx, ScriptedCaller&& scriptedCaller) { - baselineEnabled = cx->options().wasmBaseline(); - ionEnabled = cx->options().wasmIon(); +#ifdef ENABLE_WASM_GC + bool gcEnabled = cx->options().wasmGc(); +#else + bool gcEnabled = false; +#endif + + baselineEnabled = cx->options().wasmBaseline() || gcEnabled; + ionEnabled = cx->options().wasmIon() && !gcEnabled; sharedMemoryEnabled = cx->compartment()->creationOptions().getSharedMemoryAndAtomicsEnabled(); - testTiering = cx->options().testWasmAwaitTier2() || JitOptions.wasmDelayTier2; + gcTypesEnabled = gcEnabled ? HasGcTypes::True : HasGcTypes::False; + testTiering = (cx->options().testWasmAwaitTier2() || JitOptions.wasmDelayTier2) && !gcEnabled; // Debug information such as source view or debug traps will require // additional memory and permanently stay in baseline code, so we try to @@ -424,7 +431,7 @@ wasm::CompileBuffer(const CompileArgs& args, const ShareableBytes& bytecode, Uni DebugEnabled debug; InitialCompileFlags(args, d, &mode, &tier, &debug); - ModuleEnvironment env(mode, tier, debug, + ModuleEnvironment env(mode, tier, debug, args.gcTypesEnabled, args.sharedMemoryEnabled ? Shareable::True : Shareable::False); if (!DecodeModuleEnvironment(d, &env)) return nullptr; @@ -450,7 +457,9 @@ wasm::CompileTier2(const CompileArgs& args, Module& module, Atomic* cancel UniqueChars error; Decoder d(module.bytecode().bytes, 0, &error); - ModuleEnvironment env(CompileMode::Tier2, Tier::Ion, DebugEnabled::False, + 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); if (!DecodeModuleEnvironment(d, &env)) return false; @@ -572,7 +581,7 @@ wasm::CompileStreaming(const CompileArgs& args, DebugEnabled debug; InitialCompileFlags(args, d, &mode, &tier, &debug); - env.emplace(mode, tier, debug, + 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 85e13a3726f4..7d22e746d0ff 100644 --- a/js/src/wasm/WasmCompile.h +++ b/js/src/wasm/WasmCompile.h @@ -50,6 +50,7 @@ struct CompileArgs : ShareableBase bool debugEnabled; bool ionEnabled; bool sharedMemoryEnabled; + HasGcTypes gcTypesEnabled; bool testTiering; CompileArgs(Assumptions&& assumptions, ScriptedCaller&& scriptedCaller) @@ -59,6 +60,7 @@ struct CompileArgs : ShareableBase debugEnabled(false), ionEnabled(false), sharedMemoryEnabled(false), + gcTypesEnabled(HasGcTypes::False), testTiering(false) {} diff --git a/js/src/wasm/WasmDebug.cpp b/js/src/wasm/WasmDebug.cpp index eb57c55ffab1..e2738190337d 100644 --- a/js/src/wasm/WasmDebug.cpp +++ b/js/src/wasm/WasmDebug.cpp @@ -542,7 +542,7 @@ DebugState::debugGetLocalTypes(uint32_t funcIndex, ValTypeVector* locals, size_t size_t offsetInModule = range.funcLineOrBytecode(); Decoder d(maybeBytecode_->begin() + offsetInModule, maybeBytecode_->end(), offsetInModule, /* error = */ nullptr); - return DecodeLocalEntries(d, metadata().kind, locals); + return DecodeLocalEntries(d, metadata().kind, metadata().temporaryHasGcTypes, locals); } ExprType diff --git a/js/src/wasm/WasmFrameIter.cpp b/js/src/wasm/WasmFrameIter.cpp index 3807e10f8ea9..d1146bbb37ab 100644 --- a/js/src/wasm/WasmFrameIter.cpp +++ b/js/src/wasm/WasmFrameIter.cpp @@ -1139,6 +1139,7 @@ ThunkedNativeToDescription(SymbolicAddress func) case SymbolicAddress::CallImport_I32: case SymbolicAddress::CallImport_I64: case SymbolicAddress::CallImport_F64: + case SymbolicAddress::CallImport_Ref: case SymbolicAddress::CoerceInPlace_ToInt32: case SymbolicAddress::CoerceInPlace_ToNumber: MOZ_ASSERT(!NeedsBuiltinThunk(func), "not in sync with NeedsBuiltinThunk"); diff --git a/js/src/wasm/WasmGenerator.cpp b/js/src/wasm/WasmGenerator.cpp index 012f9cefe716..185b76483c44 100644 --- a/js/src/wasm/WasmGenerator.cpp +++ b/js/src/wasm/WasmGenerator.cpp @@ -840,6 +840,7 @@ ModuleGenerator::finishMetadata(const ShareableBytes& bytecode) // Copy over data from the ModuleEnvironment. metadata_->memoryUsage = env_->memoryUsage; + metadata_->temporaryHasGcTypes = env_->gcTypesEnabled; metadata_->minMemoryLength = env_->minMemoryLength; metadata_->maxMemoryLength = env_->maxMemoryLength; metadata_->startFuncIndex = env_->startFuncIndex; diff --git a/js/src/wasm/WasmInstance.cpp b/js/src/wasm/WasmInstance.cpp index dedcb4f5001a..adea424b2407 100644 --- a/js/src/wasm/WasmInstance.cpp +++ b/js/src/wasm/WasmInstance.cpp @@ -133,6 +133,10 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con case ValType::F64: args[i].set(JS::CanonicalizedDoubleValue(*(double*)&argv[i])); break; + case ValType::AnyRef: { + args[i].set(ObjectOrNullValue(*(JSObject**)&argv[i])); + break; + } case ValType::I64: case ValType::I8x16: case ValType::I16x8: @@ -188,23 +192,28 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con if (!TypeScript::ThisTypes(script)->hasType(TypeSet::UndefinedType())) return true; + // Functions with anyref in signature don't have a jit exit at the moment. + if (fi.sig().temporarilyUnsupportedAnyRef()) + return true; + const ValTypeVector& importArgs = fi.sig().args(); size_t numKnownArgs = Min(importArgs.length(), importFun->nargs()); for (uint32_t i = 0; i < numKnownArgs; i++) { TypeSet::Type type = TypeSet::UnknownType(); switch (importArgs[i]) { - case ValType::I32: type = TypeSet::Int32Type(); break; - case ValType::F32: type = TypeSet::DoubleType(); break; - case ValType::F64: type = TypeSet::DoubleType(); break; - case ValType::I64: MOZ_CRASH("NYI"); - case ValType::I8x16: MOZ_CRASH("NYI"); - case ValType::I16x8: MOZ_CRASH("NYI"); - case ValType::I32x4: MOZ_CRASH("NYI"); - case ValType::F32x4: MOZ_CRASH("NYI"); - case ValType::B8x16: MOZ_CRASH("NYI"); - case ValType::B16x8: MOZ_CRASH("NYI"); - case ValType::B32x4: MOZ_CRASH("NYI"); + case ValType::I32: type = TypeSet::Int32Type(); break; + case ValType::F32: type = TypeSet::DoubleType(); break; + case ValType::F64: type = TypeSet::DoubleType(); break; + case ValType::AnyRef: MOZ_CRASH("case guarded above"); + case ValType::I64: MOZ_CRASH("NYI"); + case ValType::I8x16: MOZ_CRASH("NYI"); + case ValType::I16x8: MOZ_CRASH("NYI"); + case ValType::I32x4: MOZ_CRASH("NYI"); + case ValType::F32x4: MOZ_CRASH("NYI"); + case ValType::B8x16: MOZ_CRASH("NYI"); + case ValType::B16x8: MOZ_CRASH("NYI"); + case ValType::B32x4: MOZ_CRASH("NYI"); } if (!TypeScript::ArgTypes(script, i)->hasType(type)) return true; @@ -265,6 +274,31 @@ Instance::callImport_f64(Instance* instance, int32_t funcImportIndex, int32_t ar return ToNumber(cx, rval, (double*)argv); } +static bool +ToRef(JSContext* cx, HandleValue val, void* addr) +{ + if (val.isNull()) { + *(JSObject**)addr = nullptr; + return true; + } + + JSObject* obj = ToObject(cx, val); + if (!obj) + return false; + *(JSObject**)addr = obj; + return true; +} + +/* static */ int32_t +Instance::callImport_ref(Instance* instance, int32_t funcImportIndex, int32_t argc, uint64_t* argv) +{ + JSContext* cx = TlsContext.get(); + RootedValue rval(cx); + if (!instance->callImport(cx, funcImportIndex, argc, argv, &rval)) + return false; + return ToRef(cx, rval, argv); +} + /* static */ uint32_t Instance::growMemory_i32(Instance* instance, uint32_t delta) { @@ -672,6 +706,11 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args) if (!ToNumber(cx, v, (double*)&exportArgs[i])) return false; break; + case ValType::AnyRef: { + if (!ToRef(cx, v, &exportArgs[i])) + return false; + break; + } case ValType::I8x16: { SimdConstant simd; if (!ToSimdConstant(cx, v, &simd)) @@ -755,6 +794,8 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args) } void* retAddr = &exportArgs[0]; + + bool expectsObject = false; JSObject* retObj = nullptr; switch (func.sig().ret()) { case ExprType::Void: @@ -771,6 +812,10 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args) case ExprType::F64: args.rval().set(NumberValue(*(double*)retAddr)); break; + case ExprType::AnyRef: + retObj = *(JSObject**)retAddr; + expectsObject = true; + break; case ExprType::I8x16: retObj = CreateSimd(cx, (int8_t*)retAddr); if (!retObj) @@ -810,7 +855,9 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args) MOZ_CRASH("Limit"); } - if (retObj) + if (expectsObject) + args.rval().set(ObjectOrNullValue(retObj)); + else if (retObj) args.rval().set(ObjectValue(*retObj)); return true; diff --git a/js/src/wasm/WasmInstance.h b/js/src/wasm/WasmInstance.h index 2ea6fe795442..6f7c7620476b 100644 --- a/js/src/wasm/WasmInstance.h +++ b/js/src/wasm/WasmInstance.h @@ -164,6 +164,7 @@ class Instance static int32_t callImport_i32(Instance*, int32_t, int32_t, uint64_t*); static int32_t callImport_i64(Instance*, int32_t, int32_t, uint64_t*); static int32_t callImport_f64(Instance*, int32_t, int32_t, uint64_t*); + static int32_t callImport_ref(Instance*, int32_t, int32_t, uint64_t*); static uint32_t growMemory_i32(Instance* instance, uint32_t delta); static uint32_t currentMemory_i32(Instance* instance); static int32_t wait_i32(Instance* instance, uint32_t byteOffset, int32_t value, int64_t timeout); diff --git a/js/src/wasm/WasmIonCompile.cpp b/js/src/wasm/WasmIonCompile.cpp index 07be484ccdd3..72c3d7693842 100644 --- a/js/src/wasm/WasmIonCompile.cpp +++ b/js/src/wasm/WasmIonCompile.cpp @@ -219,6 +219,9 @@ class FunctionCompiler case ValType::F64: ins = MConstant::New(alloc(), DoubleValue(0.0), MIRType::Double); break; + case ValType::AnyRef: + MOZ_CRASH("ion support for anyref locale default value NYI"); + break; case ValType::I8x16: ins = MSimdConstant::New(alloc(), SimdConstant::SplatX16(0), MIRType::Int8x16); break; @@ -2980,6 +2983,7 @@ SimdToLaneType(ValType type) case ValType::I64: case ValType::F32: case ValType::F64: + case ValType::AnyRef: break; } MOZ_CRASH("bad simd type"); @@ -3260,6 +3264,7 @@ EmitSimdCtor(FunctionCompiler& f, ValType type) case ValType::I64: case ValType::F32: case ValType::F64: + case ValType::AnyRef: break; } MOZ_CRASH("unexpected SIMD type"); @@ -3973,6 +3978,11 @@ EmitBodyExprs(FunctionCompiler& f) case uint16_t(Op::F64ReinterpretI64): CHECK(EmitReinterpret(f, ValType::F64, ValType::I64, MIRType::Double)); + // GC types are NYI in Ion. + case uint16_t(Op::RefNull): + case uint16_t(Op::RefIsNull): + return f.iter().unrecognizedOpcode(&op); + // Sign extensions #ifdef ENABLE_WASM_SIGNEXTEND_OPS case uint16_t(Op::I32Extend8S): @@ -4386,7 +4396,7 @@ wasm::IonCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo, ValTypeVector locals; if (!locals.appendAll(env.funcSigs[func.index]->args())) return false; - if (!DecodeLocalEntries(d, env.kind, &locals)) + if (!DecodeLocalEntries(d, env.kind, env.gcTypesEnabled, &locals)) return false; // Set up for Ion compilation. diff --git a/js/src/wasm/WasmJS.cpp b/js/src/wasm/WasmJS.cpp index 2a3cecf2d884..3321e432d386 100644 --- a/js/src/wasm/WasmJS.cpp +++ b/js/src/wasm/WasmJS.cpp @@ -1291,11 +1291,23 @@ WasmInstanceObject::getExportedFunction(JSContext* cx, HandleWasmInstanceObject RootedAtom name(cx, NumberToAtom(cx, funcIndex)); if (!name) return false; + + // Functions with anyref don't have jit entries yet, so they should + // mostly behave like asm.js functions. Pretend it's the case, until + // jit entries are implemented. + JSFunction::Flags flags = sig.temporarilyUnsupportedAnyRef() + ? JSFunction::ASMJS_NATIVE + : JSFunction::WASM_FUN; + fun.set(NewNativeFunction(cx, WasmCall, numArgs, name, gc::AllocKind::FUNCTION_EXTENDED, - SingletonObject, JSFunction::WASM_FUN)); + SingletonObject, flags)); if (!fun) return false; - fun->setWasmJitEntry(instance.code().getAddressOfJitEntry(funcIndex)); + + if (sig.temporarilyUnsupportedAnyRef()) + fun->setAsmJSIndex(funcIndex); + else + fun->setWasmJitEntry(instance.code().getAddressOfJitEntry(funcIndex)); } fun->setExtendedSlot(FunctionExtended::WASM_INSTANCE_SLOT, ObjectValue(*instanceObj)); diff --git a/js/src/wasm/WasmModule.cpp b/js/src/wasm/WasmModule.cpp index 1ef54f77be38..350ef02f33df 100644 --- a/js/src/wasm/WasmModule.cpp +++ b/js/src/wasm/WasmModule.cpp @@ -271,8 +271,10 @@ Module::finishTier2(UniqueLinkDataTier linkData2, UniqueCodeTier tier2, ModuleEn return false; } + HasGcTypes gcTypesEnabled = code().metadata().temporaryHasGcTypes; + Maybe stub2Index; - if (!stubs2->createTier2(funcExportIndices, *tier2, &stub2Index)) + if (!stubs2->createTier2(gcTypesEnabled, funcExportIndices, *tier2, &stub2Index)) return false; // Install the data in the data structures. They will not be visible diff --git a/js/src/wasm/WasmStubs.cpp b/js/src/wasm/WasmStubs.cpp index a91a5dbedd11..657de9805cf7 100644 --- a/js/src/wasm/WasmStubs.cpp +++ b/js/src/wasm/WasmStubs.cpp @@ -92,6 +92,10 @@ SetupABIArguments(MacroAssembler& masm, const FuncExport& fe, Register argv, Reg masm.load32(src, iter->gpr()); else if (type == MIRType::Int64) masm.load64(src, iter->gpr64()); + else if (type == MIRType::Pointer) + masm.loadPtr(src, iter->gpr()); + else + MOZ_CRASH("unknown GPR type"); break; #ifdef JS_CODEGEN_REGISTER_PAIR case ABIArg::GPR_PAIR: @@ -148,6 +152,10 @@ SetupABIArguments(MacroAssembler& masm, const FuncExport& fe, Register argv, Reg #endif break; } + case MIRType::Pointer: + masm.loadPtr(src, scratch); + masm.storePtr(scratch, Address(masm.getStackPointer(), iter->offsetFromArgBase())); + break; case MIRType::Double: masm.loadDouble(src, ScratchDoubleReg); masm.storeDouble(ScratchDoubleReg, @@ -204,6 +212,9 @@ StoreABIReturn(MacroAssembler& masm, const FuncExport& fe, Register argv) masm.canonicalizeDouble(ReturnDoubleReg); masm.storeDouble(ReturnDoubleReg, Address(argv, 0)); break; + case ExprType::AnyRef: + masm.storePtr(ReturnReg, Address(argv, 0)); + break; case ExprType::I8x16: case ExprType::I16x8: case ExprType::I32x4: @@ -255,13 +266,20 @@ static const unsigned NonVolatileRegsPushSize = NonVolatileRegs.gprs().size() * NonVolatileRegs.fpus().getPushSizeInBytes(); #endif -#if defined(JS_CODEGEN_ARM64) -// Stacks are 16-byte aligned, hence the extra word. -static const unsigned FramePushedBeforeAlign = NonVolatileRegsPushSize + 2 * sizeof(void*); +#ifdef ENABLE_WASM_GC +static const unsigned NumExtraPushed = 2; // tls and argv #else -static const unsigned FramePushedBeforeAlign = NonVolatileRegsPushSize + sizeof(void*); +static const unsigned NumExtraPushed = 1; // argv #endif +#ifdef JS_CODEGEN_ARM64 +static const unsigned WasmPushSize = 16; +#else +static const unsigned WasmPushSize = sizeof(void*); +#endif + +static const unsigned FramePushedBeforeAlign = NonVolatileRegsPushSize + NumExtraPushed * WasmPushSize; + static void AssertExpectedSP(const MacroAssembler& masm) { @@ -276,7 +294,7 @@ WasmPush(MacroAssembler& masm, const Operand& op) { #ifdef JS_CODEGEN_ARM64 // Allocate a pad word so that SP can remain properly aligned. - masm.reserveStack(16); + masm.reserveStack(WasmPushSize); masm.storePtr(op, Address(masm.getStackPointer(), 0)); #else masm.Push(op); @@ -289,7 +307,7 @@ WasmPop(MacroAssembler& masm, Register r) #ifdef JS_CODEGEN_ARM64 // Also pop the pad word allocated by WasmPush. masm.loadPtr(Address(masm.getStackPointer(), 0), r); - masm.freeStack(16); + masm.freeStack(WasmPushSize); #else masm.Pop(r); #endif @@ -303,6 +321,17 @@ MoveSPForJitABI(MacroAssembler& masm) #endif } +#ifdef ENABLE_WASM_GC +static void +SuppressGC(MacroAssembler& masm, int32_t increment, Register scratch) +{ + masm.loadPtr(Address(WasmTlsReg, offsetof(TlsData, cx)), scratch); + masm.add32(Imm32(increment), + Address(scratch, offsetof(JSContext, suppressGC) + + js::ThreadLocalData::offsetOfValue())); +} +#endif + static void CallFuncExport(MacroAssembler& masm, const FuncExport& fe, const Maybe& funcPtr) { @@ -319,7 +348,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, - Offsets* offsets) + HasGcTypes gcTypesEnabled, Offsets* offsets) { AssertExpectedSP(masm); masm.haltingAlign(CodeAlignment); @@ -372,6 +401,12 @@ GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe, const Maybe& funcPtr, Offsets* offsets) + const Maybe& funcPtr, HasGcTypes gcTypesEnabled, Offsets* offsets) { AssertExpectedSP(masm); @@ -540,7 +581,15 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& // left): // <-- retAddr | descriptor | callee | argc | this | arg1..N - unsigned normalBytesNeeded = StackArgBytes(fe.sig().args()); +#ifdef ENABLE_WASM_GC + // Save WasmTlsReg in the uppermost part of the reserved area, because we + // need it directly after the call. + unsigned savedTlsSize = AlignBytes(sizeof(void*), WasmStackAlignment); +#else + unsigned savedTlsSize = 0; +#endif + + unsigned normalBytesNeeded = StackArgBytes(fe.sig().args()) + savedTlsSize; MIRTypeVector coerceArgTypes; MOZ_ALWAYS_TRUE(coerceArgTypes.append(MIRType::Int32)); @@ -554,6 +603,10 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& // instruction. unsigned frameSize = StackDecrementForCall(WasmStackAlignment, 0, bytesNeeded); +#ifdef ENABLE_WASM_GC + unsigned savedTlsOffset = frameSize - sizeof(void*); +#endif + // Reserve stack space for wasm ABI arguments, set up like this: // <-- ABI args | padding masm.reserveStack(frameSize); @@ -726,12 +779,26 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& // Setup wasm register state. masm.loadWasmPinnedRegsFromTls(); +#ifdef ENABLE_WASM_GC + if (gcTypesEnabled == HasGcTypes::True) { + masm.storePtr(WasmTlsReg, Address(sp, savedTlsOffset)); + SuppressGC(masm, 1, ScratchIonEntry); + } +#endif + // Call into the real function. Note that, due to the throw stub, fp, tls // and pinned registers may be clobbered. masm.assertStackAlignment(WasmStackAlignment); CallFuncExport(masm, fe, funcPtr); masm.assertStackAlignment(WasmStackAlignment); +#ifdef ENABLE_WASM_GC + if (gcTypesEnabled == HasGcTypes::True) { + masm.loadPtr(Address(sp, savedTlsOffset), WasmTlsReg); + SuppressGC(masm, -1, WasmTlsReg); + } +#endif + // If fp is equal to the FailFP magic value (set by the throw stub), then // report the exception to the JIT caller by jumping into the exception // stub; otherwise the FP value is still set to the parent ion frame value. @@ -758,6 +825,9 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& masm.canonicalizeDouble(ReturnDoubleReg); masm.boxDouble(ReturnDoubleReg, JSReturnOperand, ScratchDoubleReg); break; + case ExprType::AnyRef: + MOZ_CRASH("return anyref in jitentry NYI"); + break; case ExprType::I64: case ExprType::I8x16: case ExprType::I16x8: @@ -845,6 +915,9 @@ StackCopy(MacroAssembler& masm, MIRType type, Register scratch, Address src, Add masm.load64(src, scratch64); masm.store64(scratch64, dst); #endif + } else if (type == MIRType::Pointer) { + masm.loadPtr(src, scratch); + masm.storePtr(scratch, dst); } else if (type == MIRType::Float32) { masm.loadFloat32(src, ScratchFloat32Reg); masm.storeFloat32(ScratchFloat32Reg, dst); @@ -878,8 +951,10 @@ FillArgumentArray(MacroAssembler& masm, const ValTypeVector& args, unsigned argO masm.breakpoint(); else masm.store64(i->gpr64(), dst); - } else { - MOZ_CRASH("unexpected input type?"); + } else if (type == MIRType::Pointer) { + if (toValue) + MOZ_CRASH("generating a jit exit for anyref NYI"); + masm.storePtr(i->gpr(), dst); } break; #ifdef JS_CODEGEN_REGISTER_PAIR @@ -926,6 +1001,8 @@ FillArgumentArray(MacroAssembler& masm, const ValTypeVector& args, unsigned argO } else if (type == MIRType::Int64) { // We can't box int64 into Values (yet). masm.breakpoint(); + } else if (type == MIRType::Pointer) { + MOZ_CRASH("generating a jit exit for anyref NYI"); } else { MOZ_ASSERT(IsFloatingPointType(type)); if (type == MIRType::Float32) { @@ -1122,6 +1199,11 @@ GenerateImportInterpExit(MacroAssembler& masm, const FuncImport& fi, uint32_t fu masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel); masm.loadDouble(argv, ReturnDoubleReg); break; + case ExprType::AnyRef: + masm.call(SymbolicAddress::CallImport_Ref); + masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel); + masm.loadPtr(argv, ReturnReg); + break; case ExprType::I8x16: case ExprType::I16x8: case ExprType::I32x4: @@ -1297,6 +1379,9 @@ GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* throwLa case ExprType::F64: masm.convertValueToDouble(JSReturnOperand, ReturnDoubleReg, &oolConvert); break; + case ExprType::AnyRef: + MOZ_CRASH("anyref returned by import (jit exit) NYI"); + break; case ExprType::I8x16: case ExprType::I16x8: case ExprType::I32x4: @@ -1701,21 +1786,22 @@ GenerateDebugTrapStub(MacroAssembler& masm, Label* throwLabel, CallableOffsets* bool wasm::GenerateEntryStubs(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& fe, - const Maybe& callee, bool isAsmJS, CodeRangeVector* codeRanges) + 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, &offsets)) + if (!GenerateInterpEntry(masm, fe, callee, gcTypesEnabled, &offsets)) return false; if (!codeRanges->emplaceBack(CodeRange::InterpEntry, fe.funcIndex(), offsets)) return false; - if (isAsmJS) + if (isAsmJS || fe.sig().temporarilyUnsupportedAnyRef()) return true; - if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, &offsets)) + if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, gcTypesEnabled, &offsets)) return false; if (!codeRanges->emplaceBack(CodeRange::JitEntry, fe.funcIndex(), offsets)) return false; @@ -1748,6 +1834,9 @@ wasm::GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& import if (!code->codeRanges.emplaceBack(CodeRange::ImportInterpExit, funcIndex, interpOffsets)) return false; + if (fi.sig().temporarilyUnsupportedAnyRef()) + continue; + JitExitOffsets jitOffsets; if (!GenerateImportJitExit(masm, fi, &throwLabel, &jitOffsets)) return false; @@ -1762,8 +1851,11 @@ wasm::GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& import const FuncExport& fe = exports[i]; if (!fe.hasEagerStubs()) continue; - if (!GenerateEntryStubs(masm, i, fe, noAbsolute, env.isAsmJS(), &code->codeRanges)) + if (!GenerateEntryStubs(masm, i, fe, noAbsolute, env.isAsmJS(), + env.gcTypesEnabled, &code->codeRanges)) + { return false; + } } JitSpew(JitSpew_Codegen, "# Emitting wasm exit stubs"); diff --git a/js/src/wasm/WasmStubs.h b/js/src/wasm/WasmStubs.h index 7b8d7fd7fea6..6dc3d0b20a11 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, CodeRangeVector* codeRanges); + bool isAsmJS, HasGcTypes gcTypesEnabled, CodeRangeVector* codeRanges); } // namespace wasm } // namespace js diff --git a/js/src/wasm/WasmTextToBinary.cpp b/js/src/wasm/WasmTextToBinary.cpp index a895737dea05..2f9900c7905e 100644 --- a/js/src/wasm/WasmTextToBinary.cpp +++ b/js/src/wasm/WasmTextToBinary.cpp @@ -115,6 +115,7 @@ class WasmToken Offset, OpenParen, Param, + RefNull, Result, Return, SetGlobal, @@ -331,6 +332,7 @@ class WasmToken case Load: case Loop: case Nop: + case RefNull: case Return: case SetGlobal: case SetLocal: @@ -888,6 +890,8 @@ WasmTokenStream::next() return WasmToken(WasmToken::Align, begin, cur_); if (consume(u"anyfunc")) return WasmToken(WasmToken::AnyFunc, begin, cur_); + if (consume(u"anyref")) + return WasmToken(WasmToken::ValueType, ValType::AnyRef, begin, cur_); #ifdef ENABLE_WASM_THREAD_OPS if (consume(u"atomic.wake")) return WasmToken(WasmToken::Wake, ThreadOp::Wake, begin, cur_); @@ -1665,6 +1669,13 @@ WasmTokenStream::next() return WasmToken(WasmToken::Result, begin, cur_); if (consume(u"return")) return WasmToken(WasmToken::Return, begin, cur_); + if (consume(u"ref.")) { + if (consume(u"null")) + return WasmToken(WasmToken::RefNull, begin, cur_); + if (consume(u"is_null")) + return WasmToken(WasmToken::UnaryOpcode, Op::RefIsNull, begin, cur_); + break; + } break; case 's': @@ -2932,6 +2943,19 @@ ParseGrowMemory(WasmParseContext& c, bool inParens) return new(c.lifo) AstGrowMemory(operand); } +static AstExpr* +ParseRefNull(WasmParseContext& c) +{ + WasmToken token; + if (!c.ts.match(WasmToken::ValueType, &token, c.error)) + return nullptr; + if (token.valueType() != ValType::AnyRef) { + c.ts.generateError(token, "only anyref is supported for nullref", c.error); + return nullptr; + } + return new(c.lifo) AstRefNull(ValType::AnyRef); +} + static AstExpr* ParseExprBody(WasmParseContext& c, WasmToken token, bool inParens) { @@ -3008,6 +3032,8 @@ ParseExprBody(WasmParseContext& c, WasmToken token, bool inParens) return new(c.lifo) AstCurrentMemory(); case WasmToken::GrowMemory: return ParseGrowMemory(c, inParens); + case WasmToken::RefNull: + return ParseRefNull(c); default: c.ts.generateError(token, c.error); return nullptr; @@ -4325,6 +4351,7 @@ ResolveExpr(Resolver& r, AstExpr& expr) case AstExprKind::Pop: case AstExprKind::Unreachable: case AstExprKind::CurrentMemory: + case AstExprKind::RefNull: return true; case AstExprKind::Drop: return ResolveDropOperator(r, expr.as()); @@ -4929,6 +4956,13 @@ EncodeWake(Encoder& e, AstWake& s) EncodeLoadStoreFlags(e, s.address()); } +static bool +EncodeRefNull(Encoder& e, AstRefNull& s) +{ + return e.writeOp(Op::RefNull) && + e.writeValType(s.refType()); +} + static bool EncodeExpr(Encoder& e, AstExpr& expr) { @@ -4939,6 +4973,8 @@ EncodeExpr(Encoder& e, AstExpr& expr) return e.writeOp(Op::Nop); case AstExprKind::Unreachable: return e.writeOp(Op::Unreachable); + case AstExprKind::RefNull: + return EncodeRefNull(e, expr.as()); case AstExprKind::BinaryOperator: return EncodeBinaryOperator(e, expr.as()); case AstExprKind::Block: diff --git a/js/src/wasm/WasmTypes.cpp b/js/src/wasm/WasmTypes.cpp index 91ee92a4c278..c97e1cfebd94 100644 --- a/js/src/wasm/WasmTypes.cpp +++ b/js/src/wasm/WasmTypes.cpp @@ -72,6 +72,9 @@ Val::writePayload(uint8_t* dst) const case ValType::B32x4: memcpy(dst, &u, jit::Simd128DataSize); return; + case ValType::AnyRef: + // TODO + MOZ_CRASH("writing imported value of AnyRef in global NYI"); } } @@ -172,7 +175,7 @@ static const unsigned sTotalBits = sizeof(ImmediateType) * 8; static const unsigned sTagBits = 1; static const unsigned sReturnBit = 1; static const unsigned sLengthBits = 4; -static const unsigned sTypeBits = 2; +static const unsigned sTypeBits = 3; static const unsigned sMaxTypes = (sTotalBits - sTagBits - sReturnBit - sLengthBits) / sTypeBits; static bool @@ -183,6 +186,7 @@ IsImmediateType(ValType vt) case ValType::I64: case ValType::F32: case ValType::F64: + case ValType::AnyRef: return true; case ValType::I8x16: case ValType::I16x8: @@ -199,7 +203,7 @@ IsImmediateType(ValType vt) static unsigned EncodeImmediateType(ValType vt) { - static_assert(3 < (1 << sTypeBits), "fits"); + static_assert(4 < (1 << sTypeBits), "fits"); switch (vt) { case ValType::I32: return 0; @@ -209,6 +213,8 @@ EncodeImmediateType(ValType vt) return 2; case ValType::F64: return 3; + case ValType::AnyRef: + return 4; case ValType::I8x16: case ValType::I16x8: case ValType::I32x4: diff --git a/js/src/wasm/WasmTypes.h b/js/src/wasm/WasmTypes.h index f43177d77649..0ef026f340a0 100644 --- a/js/src/wasm/WasmTypes.h +++ b/js/src/wasm/WasmTypes.h @@ -183,9 +183,10 @@ SizeOf(ValType vt) case ValType::B16x8: case ValType::B32x4: return 16; - default: - MOZ_CRASH("Invalid ValType"); + case ValType::AnyRef: + MOZ_CRASH("unexpected anyref"); } + MOZ_CRASH("Invalid ValType"); } static inline bool @@ -275,21 +276,34 @@ static inline jit::MIRType ToMIRType(ValType vt) { switch (vt) { - case ValType::I32: return jit::MIRType::Int32; - case ValType::I64: return jit::MIRType::Int64; - case ValType::F32: return jit::MIRType::Float32; - case ValType::F64: return jit::MIRType::Double; - case ValType::I8x16: return jit::MIRType::Int8x16; - case ValType::I16x8: return jit::MIRType::Int16x8; - case ValType::I32x4: return jit::MIRType::Int32x4; - case ValType::F32x4: return jit::MIRType::Float32x4; - case ValType::B8x16: return jit::MIRType::Bool8x16; - case ValType::B16x8: return jit::MIRType::Bool16x8; - case ValType::B32x4: return jit::MIRType::Bool32x4; + case ValType::I32: return jit::MIRType::Int32; + case ValType::I64: return jit::MIRType::Int64; + case ValType::F32: return jit::MIRType::Float32; + case ValType::F64: return jit::MIRType::Double; + case ValType::AnyRef: return jit::MIRType::Pointer; + case ValType::I8x16: return jit::MIRType::Int8x16; + case ValType::I16x8: return jit::MIRType::Int16x8; + case ValType::I32x4: return jit::MIRType::Int32x4; + case ValType::F32x4: return jit::MIRType::Float32x4; + case ValType::B8x16: return jit::MIRType::Bool8x16; + case ValType::B16x8: return jit::MIRType::Bool16x8; + case ValType::B32x4: return jit::MIRType::Bool32x4; } MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad type"); } +static inline bool +IsRefType(ValType vt) +{ + return vt == ValType::AnyRef; +} + +static inline bool +IsNumberType(ValType vt) +{ + return !IsRefType(vt); +} + // The ExprType enum represents the type of a WebAssembly expression or return // value and may either be a value type or void. Soon, expression types will be // generalized to a list of ValType and this enum will go away, replaced, @@ -297,22 +311,23 @@ ToMIRType(ValType vt) enum class ExprType { - Void = uint8_t(TypeCode::BlockVoid), + Void = uint8_t(TypeCode::BlockVoid), - I32 = uint8_t(TypeCode::I32), - I64 = uint8_t(TypeCode::I64), - F32 = uint8_t(TypeCode::F32), - F64 = uint8_t(TypeCode::F64), + I32 = uint8_t(TypeCode::I32), + I64 = uint8_t(TypeCode::I64), + F32 = uint8_t(TypeCode::F32), + F64 = uint8_t(TypeCode::F64), + AnyRef = uint8_t(TypeCode::AnyRef), - I8x16 = uint8_t(TypeCode::I8x16), - I16x8 = uint8_t(TypeCode::I16x8), - I32x4 = uint8_t(TypeCode::I32x4), - F32x4 = uint8_t(TypeCode::F32x4), - B8x16 = uint8_t(TypeCode::B8x16), - B16x8 = uint8_t(TypeCode::B16x8), - B32x4 = uint8_t(TypeCode::B32x4), + I8x16 = uint8_t(TypeCode::I8x16), + I16x8 = uint8_t(TypeCode::I16x8), + I32x4 = uint8_t(TypeCode::I32x4), + F32x4 = uint8_t(TypeCode::F32x4), + B8x16 = uint8_t(TypeCode::B8x16), + B16x8 = uint8_t(TypeCode::B16x8), + B32x4 = uint8_t(TypeCode::B32x4), - Limit = uint8_t(TypeCode::Limit) + Limit = uint8_t(TypeCode::Limit) }; static inline bool @@ -350,18 +365,19 @@ static inline const char* ToCString(ExprType type) { switch (type) { - case ExprType::Void: return "void"; - case ExprType::I32: return "i32"; - case ExprType::I64: return "i64"; - case ExprType::F32: return "f32"; - case ExprType::F64: return "f64"; - case ExprType::I8x16: return "i8x16"; - case ExprType::I16x8: return "i16x8"; - case ExprType::I32x4: return "i32x4"; - case ExprType::F32x4: return "f32x4"; - case ExprType::B8x16: return "b8x16"; - case ExprType::B16x8: return "b16x8"; - case ExprType::B32x4: return "b32x4"; + case ExprType::Void: return "void"; + case ExprType::I32: return "i32"; + case ExprType::I64: return "i64"; + case ExprType::F32: return "f32"; + case ExprType::F64: return "f64"; + case ExprType::AnyRef: return "anyref"; + case ExprType::I8x16: return "i8x16"; + case ExprType::I16x8: return "i16x8"; + case ExprType::I32x4: return "i32x4"; + case ExprType::F32x4: return "f32x4"; + case ExprType::B8x16: return "b8x16"; + case ExprType::B16x8: return "b16x8"; + case ExprType::B32x4: return "b32x4"; case ExprType::Limit:; } MOZ_CRASH("bad expression type"); @@ -450,6 +466,12 @@ enum class Shareable True }; +enum class HasGcTypes +{ + False, + True +}; + // The Val class represents a single WebAssembly value of a given value type, // mostly for the purpose of numeric literals and initializers. A Val does not // directly map to a JS value since there is not (currently) a precise @@ -569,8 +591,17 @@ class Sig bool hasI64ArgOrRet() const { if (ret() == ExprType::I64) return true; - for (ValType a : args()) { - if (a == ValType::I64) + for (ValType arg : args()) { + if (arg == ValType::I64) + return true; + } + return false; + } + bool temporarilyUnsupportedAnyRef() const { + if (ret() == ExprType::AnyRef) + return true; + for (ValType arg : args()) { + if (arg == ValType::AnyRef) return true; } return false; @@ -1437,6 +1468,7 @@ enum class SymbolicAddress CallImport_I32, CallImport_I64, CallImport_F64, + CallImport_Ref, CoerceInPlace_ToInt32, CoerceInPlace_ToNumber, CoerceInPlace_JitEntry, diff --git a/js/src/wasm/WasmValidate.cpp b/js/src/wasm/WasmValidate.cpp index 99ffe20fd991..6c4f98c896a2 100644 --- a/js/src/wasm/WasmValidate.cpp +++ b/js/src/wasm/WasmValidate.cpp @@ -302,7 +302,7 @@ wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals) } static bool -DecodeValType(Decoder& d, ModuleKind kind, ValType* type) +DecodeValType(Decoder& d, ModuleKind kind, HasGcTypes gcTypesEnabled, ValType* type) { uint8_t unchecked; if (!d.readValType(&unchecked)) @@ -315,6 +315,11 @@ DecodeValType(Decoder& d, ModuleKind kind, ValType* type) case uint8_t(ValType::I64): *type = ValType(unchecked); return true; + case uint8_t(ValType::AnyRef): + if (gcTypesEnabled == HasGcTypes::False) + break; + *type = ValType(unchecked); + return true; case uint8_t(ValType::I8x16): case uint8_t(ValType::I16x8): case uint8_t(ValType::I32x4): @@ -333,7 +338,8 @@ DecodeValType(Decoder& d, ModuleKind kind, ValType* type) } bool -wasm::DecodeLocalEntries(Decoder& d, ModuleKind kind, ValTypeVector* locals) +wasm::DecodeLocalEntries(Decoder& d, ModuleKind kind, HasGcTypes gcTypesEnabled, + ValTypeVector* locals) { uint32_t numLocalEntries; if (!d.readVarU32(&numLocalEntries)) @@ -348,7 +354,7 @@ wasm::DecodeLocalEntries(Decoder& d, ModuleKind kind, ValTypeVector* locals) return d.fail("too many locals"); ValType type; - if (!DecodeValType(d, kind, &type)) + if (!DecodeValType(d, kind, gcTypesEnabled, &type)) return false; if (!locals->appendN(type, count)) @@ -742,6 +748,20 @@ DecodeFunctionBodyExprs(const ModuleEnvironment& env, const Sig& sig, const ValT return iter.unrecognizedOpcode(&op); #endif } +#ifdef ENABLE_WASM_GC + case uint16_t(Op::RefNull): { + if (env.gcTypesEnabled == HasGcTypes::False) + return iter.unrecognizedOpcode(&op); + CHECK(iter.readRefNull()); + break; + } + case uint16_t(Op::RefIsNull): { + if (env.gcTypesEnabled == HasGcTypes::False) + return iter.unrecognizedOpcode(&op); + CHECK(iter.readConversion(ValType::AnyRef, ValType::I32, ¬hing)); + break; + } +#endif case uint16_t(Op::ThreadPrefix): { #ifdef ENABLE_WASM_THREAD_OPS switch (op.b1) { @@ -936,7 +956,7 @@ wasm::ValidateFunctionBody(const ModuleEnvironment& env, uint32_t funcIndex, uin const uint8_t* bodyBegin = d.currentPosition(); - if (!DecodeLocalEntries(d, ModuleKind::Wasm, &locals)) + if (!DecodeLocalEntries(d, ModuleKind::Wasm, env.gcTypesEnabled, &locals)) return false; if (!DecodeFunctionBodyExprs(env, sig, locals, bodyBegin + bodySize, &d)) @@ -1001,7 +1021,7 @@ DecodeTypeSection(Decoder& d, ModuleEnvironment* env) return false; for (uint32_t i = 0; i < numArgs; i++) { - if (!DecodeValType(d, ModuleKind::Wasm, &args[i])) + if (!DecodeValType(d, ModuleKind::Wasm, env->gcTypesEnabled, &args[i])) return false; } @@ -1016,7 +1036,7 @@ DecodeTypeSection(Decoder& d, ModuleEnvironment* env) if (numRets == 1) { ValType type; - if (!DecodeValType(d, ModuleKind::Wasm, &type)) + if (!DecodeValType(d, ModuleKind::Wasm, env->gcTypesEnabled, &type)) return false; result = ToExprType(type); @@ -1161,7 +1181,8 @@ GlobalIsJSCompatible(Decoder& d, ValType type, bool isMutable) static bool DecodeGlobalType(Decoder& d, ValType* type, bool* isMutable) { - if (!DecodeValType(d, ModuleKind::Wasm, type)) + // No gc types in globals at the moment. + if (!DecodeValType(d, ModuleKind::Wasm, HasGcTypes::False, type)) return false; uint8_t flags; @@ -1980,7 +2001,13 @@ wasm::Validate(JSContext* cx, const ShareableBytes& bytecode, UniqueChars* error { Decoder d(bytecode.bytes, 0, error); - ModuleEnvironment env(CompileMode::Once, Tier::Ion, DebugEnabled::False, +#ifdef ENABLE_WASM_GC + HasGcTypes gcSupport = cx->options().wasmGc() ? HasGcTypes::True : HasGcTypes::False; +#else + HasGcTypes gcSupport = HasGcTypes::False; +#endif + + ModuleEnvironment env(CompileMode::Once, Tier::Ion, DebugEnabled::False, gcSupport, cx->compartment()->creationOptions().getSharedMemoryAndAtomicsEnabled() ? Shareable::True : Shareable::False); diff --git a/js/src/wasm/WasmValidate.h b/js/src/wasm/WasmValidate.h index dbd8db356518..4cf679deb533 100644 --- a/js/src/wasm/WasmValidate.h +++ b/js/src/wasm/WasmValidate.h @@ -60,6 +60,7 @@ struct ModuleEnvironment const ModuleKind kind; const CompileMode mode; const Shareable sharedMemoryEnabled; + const HasGcTypes gcTypesEnabled; const Tier tier; // Module fields decoded from the module environment (or initialized while @@ -87,12 +88,14 @@ struct ModuleEnvironment explicit ModuleEnvironment(CompileMode mode, Tier tier, DebugEnabled debug, + HasGcTypes hasGcTypes, Shareable sharedMemoryEnabled, ModuleKind kind = ModuleKind::Wasm) : debug(debug), kind(kind), mode(mode), sharedMemoryEnabled(sharedMemoryEnabled), + gcTypesEnabled(hasGcTypes), tier(tier), memoryUsage(MemoryUsage::None), minMemoryLength(0) @@ -696,7 +699,7 @@ MOZ_MUST_USE bool EncodeLocalEntries(Encoder& d, const ValTypeVector& locals); MOZ_MUST_USE bool -DecodeLocalEntries(Decoder& d, ModuleKind kind, ValTypeVector* locals); +DecodeLocalEntries(Decoder& d, ModuleKind kind, HasGcTypes gcTypesEnabled, ValTypeVector* locals); // Returns whether the given [begin, end) prefix of a module's bytecode starts a // code section and, if so, returns the SectionRange of that code section. diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index bc1290c4ea1c..17e029ab39a3 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -773,6 +773,9 @@ ReloadPrefsCallback(const char* pref, void* data) bool useWasm = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm"); bool useWasmIon = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_ionjit"); bool useWasmBaseline = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_baselinejit"); +#ifdef ENABLE_WASM_GC + bool useWasmGc = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_gc"); +#endif bool throwOnAsmJSValidationFailure = Preferences::GetBool(JS_OPTIONS_DOT_STR "throw_on_asmjs_validation_failure"); bool useNativeRegExp = Preferences::GetBool(JS_OPTIONS_DOT_STR "native_regexp"); @@ -844,6 +847,9 @@ ReloadPrefsCallback(const char* pref, void* data) .setWasm(useWasm) .setWasmIon(useWasmIon) .setWasmBaseline(useWasmBaseline) +#ifdef ENABLE_WASM_GC + .setWasmGc(useWasmGc) +#endif .setThrowOnAsmJSValidationFailure(throwOnAsmJSValidationFailure) .setNativeRegExp(useNativeRegExp) .setAsyncStack(useAsyncStack) diff --git a/js/xpconnect/src/moz.build b/js/xpconnect/src/moz.build index c30bd297342f..2b473d2a4b6a 100644 --- a/js/xpconnect/src/moz.build +++ b/js/xpconnect/src/moz.build @@ -63,3 +63,6 @@ LOCAL_INCLUDES += [ if CONFIG['CC_TYPE'] in ('clang', 'gcc'): CXXFLAGS += ['-Wno-shadow', '-Werror=format'] + +if CONFIG['NIGHTLY_BUILD']: + DEFINES['ENABLE_WASM_GC'] = True diff --git a/layout/generic/MathMLTextRunFactory.cpp b/layout/generic/MathMLTextRunFactory.cpp index daf6462a1e4e..452dd614af38 100644 --- a/layout/generic/MathMLTextRunFactory.cpp +++ b/layout/generic/MathMLTextRunFactory.cpp @@ -636,7 +636,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, // This overrides the initial values specified in fontStyle, to avoid // inconsistencies in which attributes allow CSS changes and which do not. if (mFlags & MATH_FONT_WEIGHT_BOLD) { - font.weight = NS_FONT_WEIGHT_BOLD; + font.weight = FontWeight::Bold(); if (mFlags & MATH_FONT_STYLING_NORMAL) { font.style = NS_FONT_STYLE_NORMAL; } else { @@ -644,7 +644,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, } } else if (mFlags & MATH_FONT_STYLING_NORMAL) { font.style = NS_FONT_STYLE_NORMAL; - font.weight = NS_FONT_WEIGHT_NORMAL; + font.weight = FontWeight::Normal(); } else { mathVar = NS_MATHML_MATHVARIANT_ITALIC; } @@ -723,20 +723,20 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, if (mathVar == NS_MATHML_MATHVARIANT_BOLD && doMathvariantStyling) { font.style = NS_FONT_STYLE_NORMAL; - font.weight = NS_FONT_WEIGHT_BOLD; + font.weight = FontWeight::Bold(); } else if (mathVar == NS_MATHML_MATHVARIANT_ITALIC && doMathvariantStyling) { font.style = NS_FONT_STYLE_ITALIC; - font.weight = NS_FONT_WEIGHT_NORMAL; + font.weight = FontWeight::Normal(); } else if (mathVar == NS_MATHML_MATHVARIANT_BOLD_ITALIC && doMathvariantStyling) { font.style = NS_FONT_STYLE_ITALIC; - font.weight = NS_FONT_WEIGHT_BOLD; + font.weight = FontWeight::Bold(); } else if (mathVar != NS_MATHML_MATHVARIANT_NONE) { // Mathvariant overrides fontstyle and fontweight // Need to check to see if mathvariant is actually applied as this function // is used for other purposes. font.style = NS_FONT_STYLE_NORMAL; - font.weight = NS_FONT_WEIGHT_NORMAL; + font.weight = FontWeight::Normal(); } gfxFontGroup* newFontGroup = nullptr; diff --git a/layout/style/FontFace.h b/layout/style/FontFace.h index cf7e0a448afd..00ad5e4d353a 100644 --- a/layout/style/FontFace.h +++ b/layout/style/FontFace.h @@ -8,6 +8,7 @@ #define mozilla_dom_FontFace_h #include "mozilla/dom/FontFaceBinding.h" +#include "mozilla/FontPropertyTypes.h" #include "gfxUserFontSet.h" #include "nsAutoPtr.h" #include "nsCSSPropertyID.h" @@ -47,7 +48,7 @@ public: public: Entry(gfxUserFontSet* aFontSet, const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp index 17641c89300e..130127a94cf9 100644 --- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -15,6 +15,7 @@ #include "mozilla/dom/FontFaceSetLoadEvent.h" #include "mozilla/dom/FontFaceSetLoadEventBinding.h" #include "mozilla/dom/Promise.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/net/ReferrerPolicy.h" #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/Logging.h" @@ -205,7 +206,7 @@ void FontFaceSet::ParseFontShorthandForMatching( const nsAString& aFont, RefPtr& aFamilyList, - uint32_t& aWeight, + FontWeight& aWeight, int32_t& aStretch, uint8_t& aStyle, ErrorResult& aRv) @@ -219,7 +220,12 @@ FontFaceSet::ParseFontShorthandForMatching( aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); return; } - aWeight = weight.GetIntValue(); + if (weight.GetUnit() == eCSSUnit_FontWeight) { + aWeight = weight.GetFontWeight(); + } else { + MOZ_ASSERT(weight.GetUnit() == eCSSUnit_Enumerated); + aWeight = FontWeight(weight.GetIntValue()); + } aStretch = stretch.GetIntValue(); aStyle = style.GetIntValue(); } @@ -247,7 +253,7 @@ FontFaceSet::FindMatchingFontFaces(const nsAString& aFont, ErrorResult& aRv) { RefPtr familyList; - uint32_t weight; + FontWeight weight; int32_t stretch; uint8_t italicStyle; ParseFontShorthandForMatching(aFont, familyList, weight, stretch, italicStyle, @@ -972,7 +978,7 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName, nsCSSValue val; nsCSSUnit unit; - uint32_t weight = NS_FONT_WEIGHT_NORMAL; + FontWeight weight = FontWeight::Normal(); int32_t stretch = NS_STYLE_FONT_STRETCH_NORMAL; uint8_t italicStyle = NS_STYLE_FONT_STYLE_NORMAL; uint32_t languageOverride = NO_FONT_LANGUAGE_OVERRIDE; @@ -981,18 +987,19 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName, // set up weight aFontFace->GetDesc(eCSSFontDesc_Weight, val); unit = val.GetUnit(); - if (unit == eCSSUnit_Integer || unit == eCSSUnit_Enumerated) { - weight = val.GetIntValue(); - if (weight == 0) { - weight = NS_FONT_WEIGHT_NORMAL; - } + if (unit == eCSSUnit_FontWeight) { + weight = val.GetFontWeight(); + } else if (unit == eCSSUnit_Enumerated) { + weight = FontWeight(val.GetIntValue()); } else if (unit == eCSSUnit_Normal) { - weight = NS_FONT_WEIGHT_NORMAL; + weight = FontWeight::Normal(); } else { - NS_ASSERTION(unit == eCSSUnit_Null, - "@font-face weight has unexpected unit"); + MOZ_ASSERT(unit == eCSSUnit_Null, "@font-face weight has unexpected unit"); } + if (weight == FontWeight(0)) { + weight = FontWeight::Normal(); + } // set up stretch aFontFace->GetDesc(eCSSFontDesc_Stretch, val); unit = val.GetUnit(); @@ -1243,25 +1250,13 @@ FontFaceSet::LogMessage(gfxUserFontEntry* aUserFontEntry, nsAutoCString fontURI; aUserFontEntry->GetFamilyNameAndURIForLogging(familyName, fontURI); - char weightKeywordBuf[8]; // plenty to sprintf() a uint16_t - const char* weightKeyword; - const nsCString& weightKeywordString = - nsCSSProps::ValueToKeyword(aUserFontEntry->Weight(), - nsCSSProps::kFontWeightKTable); - if (weightKeywordString.Length() > 0) { - weightKeyword = weightKeywordString.get(); - } else { - SprintfLiteral(weightKeywordBuf, "%u", aUserFontEntry->Weight()); - weightKeyword = weightKeywordBuf; - } - nsPrintfCString message ("downloadable font: %s " - "(font-family: \"%s\" style:%s weight:%s stretch:%s src index:%d)", + "(font-family: \"%s\" style:%s weight:%g stretch:%s src index:%d)", aMessage, familyName.get(), aUserFontEntry->IsItalic() ? "italic" : "normal", - weightKeyword, + aUserFontEntry->Weight().ToFloat(), nsCSSProps::ValueToKeyword(aUserFontEntry->Stretch(), nsCSSProps::kFontStretchKTable).get(), aUserFontEntry->GetSrcIndex()); @@ -1934,7 +1929,7 @@ FontFaceSet::UserFontSet::DoRebuildUserFontSet() /* virtual */ already_AddRefed FontFaceSet::UserFontSet::CreateUserFontEntry( const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, diff --git a/layout/style/FontFaceSet.h b/layout/style/FontFaceSet.h index ec4d1675a24e..3195922433da 100644 --- a/layout/style/FontFaceSet.h +++ b/layout/style/FontFaceSet.h @@ -10,6 +10,7 @@ #include "mozilla/dom/FontFace.h" #include "mozilla/dom/FontFaceSetBinding.h" #include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/FontPropertyTypes.h" #include "gfxUserFontSet.h" #include "nsICSSLoaderObserver.h" @@ -95,9 +96,9 @@ public: uint32_t aFlags = nsIScriptError::errorFlag, nsresult aStatus = NS_OK) override; virtual void DoRebuildUserFontSet() override; - virtual already_AddRefed CreateUserFontEntry( + already_AddRefed CreateUserFontEntry( const nsTArray& aFontFaceSrcList, - uint32_t aWeight, + FontWeight aWeight, int32_t aStretch, uint8_t aStyle, const nsTArray& aFeatureSettings, @@ -312,7 +313,7 @@ private: void ParseFontShorthandForMatching( const nsAString& aFont, RefPtr& aFamilyList, - uint32_t& aWeight, + FontWeight& aWeight, int32_t& aStretch, uint8_t& aStyle, ErrorResult& aRv); diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index 621d98d7be10..cadcf7ee0eae 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -52,6 +52,7 @@ #include "mozilla/EffectCompositor.h" #include "mozilla/EffectSet.h" #include "mozilla/EventStates.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/Keyframe.h" #include "mozilla/Mutex.h" #include "mozilla/Preferences.h" @@ -1327,6 +1328,19 @@ Gecko_nsFont_SetFontFeatureValuesLookup(nsFont* aFont, aFont->featureValueLookup = aPresContext->GetFontFeatureValuesLookup(); } +float +Gecko_FontWeight_ToFloat(mozilla::FontWeight aWeight) +{ + return aWeight.ToFloat(); +} + +void +Gecko_FontWeight_SetFloat(mozilla::FontWeight* aWeight, + float aFloat) +{ + *aWeight = mozilla::FontWeight(aFloat); +} + void Gecko_nsFont_ResetFontFeatureValuesLookup(nsFont* aFont) { @@ -2306,6 +2320,13 @@ Gecko_CSSValue_Drop(nsCSSValueBorrowedMut aCSSValue) aCSSValue->~nsCSSValue(); } +void +Gecko_CSSValue_SetFontWeight(nsCSSValueBorrowedMut aCSSValue, + float weight) +{ + aCSSValue->SetFontWeight(mozilla::FontWeight(weight)); +} + void Gecko_nsStyleFont_SetLang(nsStyleFont* aFont, nsAtom* aAtom) { diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index ce326cd76bb8..85b9d4118466 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -565,6 +565,7 @@ void Gecko_CSSValue_SetKeyword(nsCSSValueBorrowedMut css_value, nsCSSKeyword key void Gecko_CSSValue_SetPercentage(nsCSSValueBorrowedMut css_value, float percent); void Gecko_CSSValue_SetPixelLength(nsCSSValueBorrowedMut aCSSValue, float aLen); void Gecko_CSSValue_SetCalc(nsCSSValueBorrowedMut css_value, nsStyleCoord::CalcValue calc); +void Gecko_CSSValue_SetFontWeight(nsCSSValueBorrowedMut css_value, float weight); void Gecko_CSSValue_SetFunction(nsCSSValueBorrowedMut css_value, int32_t len); void Gecko_CSSValue_SetString(nsCSSValueBorrowedMut css_value, const uint8_t* string, uint32_t len, nsCSSUnit unit); @@ -584,6 +585,10 @@ void Gecko_CSSValue_InitSharedList(nsCSSValueBorrowedMut css_value, uint32_t len void Gecko_CSSValue_Drop(nsCSSValueBorrowedMut css_value); NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList); +float Gecko_FontWeight_ToFloat(mozilla::FontWeight aWeight); +void Gecko_FontWeight_SetFloat(mozilla::FontWeight* aWeight, + float aFloatValue); + void Gecko_nsStyleFont_SetLang(nsStyleFont* font, nsAtom* atom); void Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource); void Gecko_nsStyleFont_FixupNoneGeneric(nsStyleFont* font, diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index 0519270bdcc4..95a2131099c6 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -463,6 +463,7 @@ structs-types = [ "mozilla::dom::CallerType", "mozilla::AnonymousCounterStyle", "mozilla::AtomArray", + "mozilla::FontWeight", "mozilla::MallocSizeOf", "mozilla::OriginFlags", "mozilla::UniquePtr", diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index b678f2744601..50434480deb4 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -9,6 +9,7 @@ #include "nsCSSValue.h" #include "mozilla/CORSMode.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/ServoBindings.h" #include "mozilla/ServoStyleSet.h" #include "mozilla/ServoTypes.h" @@ -121,6 +122,12 @@ nsCSSValue::nsCSSValue(SharedFontList* aValue) mValue.mFontFamilyList->AddRef(); } +nsCSSValue::nsCSSValue(FontWeight aWeight) + : mUnit(eCSSUnit_FontWeight) +{ + mValue.mFontWeight = aWeight; +} + nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) : mUnit(aCopy.mUnit) { @@ -180,6 +187,9 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) mValue.mFontFamilyList = aCopy.mValue.mFontFamilyList; mValue.mFontFamilyList->AddRef(); } + else if (eCSSUnit_FontWeight == mUnit) { + mValue.mFontWeight = aCopy.mValue.mFontWeight; + } else if (eCSSUnit_AtomIdent == mUnit) { mValue.mAtom = aCopy.mValue.mAtom; mValue.mAtom->AddRef(); @@ -259,6 +269,9 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const return mValue.mFontFamilyList->mNames == aOther.mValue.mFontFamilyList->mNames; } + else if (eCSSUnit_FontWeight == mUnit) { + return mValue.mFontWeight == aOther.mValue.mFontWeight; + } else if (eCSSUnit_AtomIdent == mUnit) { return mValue.mAtom == aOther.mValue.mAtom; } @@ -477,6 +490,13 @@ void nsCSSValue::SetFontFamilyListValue(already_AddRefed aValue) mValue.mFontFamilyList = aValue.take(); } +void nsCSSValue::SetFontWeight(FontWeight aWeight) +{ + Reset(); + mUnit = eCSSUnit_FontWeight; + mValue.mFontWeight = aWeight; +} + void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue) { // pairs should not be used for null/inherit/initial values @@ -895,6 +915,7 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const // Int: nothing extra to measure. case eCSSUnit_Integer: case eCSSUnit_Enumerated: + case eCSSUnit_FontWeight: break; // Float: nothing extra to measure. diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index 0ad50dbc0e67..d14e1dd1426b 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -11,6 +11,7 @@ #include "mozilla/Attributes.h" #include "mozilla/CORSMode.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/MemoryReporting.h" #include "mozilla/ServoTypes.h" #include "mozilla/SheetType.h" @@ -441,7 +442,10 @@ enum nsCSSUnit { eCSSUnit_Milliseconds = 3001, // (float) 1/1000 second // Flexible fraction (CSS Grid) - eCSSUnit_FlexFraction = 4000 // (float) Fraction of free space + eCSSUnit_FlexFraction = 4000, // (float) Fraction of free space + + // Font property types + eCSSUnit_FontWeight = 5000, // An encoded font-weight }; struct nsCSSValuePair; @@ -476,6 +480,7 @@ public: explicit nsCSSValue(mozilla::css::ImageValue* aValue); explicit nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue); explicit nsCSSValue(mozilla::SharedFontList* aValue); + explicit nsCSSValue(mozilla::FontWeight aWeight); nsCSSValue(const nsCSSValue& aCopy); nsCSSValue(nsCSSValue&& aOther) : mUnit(aOther.mUnit) @@ -631,6 +636,12 @@ public: return mozilla::WrapNotNull(mValue.mFontFamilyList); } + mozilla::FontWeight GetFontWeight() const + { + MOZ_ASSERT(mUnit == eCSSUnit_FontWeight, "not a font weight value"); + return mValue.mFontWeight; + } + // bodies of these are below inline nsCSSValuePair& GetPairValue(); inline const nsCSSValuePair& GetPairValue() const; @@ -708,6 +719,7 @@ public: void SetImageValue(mozilla::css::ImageValue* aImage); void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue); void SetFontFamilyListValue(already_AddRefed aFontListValue); + void SetFontWeight(mozilla::FontWeight aWeight); void SetPairValue(const nsCSSValuePair* aPair); void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue); void SetSharedListValue(nsCSSValueSharedList* aList); @@ -784,6 +796,7 @@ protected: nsCSSValuePairList_heap* MOZ_OWNING_REF mPairList; nsCSSValuePairList* mPairListDependent; mozilla::SharedFontList* MOZ_OWNING_REF mFontFamilyList; + mozilla::FontWeight mFontWeight; } mValue; }; diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index ace7d8153b54..87d31021e509 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -9,6 +9,7 @@ #include "nsComputedDOMStyle.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/Preferences.h" #include "nsError.h" @@ -1973,8 +1974,9 @@ nsComputedDOMStyle::DoGetFontWeight() const nsStyleFont* font = StyleFont(); - uint16_t weight = font->mFont.weight; - NS_ASSERTION(weight % 100 == 0, "unexpected value of font-weight"); + float weight = font->mFont.weight.ToFloat(); + MOZ_ASSERT(1.0f <= weight && weight <= 1000.0f, + "unexpected font-weight value"); val->SetNumber(weight); return val.forget(); diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java index 5255ee1868df..f6d0ce629bd0 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java @@ -21,8 +21,9 @@ public class TestRunnerActivity extends Activity { static GeckoRuntime sRuntime; - GeckoSession mSession; - GeckoView mView; + private GeckoSession mSession; + private GeckoView mView; + private boolean mKillProcessOnDestroy; private GeckoSession.NavigationDelegate mNavigationDelegate = new GeckoSession.NavigationDelegate() { @Override @@ -113,6 +114,13 @@ public class TestRunnerActivity extends Activity { geckoSettings.setArguments(new String[] { "-purgecaches" }); geckoSettings.setExtras(intent.getExtras()); sRuntime = GeckoRuntime.create(this, geckoSettings); + sRuntime.setDelegate(new GeckoRuntime.Delegate() { + @Override + public void onShutdown() { + mKillProcessOnDestroy = true; + finish(); + } + }); } mSession = createSession(); @@ -133,6 +141,10 @@ public class TestRunnerActivity extends Activity { protected void onDestroy() { mSession.close(); super.onDestroy(); + + if (mKillProcessOnDestroy) { + android.os.Process.killProcess(android.os.Process.myPid()); + } } public GeckoView getGeckoView() { diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java index fbf6cf80835f..63522a4aa9eb 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java @@ -6,24 +6,19 @@ package org.mozilla.geckoview; -import java.util.ArrayList; - import android.os.Parcel; import android.os.Parcelable; import android.content.Context; -import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; -import org.mozilla.gecko.annotation.WrapForJNI; import org.mozilla.gecko.EventDispatcher; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoThread; import org.mozilla.gecko.util.BundleEventListener; import org.mozilla.gecko.util.EventCallback; import org.mozilla.gecko.util.GeckoBundle; -import org.mozilla.gecko.util.ThreadUtils; public final class GeckoRuntime implements Parcelable { private static final String LOGTAG = "GeckoRuntime"; @@ -53,6 +48,7 @@ public final class GeckoRuntime implements Parcelable { } private GeckoRuntimeSettings mSettings; + private Delegate mDelegate; /** * Attach the runtime to the given context. @@ -69,6 +65,17 @@ public final class GeckoRuntime implements Parcelable { } } + private final BundleEventListener mEventListener = new BundleEventListener() { + @Override + public void handleMessage(final String event, final GeckoBundle message, + final EventCallback callback) { + if ("Gecko:Exited".equals(event) && mDelegate != null) { + mDelegate.onShutdown(); + EventDispatcher.getInstance().unregisterUiThreadListener(mEventListener, "Gecko:Exited"); + } + } + }; + /* package */ boolean init(final @NonNull GeckoRuntimeSettings settings) { if (DEBUG) { Log.d(LOGTAG, "init"); @@ -85,6 +92,9 @@ public final class GeckoRuntime implements Parcelable { return false; } mSettings = settings; + + // Bug 1453062 -- the EventDispatcher should really live here (or in GeckoThread) + EventDispatcher.getInstance().registerUiThreadListener(mEventListener, "Gecko:Exited"); return true; } Log.d(LOGTAG, "init failed (could not initiate GeckoThread)"); @@ -146,6 +156,32 @@ public final class GeckoRuntime implements Parcelable { GeckoThread.forceQuit(); } + public interface Delegate { + /** + * This is called when the runtime shuts down. Any GeckoSession instances that were + * opened with this instance are now considered closed. + **/ + void onShutdown(); + } + + /** + * Set a delegate for receiving callbacks relevant to to this GeckoRuntime. + * + * @param delegate an implementation of {@link GeckoRuntime.Delegate}. + */ + public void setDelegate(final Delegate delegate) { + mDelegate = delegate; + } + + /** + * Returns the current delegate, if any. + * + * @return an instance of {@link GeckoRuntime.Delegate} or null if no delegate has been set. + */ + public @Nullable Delegate getDelegate() { + return mDelegate; + } + @Override // Parcelable public int describeContents() { return 0; diff --git a/mobile/android/modules/geckoview/GeckoViewNavigation.jsm b/mobile/android/modules/geckoview/GeckoViewNavigation.jsm index bb5e4aa8b751..b1b5c3785825 100644 --- a/mobile/android/modules/geckoview/GeckoViewNavigation.jsm +++ b/mobile/android/modules/geckoview/GeckoViewNavigation.jsm @@ -9,6 +9,9 @@ var EXPORTED_SYMBOLS = ["GeckoViewNavigation"]; ChromeUtils.import("resource://gre/modules/GeckoViewModule.jsm"); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +ChromeUtils.defineModuleGetter(this, "BrowserUtils", + "resource://gre/modules/BrowserUtils.jsm"); + XPCOMUtils.defineLazyModuleGetters(this, { EventDispatcher: "resource://gre/modules/Messaging.jsm", LoadURIDelegate: "resource://gre/modules/LoadURIDelegate.jsm", @@ -252,7 +255,7 @@ class GeckoViewNavigation extends GeckoViewModule { // nsIBrowserDOMWindow. canClose() { debug("canClose"); - return false; + return true; } onEnable() { diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index d76304175fd4..b12338d7b356 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1396,6 +1396,9 @@ pref("javascript.options.asmjs", true); pref("javascript.options.wasm", true); pref("javascript.options.wasm_ionjit", true); pref("javascript.options.wasm_baselinejit", true); +#ifdef ENABLE_WASM_GC +pref("javascript.options.wasm_gc", false); +#endif pref("javascript.options.native_regexp", true); pref("javascript.options.parallel_parsing", true); #if !defined(RELEASE_OR_BETA) && !defined(ANDROID) && !defined(XP_IOS) diff --git a/modules/libpref/moz.build b/modules/libpref/moz.build index 931d334c1649..9e81d107b3ee 100644 --- a/modules/libpref/moz.build +++ b/modules/libpref/moz.build @@ -43,6 +43,9 @@ DEFINES['MOZ_WIDGET_TOOLKIT'] = CONFIG['MOZ_WIDGET_TOOLKIT'] if CONFIG['MOZ_ENABLE_WEBRENDER']: DEFINES['MOZ_ENABLE_WEBRENDER'] = True +if CONFIG['NIGHTLY_BUILD']: + DEFINES['ENABLE_WASM_GC'] = True + FINAL_TARGET_PP_FILES += [ 'greprefs.js', ] diff --git a/mozglue/linker/ElfLoader.cpp b/mozglue/linker/ElfLoader.cpp index e0829846b625..994caa87affa 100644 --- a/mozglue/linker/ElfLoader.cpp +++ b/mozglue/linker/ElfLoader.cpp @@ -16,8 +16,14 @@ #include "CustomElf.h" #include "Mappable.h" #include "Logging.h" +#include "Utils.h" #include +using namespace mozilla; + +// From Utils.h +Atomic gPageSize; + #if defined(ANDROID) #include #include @@ -51,7 +57,6 @@ dl_iterate_phdr(dl_phdr_cb callback, void *data) __attribute__((weak)); * containing this code. */ extern "C" Elf::Dyn _DYNAMIC[]; -using namespace mozilla; /** * dlfcn.h replacements functions diff --git a/mozglue/linker/Utils.h b/mozglue/linker/Utils.h index 4be99f831f8a..1b61cac4ce22 100644 --- a/mozglue/linker/Utils.h +++ b/mozglue/linker/Utils.h @@ -11,6 +11,7 @@ #include #include #include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" #include "mozilla/Scoped.h" /** @@ -102,12 +103,18 @@ struct AutoCloseFILETraits }; typedef mozilla::Scoped AutoCloseFILE; +extern mozilla::Atomic gPageSize; + /** * Page alignment helpers */ -static inline size_t PageSize() +static size_t PageSize() { - return 4096; + if (!gPageSize) { + gPageSize = sysconf(_SC_PAGESIZE); + } + + return gPageSize; } static inline uintptr_t AlignedPtr(uintptr_t ptr, size_t alignment) diff --git a/netwerk/base/ProxyAutoConfig.cpp b/netwerk/base/ProxyAutoConfig.cpp index 2c965f8e8f4d..d562f321bb45 100644 --- a/netwerk/base/ProxyAutoConfig.cpp +++ b/netwerk/base/ProxyAutoConfig.cpp @@ -307,8 +307,9 @@ public: // nsITimerCallback NS_IMETHOD Notify(nsITimer *timer) override { - if (mRequest) - mRequest->Cancel(NS_ERROR_NET_TIMEOUT); + nsCOMPtr request(mRequest); + if (request) + request->Cancel(NS_ERROR_NET_TIMEOUT); mTimer = nullptr; return NS_OK; } diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp index 7535eb60caa1..ca3a7a901f4f 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -2162,6 +2162,30 @@ bool NS_IsSameSiteForeign(nsIChannel* aChannel, nsIURI* aHostURI) bool isForeign = false; thirdPartyUtil->IsThirdPartyChannel(aChannel, uri, &isForeign); + + // if we are dealing with a cross origin request, we can return here + // because we already know the request is 'foreign'. + if (isForeign) { + return true; + } + + // for the purpose of same-site cookies we have to treat any cross-origin + // redirects as foreign. E.g. cross-site to same-site redirect is a problem + // with regards to CSRF. + + nsCOMPtr redirectPrincipal; + nsCOMPtr redirectURI; + for (nsIRedirectHistoryEntry* entry : loadInfo->RedirectChain()) { + entry->GetPrincipal(getter_AddRefs(redirectPrincipal)); + if (redirectPrincipal) { + redirectPrincipal->GetURI(getter_AddRefs(redirectURI)); + thirdPartyUtil->IsThirdPartyChannel(aChannel, redirectURI, &isForeign); + // if at any point we encounter a cross-origin redirect we can return. + if (isForeign) { + return true; + } + } + } return isForeign; } diff --git a/security/manager/ssl/StaticHPKPins.h b/security/manager/ssl/StaticHPKPins.h index 9a8458a7907b..5c204fab2fba 100644 --- a/security/manager/ssl/StaticHPKPins.h +++ b/security/manager/ssl/StaticHPKPins.h @@ -1163,4 +1163,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = { static const int32_t kUnknownId = -1; -static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1532033020972000); +static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1532119521329000); diff --git a/security/manager/ssl/nsSTSPreloadList.errors b/security/manager/ssl/nsSTSPreloadList.errors index 7bc3e69890c1..9927fd307edc 100644 --- a/security/manager/ssl/nsSTSPreloadList.errors +++ b/security/manager/ssl/nsSTSPreloadList.errors @@ -1,6 +1,7 @@ 00220022.net: could not connect to host 007-preisvergleich.de: could not connect to host 007kf.com: could not connect to host +00881919.com: could not connect to host 00wbf.com: could not connect to host 01100010011001010111001101110100.com: could not connect to host 029inno.com: could not connect to host @@ -20,7 +21,6 @@ 13826145000.com: could not connect to host 13th-dover.uk: could not connect to host 16164f.com: could not connect to host -166166.com: could not connect to host 1888zr.com: could not connect to host 1912x.com: could not connect to host 1921958389.rsc.cdn77.org: could not connect to host @@ -50,7 +50,7 @@ 4loc.us: could not connect to host 4web-hosting.com: could not connect to host 5000yz.com: could not connect to host -517vpn.cn: could not connect to host +52kb.net: could not connect to host 52kb1.com: could not connect to host 52neptune.com: could not connect to host 56877.com: could not connect to host @@ -93,7 +93,7 @@ achterhoekseveiligheidsbeurs.nl: could not connect to host ackis.duckdns.org: could not connect to host acpinformatique.fr: could not connect to host acrossgw.com: could not connect to host -activeworld.net: could not connect to host +activeclearweb.com: could not connect to host ad-disruptio.fr: could not connect to host adamcoffee.net: could not connect to host adamdixon.co.uk: could not connect to host @@ -117,6 +117,7 @@ agingstop.net: could not connect to host agoravm.tk: could not connect to host agowa.eu: could not connect to host agowa338.de: could not connect to host +agrikulturchic.com: could not connect to host agrilinks.org: could not connect to host ahelos.tk: could not connect to host ahkubiak.ovh: could not connect to host @@ -175,6 +176,7 @@ andrewdaws.info: could not connect to host andrewdaws.me: could not connect to host andrewdaws.tv: could not connect to host andrewrdaws.com: could not connect to host +andys-place.co.uk: could not connect to host anecuni-club.com: could not connect to host anecuni-rec.com: could not connect to host angrydragonproductions.com: could not connect to host @@ -219,6 +221,7 @@ artisense.de: could not connect to host artisticedgegranite.net: could not connect to host artofeyes.nl: could not connect to host ascii.moe: could not connect to host +asdyx.de: could not connect to host ashleyadum.com: could not connect to host asisee.co.il: could not connect to host asphaltfruehling.de: could not connect to host @@ -263,6 +266,7 @@ awan.tech: could not connect to host awei.pub: could not connect to host awf0.xyz: could not connect to host awxg.eu.org: could not connect to host +axel-fischer.net: could not connect to host axel-fischer.science: could not connect to host axxial.tk: could not connect to host azuxul.fr: could not connect to host @@ -271,9 +275,8 @@ b303.me: could not connect to host b9winner.com: could not connect to host babelfisch.eu: could not connect to host babystep.tv: could not connect to host -bacimg.com: could not connect to host +bad.horse: could not connect to host badbee.cc: could not connect to host -bairdzhang.com: could not connect to host balonmano.co: could not connect to host bandally.net: could not connect to host bandarifamily.com: could not connect to host @@ -332,6 +335,7 @@ bfrailwayclub.cf: could not connect to host bianinapiccanovias.com: could not connect to host bichonmaltes.com.br: could not connect to host bigerbio.com: could not connect to host +billaud.eu.org: could not connect to host billigpoker.dk: could not connect to host binam.center: could not connect to host binaryabstraction.com: could not connect to host @@ -384,6 +388,7 @@ boozinyan.com: could not connect to host bopera.co.uk: could not connect to host borchers-media.de: could not connect to host borisbesemer.com: could not connect to host +bouncourseplanner.net: could not connect to host boxdevigneron.fr: could not connect to host bpadvisors.eu: could not connect to host bqcp.net: could not connect to host @@ -486,6 +491,7 @@ charmyadesara.com: could not connect to host chatnbook.com: could not connect to host chatsworthelectrical.com: could not connect to host cheah.xyz: could not connect to host +cheesefusion.com: could not connect to host chellame.fr: could not connect to host chez-janine.de: could not connect to host chicorycom.net: could not connect to host @@ -497,7 +503,6 @@ chocolat-suisse.ch: could not connect to host chorkley.me: could not connect to host chrisebert.net: could not connect to host christianhoffmann.info: could not connect to host -christianpusch.de: could not connect to host christiansayswords.com: could not connect to host christophersole.com: could not connect to host chromaryu.net: could not connect to host @@ -518,9 +523,11 @@ clevelandokla.com: could not connect to host clic-music.com: could not connect to host clickomobile.com: could not connect to host clintonbloodworth.com: could not connect to host +closeli.cn: could not connect to host closingholding.com: could not connect to host cloudberlin.goip.de: could not connect to host cloudbleed.info: could not connect to host +cloudimproved.com: could not connect to host cloudwarez.xyz: could not connect to host clownish.co.il: could not connect to host clubmate.rocks: could not connect to host @@ -555,6 +562,7 @@ colo-tech.com: could not connect to host com-in.de: could not connect to host com.cc: could not connect to host comiq.io: could not connect to host +commania.co.kr: could not connect to host compeuphoria.com: could not connect to host complex-organization.com: could not connect to host complt.xyz: could not connect to host @@ -562,9 +570,9 @@ comprehensiveihc.com: could not connect to host conception.sk: could not connect to host conejovalleyelectrical.com: could not connect to host conkret.in: could not connect to host +conniesacademy.com: could not connect to host conrad.am: could not connect to host constructive.men: could not connect to host -consultorcr.net: could not connect to host continuation.io: could not connect to host corecdn.org: could not connect to host corinnanese.de: could not connect to host @@ -591,7 +599,6 @@ criticalaim.com: could not connect to host crl-autos.com: could not connect to host crow.tw: could not connect to host crox.co: could not connect to host -crypto-armory.com: could not connect to host cryptoisnotacrime.org: could not connect to host cryptoki.fr: could not connect to host cryptolosophy.io: could not connect to host @@ -661,6 +668,7 @@ ddmeportal.com: could not connect to host de-servers.de: could not connect to host deadmann.com: could not connect to host deborahmarinelli.eu: could not connect to host +decomplify.com: could not connect to host decorincasa.com.br: could not connect to host decormiernissanparts.com: could not connect to host decoyrouting.com: could not connect to host @@ -675,6 +683,7 @@ derive.cc: could not connect to host dermacarecomplex.com: could not connect to host dermapuur.nl: could not connect to host designsbykerrialee.co.uk: could not connect to host +desmaakvanplanten.be: could not connect to host detalhecomercio.com.br: could not connect to host detecte-fuite.ch: could not connect to host detecte.ch: could not connect to host @@ -751,6 +760,7 @@ draghive.net: could not connect to host dragonwork.me: could not connect to host drakfot.se: could not connect to host dreamaholic.club: could not connect to host +dreamhack.com: could not connect to host dreaming.solutions: could not connect to host dreizwosechs.de: could not connect to host driving-lessons.co.uk: could not connect to host @@ -796,6 +806,7 @@ einsteinathome.org: could not connect to host ejgconsultancy.co.uk: could not connect to host ekobudisantoso.net: could not connect to host ekong366.com: could not connect to host +elarvee.xyz: could not connect to host electricalcontrolpanels.co.uk: could not connect to host electricianumhlangarocks.co.za: could not connect to host electronicafacil.net: could not connect to host @@ -803,7 +814,9 @@ elektronring.com: could not connect to host elenorsmadness.org: could not connect to host eletesstilus.hu: could not connect to host elevateandprosper.com: could not connect to host +elia.cloud: could not connect to host elonbase.com: could not connect to host +eloxt.com: could not connect to host elsword.moe: could not connect to host eltransportquevolem.org: could not connect to host elytronsecurity.com: could not connect to host @@ -823,6 +836,7 @@ enpalmademallorca.info: could not connect to host enskat.de: could not connect to host enskatson-sippe.de: could not connect to host entaurus.com: could not connect to host +entrainr.com: could not connect to host envelope.co.nz: could not connect to host eolme.ml: could not connect to host er-music.com: could not connect to host @@ -840,6 +854,7 @@ esseriumani.com: could not connect to host essplusmed.org: could not connect to host etenendrinken.nu: could not connect to host ethanfaust.com: could not connect to host +ethiobaba.com: could not connect to host etzi.myds.me: could not connect to host euexia.fr: could not connect to host eung.ga: could not connect to host @@ -855,6 +870,7 @@ evrial.com: could not connect to host eworksmedia.com: could not connect to host exceptionalservices.us: could not connect to host exo.do: could not connect to host +expressemotion.net: could not connect to host exteriorservices.io: could not connect to host extratorrent.fyi: could not connect to host extratorrent.red: could not connect to host @@ -875,6 +891,7 @@ fafatiger.com: could not connect to host faithwatch.org: could not connect to host falkus.net: could not connect to host fallenangeldrinks.eu: could not connect to host +fam-stemmer.de: could not connect to host famer.me: could not connect to host fameuxhosting.co.uk: could not connect to host familie-leu.ch: could not connect to host @@ -927,6 +944,7 @@ flyingdoggy.net: could not connect to host fmovies.life: could not connect to host focalforest.com: could not connect to host fognini-depablo.eu: could not connect to host +foodev.de: could not connect to host forcamp.ga: could not connect to host foreverssl.com: could not connect to host forsyththeatre.com: could not connect to host @@ -954,12 +972,12 @@ freshcode.nl: could not connect to host frickelboxx.de: could not connect to host frickenate.com: could not connect to host friedhelm-wolf.de: could not connect to host -friller.com.au: could not connect to host frodriguez.xyz: could not connect to host frolov.net: could not connect to host fromix.de: could not connect to host fromlemaytoz.com: could not connect to host frosty-gaming.xyz: could not connect to host +frowin-stemmer.de: could not connect to host frp-roleplay.de: could not connect to host fsfi.is: could not connect to host ftgho.com: could not connect to host @@ -985,6 +1003,7 @@ g1jeu.com: could not connect to host gabriele-kluge.de: could not connect to host gafachi.com: could not connect to host gagor.pl: could not connect to host +gaiserik.com: could not connect to host galgoafegao.com.br: could not connect to host galgoingles.com.br: could not connect to host gam3rs.de: could not connect to host @@ -996,6 +1015,7 @@ gamhealth.net: could not connect to host garage-door.pro: could not connect to host gasbarkenora.com: could not connect to host gasnews.net: could not connect to host +gatapro.net: could not connect to host gautham.pro: could not connect to host gay-jays.com: could not connect to host gaygeeks.de: could not connect to host @@ -1026,6 +1046,7 @@ getgeek.io: could not connect to host getgeek.no: could not connect to host getgeek.nu: could not connect to host getgeek.pl: could not connect to host +geto.ml: could not connect to host getyourphix.tk: could not connect to host gevaulug.fr: could not connect to host gfoss.gr: could not connect to host @@ -1070,6 +1091,7 @@ greuel.online: could not connect to host gritte.net: could not connect to host grossmisconduct.news: could not connect to host growingmetrics.com: could not connect to host +grunwaldzki.center: could not connect to host grusig-geil.ch: could not connect to host gsmkungen.com: could not connect to host guelphhydropool.com: could not connect to host @@ -1078,9 +1100,7 @@ guildgearscore.cf: could not connect to host guinea-pig.co: could not connect to host gunhunter.com: could not connect to host gus.moe: could not connect to host -guts.me: could not connect to host gvchannel.xyz: could not connect to host -gwrtech.com: could not connect to host gxgx.org: could not connect to host gzitech.net: could not connect to host gzpblog.com: could not connect to host @@ -1098,13 +1118,13 @@ half-logic.eu.org: could not connect to host halta.info: could not connect to host hamking.tk: could not connect to host hamu.blue: could not connect to host +hang333.pw: could not connect to host hanksservice.com: could not connect to host hansen.hn: could not connect to host happytiger.eu: could not connect to host hapsfordmill.co.uk: could not connect to host hapvm.com: could not connect to host hardergayporn.com: could not connect to host -harringtonca.com: could not connect to host harrypottereditor.net: could not connect to host has-no-email-set.de: could not connect to host hasabig.wang: could not connect to host @@ -1165,6 +1185,7 @@ homesfordinner.ca: could not connect to host homewatt.co.uk: could not connect to host homoglyph.net: could not connect to host honeytracks.com: could not connect to host +honkhonk.net: could not connect to host hoodoo.io: could not connect to host hoodoo.tech: could not connect to host hopglass.eu: could not connect to host @@ -1187,6 +1208,7 @@ hudingyuan.cn: could not connect to host huiser.nl: could not connect to host hukaloh.com: could not connect to host hukkatavara.com: could not connect to host +hundter.com: could not connect to host hunger.im: could not connect to host huongquynh.com: could not connect to host huwjones.me: could not connect to host @@ -1201,6 +1223,7 @@ i4m1k0su.com: could not connect to host i95.me: could not connect to host iadttaveras.com: could not connect to host iamsoareyou.se: could not connect to host +iba.community: could not connect to host ibox.ovh: could not connect to host ibron.co: could not connect to host ibsafrica.co.za: could not connect to host @@ -1223,6 +1246,7 @@ ifcfg.me: could not connect to host ifxnet.com: could not connect to host igamingforums.com: could not connect to host ihatethissh.it: could not connect to host +ihc.im: could not connect to host iideaz.org: could not connect to host ikenmeyer.com: could not connect to host ikenmeyer.eu: could not connect to host @@ -1240,9 +1264,11 @@ imlinan.info: could not connect to host imlinan.net: could not connect to host immersionwealth.com: could not connect to host immobilien-wallat.de: could not connect to host +imoe.ac.cn: could not connect to host imoner.ga: could not connect to host imperdintechnologies.com: could not connect to host impulse-clan.de: could not connect to host +imydl.tech: could not connect to host increasetestosteronelevels.org: could not connect to host industreiler.com: could not connect to host industreiler.com.br: could not connect to host @@ -1273,6 +1299,8 @@ invenio.software: could not connect to host inventum.cloud: could not connect to host investingdiary.cn: could not connect to host investingtrader.net: could not connect to host +investorloanshub.com: could not connect to host +invitescene.com: could not connect to host invkao.com: could not connect to host iodu.re: could not connect to host ionc.ca: could not connect to host @@ -1296,6 +1324,7 @@ itpro-mg.de: could not connect to host its-schindler.de: could not connect to host its-v.de: could not connect to host itsatrap.nl: could not connect to host +itsaw.de: could not connect to host ivanilla.org: could not connect to host ivanpolchenko.com: could not connect to host ivfmeds.com: could not connect to host @@ -1304,7 +1333,6 @@ iwex.swiss: could not connect to host iwos.io: could not connect to host j0ng.xyz: could not connect to host jaaxypro.com: could not connect to host -jaccblog.com: could not connect to host jackyyf.com: could not connect to host jaimechanaga.com: could not connect to host jaion.ml: could not connect to host @@ -1334,7 +1362,6 @@ jerrypau.ca: could not connect to host jhburton.co.uk: could not connect to host jhermsmeier.de: could not connect to host jiaqiang.vip: could not connect to host -jichi.io: could not connect to host jmb.lc: could not connect to host jobmedic.com: could not connect to host joecod.es: could not connect to host @@ -1344,7 +1371,6 @@ johntomasowa.com: could not connect to host jonathanmassacand.ch: could not connect to host jonathansanchez.pro: could not connect to host jonfor.net: could not connect to host -jooto.com: could not connect to host jpod.cc: could not connect to host jsjyhzy.cc: could not connect to host juliaoantiguidades.com.br: could not connect to host @@ -1368,11 +1394,9 @@ kaloix.de: could not connect to host kamalame.co: could not connect to host kamitech.ch: could not connect to host kancolle.me: could not connect to host -kandalife.com: could not connect to host kanganer.com: could not connect to host kangzaber.com: could not connect to host kapo.info: could not connect to host -kapseli.net: could not connect to host karuneshjohri.com: could not connect to host kat.al: could not connect to host kati0.com: could not connect to host @@ -1381,6 +1405,7 @@ kawaiiku.de: could not connect to host kaydan.io: could not connect to host kayipmurekkep.com: could not connect to host kearney.io: could not connect to host +keithws.net: could not connect to host kellyandantony.com: could not connect to host kelm.me: could not connect to host kennynet.co.uk: could not connect to host @@ -1398,7 +1423,6 @@ kidbacker.com: could not connect to host kieranweightman.me: could not connect to host kievradio.com: could not connect to host kikuzuki.org: could not connect to host -killerrobots.com: could not connect to host kinderjugendfreizeitverein.de: could not connect to host kinepolis-studio.ga: could not connect to host kineto.space: could not connect to host @@ -1431,14 +1455,15 @@ korni22.org: could not connect to host kotitesti.fi: could not connect to host kotorimusic.ga: could not connect to host kottur.is: could not connect to host -kouten-jp.com: could not connect to host kozmik.co: could not connect to host kpvpn.com: could not connect to host krampus-fischamend.at: could not connect to host kriegskindernothilfe.de: could not connect to host +kriptosec.com: could not connect to host ktube.yt: could not connect to host kubusadvocaten.nl: could not connect to host kuko-crews.org: could not connect to host +kuroinu.jp: could not connect to host kuwago.io: could not connect to host kwikmed.eu: could not connect to host kwipi.com: could not connect to host @@ -1458,14 +1483,12 @@ lacasseroy.com: could not connect to host ladylikeit.com: could not connect to host laforetenchantee.ch: could not connect to host lafr4nc3.xyz: could not connect to host -lakehavasucityhomebuyerscredit.com: could not connect to host lakehavasuhomebuyercredit.com: could not connect to host lakehavasuhouserentals.com: could not connect to host landell.ml: could not connect to host langendorf-ernaehrung-training.de: could not connect to host lannainnovation.com: could not connect to host lanonfire.com: could not connect to host -lantian.pub: could not connect to host laozhu.me: could not connect to host larondinedisinfestazione.com: could not connect to host latamarissiere.eu: could not connect to host @@ -1493,7 +1516,9 @@ leelou.wedding: could not connect to host leerkotte.eu: could not connect to host legal.farm: could not connect to host legaltip.eu: could not connect to host +legoutdesplantes.be: could not connect to host leonardcamacho.me: could not connect to host +leonhooijer.nl: could not connect to host lerlivros.online: could not connect to host lescomptoirsdepierrot.com: could not connect to host lesdouceursdeliyana.com: could not connect to host @@ -1510,10 +1535,8 @@ lhsj68.com: could not connect to host lhsj78.com: could not connect to host liaozheqi.cn: could not connect to host libertas-tech.com: could not connect to host -librebox.de: could not connect to host libscode.com: could not connect to host liceserv.com: could not connect to host -lidong.me: could not connect to host lied8.eu: could not connect to host lifeinsurances.pro: could not connect to host lifeinsurances24.com: could not connect to host @@ -1537,7 +1560,9 @@ litcomphonors.com: could not connect to host littlelundgrenladies.com: could not connect to host liukang.tech: could not connect to host llvm.us: could not connect to host +lmddgtfy.net: could not connect to host lmrcouncil.gov: could not connect to host +lmsptfy.com: could not connect to host loanstreet.be: could not connect to host lobosdomain.ddns.net: could not connect to host lobosdomain.no-ip.info: could not connect to host @@ -1565,6 +1590,7 @@ lucasgaland.com: could not connect to host lucassoler.com.ar: could not connect to host lucidlogs.com: could not connect to host luganskservers.net: could not connect to host +lui.pink: could not connect to host luk.photo: could not connect to host lukasunger.cz: could not connect to host lukasunger.net: could not connect to host @@ -1580,7 +1606,6 @@ maartenterpstra.xyz: could not connect to host madeintucson.org: could not connect to host mader.jp: could not connect to host madnetwork.org: could not connect to host -magicball.co: could not connect to host magnacumlaude.co: could not connect to host maik-mahlow.de: could not connect to host mail4geek.com: could not connect to host @@ -1608,6 +1633,7 @@ marketingdesignu.cz: could not connect to host markllego.com: could not connect to host marko-fenster24.de: could not connect to host markrego.com: could not connect to host +marmotte.love: could not connect to host martin-mattel.com: could not connect to host martins.im: could not connect to host marxist.party: could not connect to host @@ -1723,7 +1749,6 @@ moeyi.xyz: could not connect to host mongla168.net: could not connect to host mongla88.net: could not connect to host monitori.ng: could not connect to host -montas.io: could not connect to host mooselook.de: could not connect to host moparcraft.com: could not connect to host moparcraft.org: could not connect to host @@ -1732,6 +1757,7 @@ morfitronik.pl: could not connect to host morganino.eu: could not connect to host morz.org: could not connect to host mosaique-lachenaie.fr: could not connect to host +mosfet.cz: could not connect to host moskva.guide: could not connect to host motherboard.services: could not connect to host motomorgen.com: could not connect to host @@ -1754,7 +1780,6 @@ msz-fotografie.de: could not connect to host mtd.ovh: could not connect to host mtirc.co: could not connect to host mtn.cc: could not connect to host -muchohentai.com: could not connect to host muga.space: could not connect to host muj-svet.cz: could not connect to host multivpn.cn.com: could not connect to host @@ -1833,6 +1858,7 @@ next-taxi.ru: could not connect to host nexusbyte.de: could not connect to host nexusconnectinternational.eu: could not connect to host nexuscorporation.in: could not connect to host +nfluence.org: could not connect to host ngiemboon.net: could not connect to host nginxyii.tk: could not connect to host ngocuong.net: could not connect to host @@ -1842,7 +1868,7 @@ niklas.pw: could not connect to host nikobradshaw.com: could not connect to host nikolasbradshaw.com: could not connect to host nimidam.com: could not connect to host -ninreiei.jp: could not connect to host +ninofink.com: could not connect to host niouininon.eu: could not connect to host nirada.info: could not connect to host nishikino-maki.com: could not connect to host @@ -1864,6 +1890,7 @@ notevencode.com: could not connect to host novascan.net: could not connect to host novfishing.ru: could not connect to host novgorod-avia.ru: could not connect to host +nowremindme.com: could not connect to host nsa.wtf: could not connect to host nsbfalconacademy.org: could not connect to host nsdev.cn: could not connect to host @@ -1909,9 +1936,7 @@ openclub24.ru: could not connect to host openconnect.com.au: could not connect to host opinion8td.com: could not connect to host orangekey.tk: could not connect to host -oranges.tokyo: could not connect to host oricejoc.com: could not connect to host -orro.ro: could not connect to host oscarmashauri.com: could not connect to host oscillation-services.fr: could not connect to host oscsdp.cz: could not connect to host @@ -1945,7 +1970,6 @@ patrickneuro.de: could not connect to host paulshir.com: could not connect to host paulshir.is: could not connect to host paveljanda.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 116" data: no] -pavelstriz.cz: could not connect to host pay.ubuntu.com: could not connect to host paymon.tj: could not connect to host paypod.org: could not connect to host @@ -1955,6 +1979,7 @@ pbytes.com: could not connect to host pcvirusclear.com: could not connect to host pear2pear.de: could not connect to host peerless.ae: could not connect to host +peervpn.net: could not connect to host peirong.me: could not connect to host pemagrid.org: could not connect to host pengisatelier.net: could not connect to host @@ -1968,6 +1993,7 @@ pfolta.net: could not connect to host pgmann.cf: could not connect to host pgmsource.com: could not connect to host pharmaboard.org: could not connect to host +phcimages.com: could not connect to host phdwuda.com: could not connect to host philippa.cool: could not connect to host phillippi.me: could not connect to host @@ -1999,7 +2025,6 @@ playsource.co: could not connect to host please-deny.me: could not connect to host pleaseuseansnisupportedbrowser.ml: could not connect to host plussizereviews.com: could not connect to host -pmbremer.de: could not connect to host pmessage.ch: could not connect to host pmklaassen.com: could not connect to host pogs.us: could not connect to host @@ -2040,7 +2065,6 @@ prism-communication.com: could not connect to host privacyforjournalists.org.au: could not connect to host privacymanatee.com: could not connect to host privcloud.org: could not connect to host -priverify.com: could not connect to host privilegevisa.fr: could not connect to host proactive.run: could not connect to host professional.cleaning: could not connect to host @@ -2098,7 +2122,6 @@ quietus.gq: could not connect to host qybot.cc: could not connect to host r-cut.fr: could not connect to host r0t.co: could not connect to host -r40.us: could not connect to host racasdecachorro.org: could not connect to host rackblue.com: could not connect to host radioafibra.com.br: could not connect to host @@ -2182,6 +2205,7 @@ roolevoi.ru: could not connect to host room2d.com: could not connect to host rootbsd.at: could not connect to host rospa100.com: could not connect to host +rosslug.org.uk: could not connect to host rostov-avia.ru: could not connect to host rotterdamjazz.info: could not connect to host royzez.com: could not connect to host @@ -2190,6 +2214,7 @@ rozalynne-dawn.ga: could not connect to host rpasafrica.com: could not connect to host rro.rs: could not connect to host rs-devdemo.host: could not connect to host +rsldb.com: could not connect to host rtc.fun: could not connect to host ruanmi.de: could not connect to host rubbix.net: could not connect to host @@ -2200,6 +2225,7 @@ rukhaiyar.com: could not connect to host run-forrest.run: could not connect to host runcarina.com: could not connect to host rundumcolumn.xyz: could not connect to host +rushball.net: could not connect to host rustbyexample.com: could not connect to host ruurdboomsma.nl: could not connect to host s0923.com: could not connect to host @@ -2258,6 +2284,7 @@ seankilgarriff.com: could not connect to host searx.pw: could not connect to host sebi.cf: could not connect to host secitem.de: could not connect to host +secpatrol.de: could not connect to host sectest.ml: could not connect to host secure-automotive-cloud.com: could not connect to host secure-automotive-cloud.org: could not connect to host @@ -2280,6 +2307,7 @@ sellmoretires.com: could not connect to host sementes.gratis: could not connect to host seomen.biz: could not connect to host seoscribe.net: could not connect to host +seproco.com: could not connect to host servecrypt.com: could not connect to host servecrypt.ru: could not connect to host server.pk: could not connect to host @@ -2323,6 +2351,7 @@ signosquecombinam.com.br: could not connect to host sijmenschoon.nl: could not connect to host sikatehtaat.fi: could not connect to host siku.pro: could not connect to host +siloportem.net: could not connect to host silqueskineyeserum.com: could not connect to host silverback.is: could not connect to host silvistefi.com: could not connect to host @@ -2335,7 +2364,6 @@ sims4hub.ga: could not connect to host sinfulforums.net: could not connect to host siqi.wang: could not connect to host sitemaxiphilippe.ch: could not connect to host -sivyerge.com: could not connect to host skarox.ru: could not connect to host sketchmyroom.com: could not connect to host skoda-im-dialog.de: could not connect to host @@ -2377,6 +2405,7 @@ sorenam.com: could not connect to host sortaweird.net: could not connect to host sosteam.jp: could not connect to host sotiran.com: could not connect to host +soulema.com: could not connect to host sourcecode.love: could not connect to host sowncloud.de: could not connect to host sp.rw: could not connect to host @@ -2386,13 +2415,14 @@ sparkbase.cn: could not connect to host sparkwood.org: could not connect to host spartantheatre.org: could not connect to host spawn.cz: could not connect to host +sperohub.lt: could not connect to host sphinx.network: could not connect to host spicydog.tk: could not connect to host spicywombat.com: could not connect to host spitfireuav.com: could not connect to host split.is: could not connect to host springsoffthegrid.com: could not connect to host -sql-und-xml.de: could not connect to host +spron.in: could not connect to host squids.space: could not connect to host squirtlesbians.net: could not connect to host sqzryang.com: could not connect to host @@ -2530,17 +2560,18 @@ thebuffalotavern.com: could not connect to host thedailyupvote.com: could not connect to host theeducationchannel.info: could not connect to host theepankar.com: could not connect to host +theevergreen.me: could not connect to host thefox.co: could not connect to host thefrk.xyz: could not connect to host thelinuxspace.com: could not connect to host thelostyankee.com: could not connect to host thenrdhrd.nl: could not connect to host +theosophie-afrique.org: could not connect to host theoverfly.co: could not connect to host theposhfudgecompany.co.uk: could not connect to host theprincegame.com: could not connect to host theprivacysolution.com: could not connect to host thequillmagazine.org: could not connect to host -therevenge.me: could not connect to host thermique.ch: could not connect to host thesehighsandlows.com: could not connect to host thesled.net: could not connect to host @@ -2583,6 +2614,7 @@ topdetoxcleanse.com: could not connect to host topnotchendings.com: could not connect to host tor2web.org: could not connect to host toretfaction.net: could not connect to host +torproject.ovh: could not connect to host torstensenf.de: could not connect to host totallynotaserver.com: could not connect to host totch.de: could not connect to host @@ -2632,6 +2664,7 @@ tutoragency.org: could not connect to host tutorio.ga: could not connect to host tuvangoicuoc.com: could not connect to host tuxhound.org: could not connect to host +twaka.com: could not connect to host twinkieman.com: could not connect to host twinkseason.com: could not connect to host twiri.net: could not connect to host @@ -2640,12 +2673,10 @@ twitter.ax: could not connect to host twotube.ie: could not connect to host twuni.org: could not connect to host tykoon.com: could not connect to host -tyler.rs: could not connect to host tylerharcourt.ca: could not connect to host tylerharcourt.com: could not connect to host tylerharcourt.net: could not connect to host tylerharcourt.org: could not connect to host -tyleromeara.com: could not connect to host tysye.ca: could not connect to host tzwe.com: could not connect to host ubalert.com: could not connect to host @@ -2675,6 +2706,7 @@ uwimonacs.org.jm: could not connect to host uygindir.ml: could not connect to host vaaddress.co: could not connect to host vacationfund.co: could not connect to host +vadennissanofhinesvilleparts.com: could not connect to host vadik.me: could not connect to host valecnatechnika.cz: could not connect to host valenhub.com: could not connect to host @@ -2706,7 +2738,6 @@ vgatest.nl: could not connect to host vicenage.com: could not connect to host viciousviscosity.xyz: could not connect to host videorullen.se: could not connect to host -viepixel.at: could not connect to host vikasbabyworld.de: could not connect to host viladochurrasco.com.br: could not connect to host villainsclothing.com.au: could not connect to host @@ -2716,7 +2747,6 @@ vinesauce.info: could not connect to host vinetalk.net: could not connect to host vipnettikasinoklubi.com: could not connect to host visiongamestudios.com: could not connect to host -visionless.me: could not connect to host visionthroughknowledge.com: could not connect to host visiontree-beta.eu: could not connect to host visiontree.eu: could not connect to host @@ -2780,6 +2810,7 @@ webtar.info: could not connect to host webtech.com.br: could not connect to host webthings.com.br: could not connect to host webtobesocial.de: could not connect to host +wecanvisit.com: could not connect to host week.report: could not connect to host weideheuvel.org: could not connect to host weiler.xyz: could not connect to host @@ -2839,6 +2870,7 @@ wp-fastsearch.de: could not connect to host wp-stack.pro: could not connect to host wp6.pw: could not connect to host wprevs.com: could not connect to host +wrara.org: could not connect to host wriedts.de: could not connect to host wsb-immo.at: could not connect to host wsdcap.com: could not connect to host @@ -2889,12 +2921,14 @@ xn--ykrp42k.com: could not connect to host xombra.com: could not connect to host xpwn.cz: could not connect to host xtzone.be: could not connect to host +xujan.com: could not connect to host xuntaosms.com: could not connect to host xwaretech.info: could not connect to host y3451.com: could not connect to host yabrt.cn: could not connect to host yafuoku.ru: could not connect to host yahoo.ax: could not connect to host +yanovich.net: could not connect to host yarchives.jp: could not connect to host yaucy.win: could not connect to host yawen.tw: could not connect to host @@ -2934,7 +2968,6 @@ z0rro.net: could not connect to host zachbolinger.com: could not connect to host zaem.tv: could not connect to host zalan.do: could not connect to host -zalohovaniburian.cz: could not connect to host zaoext.com: could not connect to host zbchen.com: could not connect to host zby.io: could not connect to host @@ -2945,6 +2978,7 @@ zero-sum.xyz: could not connect to host zero-x-baadf00d.com: could not connect to host zerocool.io: could not connect to host zerosource.net: could not connect to host +zewtie.com: could not connect to host zhangfangzhou.com: could not connect to host zhangsir.net: could not connect to host zhaochen.xyz: could not connect to host @@ -2958,7 +2992,6 @@ zobraz.cz: could not connect to host zohar.shop: could not connect to host zokster.net: could not connect to host zoological-gardens.eu: could not connect to host -zoomseoservices.com: could not connect to host zudomc.me: could not connect to host zuehlcke.de: could not connect to host zukix.com: could not connect to host @@ -2974,7 +3007,7 @@ zzw.ca: could not connect to host 007sascha.de: did not receive HSTS header 016298.com: did not receive HSTS header 020wifi.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 116" data: no] -0222aa.com: could not connect to host +0222aa.com: did not receive HSTS header 023838.com: did not receive HSTS header 02dl.net: did not receive HSTS header 040fit.nl: did not receive HSTS header @@ -3025,7 +3058,7 @@ zzw.ca: could not connect to host 16packets.com: could not connect to host 173vpn.cn: could not connect to host 173vpns.com: did not receive HSTS header -173vpnv.com: did not receive HSTS header +173vpnv.com: could not connect to host 188betwarriors.co.uk: could not connect to host 188trafalgar.ca: did not receive HSTS header 189dv.com: did not receive HSTS header @@ -3061,7 +3094,7 @@ zzw.ca: could not connect to host 2intermediate.co.uk: did not receive HSTS header 2or3.tk: could not connect to host 2smart4food.com: did not receive HSTS header -2ss.jp: could not connect to host +2ss.jp: did not receive HSTS header 300651.ru: did not receive HSTS header 300mbmovie24.com: could not connect to host 300mbmovies4u.cc: could not connect to host @@ -3121,7 +3154,7 @@ zzw.ca: could not connect to host 60ych.net: did not receive HSTS header 6120.eu: did not receive HSTS header 64616e.xyz: could not connect to host -660011.com: max-age too low: 0 +660011.com: could not connect to host 69square.com: could not connect to host 721av.com: max-age too low: 2592000 7777av.co: could not connect to host @@ -3164,7 +3197,7 @@ a9c.co: could not connect to host aa7733.com: could not connect to host aaeblog.com: did not receive HSTS header aaeblog.net: did not receive HSTS header -aaeblog.org: could not connect to host +aaeblog.org: did not receive HSTS header aanbieders.ga: did not receive HSTS header aaoo.net: could not connect to host aapp.space: could not connect to host @@ -3252,6 +3285,7 @@ adoal.net: did not receive HSTS header adoge.me: could not connect to host adonairelogios.com.br: could not connect to host adopteunsiteflash.com: could not connect to host +adprospb.com: did not receive HSTS header adquisitio.de: could not connect to host adquisitio.in: could not connect to host adriancohea.ninja: did not receive HSTS header @@ -3360,7 +3394,6 @@ alexperry.io: could not connect to host alexyang.me: did not receive HSTS header alfa24.pro: could not connect to host alfredxing.com: did not receive HSTS header -alicestudio.it: did not receive HSTS header alistairpialek.com: max-age too low: 86400 alittlebitcheeky.com: did not receive HSTS header aljmz.com: could not connect to host @@ -3376,7 +3409,6 @@ allgrass.es: did not receive HSTS header allgrass.net: did not receive HSTS header alliance-compacts.com: did not receive HSTS header allinnote.com: could not connect to host -allkindzabeats.com: did not receive HSTS header allmbw.com: could not connect to host allmystery.de: did not receive HSTS header allo-symo.fr: did not receive HSTS header @@ -3404,7 +3436,6 @@ altamarea.se: could not connect to host alteqnia.com: could not connect to host altfire.ca: could not connect to host altmv.com: max-age too low: 7776000 -altoneum.com: could not connect to host aluminium-scaffolding.co.uk: could not connect to host alunjam.es: did not receive HSTS header alusta.co: could not connect to host @@ -3420,6 +3451,7 @@ amerhd.com: could not connect to host american-truck-simulator.de: could not connect to host american-truck-simulator.net: could not connect to host americanbio.com: did not receive HSTS header +americanoutlawjeepparts.com: did not receive HSTS header americansforcommunitydevelopment.org: did not receive HSTS header americansportsinstitute.org: did not receive HSTS header americanworkwear.nl: did not receive HSTS header @@ -3458,6 +3490,7 @@ andrerose.ca: did not receive HSTS header andrew.fi: did not receive HSTS header andrew.london: did not receive HSTS header andrewbroekman.com: did not receive HSTS header +andrewhowden.com: did not receive HSTS header andrewmichaud.beer: could not connect to host andrewregan.me: could not connect to host andrewvoce.com: did not receive HSTS header @@ -3465,7 +3498,7 @@ andrewyg.net: could not connect to host andreypopp.com: could not connect to host androidprosmart.com: could not connect to host androled.fr: max-age too low: 5184000 -andronika.net: did not receive HSTS header +andronika.net: could not connect to host androoz.se: could not connect to host andyclark.io: could not connect to host andycraftz.eu: did not receive HSTS header @@ -3627,7 +3660,7 @@ arvamus.eu: could not connect to host arzaroth.com: did not receive HSTS header as.se: could not connect to host as9178.net: could not connect to host -asadzulfahri.com: did not receive HSTS header +asadzulfahri.com: could not connect to host asahikoji.net: could not connect to host asasuou.pw: could not connect to host asc16.com: could not connect to host @@ -3769,6 +3802,7 @@ babyliss-pro.net: did not receive HSTS header babymasaze.cz: did not receive HSTS header babysaying.me: could not connect to host bacchanallia.com: could not connect to host +bacimg.com: did not receive HSTS header back-bone.nl: did not receive HSTS header backenmachtgluecklich.de: max-age too low: 2592000 backgroundchecks.online: did not receive HSTS header @@ -3833,7 +3867,6 @@ baud.ninja: could not connect to host baudairenergyservices.com: did not receive HSTS header baum.ga: could not connect to host baumstark.ca: could not connect to host -baychimo.com: did not receive HSTS header bayinstruments.com: could not connect to host baysse.eu: could not connect to host bazarstupava.sk: could not connect to host @@ -3999,7 +4032,6 @@ birgitandmerlin.com: did not receive HSTS header birkman.com: could not connect to host bismarck.moe: did not receive HSTS header bisterfeldt.com: could not connect to host -bistrocean.com: did not receive HSTS header bitbit.org: did not receive HSTS header bitbr.net: did not receive HSTS header bitcantor.com: did not receive HSTS header @@ -4117,6 +4149,7 @@ bohan.life: could not connect to host boiadeirodeberna.com: could not connect to host bokeyy.com: could not connect to host boltdata.io: could not connect to host +boltn.uk: did not receive HSTS header bolwerk.com.br: did not receive HSTS header bonapp.restaurant: could not connect to host boneko.de: could not connect to host @@ -4326,6 +4359,7 @@ c2lab.net: did not receive HSTS header c3-compose.com: could not connect to host c3b.info: could not connect to host c3ie.com: did not receive HSTS header +c4.hk: did not receive HSTS header cabsites.com: could not connect to host cabusar.fr: did not receive HSTS header caconnect.org: could not connect to host @@ -4389,6 +4423,7 @@ carlo.mx: did not receive HSTS header carlolly.co.uk: could not connect to host carlosalves.info: could not connect to host carlsbouncycastlesandhottubs.co.uk: did not receive HSTS header +carlscatering.com: did not receive HSTS header carpliyz.com: did not receive HSTS header carroarmato0.be: did not receive HSTS header carsforbackpackers.com: could not connect to host @@ -4494,6 +4529,7 @@ chaska.co.za: did not receive HSTS header chat-porc.eu: did not receive HSTS header chatbot.me: did not receive HSTS header chateauconstellation.ch: did not receive HSTS header +chatint.com: did not receive HSTS header chatup.cf: could not connect to host chaulootz.com: did not receive HSTS header chcemvediet.sk: max-age too low: 1555200 @@ -4747,6 +4783,7 @@ consciousbrands.net.au: could not connect to host consejosdehogar.com: did not receive HSTS header console.python.org: did not receive HSTS header console.support: did not receive HSTS header +consultorcr.net: did not receive HSTS header consumer.gov: did not receive HSTS header consumidor.gov: did not receive HSTS header contactbig.com: did not receive HSTS header @@ -4917,7 +4954,7 @@ cuvva.insure: did not receive HSTS header cvjm-memmingen.de: did not receive HSTS header cvtparking.co.uk: did not receive HSTS header cwage.com: could not connect to host -cwrcoding.com: did not receive HSTS header +cwrcoding.com: could not connect to host cyanogenmod.xxx: could not connect to host cyber-perikarp.eu: could not connect to host cybercecurity.com: did not receive HSTS header @@ -5035,7 +5072,7 @@ dccraft.net: could not connect to host dctxf.com: did not receive HSTS header dcuofriends.net: could not connect to host dcurt.is: did not receive HSTS header -dcw.io: did not receive HSTS header +dcw.io: could not connect to host ddatsh.com: did not receive HSTS header ddocu.me: did not receive HSTS header deadsoul.net: max-age too low: 0 @@ -5133,11 +5170,12 @@ devopps.me: did not receive HSTS header devopsconnected.com: could not connect to host devtub.com: did not receive HSTS header devuan.org: did not receive HSTS header +devyn.ca: did not receive HSTS header dewebwerf.nl: did not receive HSTS header dewin.io: could not connect to host dfrance.com.br: did not receive HSTS header dfviana.com.br: max-age too low: 2592000 -dhaynes.xyz: max-age too low: 2592000 +dhaynes.xyz: did not receive HSTS header dhpcs.com: did not receive HSTS header dhpiggott.net: did not receive HSTS header diablotine.rocks: could not connect to host @@ -5225,7 +5263,6 @@ dmcibulldog.com: did not receive HSTS header dmdre.com: did not receive HSTS header dmix.ca: could not connect to host dmtry.me: did not receive HSTS header -dmwall.cn: did not receive HSTS header dmz.ninja: could not connect to host dnsbird.net: could not connect to host dnscrypt.org: max-age too low: 0 @@ -5290,7 +5327,6 @@ dotbrick.co.th: did not receive HSTS header dotspaperie.com: could not connect to host doublethink.online: could not connect to host doubleyummy.uk: did not receive HSTS header -douglasstafford.com: did not receive HSTS header dovecotadmin.org: could not connect to host doveholesband.co.uk: did not receive HSTS header dovetailnow.com: could not connect to host @@ -5369,10 +5405,10 @@ dullsir.com: could not connect to host dunashoes.com: could not connect to host dune.io: could not connect to host dunea.nl: did not receive HSTS header +dung-massage.fr: did not receive HSTS header duole30.com: could not connect to host duongpho.com: did not receive HSTS header duskopy.top: could not connect to host -dutchessuganda.com: did not receive HSTS header dutchrank.com: did not receive HSTS header dutyfreeonboard.com: did not receive HSTS header duuu.ch: could not connect to host @@ -5529,7 +5565,6 @@ elenoon.ir: did not receive HSTS header elgacien.de: could not connect to host elglobo.com.mx: max-age too low: 86400 elguillatun.cl: did not receive HSTS header -elhall.ru: did not receive HSTS header elimdengelen.com: did not receive HSTS header elitecovering.fr: did not receive HSTS header elitefishtank.com: could not connect to host @@ -5618,6 +5653,7 @@ eqim.me: could not connect to host equate.net.au: did not receive HSTS header equatetechnologies.com.au: did not receive HSTS header equilibre-yoga-jennifer-will.com: could not connect to host +equippers.de: did not receive HSTS header equitee.co: did not receive HSTS header equityflows.com: did not receive HSTS header erawanarifnugroho.com: did not receive HSTS header @@ -5743,6 +5779,7 @@ expowerhps.com: did not receive HSTS header expressfinance.co.za: did not receive HSTS header extramoney.cash: did not receive HSTS header extrathemeshowcase.net: could not connect to host +extratorrent.cool: did not receive HSTS header extratorrentlive.xyz: could not connect to host extratorrents.tech: could not connect to host extreemhost.nl: did not receive HSTS header @@ -5833,6 +5870,7 @@ fbox.li: could not connect to host fdj.im: could not connect to host fdt.name: did not receive HSTS header feard.space: could not connect to host +featuredmen.com: max-age too low: 0 fedemo.top: did not receive HSTS header federalregister.gov: did not receive HSTS header fedo.moe: could not connect to host @@ -5897,7 +5935,6 @@ finpt.com: did not receive HSTS header finsterlebnis.de: did not receive HSTS header fintechnics.com: did not receive HSTS header fiodental.com.br: did not receive HSTS header -fioulmarket.fr: did not receive HSTS header firebaseio-demo.com: could not connect to host firebird.io: could not connect to host firefall.rocks: could not connect to host @@ -6056,7 +6093,6 @@ frasesaniversarios.com.br: did not receive HSTS header frasesdeamizade.pt: could not connect to host frasys.io: did not receive HSTS header fraudempire.com: could not connect to host -fredriksslekt.se: did not receive HSTS header freeasinlliure.org: did not receive HSTS header freeflow.tv: could not connect to host freekdevries.nl: did not receive HSTS header @@ -6284,7 +6320,6 @@ ghid-pitesti.ro: did not receive HSTS header ghkim.net: could not connect to host ghostblog.info: did not receive HSTS header giakki.eu: could not connect to host -gianlucapartengo.photography: did not receive HSTS header giant-powerfit.co.uk: did not receive HSTS header gibraltar-firma.com: did not receive HSTS header gidea.nu: could not connect to host @@ -6642,9 +6677,7 @@ heathmanners.com: could not connect to host heavystresser.com: could not connect to host hebaus.com: could not connect to host heidilein.info: did not receive HSTS header -heikorichter.name: did not receive HSTS header heimnetze.org: could not connect to host -heinemeier.dk: did not receive HSTS header helencrump.co.uk: did not receive HSTS header helgakristoffer.com: could not connect to host helgakristoffer.wedding: could not connect to host @@ -6793,8 +6826,6 @@ hppub.org: could not connect to host hppub.site: could not connect to host hqhost.net: did not receive HSTS header hr-intranet.com: could not connect to host -hr-tech.shop: did not receive HSTS header -hr-tech.store: did not receive HSTS header hrackydomino.cz: did not receive HSTS header hrfhomelottery.com: did not receive HSTS header hrk.io: could not connect to host @@ -6813,7 +6844,6 @@ huarongdao.com: did not receive HSTS header hubert.systems: did not receive HSTS header hugocollignon.fr: could not connect to host humanesources.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 116" data: no] -humblebee.co.uk: did not receive HSTS header humblefinances.com: did not receive HSTS header humeurs.net: could not connect to host humortuga.pt: could not connect to host @@ -6847,6 +6877,7 @@ i-rickroll-n.pw: could not connect to host i10z.com: could not connect to host i496.eu: did not receive HSTS header iacono.com.br: did not receive HSTS header +iamcarrico.com: did not receive HSTS header iamokay.nl: did not receive HSTS header iamreubin.co.uk: did not receive HSTS header iamveto.com: could not connect to host @@ -6917,7 +6948,7 @@ ijn-dd.nl: could not connect to host ijoda.com: could not connect to host ik-life.com: did not receive HSTS header ikocik.sk: could not connect to host -ikon.name: did not receive HSTS header +ikon.name: could not connect to host ikwilguidobellen.nl: could not connect to host ikzoekjeugdhulp.nl: did not receive HSTS header ilbuongiorno.it: did not receive HSTS header @@ -6957,7 +6988,7 @@ immunicity.rocks: could not connect to host immunicity.st: did not receive HSTS header immunicity.today: could not connect to host immunicity.top: could not connect to host -immunicity.win: could not connect to host +immunicity.win: max-age too low: 0 immunicity.works: could not connect to host immunicity.world: could not connect to host imolug.org: did not receive HSTS header @@ -6969,7 +7000,6 @@ imprenta-es.com: did not receive HSTS header imu.li: did not receive HSTS header imusic.dk: did not receive HSTS header imy.life: could not connect to host -imydl.com: did not receive HSTS header inb4.us: could not connect to host inbox.li: did not receive HSTS header incendiary-arts.com: could not connect to host @@ -6980,7 +7010,6 @@ indiecert.net: could not connect to host indiemods.com: could not connect to host indien.guide: could not connect to host indilens.com: did not receive HSTS header -indochina.io: could not connect to host indoorskiassen.nl: did not receive HSTS header indredouglas.me: could not connect to host industrybazar.com: max-age too low: 2592000 @@ -7056,7 +7085,7 @@ internetradiocharts.de: did not receive HSTS header internshipandwork.com: did not receive HSTS header internshipandwork.ru: did not receive HSTS header interociter-enterprises.com: could not connect to host -intersectraven.net: could not connect to host +intersectraven.net: did not receive HSTS header interserved.com: did not receive HSTS header intervisteperstrada.com: could not connect to host intexplore.org: could not connect to host @@ -7069,7 +7098,6 @@ intranetsec.fr: could not connect to host introvertedtravel.space: did not receive HSTS header intrp.net: did not receive HSTS header intxt.net: did not receive HSTS header -inventtheworld.com.au: did not receive HSTS header investcountry.com: did not receive HSTS header investnext.com: max-age too low: 43200 invictusmc.uk: could not connect to host @@ -7237,6 +7265,7 @@ japaripark.com: could not connect to host japlex.com: could not connect to host jaqen.ch: could not connect to host jaredbates.net: did not receive HSTS header +jarivisual.com: did not receive HSTS header jarnail.ca: did not receive HSTS header jaroslavtrsek.cz: did not receive HSTS header jarsater.com: could not connect to host @@ -7273,7 +7302,6 @@ jcraft.us: did not receive HSTS header jctf.io: could not connect to host jdav-leipzig.de: could not connect to host jdgonzalez95.com: did not receive HSTS header -jebengotai.com: could not connect to host jeff393.com: could not connect to host jeffreymagee.com: did not receive HSTS header jehovahsays.net: did not receive HSTS header @@ -7342,6 +7370,7 @@ joakimalgroy.com: could not connect to host jobers.ch: did not receive HSTS header jobers.pt: did not receive HSTS header jobflyapp.com: could not connect to host +joblab.com.ua: did not receive HSTS header jobshq.com: could not connect to host jobss.co.uk: could not connect to host jodel.ninja: did not receive HSTS header @@ -7420,7 +7449,7 @@ junge-selbsthilfe.info: could not connect to host junglegoat.xyz: did not receive HSTS header junjung.me: could not connect to host junqtion.com: could not connect to host -junqueiropolis.com: max-age too low: 0 +junqueiropolis.com: did not receive HSTS header jupp0r.de: did not receive HSTS header juristas.com.br: did not receive HSTS header jurke.com: did not receive HSTS header @@ -7441,6 +7470,7 @@ jvoice.net: could not connect to host jvwdev.nl: did not receive HSTS header jwilsson.me: could not connect to host jxm.in: could not connect to host +jym.fit: did not receive HSTS header jysperm.me: did not receive HSTS header jznet.org: could not connect to host k-dev.de: could not connect to host @@ -7450,7 +7480,6 @@ k1cp.com: could not connect to host k38.cc: did not receive HSTS header ka-clan.com: could not connect to host kaanduman.com: did not receive HSTS header -kaasbesteld.nl: did not receive HSTS header kaasbijwijn.nl: did not receive HSTS header kabinapp.com: could not connect to host kabuabc.com: could not connect to host @@ -7531,7 +7560,6 @@ kermadec.blog: could not connect to host kermadec.net: could not connect to host kernl.us: did not receive HSTS header keskeces.com: did not receive HSTS header -kevinmoreland.com: did not receive HSTS header kevinroebert.de: did not receive HSTS header keymaster.lookout.com: did not receive HSTS header kfbrussels.be: could not connect to host @@ -7648,7 +7676,6 @@ kotovstyle.ru: could not connect to host koukni.cz: did not receive HSTS header kourpe.online: could not connect to host kousaku.jp: could not connect to host -koyaanis.com: did not receive HSTS header kpdyer.com: did not receive HSTS header kpebetka.net: did not receive HSTS header kpn-dnssec.com: did not receive HSTS header @@ -7741,6 +7768,7 @@ lahora.com.ec: did not receive HSTS header lainchan.org: did not receive HSTS header laisashop.com.br: could not connect to host lakarwebb.se: did not receive HSTS header +lakehavasucityhomebuyerscredit.com: did not receive HSTS header laltroweb.it: did not receive HSTS header lamaland.ru: did not receive HSTS header lamarieealhonneur.com: did not receive HSTS header @@ -7762,7 +7790,7 @@ landscape.canonical.com: max-age too low: 2592000 landscapingmedic.com: did not receive HSTS header langenbach.rocks: could not connect to host langendries.eu: could not connect to host -langhun.me: did not receive HSTS header +langhun.me: could not connect to host laniakean.com: did not receive HSTS header lansinoh.co.uk: did not receive HSTS header lanzainc.xyz: did not receive HSTS header @@ -7901,6 +7929,7 @@ lightnovelsekai.com: could not connect to host lightpaste.com: could not connect to host lightworkerandempathsupport.com: max-age too low: 300 lightworx.io: did not receive HSTS header +likeablehub.com: did not receive HSTS header lila.pink: did not receive HSTS header lilapmedia.com: could not connect to host lillpopp.eu: did not receive HSTS header @@ -8014,7 +8043,7 @@ lothuytinhsi.com: could not connect to host lotos-ag.ch: did not receive HSTS header lotsencafe.de: did not receive HSTS header lottosonline.com: did not receive HSTS header -lotuscloud.de: did not receive HSTS header +lotuscloud.de: could not connect to host lotuscloud.org: could not connect to host louduniverse.net: did not receive HSTS header louiewatch.com: could not connect to host @@ -8146,6 +8175,7 @@ makeitdynamic.com: could not connect to host makerstuff.net: did not receive HSTS header makeshiftco.de: did not receive HSTS header makeyourank.com: max-age too low: 200 +malash.me: did not receive HSTS header maldiverna.guide: could not connect to host maleexcel.com: did not receive HSTS header malena.com.ua: did not receive HSTS header @@ -8193,6 +8223,7 @@ maosi.xin: could not connect to host maple5.com: could not connect to host maplenorth.co: did not receive HSTS header mapresidentielle.fr: did not receive HSTS header +maranatha.pl: did not receive HSTS header marcelparra.com: could not connect to host marchagen.nl: did not receive HSTS header marchhappy.tech: did not receive HSTS header @@ -8241,7 +8272,7 @@ martineve.com: did not receive HSTS header martinkup.cz: did not receive HSTS header martinp.no: could not connect to host martinreed.net: did not receive HSTS header -martinrogalla.com: did not receive HSTS header +martinrogalla.com: could not connect to host marumagic.com: did not receive HSTS header marvinkeller.de: did not receive HSTS header marykshoup.com: did not receive HSTS header @@ -8314,7 +8345,6 @@ mcmillansedationdentistry.com: did not receive HSTS header mcooperlaw.com: did not receive HSTS header mcuexchange.com: did not receive HSTS header mdfnet.se: did not receive HSTS header -mdkr.nl: did not receive HSTS header mdscomp.net: did not receive HSTS header meadowfenfarm.com: could not connect to host meat-education.com: could not connect to host @@ -8328,7 +8358,6 @@ mediafinancelab.org: did not receive HSTS header mediamag.am: max-age too low: 0 mediawikicn.org: could not connect to host medienservice-fritz.de: did not receive HSTS header -medifab.online: did not receive HSTS header medirich.co: could not connect to host meditek-dv.ru: could not connect to host mediterenopmaandag.nl: did not receive HSTS header @@ -8432,7 +8461,7 @@ midirs.org: did not receive HSTS header midonet.org: did not receive HSTS header midriversmotorsllc.com: did not receive HSTS header midwestwomenworkers.org: could not connect to host -miegl.cz: could not connect to host +miegl.cz: did not receive HSTS header miemie.jp: could not connect to host migeeks.de: did not receive HSTS header mightydicks.io: could not connect to host @@ -8487,7 +8516,7 @@ minecraftforums.ml: could not connect to host minecraftserverz.com: could not connect to host minecraftvoter.com: could not connect to host mineover.es: could not connect to host -mingo.nl: max-age too low: 2592000 +mingo.nl: could not connect to host minh.at: did not receive HSTS header mini-piraten.de: did not receive HSTS header minikneet.nl: could not connect to host @@ -8640,6 +8669,7 @@ mountainmusicpromotions.com: did not receive HSTS header movabletype.net: max-age too low: 3600 moviedollars.com: did not receive HSTS header moviesabout.net: could not connect to host +moviespur.info: did not receive HSTS header movio.ga: did not receive HSTS header moy-gorod.od.ua: did not receive HSTS header mozart-game.cz: could not connect to host @@ -8651,7 +8681,6 @@ mp3donusturucu.net: did not receive HSTS header mp3juices.is: max-age too low: 0 mpintaamalabanna.it: did not receive HSTS header mpkossen.com: did not receive HSTS header -mqas.net: did not receive HSTS header mr-hosting.com: could not connect to host mrawe.com: could not connect to host mrdani.net: could not connect to host @@ -8772,7 +8801,6 @@ n-rickroll-e.pw: could not connect to host n0psled.nl: could not connect to host n2x.in: could not connect to host n4l.pw: could not connect to host -n64chan.me: did not receive HSTS header n8ch.net: could not connect to host nabru.co.uk: did not receive HSTS header nabu-bad-nauheim.de: did not receive HSTS header @@ -8804,6 +8832,7 @@ nanokamo.com: did not receive HSTS header nanrenba.net: could not connect to host nansay.cn: could not connect to host nanto.eu: could not connect to host +naomiheji.com: did not receive HSTS header narach.com: did not receive HSTS header nargele.eu: did not receive HSTS header narodniki.com: did not receive HSTS header @@ -8831,7 +8860,6 @@ navjobs.com: did not receive HSTS header nbb.io: could not connect to host nbg-ha.de: could not connect to host ncc60205.info: could not connect to host -nchristo.com: did not receive HSTS header ncpc.gov: could not connect to host ncpw.gov: did not receive HSTS header nct.org.uk: did not receive HSTS header @@ -8877,6 +8905,7 @@ netresourcedesign.com: could not connect to host netsafeid.biz: did not receive HSTS header netsparkercloud.com: did not receive HSTS header nettefoundation.com: could not connect to host +nettia.fi: did not receive HSTS header netweaver.uk: did not receive HSTS header networx-online.de: could not connect to host netzbit.de: could not connect to host @@ -9008,7 +9037,7 @@ notenoughtime.de: could not connect to host nothing.net.nz: max-age too low: 7776000 noticia.do: did not receive HSTS header notjustbitchy.com: did not receive HSTS header -nottheonion.net: could not connect to host +nottheonion.net: did not receive HSTS header nou.si: could not connect to host nouvelle-vague-saint-cast.fr: did not receive HSTS header nova-elearning.com: could not connect to host @@ -9505,6 +9534,7 @@ phdsupply.com: could not connect to host philadelphiacandies.com: did not receive HSTS header phillmoore.com: did not receive HSTS header phillprice.com: did not receive HSTS header +philonas.net: did not receive HSTS header philpropertygroup.com: could not connect to host phoebe.co.nz: did not receive HSTS header phoenicis.com.ua: did not receive HSTS header @@ -9517,6 +9547,7 @@ phototag.org: did not receive HSTS header php-bach.org: could not connect to host phperformances.fr: did not receive HSTS header phrasing.me: could not connect to host +phurl.io: did not receive HSTS header physicaltherapist.com: did not receive HSTS header pi-eng.fr: did not receive HSTS header pianetaottica.net: could not connect to host @@ -9693,7 +9724,7 @@ premioambiente.it: did not receive HSTS header premiumzweirad.de: max-age too low: 7776000 prepandgo-euro.com: could not connect to host preparedcapital.com: max-age too low: 300 -preppertactics.com: did not receive HSTS header +preppertactics.com: could not connect to host presidentials2016.com: could not connect to host press-anime-nenkan.com: did not receive HSTS header pressenews.net: did not receive HSTS header @@ -9785,7 +9816,7 @@ pstudio.me: did not receive HSTS header psw.academy: could not connect to host psw.consulting: could not connect to host psylab.cc: did not receive HSTS header -psylab.re: could not connect to host +psylab.re: did not receive HSTS header psylab.vip: did not receive HSTS header ptn.moscow: could not connect to host ptonet.com: could not connect to host @@ -9902,6 +9933,7 @@ raidstone.com: could not connect to host raidstone.net: could not connect to host raidstone.rocks: could not connect to host rainbowbarracuda.com: could not connect to host +rainel.at: did not receive HSTS header ramarka.de: could not connect to host ramon-c.nl: could not connect to host ramonj.nl: could not connect to host @@ -9953,6 +9985,7 @@ rcafox.com: could not connect to host rcorporation.be: did not receive HSTS header rcpcbd.com: could not connect to host rcvd.io: did not receive HSTS header +rdmrotterdam.nl: did not receive HSTS header rdns.im: did not receive HSTS header rdyrda.fr: could not connect to host re-customer.net: did not receive HSTS header @@ -10149,7 +10182,7 @@ rondoniatec.com.br: did not receive HSTS header ronvandordt.info: did not receive HSTS header ronwo.de: max-age too low: 1 roo.ie: could not connect to host -rool.me: could not connect to host +rool.me: did not receive HSTS header rootforum.org: did not receive HSTS header rootservice.org: did not receive HSTS header rootwpn.com: could not connect to host @@ -10157,6 +10190,7 @@ rop.io: could not connect to host roquecenter.org: did not receive HSTS header rorymcdaniel.com: did not receive HSTS header roseitsolutions.uk: did not receive HSTS header +rossclark.com: did not receive HSTS header rossen.be: did not receive HSTS header rossiworld.com: did not receive HSTS header rotex1840.de: did not receive HSTS header @@ -10173,7 +10207,7 @@ royalsignaturecruise.com: could not connect to host roychan.org: max-age too low: 0 rozeapp.nl: could not connect to host rr.in.th: could not connect to host -rrke.cc: could not connect to host +rrke.cc: did not receive HSTS header rsajeey.info: could not connect to host rsampaio.info: did not receive HSTS header rsf.io: could not connect to host @@ -10314,6 +10348,7 @@ schachburg.de: did not receive HSTS header schadegarant.net: could not connect to host schau-rein.co.at: did not receive HSTS header schauer.so: could not connect to host +schd.io: did not receive HSTS header schermreparatierotterdam.nl: did not receive HSTS header schmitt.ovh: could not connect to host schnell-abnehmen.tips: did not receive HSTS header @@ -10337,7 +10372,6 @@ schwetz.net: could not connect to host scicasts.com: max-age too low: 7776000 scienceathome.org: did not receive HSTS header sciencebase.gov: did not receive HSTS header -scionasset.com: did not receive HSTS header scivillage.com: did not receive HSTS header sckc.stream: could not connect to host sclgroup.cc: did not receive HSTS header @@ -10410,6 +10444,7 @@ security-thoughts.org: could not connect to host securityarena.com: could not connect to host securitybsides.pl: did not receive HSTS header securityglance.com: could not connect to host +securityheaders.io: did not receive HSTS header securityinet.biz: did not receive HSTS header securityinet.net: did not receive HSTS header securityinet.org.il: could not connect to host @@ -10616,6 +10651,7 @@ simyo.nl: did not receive HSTS header sin30.net: could not connect to host sincai666.com: could not connect to host sincron.org: could not connect to host +sinefili.com: did not receive HSTS header sinful.pw: could not connect to host singul4rity.com: could not connect to host sinneserweiterung.de: could not connect to host @@ -10731,7 +10767,6 @@ snippet.host: could not connect to host snod.land: did not receive HSTS header snoozedds.com: max-age too low: 600 snoqualmiefiber.org: could not connect to host -snrat.com: did not receive HSTS header sobabox.ru: could not connect to host sobinski.pl: did not receive HSTS header soccergif.com: could not connect to host @@ -11284,7 +11319,7 @@ the-delta.net.eu.org: could not connect to host the-paddies.de: did not receive HSTS header the-sky-of-valkyries.com: could not connect to host the.ie: max-age too low: 0 -theamateurs.net: could not connect to host +theamateurs.net: did not receive HSTS header theamp.com: did not receive HSTS header theater.cf: could not connect to host theavenuegallery.com: did not receive HSTS header @@ -11324,7 +11359,7 @@ thegreenpark.co.uk: did not receive HSTS header thegreenvpn.com: did not receive HSTS header thehiddenbay.eu: could not connect to host thehiddenbay.me: max-age too low: 0 -thehiddenbay.net: max-age too low: 0 +thehiddenbay.net: could not connect to host thehighersideclothing.com: did not receive HSTS header thehistory.me: could not connect to host thehonorguard.org: did not receive HSTS header @@ -11384,7 +11419,6 @@ thisisforager.com: could not connect to host thiswasalreadymyusername.tk: could not connect to host thiswebhost.com: did not receive HSTS header thkb.net: could not connect to host -thole.org: did not receive HSTS header thomas-ferney.fr: did not receive HSTS header thomas-gibertie.fr: did not receive HSTS header thomas-suchon.fr: did not receive HSTS header @@ -11425,7 +11459,7 @@ tikutiku.pl: could not connect to host tildebot.com: could not connect to host tilient.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 116" data: no] tilikum.io: did not receive HSTS header -tilkah.com.au: could not connect to host +tilkah.com.au: did not receive HSTS header tillcraft.com: could not connect to host timbeilby.com: could not connect to host timbuktutimber.com: did not receive HSTS header @@ -11439,6 +11473,7 @@ timeserver1.de: could not connect to host timeserver2.de: could not connect to host timeserver3.de: could not connect to host timestamp.io: did not receive HSTS header +timetab.org: did not receive HSTS header timhjalpen.se: could not connect to host timotrans.de: did not receive HSTS header timotrans.eu: did not receive HSTS header @@ -11825,6 +11860,7 @@ ur-lauber.de: did not receive HSTS header urandom.eu.org: did not receive HSTS header urban-garden.lt: could not connect to host urban-garden.lv: could not connect to host +urbanstylestaging.com: did not receive HSTS header urbpic.com: could not connect to host urlchomp.com: did not receive HSTS header urology.wiki: did not receive HSTS header @@ -11865,7 +11901,7 @@ uzmandroid.net: could not connect to host uzmandroid.top: could not connect to host v-desk.ga: did not receive HSTS header v0rtex.xyz: could not connect to host -v0tti.com: did not receive HSTS header +v0tti.com: could not connect to host v12.co.uk: did not receive HSTS header v2.pw: did not receive HSTS header v2ex.us: could not connect to host @@ -11873,7 +11909,7 @@ v4s.ro: did not receive HSTS header v4veedu.com: could not connect to host v7.cl: could not connect to host v789xl.com: did not receive HSTS header -vaalmarketplace.co.za: could not connect to host +vaalmarketplace.co.za: did not receive HSTS header vacationality.com: could not connect to host vackerbetong.se: could not connect to host vacuumreviewcenter.com: did not receive HSTS header @@ -11895,6 +11931,7 @@ vampirism.eu: could not connect to host vanacht.co.za: did not receive HSTS header vanajahosting.com: did not receive HSTS header vanderkley.it: could not connect to host +vanderrijt.nl: did not receive HSTS header vanestack.com: could not connect to host vanitas.xyz: did not receive HSTS header vanitynailworkz.com: could not connect to host @@ -12109,14 +12146,12 @@ wapt.fr: did not receive HSTS header warandpeace.xyz: could not connect to host wardsegers.be: did not receive HSTS header warehost.de: did not receive HSTS header -warekit.io: did not receive HSTS header warhistoryonline.com: did not receive HSTS header warped.com: did not receive HSTS header warrencreative.com: did not receive HSTS header warsentech.com: could not connect to host warsh.moe: did not receive HSTS header warumsuchen.at: did not receive HSTS header -wasatchconstables.com: did not receive HSTS header wasatchcrest.com: did not receive HSTS header watchium.com: did not receive HSTS header waterforlife.net.au: did not receive HSTS header @@ -12129,6 +12164,7 @@ wavefrontsystemstech.com: could not connect to host waylaydesign.com: did not receive HSTS header waylee.net: did not receive HSTS header wbci.us: did not receive HSTS header +wealthformyhealth.com: did not receive HSTS header wear2work.nl: could not connect to host wearedisneyland.com: did not receive HSTS header weaverhairextensions.nl: could not connect to host @@ -12228,6 +12264,7 @@ whatsstalk.me: could not connect to host whatsyouroffer.co.uk: did not receive HSTS header wheresben.today: could not connect to host whisker.network: could not connect to host +whistler-transfers.com: did not receive HSTS header whitehat.id: could not connect to host whiterabbit.org: did not receive HSTS header whiterabbitcakery.com: could not connect to host @@ -12320,7 +12357,6 @@ wordbits.net: did not receive HSTS header work-and-jockel.de: did not receive HSTS header workfone.io: could not connect to host workpermit.com.vn: could not connect to host -worksofwyoming.org: did not receive HSTS header worldlist.org: could not connect to host worldpovertysolutions.org: did not receive HSTS header worldsbeststory.com: did not receive HSTS header @@ -12332,9 +12368,7 @@ wowinvasion.com: did not receive HSTS header wp-rescue.com.au: did not receive HSTS header wpblog.com.tw: could not connect to host wpcarer.pro: could not connect to host -wpcharged.nz: did not receive HSTS header wpfortify.com: could not connect to host -wpg-inc.com: did not receive HSTS header wphome.org: could not connect to host wphostingspot.com: did not receive HSTS header wplatin.com: could not connect to host @@ -12347,7 +12381,7 @@ wql.zj.cn: did not receive HSTS header wrbunderwriting.com: did not receive HSTS header wrfu.co.nz: did not receive HSTS header wrightdoumawedding.com: could not connect to host -writeapp.me: did not receive HSTS header +writeapp.me: could not connect to host wrldevelopment.com: did not receive HSTS header wroffle.com: did not receive HSTS header wrwg.ca: could not connect to host @@ -12377,7 +12411,7 @@ www-8003.com: did not receive HSTS header www-88599.com: did not receive HSTS header www-9995.com: did not receive HSTS header www-djbet.com: did not receive HSTS header -www-jinshavip.com: did not receive HSTS header +www-jinshavip.com: could not connect to host www.cueup.com: could not connect to host www.cyveillance.com: did not receive HSTS header www.developer.mydigipass.com: could not connect to host @@ -12512,7 +12546,7 @@ xtrim.ru: did not receive HSTS header xuexb.com: did not receive HSTS header xunn.io: did not receive HSTS header xupeng.me: did not receive HSTS header -xuyh0120.win: could not connect to host +xuyh0120.win: did not receive HSTS header xxbase.com: could not connect to host xynex.us: could not connect to host y-o-w.com: did not receive HSTS header @@ -12620,7 +12654,6 @@ zao.fi: could not connect to host zaoshanghao-dajia.rhcloud.com: could not connect to host zap.yt: did not receive HSTS header zarooba.com: could not connect to host -zary.me: did not receive HSTS header zavca.com: could not connect to host zbasenem.pl: did not receive HSTS header zbigniewgalucki.eu: did not receive HSTS header @@ -12645,8 +12678,8 @@ zentience.org: did not receive HSTS header zentraler-kreditausschuss.de: did not receive HSTS header zentralwolke.de: did not receive HSTS header zenwears.com: could not connect to host -zera.com.au: could not connect to host -zerekin.net: did not receive HSTS header +zera.com.au: max-age too low: 0 +zerekin.net: could not connect to host zeroday.sk: did not receive HSTS header zerofox.gq: could not connect to host zeroml.ml: could not connect to host diff --git a/security/manager/ssl/nsSTSPreloadList.inc b/security/manager/ssl/nsSTSPreloadList.inc index 580803c3e2d5..68f408c8cf24 100644 --- a/security/manager/ssl/nsSTSPreloadList.inc +++ b/security/manager/ssl/nsSTSPreloadList.inc @@ -8,7 +8,7 @@ /*****************************************************************************/ #include -const PRTime gPreloadListExpirationTime = INT64_C(1534452208072000); +const PRTime gPreloadListExpirationTime = INT64_C(1534538708637000); %% 0-1.party, 1 0.me.uk, 1 @@ -1330,7 +1330,7 @@ acg18.us, 0 acgaudio.com, 1 acgpiano.club, 1 achalay.org, 1 -acheconcursos.com.br, 1 +acheconcursos.com.br, 0 achenar.net, 1 acheter-ethylotest.fr, 1 achow101.com, 1 @@ -1389,7 +1389,7 @@ activecare-monitor.com, 1 activeclearweb.com, 1 activehire.co.uk, 1 activeleisure.ie, 1 -activeworld.net, 1 +activeworld.net, 0 activitesaintnicaise.org, 1 activityeventhire.co.uk, 1 actom.cc, 1 @@ -1507,7 +1507,6 @@ adorecricket.com, 1 adorewe.com, 1 adoriasoft.com, 0 adoucisseur.shop, 1 -adprospb.com, 1 adquisitio.co.uk, 1 adquisitio.es, 1 adquisitio.fr, 1 @@ -2021,6 +2020,7 @@ alibangash.com, 1 alibip.de, 1 alice-noutore.com, 1 alice.tw, 1 +alicestudio.it, 1 alicetone.net, 1 alicialab.org, 1 alien.bz, 1 @@ -2091,6 +2091,7 @@ allinone-ranking150.com, 1 allinonecyprus.com, 1 allis.studio, 1 alljamin.com, 1 +allkindzabeats.com, 1 allladyboys.com, 1 allmebel.ru, 1 allmend-ru.de, 1 @@ -2200,6 +2201,7 @@ altitudemoversdenver.com, 1 altkremsmuensterer.at, 1 altoa.cz, 1 altonblom.com, 1 +altoneum.com, 1 altopartners.com, 1 altopia.com, 1 altphotos.com, 1 @@ -2291,7 +2293,6 @@ american.dating, 1 americandistribuidora.com, 1 americanfoundationbr.com, 1 americanmediainstitute.com, 1 -americanoutlawjeepparts.com, 1 americasbasementcontractor.com, 1 americkykongres.cz, 1 amerigroup.com, 1 @@ -2435,7 +2436,6 @@ andrewdaws.io, 1 andrewdaws.me, 1 andrewdaws.tv, 1 andrewensley.com, 1 -andrewhowden.com, 1 andrewimeson.com, 1 andrewin.ru, 1 andrewmichaud.com, 1 @@ -3756,7 +3756,6 @@ babystep.tv, 1 bacgrouppublishing.com, 1 bachata.info, 1 baches-piscines.com, 1 -bacimg.com, 1 baciu.ch, 1 backeby.eu, 1 backgroundz.net, 1 @@ -4039,6 +4038,7 @@ bauthier-occasions.be, 1 bautied.de, 1 bauunternehmen-herr.de, 1 bayareaenergyevents.com, 1 +baychimo.com, 1 bayden.com, 1 bayer-stefan.com, 1 bayer-stefan.de, 1 @@ -4774,7 +4774,7 @@ birdslabel.com, 1 birdymanbestreviews.com, 1 birgit-rydlewski.de, 1 birkengarten.ch, 1 -birkhoff.me, 1 +birkhoff.me, 0 birminghamcastlehire.co.uk, 1 birminghamsunset.com, 1 birthdaytip.com, 1 @@ -4789,6 +4789,7 @@ bismarck-tb.de, 1 bison.co, 1 bissalama.org, 1 bisschopssteeg.nl, 1 +bistrocean.com, 1 bistrotdelagare.fr, 1 biswas.me, 1 bit-cloud.de, 1 @@ -5218,7 +5219,6 @@ bologna-disinfestazioni.it, 1 bolovegna.it, 1 bolt.cm, 0 bolte.org, 1 -boltn.uk, 1 bomb.codes, 1 bomberus.de, 1 bombsquad.studio, 1 @@ -6068,7 +6068,6 @@ c2o2.xyz, 1 c3.pm, 1 c3vo.de, 1 c3w.at, 1 -c4.hk, 1 c4539.com, 1 c4k3.net, 1 c7dn.com, 1 @@ -6378,7 +6377,6 @@ carloshmm.com, 1 carloshmm.stream, 1 carlosjeurissen.com, 1 carlovanwyk.com, 1 -carlscatering.com, 1 carnaticalifornia.com, 1 carnet-du-voyageur.com, 1 carnildo.com, 1 @@ -6860,7 +6858,6 @@ chateau-de-lisle.fr, 1 chateaudestrainchamps.com, 1 chateaudevaugrigneuse.com, 1 chatfacile.org, 1 -chatint.com, 1 chatitaly.org, 1 chatme.im, 0 chatnbook.com, 1 @@ -7241,7 +7238,7 @@ cirugiasplasticas.com.mx, 1 cirujanooral.com, 1 cirurgicagervasio.com.br, 1 cirurgicalucena.com.br, 1 -ciscodude.net, 0 +ciscodude.net, 1 cisoaid.com, 1 ciss.ltd, 1 cisy.me, 1 @@ -7975,7 +7972,6 @@ constructive.men, 1 consul.io, 1 consultcelerity.com, 1 consultingroupitaly.com, 1 -consultorcr.net, 1 consultpetkov.com, 1 consumeractionlawgroup.com, 1 consumerfiles.com, 1 @@ -9580,7 +9576,6 @@ devpsy.info, 1 devrandom.net, 1 devstaff.gr, 1 devtestfan1.gov, 1 -devyn.ca, 1 devzero.io, 1 dewaard.de, 1 dewalch.net, 1 @@ -10008,6 +10003,7 @@ dmlogic.com, 1 dmmkenya.co.ke, 1 dmmultionderhoud.nl, 1 dmschilderwerken.nl, 1 +dmwall.cn, 1 dmxledlights.com, 1 dn3s.me, 1 dn42.eu, 0 @@ -10269,6 +10265,7 @@ doublestat.me, 1 doubleup.com.au, 1 doucheba.gs, 0 dougferris.id.au, 1 +douglasstafford.com, 1 doujin-domain.cz, 1 doujin.nagoya, 1 doujinshi.info, 1 @@ -10560,7 +10557,6 @@ duncancmt.com, 1 duncanfamilytrust.org, 1 duncanwinfrey.com, 1 dundalkdonnie.com, 1 -dung-massage.fr, 1 dungeon-bbs.de, 1 dungi.org, 1 dunklau.fr, 1 @@ -10593,6 +10589,7 @@ dustyspokesbnb.ca, 1 dutch.desi, 1 dutch1.nl, 1 dutchdare.nl, 1 +dutchessuganda.com, 1 dutchrank.nl, 1 dutchwanderers.nl, 1 dutchweballiance.nl, 1 @@ -10936,7 +10933,7 @@ educators.co.nz, 1 educatoys.com.br, 1 educnum.fr, 1 eductf.org, 1 -eduid.se, 1 +eduid.se, 0 eduif.nl, 0 edumundo.nl, 1 eduroam.no, 1 @@ -11189,6 +11186,7 @@ elfe.de, 1 elgosblanc.com, 0 elguadia.faith, 1 elhall.pro, 1 +elhall.ru, 1 elhamadimi.com, 1 elhossari.com, 1 elia.cloud, 1 @@ -11598,7 +11596,6 @@ equinox.io, 1 equipandoloja.net.br, 1 equipedefrance.tv, 1 equipeferramentas.com.br, 1 -equippers.de, 1 equipsupply.com, 1 equk.co.uk, 1 er-music.com, 1 @@ -12262,7 +12259,6 @@ extintormadrid.com, 1 extradesktops.com, 0 extranetpuc.com.br, 1 extrapagetab.com, 1 -extratorrent.cool, 0 extratorrent.fyi, 1 extratorrent.red, 1 extratorrent.world, 1 @@ -12601,7 +12597,6 @@ feastr-dev.de, 1 feastr.de, 1 feastr.io, 1 featherweightlabs.com, 1 -featuredmen.com, 0 feb.gov, 1 fecik.sk, 1 fed51.com, 1 @@ -12879,6 +12874,7 @@ fintry.ca, 1 finvantage.com, 1 fionamcbride.com, 1 fiork.com, 1 +fioulmarket.fr, 1 fir3net.com, 1 fire-wolf.com, 1 fireandelectrical.co.uk, 1 @@ -13433,6 +13429,7 @@ frederikschoell.de, 0 frederikvig.com, 1 fredliang.cn, 1 fredloya.com, 1 +fredriksslekt.se, 1 fredtec.ru, 1 fredvoyage.fr, 1 free-your-pc.com, 1 @@ -14365,6 +14362,7 @@ giac.org, 1 giacomodrago.com, 1 giacomodrago.it, 1 giacomopelagatti.it, 1 +gianlucapartengo.photography, 1 gianproperties.com, 1 giant-panda.com, 1 giant-tortoise.com, 1 @@ -15653,6 +15651,7 @@ heid.ws, 1 heidisheroes.org, 1 heijblok.com, 1 heijdel.nl, 1 +heikorichter.name, 1 heiland.io, 1 heiliger-gral.info, 1 heilpraxis-bgl.de, 1 @@ -15661,6 +15660,7 @@ heimdallr.nl, 1 heimonen.eu, 1 heimprofis.de, 1 heinemann.io, 1 +heinemeier.dk, 1 heinpost.nl, 0 heinzelmann.co, 1 heisenberg.co, 1 @@ -15945,7 +15945,7 @@ hinrich.de, 1 hinterhofbu.de, 1 hintermeier-rae.at, 1 hinterposemuckel.de, 1 -hintss.pw, 1 +hintss.pw, 0 hiphop.ren, 1 hipi.jp, 1 hipnoseinstitute.org, 1 @@ -16323,6 +16323,8 @@ hpnow.com.br, 1 hqq.tv, 1 hquest.pro.br, 1 hqwebhosting.tk, 0 +hr-tech.shop, 1 +hr-tech.store, 1 hr98.tk, 1 hr98.xyz, 1 hrabogados.com, 1 @@ -16448,6 +16450,7 @@ humblebee.be, 1 humblebee.bg, 1 humblebee.ch, 1 humblebee.co.in, 1 +humblebee.co.uk, 1 humblebee.com.mx, 1 humblebee.com.ph, 1 humblebee.cz, 1 @@ -16605,7 +16608,6 @@ iainsimms.co.uk, 1 iainsimms.com, 1 iainsimms.me, 1 ialis.me, 1 -iamcarrico.com, 1 iamhansen.xyz, 1 iamjoshellis.com, 1 iamle.com, 1 @@ -17022,6 +17024,7 @@ imrunner.com, 1 imrunner.ru, 1 ims-sargans.ch, 1 imscompany.com, 1 +imydl.com, 1 imydl.tech, 1 imyunya.com, 1 imyvm.com, 1 @@ -17077,6 +17080,7 @@ indigoinflatables.com, 1 indigosakura.com, 1 indiraactive.com, 1 inditip.com, 1 +indochina.io, 1 indogerman.de, 1 indogermanstartup.com, 1 indogermantrade.de, 1 @@ -17424,6 +17428,7 @@ inventix.nl, 1 inventoryexpress.xyz, 1 inventoryimages.co.uk, 1 inventoryimages.com, 1 +inventtheworld.com.au, 1 inventum.cloud, 1 inverselink-user-content.com, 1 inverselink.com, 1 @@ -18039,7 +18044,6 @@ jardins-utopie.net, 1 jaredeberle.org, 0 jaredfernandez.com, 1 jaredfraser.com, 1 -jarivisual.com, 1 jarl.ninja, 1 jarniashop.se, 1 jaroku.com, 1 @@ -18133,6 +18137,7 @@ jeanmarieayer.ch, 1 jeannecalment.com, 1 jeannelucienne.fr, 1 jeanneret-combustibles.ch, 1 +jebengotai.com, 1 jec-dekrone.be, 1 jecho.cn, 1 jedayoshi.me, 1 @@ -18350,7 +18355,6 @@ jobbkk.com, 1 jobbsafari.no, 1 jobbsafari.se, 1 jobindex.dk, 1 -joblab.com.ua, 1 joblife.co.za, 1 jobmedic.com, 1 jobmob.co.il, 1 @@ -18762,7 +18766,6 @@ jwolt-lx.com, 1 jwschuepfheim.ch, 1 jxir.de, 1 jyggen.com, 1 -jym.fit, 1 jyoti-fairworks.org, 1 jzachpearson.com, 1 jzbk.org, 1 @@ -18782,6 +18785,7 @@ k8r.eu, 1 k9swx.com, 1 kaamoscreations.com, 1 kaangenc.me, 1 +kaasbesteld.nl, 1 kaashosting.nl, 1 kaatha-kamrater.se, 1 kab-s.de, 1 @@ -19173,6 +19177,7 @@ kevinhq.com, 1 kevinkla.es, 1 kevinlocke.name, 1 kevinmeijer.nl, 1 +kevinmoreland.com, 1 kevinmorssink.nl, 1 kevinpirnie.com, 1 kevinratcliff.com, 1 @@ -19694,6 +19699,7 @@ kowalmik.tk, 1 kowalstwo.com.pl, 1 kowarschick.de, 1 kowshiksundararajan.com, 1 +koyaanis.com, 1 kozmik.co, 1 kozuch.biz, 1 kpfanworld.com, 1 @@ -20038,7 +20044,6 @@ lak-berlin.de, 1 lakatrop.com, 1 lakedavid.com.au, 1 lakefrontlittleelm.com, 1 -lakehavasucityhomebuyerscredit.com, 1 lakehavasucitynews.com, 1 lakehavasuhomebuyercredit.com, 1 lakehavasuhomes.info, 1 @@ -20729,7 +20734,6 @@ lihaul.dnsalias.net, 1 lijero.co, 1 likc.me, 1 like.lgbt, 1 -likeablehub.com, 1 likeabox.de, 1 likeaross.com, 0 likegeeks.com, 1 @@ -21698,7 +21702,6 @@ maktoob.search.yahoo.com, 0 maku.edu.tr, 1 malachiteauth.com, 1 malamutedoalasca.com.br, 1 -malash.me, 1 malasuk.com, 1 malaysia.search.yahoo.com, 0 malaysian.dating, 1 @@ -21844,7 +21847,6 @@ maquinariaspesadas.org, 1 mar-eco.no, 1 marabumadrid.com, 1 marakovits.net, 1 -maranatha.pl, 1 marbinvest.com, 1 marble.com, 1 marbogardenlidkoping.se, 1 @@ -22331,6 +22333,7 @@ mdek.at, 1 mdewendt.de, 1 mdf-bis.com, 1 mdiv.pl, 1 +mdkr.nl, 1 mdlayher.com, 1 mdma.net, 1 mdmed.clinic, 1 @@ -22412,6 +22415,7 @@ medicinskavranje.edu.rs, 1 medicocompetente.it, 1 medicoresponde.com.br, 1 medienweite.de, 1 +medifab.online, 1 medifi.com, 1 medigap-quote.net, 1 medinside.ch, 1 @@ -23498,7 +23502,6 @@ movienang.com, 1 movienized.de, 1 moviepilot.com, 1 moviesetc.net, 1 -moviespur.info, 1 movil.uno, 1 movimento-terra.it, 1 moving-pixtures.de, 1 @@ -23537,6 +23540,7 @@ mpserver12.org, 1 mpsgarage.com.au, 1 mpsoundcraft.com, 1 mpy.ovh, 1 +mqas.net, 1 mr-anderson.org, 1 mr-coffee.net, 1 mr-labo.jp, 1 @@ -24094,6 +24098,7 @@ n26.com, 1 n2servers.com, 1 n3twork.net, 1 n4v.eu, 1 +n64chan.me, 1 n6a.net, 1 n7.education, 1 na-school.nl, 1 @@ -24118,7 +24123,7 @@ nadyaolcer.fr, 1 nafod.net, 1 naga-semi.com, 1 nagaragem.com.br, 1 -nagashi.ma, 1 +nagashi.ma, 0 nagaya.biz, 1 nagb.gov, 1 nagb.org, 1 @@ -24182,7 +24187,6 @@ nanubo.com, 1 nanubo.de, 1 naoar.com, 1 naomi.es, 0 -naomiheji.com, 1 naotone.com, 1 napcae.de, 1 naphex.rocks, 1 @@ -24365,6 +24369,7 @@ ncconsumer.org, 1 ncdesigns-studio.com, 1 ncea.net.au, 1 nchangfong.com, 1 +nchristo.com, 1 ncic.gg, 1 nclvle.co.uk, 1 ncrmnt.org, 1 @@ -24581,7 +24586,6 @@ netsystems.pro, 1 nettamente.com, 1 nette.org, 1 nettegeschenke.de, 1 -nettia.fi, 1 netto-service.ch, 1 nettools.link, 1 nettopower.dk, 1 @@ -26847,7 +26851,6 @@ philippheenen.de, 1 philippkeschl.at, 1 phillipgoldfarb.com, 1 phillippi.me, 1 -philonas.net, 1 philosoftware.com.br, 1 philosopherswool.com, 1 philosophyguides.org, 1 @@ -26911,7 +26914,6 @@ phuket-idc.de, 1 phunehehe.net, 1 phuong.faith, 1 phurl.de, 1 -phurl.io, 1 phus.lu, 1 physicalism.com, 1 physicalist.com, 1 @@ -28505,7 +28507,6 @@ rainbowbay.org, 1 rainbowinflatables.co.uk, 1 rainbowstore.com.au, 1 rainbowstore.com.ua, 1 -rainel.at, 1 rainforest.engineering, 1 rainpaper.com, 1 rainstormsinjuly.co, 1 @@ -28668,7 +28669,6 @@ rdfproject.it, 1 rdfz.tech, 1 rdh.asia, 1 rdl.at, 0 -rdmrotterdam.nl, 1 rdmtaxservice.com, 1 rdns.cc, 1 re-curi.com, 1 @@ -28950,7 +28950,7 @@ rejahrehim.com, 1 rejsehuskelisten.dk, 1 rejushiiplotter.ru, 1 rekorsanat.com.tr, 1 -rekyou.com, 1 +rekyou.com, 0 relates.link, 1 relatethesport.com, 0 relatic.net, 1 @@ -29576,7 +29576,6 @@ rosewoodranch.com, 1 rosi-royal.com, 1 roslynpad.net, 1 rospa100.com, 1 -rossclark.com, 1 rosset.me, 1 rosset.net, 1 rossfrancis.co.uk, 1 @@ -30262,7 +30261,6 @@ schaper-sport.com, 1 schatmeester.be, 1 schatzibaers.de, 1 schawe.me, 1 -schd.io, 1 scheduleme.io, 1 scheemadigital.com, 1 schefczyk.com, 1 @@ -30398,6 +30396,7 @@ scijinks.gov, 1 scimage.com, 1 scintilla.nl, 1 scintillating.stream, 1 +scionasset.com, 1 scis.com.ua, 1 scistarter.com, 1 scitopia.me, 1 @@ -30622,7 +30621,6 @@ securitybrief.com.au, 1 securitybrief.eu, 1 securityfest.com, 1 securityheaders.com, 1 -securityheaders.io, 1 securityinet.com, 0 securitykey.co, 1 securitymap.wiki, 1 @@ -31459,7 +31457,6 @@ sinatrafamily.com, 1 sinceschool.com, 1 sinclairinat0r.com, 1 sinde.ru, 1 -sinefili.com, 1 sinergy.ch, 1 sinfield.com, 0 sinfulforums.net, 1 @@ -31656,7 +31653,7 @@ sladic.si, 0 slainvet.net, 1 slamdjapan.com, 1 slamix.nl, 1 -slane.cn, 1 +slane.cn, 0 slangbellor.com, 1 slapen17.nl, 1 slaps.be, 1 @@ -31902,6 +31899,7 @@ snowhaze.ch, 1 snowhaze.com, 1 snowplane.net, 1 snowraven.de, 1 +snrat.com, 1 snrub.co, 1 snuff.porn, 1 snughealth.org.uk, 1 @@ -34376,6 +34374,7 @@ thisoldearth.com, 1 thisserver.dontexist.net, 1 thistleandleaves.com, 1 thm.vn, 1 +thole.org, 1 thom4s.info, 1 thomalaudan.de, 1 thomas-bertran.com, 1 @@ -34537,7 +34536,6 @@ timeglass.de, 1 timer.fit, 1 timersuite.com, 1 timestamp.uk, 1 -timetab.org, 1 timetech.io, 1 timetotrade.com, 1 timewasters.nl, 1 @@ -35944,7 +35942,6 @@ urbanmelbourne.info, 1 urbanmic.com, 1 urbannewsservice.com, 1 urbansparrow.in, 1 -urbanstylestaging.com, 1 urbanwildlifealliance.org, 0 urbexdk.nl, 1 urcentral.com, 1 @@ -36156,7 +36153,6 @@ vanderbiltcisa.org, 1 vanderkrieken.org, 1 vanderkroon.nl, 1 vandermeer.frl, 1 -vanderrijt.nl, 1 vanderstraeten.dynv6.net, 1 vanderziel.org, 1 vaneigenkweek.be, 1 @@ -36734,7 +36730,7 @@ volgavibes.ru, 0 voliere-info.nl, 0 volker-gropp.de, 1 volkergropp.de, 1 -volkerwesselstransfer.nl, 1 +volkerwesselstransfer.nl, 0 volkerwesselswave.nl, 0 volkswurst.de, 1 vollans.id.au, 1 @@ -36763,7 +36759,7 @@ vorodevops.com, 1 vos-fleurs.ch, 1 vos-fleurs.com, 1 vosgym.jp, 1 -voshod.org, 0 +voshod.org, 1 vosjesweb.nl, 1 vosky.fr, 1 vosn.de, 1 @@ -36980,6 +36976,7 @@ waonui.io, 1 warcraftjournal.org, 1 wardow.com, 1 warebouncycastles.co.uk, 1 +warekit.io, 1 warekon.com, 1 warekon.dk, 1 warenits.at, 0 @@ -36996,6 +36993,7 @@ warr.ath.cx, 1 warringtonkidsbouncycastles.co.uk, 1 warschild.org, 1 wartorngalaxy.com, 1 +wasatchconstables.com, 1 waschpark-hantschel.de, 1 wasema.com, 1 wasfestes.de, 1 @@ -37073,7 +37071,6 @@ we.serveftp.net, 1 weacceptbitcoin.gr, 1 wealthcentral.com.au, 1 wealthfactory.com, 0 -wealthformyhealth.com, 1 wealthprojector.com, 1 wealthprojector.com.au, 1 wealthreport.com.au, 1 @@ -37506,7 +37503,6 @@ whisperinghoperanch.org, 1 whisperlab.org, 1 whistleb.com, 1 whistleblower.gov, 1 -whistler-transfers.com, 1 whitby-brewery.com, 1 whitealps.at, 1 whitealps.be, 1 @@ -37882,6 +37878,7 @@ workray.com, 1 works-ginan.jp, 1 workshopszwolle.nl, 1 workshopzwolle.com, 1 +worksofwyoming.org, 1 workwithgo.com, 1 world-education-association.org, 1 world-in-my-eyes.com, 1 @@ -37939,12 +37936,14 @@ wpac.de, 1 wpandup.org, 1 wpcanban.com, 1 wpcdn.bid, 1 +wpcharged.nz, 1 wpcheck.io, 1 wpdesigner.ir, 1 wpdirecto.com, 1 wpdublin.com, 1 wpenhance.com, 1 wpformation.com, 1 +wpg-inc.com, 1 wphelpwithhomework.tk, 1 wphostingblog.nl, 1 wpinfos.de, 1 @@ -39020,6 +39019,7 @@ zargaripour.com, 1 zargescases.co.uk, 1 zarmarket.org, 1 zarpo.com.br, 1 +zary.me, 1 zatsepin.by, 1 zaufanatrzeciastrona.pl, 1 zavec.com.ec, 1 @@ -39239,7 +39239,7 @@ zoola.io, 1 zoological-gardens.eu, 1 zoom.earth, 1 zoomek.com, 1 -zoomseoservices.com, 1 +zoomseoservices.com, 0 zooom.azurewebsites.net, 1 zooom2.azurewebsites.net, 1 zooparadies.eu, 1 diff --git a/servo/components/style/gecko/rules.rs b/servo/components/style/gecko/rules.rs index ccf49f829700..2f1442796569 100644 --- a/servo/components/style/gecko/rules.rs +++ b/servo/components/style/gecko/rules.rs @@ -25,7 +25,7 @@ impl<'a> ToNsCssValue for &'a FamilyName { impl ToNsCssValue for font_weight::T { fn convert(self, nscssvalue: &mut nsCSSValue) { - nscssvalue.set_integer(self.0 as i32) + nscssvalue.set_font_weight(self.0) } } @@ -34,7 +34,7 @@ impl<'a> ToNsCssValue for &'a FontWeight { match *self { FontWeight::Normal => nscssvalue.set_enum(structs::NS_FONT_WEIGHT_NORMAL as i32), FontWeight::Bold => nscssvalue.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32), - FontWeight::Weight(weight) => nscssvalue.set_integer(weight.0 as i32), + FontWeight::Weight(weight) => nscssvalue.set_font_weight(weight.0), } } } diff --git a/servo/components/style/gecko_bindings/sugar/ns_css_value.rs b/servo/components/style/gecko_bindings/sugar/ns_css_value.rs index 4507e3fbd6b7..456935615106 100644 --- a/servo/components/style/gecko_bindings/sugar/ns_css_value.rs +++ b/servo/components/style/gecko_bindings/sugar/ns_css_value.rs @@ -177,6 +177,11 @@ impl nsCSSValue { self.set_string_from_atom_internal(s, nsCSSUnit::eCSSUnit_Local_Font); } + /// Set to a font weight + pub fn set_font_weight(&mut self, w: u16) { + unsafe { bindings::Gecko_CSSValue_SetFontWeight(self, w as f32) } + } + fn set_int_internal(&mut self, value: i32, unit: nsCSSUnit) { unsafe { bindings::Gecko_CSSValue_SetInt(self, value, unit) } } diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index 16c75025f41f..067d014442d4 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -25,6 +25,8 @@ use gecko_bindings::bindings::Gecko_CopyFontFamilyFrom; use gecko_bindings::bindings::Gecko_CopyImageValueFrom; use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom; use gecko_bindings::bindings::Gecko_EnsureImageLayersLength; +use gecko_bindings::bindings::Gecko_FontWeight_SetFloat; +use gecko_bindings::bindings::Gecko_FontWeight_ToFloat; use gecko_bindings::bindings::Gecko_SetCursorArrayLength; use gecko_bindings::bindings::Gecko_SetCursorImageValue; use gecko_bindings::bindings::Gecko_StyleTransition_SetUnsupportedProperty; @@ -2599,13 +2601,15 @@ fn static_assert() { } pub fn set_font_weight(&mut self, v: longhands::font_weight::computed_value::T) { - self.gecko.mFont.weight = v.0; + unsafe { Gecko_FontWeight_SetFloat(&mut self.gecko.mFont.weight, v.0 as f32) }; } ${impl_simple_copy('font_weight', 'mFont.weight')} pub fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T { - debug_assert!(self.gecko.mFont.weight <= ::std::u16::MAX); - longhands::font_weight::computed_value::T(self.gecko.mFont.weight) + let weight: f32 = unsafe { Gecko_FontWeight_ToFloat(self.gecko.mFont.weight) }; + debug_assert!(weight >= 0.0 && + weight <= ::std::u16::MAX as f32); + longhands::font_weight::computed_value::T(weight as u16) } ${impl_simple_type_with_conversion("font_synthesis", "mFont.synthesis")} diff --git a/servo/components/style/values/computed/font.rs b/servo/components/style/values/computed/font.rs index 0863311fe17b..c270969a52f1 100644 --- a/servo/components/style/values/computed/font.rs +++ b/servo/components/style/values/computed/font.rs @@ -75,10 +75,12 @@ impl FontWeight { } /// Convert from an Gecko weight - pub fn from_gecko_weight(weight: u16) -> Self { + #[cfg(feature = "gecko")] + pub fn from_gecko_weight(weight: structs::FontWeight) -> Self { // we allow a wider range of weights than is parseable // because system fonts may provide custom values - FontWeight(weight) + let weight = unsafe { bindings::Gecko_FontWeight_ToFloat(weight) }; + FontWeight(weight as u16) } /// Weither this weight is bold diff --git a/taskcluster/ci/config.yml b/taskcluster/ci/config.yml index 67dece91d655..e56b3569ce7c 100755 --- a/taskcluster/ci/config.yml +++ b/taskcluster/ci/config.yml @@ -1,4 +1,5 @@ trust-domain: gecko +project-repo-param-prefix: '' treeherder: group-names: 'cram': 'Cram tests' diff --git a/taskcluster/ci/repo-update-bb/kind.yml b/taskcluster/ci/repo-update-bb/kind.yml deleted file mode 100644 index 2c6576484eaa..000000000000 --- a/taskcluster/ci/repo-update-bb/kind.yml +++ /dev/null @@ -1,21 +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/. - -loader: taskgraph.loader.transform:loader - -transforms: - - taskgraph.transforms.job:transforms - - taskgraph.transforms.task:transforms - - -jobs: - hsts-hpkp-blocklist: - name: periodic_file_update - description: HSTS, HPKP, and Blocklist update - worker-type: buildbot-bridge/buildbot-bridge - run-on-projects: [] # Only run via cron - run: - using: buildbot - product: firefox - buildername: Linux x86-64 {branch} periodic file update diff --git a/taskcluster/docs/actions.rst b/taskcluster/docs/actions.rst index a3497e0c597f..92fc9437a54d 100644 --- a/taskcluster/docs/actions.rst +++ b/taskcluster/docs/actions.rst @@ -52,7 +52,7 @@ To create a new callback action you must create a file description="Simple **proof-of-concept** callback action", order=10000, # Order in which it should appear relative to other actions ) - def hello_world_action(parameters, input, task_group_id, task_id, task): + def hello_world_action(parameters, graph_config, input, task_group_id, task_id, task): # parameters is an instance of taskgraph.parameters.Parameters # it carries decision task parameters from the original decision task. # input, task_id, and task should all be None @@ -112,7 +112,7 @@ The example action below will be shown in the context-menu for tasks with order=1, context=[{'platform': 'linux'}] ) - def retrigger_action(parameters, input, task_group_id, task_id, task): + def retrigger_action(parameters, graph_config, input, task_group_id, task_id, task): # input will be None print "Retriggering: {}".format(task_id) print "task definition: {}".format(task) @@ -175,7 +175,7 @@ both ``input`` and ``context``:: 'additionalProperties': False, }, ) - def retrigger_action(parameters, input, task_group_id, task_id, task): + def retrigger_action(parameters, graph_config, input, task_group_id, task_id, task): print "Create all pruned tasks with priority: {}".format(input['priority']) if input['runTalos']: print "Also running talos jobs..." @@ -211,7 +211,7 @@ The feature is illustrated below:: # Define an action that is only included if this is a push to try available=lambda parameters: parameters.get('project', None) == 'try', ) - def try_only_action(parameters, input, task_group_id, task_id, task): + def try_only_action(parameters, graph_config, input, task_group_id, task_id, task): print "My try-only action" Properties of ``parameters`` are documented in the @@ -245,7 +245,7 @@ The example below illustrates how to create such an action in Python:: 'default': 'low', }, ) - def task_template_builder(parameters): + def task_template_builder(parameters, graph_config): # The task template builder may return None to signal that the action # isn't available. if parameters.get('project', None) != 'try': diff --git a/taskcluster/docs/kinds.rst b/taskcluster/docs/kinds.rst index fb202d09ea14..569e05541e17 100644 --- a/taskcluster/docs/kinds.rst +++ b/taskcluster/docs/kinds.rst @@ -375,12 +375,6 @@ repo-update Repo-Update tasks are tasks that perform some action on the project repo itself, in order to update its state in some way. -repo-update-bb --------------- -Repo-Update tasks are tasks that perform some action on the project repo itself, -in order to update its state in some way. This kind is the older, buildbot version. -It will be removed after the migration to taskcluster. - partials -------- Partials takes the complete.mar files produced in previous tasks and generates partial diff --git a/taskcluster/mach_commands.py b/taskcluster/mach_commands.py index 630fb168fe16..bfe8c7c6f199 100644 --- a/taskcluster/mach_commands.py +++ b/taskcluster/mach_commands.py @@ -212,6 +212,8 @@ class MachCommands(MachCommandBase): @SubCommand('taskgraph', 'action-callback', description='Run action callback used by action tasks') + @CommandArgument('--root', '-r', default='taskcluster/ci', + help="root of the taskgraph definition relative to topsrcdir") def action_callback(self, **options): import taskgraph.actions try: @@ -223,6 +225,7 @@ class MachCommands(MachCommandBase): input = json.loads(os.environ.get('ACTION_INPUT', 'null')) callback = os.environ.get('ACTION_CALLBACK', None) parameters = json.loads(os.environ.get('ACTION_PARAMETERS', '{}')) + root = options['root'] return taskgraph.actions.trigger_action_callback( task_group_id=task_group_id, @@ -231,6 +234,7 @@ class MachCommands(MachCommandBase): input=input, callback=callback, parameters=parameters, + root=root, test=False) except Exception: traceback.print_exc() @@ -238,6 +242,8 @@ class MachCommands(MachCommandBase): @SubCommand('taskgraph', 'test-action-callback', description='Run an action callback in a testing mode') + @CommandArgument('--root', '-r', default='taskcluster/ci', + help="root of the taskgraph definition relative to topsrcdir") @CommandArgument('--parameters', '-p', default='project=mozilla-central', help='parameters file (.yml or .json; see ' '`taskcluster/docs/parameters.rst`)`') @@ -285,6 +291,8 @@ class MachCommands(MachCommandBase): parameters = taskgraph.parameters.load_parameters_file(options['parameters']) parameters.check() + root = options['root'] + return taskgraph.actions.trigger_action_callback( task_group_id=options['task_group_id'], task_id=task_id, @@ -292,6 +300,7 @@ class MachCommands(MachCommandBase): input=input, callback=options['callback'], parameters=parameters, + root=root, test=True) except Exception: traceback.print_exc() diff --git a/taskcluster/taskgraph/actions/add_new_jobs.py b/taskcluster/taskgraph/actions/add_new_jobs.py index a7a64e17931c..60b0b8736be7 100644 --- a/taskcluster/taskgraph/actions/add_new_jobs.py +++ b/taskcluster/taskgraph/actions/add_new_jobs.py @@ -31,8 +31,9 @@ from .util import (create_tasks, fetch_graph_and_labels) } } ) -def add_new_jobs_action(parameters, input, task_group_id, task_id, task): - decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(parameters) +def add_new_jobs_action(parameters, graph_config, input, task_group_id, task_id, task): + decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels( + parameters, graph_config) to_run = [] for elem in input['tasks']: diff --git a/taskcluster/taskgraph/actions/add_talos.py b/taskcluster/taskgraph/actions/add_talos.py index 6c141bde453d..2698529f295e 100644 --- a/taskcluster/taskgraph/actions/add_talos.py +++ b/taskcluster/taskgraph/actions/add_talos.py @@ -36,8 +36,9 @@ logger = logging.getLogger(__name__) 'additionalProperties': False }, ) -def add_all_talos(parameters, input, task_group_id, task_id, task): - decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(parameters) +def add_all_talos(parameters, graph_config, input, task_group_id, task_id, task): + decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels( + parameters, graph_config) times = input.get('times', 1) for i in xrange(times): diff --git a/taskcluster/taskgraph/actions/backfill.py b/taskcluster/taskgraph/actions/backfill.py index 4de8086914d7..4ca1898a699a 100644 --- a/taskcluster/taskgraph/actions/backfill.py +++ b/taskcluster/taskgraph/actions/backfill.py @@ -48,7 +48,7 @@ logger = logging.getLogger(__name__) }, available=lambda parameters: parameters.get('project', None) != 'try' ) -def backfill_action(parameters, input, task_group_id, task_id, task): +def backfill_action(parameters, graph_config, input, task_group_id, task_id, task): label = task['metadata']['name'] pushes = [] depth = input.get('depth', 5) @@ -82,7 +82,7 @@ def backfill_action(parameters, input, task_group_id, task_id, task): push_params = get_artifact_from_index( INDEX_TMPL.format(parameters['project'], push), 'public/parameters.yml') - push_decision_task_id = find_decision_task(push_params) + push_decision_task_id = find_decision_task(push_params, graph_config) except HTTPError as e: logger.info('Skipping {} due to missing index artifacts! Error: {}'.format(push, e)) continue diff --git a/taskcluster/taskgraph/actions/mochitest_retrigger.py b/taskcluster/taskgraph/actions/mochitest_retrigger.py index 496ba16c61d1..e877a6346a7b 100644 --- a/taskcluster/taskgraph/actions/mochitest_retrigger.py +++ b/taskcluster/taskgraph/actions/mochitest_retrigger.py @@ -79,8 +79,9 @@ logger = logging.getLogger(__name__) 'required': ['path'] } ) -def mochitest_retrigger_action(parameters, input, task_group_id, task_id, task): - decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(parameters) +def mochitest_retrigger_action(parameters, graph_config, input, task_group_id, task_id, task): + decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels( + parameters, graph_config) pre_task = full_task_graph.tasks[task['metadata']['name']] diff --git a/taskcluster/taskgraph/actions/registry.py b/taskcluster/taskgraph/actions/registry.py index f2516c906c68..09d74889375b 100644 --- a/taskcluster/taskgraph/actions/registry.py +++ b/taskcluster/taskgraph/actions/registry.py @@ -11,10 +11,10 @@ import os import re import yaml from slugid import nice as slugid -from mozbuild.util import memoize from types import FunctionType from collections import namedtuple from taskgraph import create, GECKO +from taskgraph.generator import load_graph_config from taskgraph.util import taskcluster from taskgraph.parameters import Parameters @@ -173,19 +173,26 @@ def register_callback_action(name, title, symbol, description, order=10000, assert cb.__name__ not in callbacks, 'callback name {} is not unique'.format(cb.__name__) @register_task_action(name, title, description, order, context, schema) - def build_callback_action_task(parameters): + def build_callback_action_task(parameters, graph_config): if not available(parameters): return None - match = re.match(r'https://(hg.mozilla.org)/(.*?)/?$', parameters['head_repository']) + repo_param = '{}head_repository'.format(graph_config['project-repo-param-prefix']) + revision = parameters['{}head_rev'.format(graph_config['project-repo-param-prefix'])] + match = re.match(r'https://(hg.mozilla.org)/(.*?)/?$', parameters[repo_param]) if not match: - raise Exception('Unrecognized head_repository') + raise Exception('Unrecognized {}'.format(repo_param)) repo_scope = 'assume:repo:{}/{}:branch:default'.format( match.group(1), match.group(2)) task_group_id = os.environ.get('TASK_ID', slugid()) - template = os.path.join(GECKO, '.taskcluster.yml') + # FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=1454034 + # trust-domain works, but isn't semantically correct here. + if graph_config['trust-domain'] == 'comm': + template = os.path.join(GECKO, 'comm', '.taskcluster.yml') + else: + template = os.path.join(GECKO, '.taskcluster.yml') with open(template, 'r') as f: taskcluster_yml = yaml.safe_load(f) @@ -198,14 +205,14 @@ def register_callback_action(name, title, symbol, description, order=10000, '$let': { 'tasks_for': 'action', 'repository': { - 'url': parameters['head_repository'], + 'url': parameters[repo_param], 'project': parameters['project'], 'level': parameters['level'], }, 'push': { 'owner': 'mozilla-taskcluster-maintenance@mozilla.com', 'pushlog_id': parameters['pushlog_id'], - 'revision': parameters['head_rev'], + 'revision': revision, }, 'action': { 'name': name, @@ -225,7 +232,7 @@ def register_callback_action(name, title, symbol, description, order=10000, return register_callback -def render_actions_json(parameters): +def render_actions_json(parameters, graph_config): """ Render JSON object for the ``public/actions.json`` artifact. @@ -241,8 +248,8 @@ def render_actions_json(parameters): """ assert isinstance(parameters, Parameters), 'requires instance of Parameters' result = [] - for action in sorted(get_actions(), key=lambda action: action.order): - task = action.task_template_builder(parameters) + for action in sorted(_get_actions(graph_config), key=lambda action: action.order): + task = action.task_template_builder(parameters, graph_config) if task: assert is_json(task), 'task must be a JSON compatible object' res = { @@ -266,26 +273,27 @@ def render_actions_json(parameters): } -def trigger_action_callback(task_group_id, task_id, task, input, callback, parameters, +def trigger_action_callback(task_group_id, task_id, task, input, callback, parameters, root, test=False): """ Trigger action callback with the given inputs. If `test` is true, then run the action callback in testing mode, without actually creating tasks. """ - cb = get_callbacks().get(callback, None) + graph_config = load_graph_config(root) + callbacks = _get_callbacks(graph_config) + cb = callbacks.get(callback, None) if not cb: raise Exception('Unknown callback: {}. Known callbacks: {}'.format( - callback, get_callbacks().keys())) + callback, callbacks)) if test: create.testing = True taskcluster.testing = True - cb(Parameters(**parameters), input, task_group_id, task_id, task) + cb(Parameters(**parameters), graph_config, input, task_group_id, task_id, task) -@memoize -def _load(): +def _load(graph_config): # Load all modules from this folder, relying on the side-effects of register_ # functions to populate the action registry. actions_dir = os.path.dirname(__file__) @@ -295,13 +303,13 @@ def _load(): if f.endswith('.yml'): with open(os.path.join(actions_dir, f), 'r') as d: frontmatter, template = yaml.safe_load_all(d) - register_task_action(**frontmatter)(lambda _: template) + register_task_action(**frontmatter)(lambda _p, _g: template) return callbacks, actions -def get_callbacks(): - return _load()[0] +def _get_callbacks(graph_config): + return _load(graph_config)[0] -def get_actions(): - return _load()[1] +def _get_actions(graph_config): + return _load(graph_config)[1] diff --git a/taskcluster/taskgraph/actions/release_promotion.py b/taskcluster/taskgraph/actions/release_promotion.py index c73c75f0aba0..388327efb533 100644 --- a/taskcluster/taskgraph/actions/release_promotion.py +++ b/taskcluster/taskgraph/actions/release_promotion.py @@ -212,7 +212,7 @@ def is_release_promotion_available(parameters): "required": ['release_promotion_flavor', 'build_number'], } ) -def release_promotion_action(parameters, input, task_group_id, task_id, task): +def release_promotion_action(parameters, graph_config, input, task_group_id, task_id, task): release_promotion_flavor = input['release_promotion_flavor'] promotion_config = RELEASE_PROMOTION_CONFIG[release_promotion_flavor] release_history = {} @@ -262,8 +262,8 @@ def release_promotion_action(parameters, input, task_group_id, task_id, task): if not previous_graph_ids: revision = input.get('revision') parameters['pushlog_id'] = parameters['pushlog_id'] or \ - find_hg_revision_pushlog_id(parameters, revision) - previous_graph_ids = [find_decision_task(parameters)] + find_hg_revision_pushlog_id(parameters, graph_config, revision) + previous_graph_ids = [find_decision_task(parameters, graph_config)] # Download parameters from the first decision task parameters = get_artifact(previous_graph_ids[0], "public/parameters.yml") diff --git a/taskcluster/taskgraph/actions/rerun.py b/taskcluster/taskgraph/actions/rerun.py index aa025e24782a..27029585cad1 100644 --- a/taskcluster/taskgraph/actions/rerun.py +++ b/taskcluster/taskgraph/actions/rerun.py @@ -37,9 +37,10 @@ RERUN_STATES = ('exception', 'failed') 'properties': {} } ) -def rerun_action(parameters, input, task_group_id, task_id, task): +def rerun_action(parameters, graph_config, input, task_group_id, task_id, task): parameters = dict(parameters) - decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(parameters) + decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels( + parameters, graph_config) label = task['metadata']['name'] if task_id not in label_to_taskid.values(): logger.error( diff --git a/taskcluster/taskgraph/actions/retrigger.py b/taskcluster/taskgraph/actions/retrigger.py index 1576e6f786a2..a547372628e2 100644 --- a/taskcluster/taskgraph/actions/retrigger.py +++ b/taskcluster/taskgraph/actions/retrigger.py @@ -48,8 +48,9 @@ logger = logging.getLogger(__name__) } } ) -def retrigger_action(parameters, input, task_group_id, task_id, task): - decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(parameters) +def retrigger_action(parameters, graph_config, input, task_group_id, task_id, task): + decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels( + parameters, graph_config) label = task['metadata']['name'] with_downstream = ' ' diff --git a/taskcluster/taskgraph/actions/run_missing_tests.py b/taskcluster/taskgraph/actions/run_missing_tests.py index 658e1ebad807..49c050e024cc 100644 --- a/taskcluster/taskgraph/actions/run_missing_tests.py +++ b/taskcluster/taskgraph/actions/run_missing_tests.py @@ -28,8 +28,9 @@ logger = logging.getLogger(__name__) order=100, # Useful for sheriffs, but not top of the list context=[], # Applies to decision task ) -def run_missing_tests(parameters, input, task_group_id, task_id, task): - decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(parameters) +def run_missing_tests(parameters, graph_config, input, task_group_id, task_id, task): + decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels( + parameters, graph_config) target_tasks = get_artifact(decision_task_id, "public/target-tasks.json") # The idea here is to schedule all tasks of the `test` kind that were diff --git a/taskcluster/taskgraph/actions/util.py b/taskcluster/taskgraph/actions/util.py index 081c22137390..78af1667b041 100644 --- a/taskcluster/taskgraph/actions/util.py +++ b/taskcluster/taskgraph/actions/util.py @@ -24,18 +24,21 @@ logger = logging.getLogger(__name__) PUSHLOG_TMPL = '{}/json-pushes?version=2&changeset={}&tipsonly=1&full=1' -def find_decision_task(parameters): +def find_decision_task(parameters, graph_config): """Given the parameters for this action, find the taskId of the decision task""" - return find_task_id('gecko.v2.{}.pushlog-id.{}.decision'.format( + return find_task_id('{}.v2.{}.pushlog-id.{}.decision'.format( + graph_config['trust-domain'], parameters['project'], parameters['pushlog_id'])) -def find_hg_revision_pushlog_id(parameters, revision): +def find_hg_revision_pushlog_id(parameters, graph_config, revision): """Given the parameters for this action and a revision, find the pushlog_id of the revision.""" - pushlog_url = PUSHLOG_TMPL.format(parameters['head_repository'], revision) + + repo_param = '{}head_repository'.format(graph_config['project-repo-param-prefix']) + pushlog_url = PUSHLOG_TMPL.format(parameters[repo_param], revision) r = requests.get(pushlog_url) r.raise_for_status() pushes = r.json()['pushes'].keys() @@ -63,8 +66,8 @@ def find_existing_tasks_from_previous_kinds(full_task_graph, previous_graph_ids, return existing_tasks -def fetch_graph_and_labels(parameters): - decision_task_id = find_decision_task(parameters) +def fetch_graph_and_labels(parameters, graph_config): + decision_task_id = find_decision_task(parameters, graph_config) # First grab the graph and labels generated during the initial decision task full_task_graph = get_artifact(decision_task_id, "public/full-task-graph.json") @@ -73,7 +76,8 @@ def fetch_graph_and_labels(parameters): # Now fetch any modifications made by action tasks and swap out new tasks # for old ones - namespace = 'gecko.v2.{}.pushlog-id.{}.actions'.format( + namespace = '{}.v2.{}.pushlog-id.{}.actions'.format( + graph_config['trust-domain'], parameters['project'], parameters['pushlog_id']) for action in list_tasks(namespace): diff --git a/taskcluster/taskgraph/config.py b/taskcluster/taskgraph/config.py index 34641a0a051c..d7b1a5417280 100644 --- a/taskcluster/taskgraph/config.py +++ b/taskcluster/taskgraph/config.py @@ -11,12 +11,16 @@ graph_config_schema = Schema({ # The trust-domain for this graph. # (See https://firefox-source-docs.mozilla.org/taskcluster/taskcluster/taskgraph.html#taskgraph-trust-domain) # noqa Required('trust-domain'): basestring, + # This specifes the prefix for repo parameters that refer to the project being built. + # This selects between `head_rev` and `comm_head_rev` and related paramters. + # (See http://firefox-source-docs.mozilla.org/taskcluster/taskcluster/parameters.html#push-information # noqa + # and http://firefox-source-docs.mozilla.org/taskcluster/taskcluster/parameters.html#comm-push-information) # noqa + Required('project-repo-param-prefix'): basestring, Required('treeherder'): { # Mapping of treeherder group symbols to descriptive names Required('group-names'): {basestring: basestring} }, Required('index'): { - Required('products'): [basestring], }, Required('try'): { diff --git a/taskcluster/taskgraph/decision.py b/taskcluster/taskgraph/decision.py index 71fcafa31b4e..c1d42b127906 100644 --- a/taskcluster/taskgraph/decision.py +++ b/taskcluster/taskgraph/decision.py @@ -131,7 +131,7 @@ def taskgraph_decision(options, parameters=None): write_artifact('parameters.yml', dict(**parameters)) # write out the public/actions.json file - write_artifact('actions.json', render_actions_json(parameters)) + write_artifact('actions.json', render_actions_json(parameters, tgg.graph_config)) # write out the full graph for reference full_task_json = tgg.full_task_graph.to_json() diff --git a/taskcluster/taskgraph/generator.py b/taskcluster/taskgraph/generator.py index fa4d921442fd..1055710535ed 100644 --- a/taskcluster/taskgraph/generator.py +++ b/taskcluster/taskgraph/generator.py @@ -213,6 +213,15 @@ class TaskGraphGenerator(object): """ return self._run_until('morphed_task_graph') + @property + def graph_config(self): + """ + The configuration for this graph. + + @type: TaskGraph + """ + return self._run_until('graph_config') + def _load_kinds(self, graph_config): for kind_name in os.listdir(self.root_dir): try: @@ -224,6 +233,8 @@ class TaskGraphGenerator(object): logger.info("Loading graph configuration.") graph_config = load_graph_config(self.root_dir) + yield verifications('graph_config', graph_config) + logger.info("Loading kinds") # put the kinds into a graph and sort topologically so that kinds are loaded # in post-order diff --git a/taskcluster/taskgraph/target_tasks.py b/taskcluster/taskgraph/target_tasks.py index b9242285508f..ad1a83e518af 100644 --- a/taskcluster/taskgraph/target_tasks.py +++ b/taskcluster/taskgraph/target_tasks.py @@ -619,5 +619,5 @@ def target_tasks_file_update(full_task_graph, parameters, graph_config): """ def filter(task): # For now any task in the repo-update kind is ok - return task.kind in ['repo-update', 'repo-update-bb'] + return task.kind in ['repo-update'] return [l for l, t in full_task_graph.tasks.iteritems() if filter(t)] diff --git a/taskcluster/taskgraph/transforms/task.py b/taskcluster/taskgraph/transforms/task.py index 8996bf528dc1..1d9d0f9fc830 100644 --- a/taskcluster/taskgraph/transforms/task.py +++ b/taskcluster/taskgraph/transforms/task.py @@ -614,25 +614,9 @@ V2_L10N_TEMPLATES = [ # the roots of the treeherder routes TREEHERDER_ROUTE_ROOT = 'tc-treeherder' -# Which repository repository revision to use when reporting results to treeherder. -DEFAULT_BRANCH_REV_PARAM = 'head_rev' -BRANCH_REV_PARAM = { - 'comm-esr45': 'comm_head_rev', - 'comm-esr52': 'comm_head_rev', - 'comm-beta': 'comm_head_rev', - 'comm-central': 'comm_head_rev', - 'comm-aurora': 'comm_head_rev', - 'try-comm-central': 'comm_head_rev', -} - def get_branch_rev(config): - return config.params[ - BRANCH_REV_PARAM.get( - config.params['project'], - DEFAULT_BRANCH_REV_PARAM - ) - ] + return config.params['{}head_rev'.format(config.graph_config['project-repo-param-prefix'])] COALESCE_KEY = '{project}.{job-identifier}' @@ -1549,7 +1533,7 @@ def build_task(config, tasks): ) if 'expires-after' not in task: - task['expires-after'] = '28 days' if config.params['project'] == 'try' else '1 year' + task['expires-after'] = '28 days' if config.params.is_try() else '1 year' if 'deadline-after' not in task: task['deadline-after'] = '1 day' diff --git a/taskcluster/taskgraph/transforms/tests.py b/taskcluster/taskgraph/transforms/tests.py index cc5521a981be..8a83d443299e 100644 --- a/taskcluster/taskgraph/transforms/tests.py +++ b/taskcluster/taskgraph/transforms/tests.py @@ -491,7 +491,7 @@ def setup_talos(config, tests): # Per https://bugzilla.mozilla.org/show_bug.cgi?id=1357753#c3, branch # name is only required for try - if config.params['project'] == 'try': + if config.params.is_try(): extra_options.append('--branch-name') extra_options.append('try') @@ -596,7 +596,7 @@ def set_expires_after(config, tests): keep storage costs low.""" for test in tests: if 'expires-after' not in test: - if config.params['project'] == 'try': + if config.params.is_try(): test['expires-after'] = "14 days" else: test['expires-after'] = "1 year" @@ -976,7 +976,7 @@ def make_job_description(config, tests): jobdesc['when'] = test['when'] elif 'optimization' in test: jobdesc['optimization'] = test['optimization'] - elif config.params['project'] != 'try' and suite not in INCLUSIVE_COMPONENTS: + elif not config.params.is_try() and suite not in INCLUSIVE_COMPONENTS: # for non-try branches and non-inclusive suites, include SETA jobdesc['optimization'] = {'skip-unless-schedules-or-seta': schedules} else: diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index a988c054bc32..7b9ecc33961f 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -2053,29 +2053,29 @@ }, "TLS_EARLY_DATA_NEGOTIATED": { "record_in_processes": ["main", "content"], - "expires_in_version": "62", + "expires_in_version": "66", "kind": "enumerated", "n_values": 3, "description": "Sending TLS early data was possible: 0 - not possible, 1 - possible but not used, 2 - possible and used.", - "alert_emails": ["necko@mozilla.com"], + "alert_emails": ["necko@mozilla.com", "ddamjanovic@mozilla.com"], "bug_numbers": [1296288] }, "TLS_EARLY_DATA_ACCEPTED": { "record_in_processes": ["main", "content"], - "expires_in_version": "62", + "expires_in_version": "66", "kind": "boolean", "description": "TLS early data was used and it was accepted (true) or rejected (false) by the remote host.", - "alert_emails": ["necko@mozilla.com"], + "alert_emails": ["necko@mozilla.com", "ddamjanovic@mozilla.com"], "bug_numbers": [1296288] }, "TLS_EARLY_DATA_BYTES_WRITTEN": { "record_in_processes": ["main", "content"], - "expires_in_version": "62", + "expires_in_version": "66", "kind": "exponential", "high": 60000, "n_buckets": 100, "description": "Amount of bytes sent using TLS early data at the start of a TLS connection for a given channel.", - "alert_emails": ["necko@mozilla.com"], + "alert_emails": ["necko@mozilla.com", "ddamjanovic@mozilla.com"], "bug_numbers": [1296288] }, "SSL_HANDSHAKE_VERSION": { diff --git a/toolkit/components/telemetry/TelemetrySession.jsm b/toolkit/components/telemetry/TelemetrySession.jsm index 2d3f48c49518..b030fa4af34b 100644 --- a/toolkit/components/telemetry/TelemetrySession.jsm +++ b/toolkit/components/telemetry/TelemetrySession.jsm @@ -767,8 +767,6 @@ var Impl = { ret.startupInterrupted = Number(Services.startup.interrupted); - ret.js = Cu.getJSEngineTelemetryValue(); - let maximalNumberOfConcurrentThreads = Telemetry.maximalNumberOfConcurrentThreads; if (maximalNumberOfConcurrentThreads) { ret.maximalNumberOfConcurrentThreads = maximalNumberOfConcurrentThreads; diff --git a/toolkit/components/telemetry/docs/data/main-ping.rst b/toolkit/components/telemetry/docs/data/main-ping.rst index 9fcabda12f70..c4e7d17fc1a9 100644 --- a/toolkit/components/telemetry/docs/data/main-ping.rst +++ b/toolkit/components/telemetry/docs/data/main-ping.rst @@ -184,7 +184,7 @@ Structure: // ... } -As of Firefox 59 this section no longer contains any entries. +As of Firefox 59 this section no longer contains any entries, as of Firefox 61 this section is removed. maximalNumberOfConcurrentThreads ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -697,4 +697,5 @@ Version History - Stopped reporting ``childPayloads`` (`bug 1443599 `_). - Stopped reporting ``saved-session`` pings on Firefox Desktop (`bug 1443603 `_). + - Stopped reporting ``simpleMeasurements.js`` (`bug 1278920 `_). - Stopped reporting ``UITelemetry`` (`bug 1443605 `_) diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index d442334e0c16..327f27523e7d 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1716,8 +1716,8 @@ DumpHelp() " --new-instance Open new instance, not a new window in running instance.\n" " --UILocale Start with resources as UI Locale.\n" " --safe-mode Disables extensions and themes for this session.\n" - " -MOZ_LOG Treated as MOZ_LOG= environment variable, overrides it.\n" - " -MOZ_LOG_FILE Treated as MOZ_LOG_FILE= environment variable, overrides it.\n" + " -MOZ_LOG= Treated as MOZ_LOG= environment variable, overrides it.\n" + " -MOZ_LOG_FILE= Treated as MOZ_LOG_FILE= environment variable, overrides it.\n" " If MOZ_LOG_FILE is not specified as an argument or as an environment variable,\n" " logging will be written to stdout.\n" , (const char*)gAppData->name); diff --git a/widget/android/nsLookAndFeel.cpp b/widget/android/nsLookAndFeel.cpp index 09c31e960772..c3877bcc480e 100644 --- a/widget/android/nsLookAndFeel.cpp +++ b/widget/android/nsLookAndFeel.cpp @@ -9,6 +9,7 @@ #include "nsLookAndFeel.h" #include "gfxFont.h" #include "gfxFontConstants.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/gfx/2D.h" using namespace mozilla; @@ -466,7 +467,7 @@ nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName, { aFontName.AssignLiteral("\"Roboto\""); aFontStyle.style = NS_FONT_STYLE_NORMAL; - aFontStyle.weight = NS_FONT_WEIGHT_NORMAL; + aFontStyle.weight = FontWeight::Normal(); aFontStyle.stretch = NS_FONT_STRETCH_NORMAL; aFontStyle.size = 9.0 * 96.0f / 72.0f * aDevPixPerCSSPixel; aFontStyle.systemFont = true; diff --git a/widget/cocoa/nsLookAndFeel.mm b/widget/cocoa/nsLookAndFeel.mm index c2cb595f366a..b8b022b778f5 100644 --- a/widget/cocoa/nsLookAndFeel.mm +++ b/widget/cocoa/nsLookAndFeel.mm @@ -13,6 +13,7 @@ #include "gfxFont.h" #include "gfxFontConstants.h" #include "gfxPlatformMac.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/gfx/2D.h" #include "mozilla/widget/WidgetMessageUtils.h" @@ -565,7 +566,7 @@ nsLookAndFeel::GetFontImpl(FontID aID, nsString &aFontName, // hack for now if (aID == eFont_Window || aID == eFont_Document) { aFontStyle.style = NS_FONT_STYLE_NORMAL; - aFontStyle.weight = NS_FONT_WEIGHT_NORMAL; + aFontStyle.weight = mozilla::FontWeight::Normal(); aFontStyle.stretch = NS_FONT_STRETCH_NORMAL; aFontStyle.size = 14 * aDevPixPerCSSPixel; aFontStyle.systemFont = true; diff --git a/widget/gtk/nsLookAndFeel.cpp b/widget/gtk/nsLookAndFeel.cpp index 696ab419ad1d..ea3d0db3da09 100644 --- a/widget/gtk/nsLookAndFeel.cpp +++ b/widget/gtk/nsLookAndFeel.cpp @@ -18,6 +18,7 @@ #include #include "gfxPlatformGtk.h" +#include "mozilla/FontPropertyTypes.h" #include "ScreenHelperGTK.h" #include "gtkdrawing.h" @@ -722,7 +723,8 @@ GetSystemFontInfo(GtkStyleContext *aStyle, NS_ConvertUTF8toUTF16 family(pango_font_description_get_family(desc)); *aFontName = quote + family + quote; - aFontStyle->weight = pango_font_description_get_weight(desc); + aFontStyle->weight = + mozilla::FontWeight(pango_font_description_get_weight(desc)); // FIXME: Set aFontStyle->stretch correctly! aFontStyle->stretch = NS_FONT_STRETCH_NORMAL; diff --git a/widget/headless/HeadlessLookAndFeelGTK.cpp b/widget/headless/HeadlessLookAndFeelGTK.cpp index ab9c8418fe6a..90744e5aee82 100644 --- a/widget/headless/HeadlessLookAndFeelGTK.cpp +++ b/widget/headless/HeadlessLookAndFeelGTK.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "HeadlessLookAndFeel.h" +#include "mozilla/FontPropertyTypes.h" #include "nsIContent.h" using mozilla::LookAndFeel; @@ -337,7 +338,7 @@ HeadlessLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName, { // Default to san-serif for everything. aFontStyle.style = NS_FONT_STYLE_NORMAL; - aFontStyle.weight = NS_FONT_WEIGHT_NORMAL; + aFontStyle.weight = FontWeight::Normal(); aFontStyle.stretch = NS_FONT_STRETCH_NORMAL; aFontStyle.size = 14 * aDevPixPerCSSPixel; aFontStyle.systemFont = true; diff --git a/widget/uikit/nsLookAndFeel.mm b/widget/uikit/nsLookAndFeel.mm index b26e961b3093..437c808c6d29 100644 --- a/widget/uikit/nsLookAndFeel.mm +++ b/widget/uikit/nsLookAndFeel.mm @@ -7,6 +7,8 @@ #import #include "nsLookAndFeel.h" + +#include "mozilla/FontPropertyTypes.h" #include "nsStyleConsts.h" #include "gfxFont.h" #include "gfxFontConstants.h" @@ -400,7 +402,7 @@ nsLookAndFeel::GetFontImpl(FontID aID, nsString &aFontName, // hack for now if (aID == eFont_Window || aID == eFont_Document) { aFontStyle.style = NS_FONT_STYLE_NORMAL; - aFontStyle.weight = NS_FONT_WEIGHT_NORMAL; + aFontStyle.weight = FontWeight::Normal(); aFontStyle.stretch = NS_FONT_STRETCH_NORMAL; aFontStyle.size = 14 * aDevPixPerCSSPixel; aFontStyle.systemFont = true; diff --git a/widget/windows/nsLookAndFeel.cpp b/widget/windows/nsLookAndFeel.cpp index 9ca99ccfbee2..2bba91978aa4 100755 --- a/widget/windows/nsLookAndFeel.cpp +++ b/widget/windows/nsLookAndFeel.cpp @@ -10,6 +10,7 @@ #include "nsUXThemeData.h" #include "nsUXThemeConstants.h" #include "WinUtils.h" +#include "mozilla/FontPropertyTypes.h" #include "mozilla/Telemetry.h" #include "mozilla/WindowsVersion.h" #include "gfxFontConstants.h" @@ -707,7 +708,7 @@ GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID, // FIXME: Other weights? aFontStyle.weight = (ptrLogFont->lfWeight == FW_BOLD ? - NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL); + FontWeight::Bold() : FontWeight::Normal()); // FIXME: Set aFontStyle->stretch correctly! aFontStyle.stretch = NS_FONT_STRETCH_NORMAL; diff --git a/xpcom/base/LogCommandLineHandler.cpp b/xpcom/base/LogCommandLineHandler.cpp new file mode 100644 index 000000000000..73b5b82ae7c6 --- /dev/null +++ b/xpcom/base/LogCommandLineHandler.cpp @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "LogCommandLineHandler.h" + +#include "mozilla/Tokenizer.h" +#include "nsDebug.h" + +namespace mozilla { + +void LoggingHandleCommandLineArgs(int argc, char const* const* argv, + std::function const& consumer) +{ + // Keeps the name of a pending env var (MOZ_LOG or MOZ_LOG_FILE) that + // we expect to get a value for in the next iterated arg. + // Used for the `-MOZ_LOG ` form of argument. + nsAutoCString env; + + auto const names = { + NS_LITERAL_CSTRING("MOZ_LOG"), + NS_LITERAL_CSTRING("MOZ_LOG_FILE") + }; + + for (int arg = 1; arg < argc; ++arg) { + Tokenizer p(argv[arg]); + + if (!env.IsEmpty() && p.CheckChar('-')) { + NS_WARNING("Expects value after -MOZ_LOG(_FILE) argument, but another argument found"); + + // We only expect values for the pending env var, start over + p.Rollback(); + env.Truncate(); + } + + if (env.IsEmpty()) { + if (!p.CheckChar('-')) { + continue; + } + // We accept `-MOZ_LOG` as well as `--MOZ_LOG`. + Unused << p.CheckChar('-'); + + for (auto const& name : names) { + if (!p.CheckWord(name)) { + continue; + } + + env.Assign(name); + env.Append('='); + break; + } + + if (env.IsEmpty()) { + // An unknonwn argument, ignore. + continue; + } + + // We accept `-MOZ_LOG ` as well as `-MOZ_LOG=`. + + if (p.CheckEOF()) { + // We have a lone `-MOZ_LOG` arg, the next arg is expected to be + // the value, |env| is now prepared as `MOZ_LOG=`. + continue; + } + + if (!p.CheckChar('=')) { + // There is a character after the arg name and it's not '=', + // ignore this argument. + NS_WARNING("-MOZ_LOG(_FILE) argument not in a proper form"); + + env.Truncate(); + continue; + } + } + + // This can be non-empty from previous iteration or in this iteration. + if (!env.IsEmpty()) { + nsDependentCSubstring value; + Unused << p.ReadUntil(Tokenizer::Token::EndOfFile(), value); + env.Append(value); + + consumer(env); + + env.Truncate(); + } + } +} + +} // mozilla \ No newline at end of file diff --git a/xpcom/base/LogCommandLineHandler.h b/xpcom/base/LogCommandLineHandler.h new file mode 100644 index 000000000000..ebc774b71ba1 --- /dev/null +++ b/xpcom/base/LogCommandLineHandler.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef LogCommandLineHandler_h +#define LogCommandLineHandler_h + +#include +#include "nsString.h" + +namespace mozilla { + +/** + * A helper function parsing provided command line arguments and handling two + * specific args: + * + * -MOZ_LOG=modulelist + * -MOZ_LOG_FILE=file/path + * + * both expecting an argument, and corresponding to the same-name environment + * variables we use for logging setup. + * + * When an argument is found in the proper form, the consumer callback is called + * with a string in a follwing form, note that we do this for every occurence, + * and not just at the end of the parsing: + * + * "MOZ_LOG=modulelist" or "MOZ_LOG_FILE=file/path" + * + * All the following forms of arguments of the application are possible: + * + * --MOZ_LOG modulelist + * -MOZ_LOG modulelist + * --MOZ_LOG=modulelist + * -MOZ_LOG=modulelist + * + * The motivation for a separte function and not implementing a command line + * handler interface is that we need to process this very early during the + * application startup. Command line handlers are proccessed way later + * after logging has already been set up. + */ +void +LoggingHandleCommandLineArgs(int argc, char const* const* argv, + std::function const& consumer); + +} // mozilla + +#endif diff --git a/xpcom/base/Logging.cpp b/xpcom/base/Logging.cpp index d9f46b53a44f..14de8ab83df7 100644 --- a/xpcom/base/Logging.cpp +++ b/xpcom/base/Logging.cpp @@ -20,6 +20,7 @@ #include "nsClassHashtable.h" #include "nsDebug.h" #include "NSPRLogModulesParser.h" +#include "LogCommandLineHandler.h" #include "prenv.h" #ifdef XP_WIN @@ -191,39 +192,6 @@ public: delete logFile; } - void HandleCommandLineArgs(int argc, char* argv[]) - { - for (int arg = 2; arg < argc; ++arg) { - if (argv[arg][0] == '-') { - continue; - } - - for (auto name : {"-MOZ_LOG", "-MOZ_LOG_FILE"}) { - if (strcmp(name, argv[arg - 1])) { - continue; - } - - // We deliberately set/rewrite the environment variables - // so that when child processes are spawned w/o passing - // the arguments they still inherit the logging settings - // as well as sandboxing can be correctly set. - // Scripts can pass -MOZ_LOG=$MOZ_LOG,modules as an argument - // to merge existing settings, if required. - - nsAutoCString env; - env.Assign(name + 1); - env.Append('='); - env.Append(argv[arg]); - - // PR_SetEnv takes ownership of the string. - PR_SetEnv(ToNewCString(env)); - - ++arg; - break; - } - } - } - /** * Loads config from command line args or env vars if present, in * this specific order of priority. @@ -238,7 +206,18 @@ public: MOZ_DIAGNOSTIC_ASSERT(!mInitialized); mInitialized = true; - HandleCommandLineArgs(argc, argv); + LoggingHandleCommandLineArgs(argc, static_cast(argv), + [](nsACString const& env) { + // We deliberately set/rewrite the environment variables + // so that when child processes are spawned w/o passing + // the arguments they still inherit the logging settings + // as well as sandboxing can be correctly set. + // Scripts can pass -MOZ_LOG=$MOZ_LOG,modules as an argument + // to merge existing settings, if required. + + // PR_SetEnv takes ownership of the string. + PR_SetEnv(ToNewCString(env)); + }); bool shouldAppend = false; bool addTimestamp = false; diff --git a/xpcom/base/Logging.h b/xpcom/base/Logging.h index 60fe699c438f..ef03960c2f99 100644 --- a/xpcom/base/Logging.h +++ b/xpcom/base/Logging.h @@ -191,7 +191,6 @@ void log_print(const LogModule* aModule, } // namespace mozilla - // Helper macro used convert MOZ_LOG's third parameter, |_args|, from a // parenthesized form to a varargs form. For example: // ("%s", "a message") => "%s", "a message" diff --git a/xpcom/base/moz.build b/xpcom/base/moz.build index 8774354a7a4e..55015b077477 100644 --- a/xpcom/base/moz.build +++ b/xpcom/base/moz.build @@ -139,6 +139,7 @@ UNIFIED_SOURCES += [ 'ErrorNames.cpp', 'HoldDropJSObjects.cpp', 'JSObjectHolder.cpp', + 'LogCommandLineHandler.cpp', 'Logging.cpp', 'LogModulePrefWatcher.cpp', 'nsClassInfoImpl.cpp', diff --git a/xpcom/io/SlicedInputStream.cpp b/xpcom/io/SlicedInputStream.cpp index b2e2ba522204..23acf8decae3 100644 --- a/xpcom/io/SlicedInputStream.cpp +++ b/xpcom/io/SlicedInputStream.cpp @@ -6,6 +6,7 @@ #include "SlicedInputStream.h" #include "mozilla/ipc/InputStreamUtils.h" +#include "mozilla/ScopeExit.h" #include "nsISeekableStream.h" #include "nsStreamUtils.h" @@ -274,40 +275,42 @@ SlicedInputStream::AsyncWait(nsIInputStreamCallback* aCallback, nsCOMPtr callback = aCallback ? this : nullptr; - MutexAutoLock lock(mMutex); + uint32_t flags = aFlags; + uint32_t requestedCount = aRequestedCount; - if (mAsyncWaitCallback && aCallback) { - return NS_ERROR_FAILURE; - } + { + MutexAutoLock lock(mMutex); - mAsyncWaitCallback = aCallback; - - // If we haven't started retrieving data, let's see if we can seek. - // If we cannot seek, we will do consecutive reads. - if (mCurPos < mStart && mWeakSeekableInputStream) { - nsresult rv = - mWeakSeekableInputStream->Seek(nsISeekableStream::NS_SEEK_SET, mStart); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; + if (mAsyncWaitCallback && aCallback) { + return NS_ERROR_FAILURE; } - mCurPos = mStart; + mAsyncWaitCallback = aCallback; + + // If we haven't started retrieving data, let's see if we can seek. + // If we cannot seek, we will do consecutive reads. + if (mCurPos < mStart && mWeakSeekableInputStream) { + nsresult rv = + mWeakSeekableInputStream->Seek(nsISeekableStream::NS_SEEK_SET, mStart); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + mCurPos = mStart; + } + + mAsyncWaitFlags = aFlags; + mAsyncWaitRequestedCount = aRequestedCount; + mAsyncWaitEventTarget = aEventTarget; + + // If we are not at the right position, let's do an asyncWait just internal. + if (mCurPos < mStart) { + flags = 0; + requestedCount = mStart - mCurPos; + } } - mAsyncWaitFlags = aFlags; - mAsyncWaitRequestedCount = aRequestedCount; - mAsyncWaitEventTarget = aEventTarget; - - // If we are not at the right position, let's do an asyncWait just internal. - if (mCurPos < mStart) { - uint64_t diff = mStart - mCurPos; - - MutexAutoUnlock unlock(mMutex); - return mWeakAsyncInputStream->AsyncWait(callback, 0, diff, aEventTarget); - } - - MutexAutoUnlock unlock(mMutex); - return mWeakAsyncInputStream->AsyncWait(callback, aFlags, aRequestedCount, + return mWeakAsyncInputStream->AsyncWait(callback, flags, requestedCount, aEventTarget); } @@ -320,63 +323,77 @@ SlicedInputStream::OnInputStreamReady(nsIAsyncInputStream* aStream) MOZ_ASSERT(mWeakAsyncInputStream); MOZ_ASSERT(mWeakAsyncInputStream == aStream); - MutexAutoLock lock(mMutex); + nsCOMPtr callback; + uint32_t asyncWaitFlags = 0; + uint32_t asyncWaitRequestedCount = 0; + nsCOMPtr asyncWaitEventTarget; - // We have been canceled in the meanwhile. - if (!mAsyncWaitCallback) { - return NS_OK; - } + { + MutexAutoLock lock(mMutex); - if (mCurPos < mStart) { - char buf[4096]; - while (mCurPos < mStart) { - uint32_t bytesRead; - uint64_t bufCount = XPCOM_MIN(mStart - mCurPos, (uint64_t)sizeof(buf)); - nsresult rv = mInputStream->Read(buf, bufCount, &bytesRead); - if (NS_SUCCEEDED(rv) && bytesRead == 0) { - mClosed = true; - return RunAsyncWaitCallback(lock); - } - - if (rv == NS_BASE_STREAM_WOULD_BLOCK) { - uint64_t diff = mStart - mCurPos; - MutexAutoUnlock unlock(mMutex); - return mWeakAsyncInputStream->AsyncWait(this, 0, diff, - mAsyncWaitEventTarget); - } - - if (NS_WARN_IF(NS_FAILED(rv))) { - return RunAsyncWaitCallback(lock); - } - - mCurPos += bytesRead; + // We have been canceled in the meanwhile. + if (!mAsyncWaitCallback) { + return NS_OK; } - uint32_t asyncWaitFlags = mAsyncWaitFlags; - uint32_t asyncWaitRequestedCount = mAsyncWaitRequestedCount; - nsCOMPtr asyncWaitEventTarget = mAsyncWaitEventTarget; + auto raii = MakeScopeExit([&] { + mMutex.AssertCurrentThreadOwns(); + mAsyncWaitCallback = nullptr; + mAsyncWaitEventTarget = nullptr; + }); - MutexAutoUnlock unlock(mMutex); + asyncWaitFlags = mAsyncWaitFlags; + asyncWaitRequestedCount = mAsyncWaitRequestedCount; + asyncWaitEventTarget = mAsyncWaitEventTarget; - // Now we are ready to do the 'real' asyncWait. - return mWeakAsyncInputStream->AsyncWait(this, asyncWaitFlags, - asyncWaitRequestedCount, - asyncWaitEventTarget); + // If at the end of this locked block, the callback is not null, it will be + // executed, otherwise, we are going to exec another AsyncWait(). + callback = mAsyncWaitCallback; + + if (mCurPos < mStart) { + char buf[4096]; + nsresult rv = NS_OK; + while (mCurPos < mStart) { + uint32_t bytesRead; + uint64_t bufCount = XPCOM_MIN(mStart - mCurPos, (uint64_t)sizeof(buf)); + rv = mInputStream->Read(buf, bufCount, &bytesRead); + if (NS_SUCCEEDED(rv) && bytesRead == 0) { + mClosed = true; + break; + } + + if (rv == NS_BASE_STREAM_WOULD_BLOCK) { + asyncWaitFlags = 0; + asyncWaitRequestedCount = mStart - mCurPos; + // Here we want to exec another AsyncWait(). + callback = nullptr; + break; + } + + if (NS_WARN_IF(NS_FAILED(rv))) { + break; + } + + mCurPos += bytesRead; + } + + // Now we are ready to do the 'real' asyncWait. + if (mCurPos >= mStart) { + // We don't want to nullify the callback now, because it will be needed + // at the next ::OnInputStreamReady. + raii.release(); + callback = nullptr; + } + } } - return RunAsyncWaitCallback(lock); -} + if (callback) { + return callback->OnInputStreamReady(this); + } -nsresult -SlicedInputStream::RunAsyncWaitCallback(const MutexAutoLock& aProofOfLock) -{ - nsCOMPtr callback = mAsyncWaitCallback; - - mAsyncWaitCallback = nullptr; - mAsyncWaitEventTarget = nullptr; - - MutexAutoUnlock unlock(mMutex); - return callback->OnInputStreamReady(this); + return mWeakAsyncInputStream->AsyncWait(this, asyncWaitFlags, + asyncWaitRequestedCount, + asyncWaitEventTarget); } // nsIIPCSerializableInputStream diff --git a/xpcom/io/SlicedInputStream.h b/xpcom/io/SlicedInputStream.h index df48e488915e..a1bf63069410 100644 --- a/xpcom/io/SlicedInputStream.h +++ b/xpcom/io/SlicedInputStream.h @@ -57,9 +57,6 @@ private: void SetSourceStream(already_AddRefed aInputStream); - nsresult - RunAsyncWaitCallback(const MutexAutoLock& aProofOfLock); - nsCOMPtr mInputStream; // Raw pointers because these are just QI of mInputStream. diff --git a/xpcom/tests/gtest/TestLogCommandLineHandler.cpp b/xpcom/tests/gtest/TestLogCommandLineHandler.cpp new file mode 100644 index 000000000000..be35c7cb3ee6 --- /dev/null +++ b/xpcom/tests/gtest/TestLogCommandLineHandler.cpp @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "LogCommandLineHandler.h" + +#include +#include "nsString.h" +#include "nsTArray.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/UniquePtrExtensions.h" +#include "plstr.h" +#include "gtest/gtest.h" + +using namespace mozilla; + +template +constexpr size_t array_size(T (&)[N]) +{ + return N; +} + +TEST(LogCommandLineHandler, Empty) +{ + bool callbackInvoked = false; + auto callback = [&](nsACString const& env) mutable { + callbackInvoked = true; + }; + + mozilla::LoggingHandleCommandLineArgs(0, nullptr, callback); + EXPECT_FALSE(callbackInvoked); + + char const* argv1[] = { "" }; + mozilla::LoggingHandleCommandLineArgs(array_size(argv1), argv1, callback); + EXPECT_FALSE(callbackInvoked); +} + +TEST(LogCommandLineHandler, MOZ_LOG_regular) +{ + nsTArray results; + + auto callback = [&](nsACString const& env) mutable { + results.AppendElement(env); + }; + + char const* argv1[] = { "", "-MOZ_LOG", "module1:5,module2:4,sync,timestamp" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv1), argv1, callback); + EXPECT_TRUE(results.Length() == 1); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=module1:5,module2:4,sync,timestamp").Equals(results[0])); + + char const* argv2[] = { "", "-MOZ_LOG=modules" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv2), argv2, callback); + EXPECT_TRUE(results.Length() == 1); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + + char const* argv3[] = { "", "--MOZ_LOG", "modules" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv3), argv3, callback); + EXPECT_TRUE(results.Length() == 1); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + + char const* argv4[] = { "", "--MOZ_LOG=modules" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv4), argv4, callback); + EXPECT_TRUE(results.Length() == 1); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); +} + +TEST(LogCommandLineHandler, MOZ_LOG_and_FILE_regular) +{ + nsTArray results; + + auto callback = [&](nsACString const& env) mutable { + results.AppendElement(env); + }; + + char const* argv1[] = { "", "-MOZ_LOG", "modules", "-MOZ_LOG_FILE", "c:\\file/path" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv1), argv1, callback); + EXPECT_TRUE(results.Length() == 2); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG_FILE=c:\\file/path").Equals(results[1])); + + char const* argv2[] = { "", "-MOZ_LOG=modules", "-MOZ_LOG_FILE=file" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv2), argv2, callback); + EXPECT_TRUE(results.Length() == 2); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG_FILE=file").Equals(results[1])); + + char const* argv3[] = { "", "--MOZ_LOG", "modules", "--MOZ_LOG_FILE", "file" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv3), argv3, callback); + EXPECT_TRUE(results.Length() == 2); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG_FILE=file").Equals(results[1])); + + char const* argv4[] = { "", "--MOZ_LOG=modules", "--MOZ_LOG_FILE=file" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv4), argv4, callback); + EXPECT_TRUE(results.Length() == 2); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG_FILE=file").Equals(results[1])); + + char const* argv5[] = { "", "--MOZ_LOG", "modules", "-P", "foo", "--MOZ_LOG_FILE", "file" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv5), argv5, callback); + EXPECT_TRUE(results.Length() == 2); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG_FILE=file").Equals(results[1])); +} + +TEST(LogCommandLineHandler, MOZ_LOG_fuzzy) +{ + nsTArray results; + + auto callback = [&](nsACString const& env) mutable { + results.AppendElement(env); + }; + + char const* argv1[] = { "", "-MOZ_LOG" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv1), argv1, callback); + EXPECT_TRUE(results.Length() == 0); + + char const* argv2[] = { "", "modules" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv2), argv2, callback); + EXPECT_TRUE(results.Length() == 0); + + char const* argv3[] = { "", "-MOZ_LOG,modules", "-MOZ_LOG" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv3), argv3, callback); + EXPECT_TRUE(results.Length() == 0); + + char const* argv4[] = { "", "-MOZ_LOG", "-MOZ_LOG", "-MOZ_LOG" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv4), argv4, callback); + EXPECT_TRUE(results.Length() == 0); + + char const* argv5[] = { "", "-MOZ_LOG", "-diffent_command", "modules" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv5), argv5, callback); + EXPECT_TRUE(results.Length() == 0); +} + +TEST(LogCommandLineHandler, MOZ_LOG_overlapping) +{ + nsTArray results; + + auto callback = [&](nsACString const& env) mutable { + results.AppendElement(env); + }; + + char const* argv1[] = { "", "-MOZ_LOG=modules1", "-MOZ_LOG=modules2" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv1), argv1, callback); + EXPECT_TRUE(results.Length() == 2); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules1").Equals(results[0])); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules2").Equals(results[1])); + + char const* argv2[] = { "", "-MOZ_LOG", "--MOZ_LOG", "modules" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv2), argv2, callback); + EXPECT_TRUE(results.Length() == 1); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + + char const* argv3[] = { "", "-MOZ_LOG_FILE", "-MOZ_LOG", "modules" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv3), argv3, callback); + EXPECT_TRUE(results.Length() == 1); + EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + + char const* argv4[] = { "", "-MOZ_LOG", "-MOZ_LOG_FILE", "-MOZ_LOG" }; + results.Clear(); + mozilla::LoggingHandleCommandLineArgs(array_size(argv4), argv4, callback); + EXPECT_TRUE(results.Length() == 0); +} diff --git a/xpcom/tests/gtest/moz.build b/xpcom/tests/gtest/moz.build index 22c491870969..28f20360e543 100644 --- a/xpcom/tests/gtest/moz.build +++ b/xpcom/tests/gtest/moz.build @@ -25,6 +25,7 @@ UNIFIED_SOURCES += [ 'TestFile.cpp', 'TestGCPostBarriers.cpp', 'TestID.cpp', + 'TestLogCommandLineHandler.cpp', 'TestMoveString.cpp', 'TestMozPromise.cpp', 'TestMultiplexInputStream.cpp',