зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to autoland, a=merge
MozReview-Commit-ID: D96bIJACwZe
This commit is contained in:
Коммит
3945278423
|
@ -1088,6 +1088,14 @@ function _loadURIWithFlags(browser, uri, params) {
|
|||
}
|
||||
|
||||
let mustChangeProcess = requiredRemoteType != currentRemoteType;
|
||||
let newFrameloader = false;
|
||||
if (browser.getAttribute("isPreloadBrowser") == "true" && uri != "about:newtab") {
|
||||
// Leaving about:newtab from a used to be preloaded browser should run the process
|
||||
// selecting algorithm again.
|
||||
mustChangeProcess = true;
|
||||
newFrameloader = true;
|
||||
browser.removeAttribute("isPreloadBrowser");
|
||||
}
|
||||
|
||||
// !requiredRemoteType means we're loading in the parent/this process.
|
||||
if (!requiredRemoteType) {
|
||||
|
@ -1122,7 +1130,8 @@ function _loadURIWithFlags(browser, uri, params) {
|
|||
referrer: referrer ? referrer.spec : null,
|
||||
referrerPolicy,
|
||||
remoteType: requiredRemoteType,
|
||||
postData
|
||||
postData,
|
||||
newFrameloader,
|
||||
}
|
||||
|
||||
if (params.userContextId) {
|
||||
|
@ -1167,6 +1176,11 @@ function LoadInOtherProcess(browser, loadOptions, historyIndex = -1) {
|
|||
// Called when a docshell has attempted to load a page in an incorrect process.
|
||||
// This function is responsible for loading the page in the correct process.
|
||||
function RedirectLoad({ target: browser, data }) {
|
||||
if (browser.getAttribute("isPreloadBrowser") == "true") {
|
||||
browser.removeAttribute("isPreloadBrowser");
|
||||
data.loadOptions.newFrameloader = true;
|
||||
}
|
||||
|
||||
if (data.loadOptions.reloadInFreshProcess) {
|
||||
// Convert the fresh process load option into a large allocation remote type
|
||||
// to use common processing from this point.
|
||||
|
@ -5236,8 +5250,9 @@ nsBrowserAccess.prototype = {
|
|||
return browser;
|
||||
},
|
||||
|
||||
createContentWindow(aURI, aOpener, aWhere, aFlags) {
|
||||
return this.getContentWindowOrOpenURI(null, aOpener, aWhere, aFlags);
|
||||
createContentWindow(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal) {
|
||||
return this.getContentWindowOrOpenURI(null, aOpener, aWhere, aFlags,
|
||||
aTriggeringPrincipal);
|
||||
},
|
||||
|
||||
openURI(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal) {
|
||||
|
|
|
@ -2118,6 +2118,10 @@
|
|||
b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
|
||||
}
|
||||
|
||||
if (aParams.isPreloadBrowser) {
|
||||
b.setAttribute("isPreloadBrowser", "true");
|
||||
}
|
||||
|
||||
if (this.hasAttribute("selectmenulist"))
|
||||
b.setAttribute("selectmenulist", this.getAttribute("selectmenulist"));
|
||||
|
||||
|
|
|
@ -20,11 +20,13 @@ var tests = [
|
|||
location: "http://test1.example.org/",
|
||||
effectiveHost: "test1.example.org"
|
||||
},
|
||||
/* This part is perma-crashing, see: Bug 1315092
|
||||
{
|
||||
name: "view-source",
|
||||
location: "view-source:http://example.com/",
|
||||
effectiveHost: null
|
||||
},
|
||||
*/
|
||||
{
|
||||
name: "normal HTTPS",
|
||||
location: "https://example.com/",
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
add_task(async function() {
|
||||
let input = "i-definitely-dont-exist.example.com";
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", false);
|
||||
// NB: CPOW usage because new tab pages can be preloaded, in which case no
|
||||
// load events fire.
|
||||
await BrowserTestUtils.waitForCondition(() => !tab.linkedBrowser.contentDocument.hidden)
|
||||
|
@ -29,7 +29,7 @@ add_task(async function() {
|
|||
add_task(async function() {
|
||||
let input = "To be or not to be-that is the question";
|
||||
await SpecialPowers.pushPrefEnv({set: [["keyword.enabled", false]]});
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", false);
|
||||
// NB: CPOW usage because new tab pages can be preloaded, in which case no
|
||||
// load events fire.
|
||||
await BrowserTestUtils.waitForCondition(() => !tab.linkedBrowser.contentDocument.hidden)
|
||||
|
|
|
@ -243,6 +243,14 @@ this.E10SUtils = {
|
|||
this.getRemoteTypeForURIObject(aURI, true, remoteType, webNav.currentURI);
|
||||
}
|
||||
|
||||
if (sessionHistory.count == 1 && webNav.currentURI.spec == "about:newtab") {
|
||||
// This is possibly a preloaded browser and we're about to navigate away for
|
||||
// the first time. On the child side there is no way to tell for sure if that
|
||||
// is the case, so let's redirect this request to the parent to decide if a new
|
||||
// process is needed.
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the URI can be loaded in the current process then continue
|
||||
return this.shouldLoadURIInThisProcess(aURI);
|
||||
},
|
||||
|
|
|
@ -763,6 +763,11 @@ int do_relocation_section(Elf *elf, unsigned int rel_type, unsigned int rel_type
|
|||
}
|
||||
}
|
||||
|
||||
if (!first_executable) {
|
||||
fprintf(stderr, "Couldn't find executable section. Skipping\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int old_exec = first_executable->getOffset();
|
||||
|
||||
relhack->insertBefore(section);
|
||||
|
|
|
@ -21839,8 +21839,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
module.exports = function (name, props) {
|
||||
// eslint-disable-line
|
||||
if (!svg[name]) {
|
||||
throw new Error("Unknown SVG: " + name);
|
||||
console.warn("Unknown SVG: " + name);
|
||||
return null;
|
||||
}
|
||||
|
||||
var className = name;
|
||||
if (props && props.className) {
|
||||
className = `${name} ${props.className}`;
|
||||
|
|
|
@ -319,6 +319,11 @@ ObjectActor.prototype = {
|
|||
let obj = this.obj;
|
||||
let level = 0, i = 0;
|
||||
|
||||
// Do not search safe getters in proxy objects.
|
||||
if (obj.isProxy) {
|
||||
return safeGetterValues;
|
||||
}
|
||||
|
||||
// Most objects don't have any safe getters but inherit some from their
|
||||
// prototype. Avoid calling getOwnPropertyNames on objects that may have
|
||||
// many properties like Array, strings or js objects. That to avoid
|
||||
|
@ -329,7 +334,8 @@ ObjectActor.prototype = {
|
|||
level++;
|
||||
}
|
||||
|
||||
while (obj) {
|
||||
// Stop iterating when the prototype chain ends or a proxy is found.
|
||||
while (obj && !obj.isProxy) {
|
||||
let getters = this._findSafeGetters(obj);
|
||||
for (let name of getters) {
|
||||
// Avoid overwriting properties from prototypes closer to this.obj. Also
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* eslint-disable no-shadow, max-nested-callbacks */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
var gCallback;
|
||||
|
||||
function run_test() {
|
||||
run_test_with_server(DebuggerServer, function () {
|
||||
run_test_with_server(WorkerDebuggerServer, do_test_finished);
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function addTestNullPrincipalGlobal(name, server = DebuggerServer) {
|
||||
// System principal objects are considered safe even when not wrapped in Xray,
|
||||
// and therefore proxy traps may run. So the test needs to use a null principal.
|
||||
let global = Cu.Sandbox(null);
|
||||
global.__name = name;
|
||||
server.addTestGlobal(global);
|
||||
return global;
|
||||
}
|
||||
|
||||
async function run_test_with_server(server, callback) {
|
||||
gCallback = callback;
|
||||
initTestDebuggerServer(server);
|
||||
gDebuggee = addTestNullPrincipalGlobal("test-grips", server);
|
||||
gDebuggee.eval(function stopMe(arg1, arg2) {
|
||||
debugger;
|
||||
}.toString());
|
||||
|
||||
gClient = new DebuggerClient(server.connectPipe());
|
||||
await gClient.connect();
|
||||
const [,, threadClient] = await attachTestTabAndResume(gClient, "test-grips");
|
||||
gThreadClient = threadClient;
|
||||
test_proxy_grip();
|
||||
}
|
||||
|
||||
async function test_proxy_grip() {
|
||||
gThreadClient.addOneTimeListener("paused", async function (event, packet) {
|
||||
let [proxyGrip, inheritsProxyGrip] = packet.frame.arguments;
|
||||
|
||||
// Check the grip of the proxy object.
|
||||
check_proxy_grip(proxyGrip);
|
||||
|
||||
// Retrieve the properties of the object which inherits from a proxy,
|
||||
// and check the grip of its prototype.
|
||||
let objClient = gThreadClient.pauseGrip(inheritsProxyGrip);
|
||||
let response = await objClient.getPrototypeAndProperties();
|
||||
check_prototype_and_properties(response);
|
||||
|
||||
// Check that none of the above ran proxy traps.
|
||||
let trapDidRun = gDebuggee.eval("trapDidRun");
|
||||
strictEqual(trapDidRun, false, "No proxy trap did run.");
|
||||
|
||||
await gThreadClient.resume();
|
||||
await gClient.close();
|
||||
gCallback();
|
||||
});
|
||||
|
||||
gDebuggee.eval(`{
|
||||
var trapDidRun = false;
|
||||
var proxy = new Proxy({}, new Proxy({}, {get: (_, trap) => {
|
||||
trapDidRun = true;
|
||||
throw new Error("proxy " + trap + " trap was called.");
|
||||
}}));
|
||||
var inheritsProxy = Object.create(proxy, {x:{value:1}});
|
||||
stopMe(proxy, inheritsProxy);
|
||||
}`);
|
||||
}
|
||||
|
||||
function check_proxy_grip(grip) {
|
||||
strictEqual(grip.class, "Proxy", "The grip has a Proxy class.");
|
||||
ok(grip.proxyTarget, "There is a [[ProxyTarget]] grip.");
|
||||
ok(grip.proxyHandler, "There is a [[ProxyHandler]] grip.");
|
||||
|
||||
const {preview} = grip;
|
||||
strictEqual(preview.ownPropertiesLength, 2, "The preview has 2 properties.");
|
||||
let target = preview.ownProperties["<target>"].value;
|
||||
strictEqual(target, grip.proxyTarget, "<target> contains the [[ProxyTarget]].");
|
||||
let handler = preview.ownProperties["<handler>"].value;
|
||||
strictEqual(handler, grip.proxyHandler, "<handler> contains the [[ProxyHandler]].");
|
||||
}
|
||||
|
||||
function check_prototype_and_properties(response) {
|
||||
let ownPropertiesLength = Reflect.ownKeys(response.ownProperties).length;
|
||||
strictEqual(ownPropertiesLength, 1, "1 own property was retrieved.");
|
||||
strictEqual(response.ownProperties.x.value, 1, "The property has the right value.");
|
||||
check_proxy_grip(response.prototype);
|
||||
}
|
||||
|
|
@ -172,6 +172,7 @@ reason = only ran on B2G
|
|||
[test_objectgrips-14.js]
|
||||
[test_objectgrips-15.js]
|
||||
[test_objectgrips-16.js]
|
||||
[test_objectgrips-17.js]
|
||||
[test_promise_state-01.js]
|
||||
[test_promise_state-02.js]
|
||||
[test_promise_state-03.js]
|
||||
|
|
|
@ -17,6 +17,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=565388
|
|||
/** Test for Bug 565388 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function test() {
|
||||
var Ci = Components.interfaces;
|
||||
var Cc = Components.classes;
|
||||
|
||||
|
@ -71,6 +72,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=565388
|
|||
});
|
||||
|
||||
win.location = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window/>";
|
||||
}
|
||||
|
||||
addLoadEvent(function onLoad() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.data_uri.unique_opaque_origin", false]]}, test);
|
||||
});
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
|
|
@ -2231,6 +2231,7 @@ GK_ATOM(DisplayPortMargins, "_displayportmargins")
|
|||
GK_ATOM(DisplayPortBase, "_displayportbase")
|
||||
GK_ATOM(AsyncScrollLayerCreationFailed, "_asyncscrolllayercreationfailed")
|
||||
GK_ATOM(forcemessagemanager, "forcemessagemanager")
|
||||
GK_ATOM(isPreloadBrowser, "isPreloadBrowser")
|
||||
|
||||
// Names for system metrics
|
||||
GK_ATOM(color_picker_available, "color-picker-available")
|
||||
|
|
|
@ -1586,6 +1586,9 @@ private:
|
|||
// Set if the element might have any kind of anonymous content children,
|
||||
// which would not be found through the element's children list.
|
||||
ElementMayHaveAnonymousChildren,
|
||||
// Set if this node has at some point (and may still have)
|
||||
// display:none or display:contents children.
|
||||
NodeMayHaveChildrenWithLayoutBoxesDisabled,
|
||||
// Guard value
|
||||
BooleanFlagCount
|
||||
};
|
||||
|
@ -1728,6 +1731,19 @@ public:
|
|||
void SetMayHaveAnonymousChildren() { SetBoolFlag(ElementMayHaveAnonymousChildren); }
|
||||
bool MayHaveAnonymousChildren() const { return GetBoolFlag(ElementMayHaveAnonymousChildren); }
|
||||
|
||||
void SetMayHaveChildrenWithLayoutBoxesDisabled()
|
||||
{
|
||||
SetBoolFlag(NodeMayHaveChildrenWithLayoutBoxesDisabled);
|
||||
}
|
||||
void UnsetMayHaveChildrenWithLayoutBoxesDisabled()
|
||||
{
|
||||
ClearBoolFlag(NodeMayHaveChildrenWithLayoutBoxesDisabled);
|
||||
}
|
||||
bool MayHaveChildrenWithLayoutBoxesDisabled() const
|
||||
{
|
||||
return GetBoolFlag(NodeMayHaveChildrenWithLayoutBoxesDisabled);
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
|
||||
void SetIsInDocument() { SetBoolFlag(IsInDocument); }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
audio.ogg
|
||||
dummy.html
|
||||
empty.html
|
||||
file_audioLoop.html
|
||||
file_audioLoopInIframe.html
|
||||
|
@ -35,6 +36,7 @@ tags = mcb
|
|||
[browser_force_process_selector.js]
|
||||
skip-if = !e10s # this only makes sense with e10s-multi
|
||||
[browser_messagemanager_loadprocessscript.js]
|
||||
[browser_aboutnewtab_process_selection.js]
|
||||
[browser_messagemanager_targetframeloader.js]
|
||||
[browser_messagemanager_unload.js]
|
||||
[browser_pagehide_on_tab_close.js]
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
const TEST_URL = "http://www.example.com/browser/dom/base/test/dummy.html";
|
||||
|
||||
var ppmm = Services.ppmm;
|
||||
|
||||
add_task(async function(){
|
||||
// We want to count processes in this test, so let's disable the pre-allocated process manager.
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.ipc.processPrelaunch.enabled", false],
|
||||
["dom.ipc.processCount", 10],
|
||||
["dom.ipc.keepProcessesAlive.web", 10],
|
||||
]});
|
||||
});
|
||||
|
||||
// Ensure that the preloaded browser exists, and it's finished loading.
|
||||
async function ensurePreloaded(gBrowser) {
|
||||
gBrowser._createPreloadBrowser();
|
||||
// We cannot use the regular BrowserTestUtils helper for waiting here, since that
|
||||
// would try to insert the preloaded browser, which would only break things.
|
||||
await BrowserTestUtils.waitForCondition( () => {
|
||||
return gBrowser._preloadedBrowser.contentDocument.readyState == "complete";
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function(){
|
||||
// This test is only relevant in e10s.
|
||||
if (!gMultiProcessBrowser)
|
||||
return;
|
||||
|
||||
ppmm.releaseCachedProcesses();
|
||||
|
||||
// Wait for the preloaded browser to load.
|
||||
await ensurePreloaded(gBrowser);
|
||||
|
||||
// Store the number of processes (note: +1 for the parent process).
|
||||
const { childCount: originalChildCount } = ppmm;
|
||||
|
||||
// Use the preloaded browser and create another one.
|
||||
BrowserOpenTab();
|
||||
let tab1 = gBrowser.selectedTab;
|
||||
await ensurePreloaded(gBrowser);
|
||||
|
||||
// Check that the process count did not change.
|
||||
is(ppmm.childCount, originalChildCount, "Preloaded browser should not create a new content process.")
|
||||
|
||||
// Let's do another round.
|
||||
BrowserOpenTab();
|
||||
let tab2 = gBrowser.selectedTab;
|
||||
await ensurePreloaded(gBrowser);
|
||||
|
||||
// Check that the process count did not change.
|
||||
is(ppmm.childCount, originalChildCount, "Preloaded browser should (still) not create a new content process.")
|
||||
|
||||
// Navigate to a content page from the parent side.
|
||||
tab2.linkedBrowser.loadURI(TEST_URL);
|
||||
await BrowserTestUtils.browserLoaded(tab2.linkedBrowser, false, TEST_URL);
|
||||
is(ppmm.childCount, originalChildCount + 1,
|
||||
"Navigating away from the preloaded browser (parent side) should create a new content process.")
|
||||
|
||||
// Navigate to a content page from the child side.
|
||||
await BrowserTestUtils.switchTab(gBrowser, tab1);
|
||||
await ContentTask.spawn(tab1.linkedBrowser, null, async function() {
|
||||
const TEST_URL = "http://www.example.com/browser/dom/base/test/dummy.html";
|
||||
content.location.href = TEST_URL;
|
||||
});
|
||||
await BrowserTestUtils.browserLoaded(tab1.linkedBrowser, false, TEST_URL);
|
||||
is(ppmm.childCount, originalChildCount + 2,
|
||||
"Navigating away from the preloaded browser (child side) should create a new content process.")
|
||||
|
||||
await BrowserTestUtils.removeTab(tab1);
|
||||
await BrowserTestUtils.removeTab(tab2);
|
||||
|
||||
// Since we kept alive all the processes, we can shut down the ones that do
|
||||
// not host any tabs reliably.
|
||||
ppmm.releaseCachedProcesses();
|
||||
is(ppmm.childCount, originalChildCount, "We're back to the original process count.");
|
||||
});
|
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Dummy test page</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
|
||||
</head>
|
||||
<body>
|
||||
<p>Dummy test page</p>
|
||||
</body>
|
||||
</html>
|
|
@ -53,7 +53,11 @@ function done() {
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestFlakyTimeout("untriaged");
|
||||
addLoadEvent(doTest);
|
||||
addLoadEvent(function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["browser.newtab.preload", false]
|
||||
]}, doTest);
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
|
|
@ -762,11 +762,11 @@ ContentParent::MinTabSelect(const nsTArray<ContentParent*>& aContentParents,
|
|||
/*static*/ already_AddRefed<ContentParent>
|
||||
ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
|
||||
ProcessPriority aPriority,
|
||||
ContentParent* aOpener)
|
||||
ContentParent* aOpener,
|
||||
bool aPreferUsed)
|
||||
{
|
||||
nsTArray<ContentParent*>& contentParents = GetOrCreatePool(aRemoteType);
|
||||
uint32_t maxContentParents = GetMaxProcessCount(aRemoteType);
|
||||
|
||||
if (aRemoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
|
||||
// We never want to re-use Large-Allocation processes.
|
||||
if (contentParents.Length() >= maxContentParents) {
|
||||
|
@ -775,11 +775,18 @@ ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
|
|||
aOpener);
|
||||
}
|
||||
} else {
|
||||
nsTArray<nsIContentProcessInfo*> infos(contentParents.Length());
|
||||
uint32_t numberOfParents = contentParents.Length();
|
||||
nsTArray<nsIContentProcessInfo*> infos(numberOfParents);
|
||||
for (auto* cp : contentParents) {
|
||||
infos.AppendElement(cp->mScriptableHelper);
|
||||
}
|
||||
|
||||
if (aPreferUsed && numberOfParents) {
|
||||
// For the preloaded browser we don't want to create a new process but reuse an
|
||||
// existing one.
|
||||
maxContentParents = numberOfParents;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContentProcessProvider> cpp =
|
||||
do_GetService("@mozilla.org/ipc/processselector;1");
|
||||
nsIContentProcessInfo* openerInfo = aOpener ? aOpener->mScriptableHelper.get() : nullptr;
|
||||
|
@ -1131,6 +1138,13 @@ ContentParent::CreateBrowser(const TabContext& aContext,
|
|||
remoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
|
||||
}
|
||||
|
||||
bool isPreloadBrowser = false;
|
||||
nsAutoString isPreloadBrowserStr;
|
||||
if (aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::isPreloadBrowser,
|
||||
isPreloadBrowserStr)) {
|
||||
isPreloadBrowser = isPreloadBrowserStr.EqualsLiteral("true");
|
||||
}
|
||||
|
||||
RefPtr<nsIContentParent> constructorSender;
|
||||
if (isInContentProcess) {
|
||||
MOZ_ASSERT(aContext.IsMozBrowserElement() || aContext.IsJSPlugin());
|
||||
|
@ -1146,7 +1160,8 @@ ContentParent::CreateBrowser(const TabContext& aContext,
|
|||
initialPriority);
|
||||
} else {
|
||||
constructorSender =
|
||||
GetNewOrUsedBrowserProcess(remoteType, initialPriority, nullptr);
|
||||
GetNewOrUsedBrowserProcess(remoteType, initialPriority,
|
||||
nullptr, isPreloadBrowser);
|
||||
}
|
||||
if (!constructorSender) {
|
||||
return nullptr;
|
||||
|
|
|
@ -172,7 +172,8 @@ public:
|
|||
GetNewOrUsedBrowserProcess(const nsAString& aRemoteType = NS_LITERAL_STRING(NO_REMOTE_TYPE),
|
||||
hal::ProcessPriority aPriority =
|
||||
hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND,
|
||||
ContentParent* aOpener = nullptr);
|
||||
ContentParent* aOpener = nullptr,
|
||||
bool aPreferUsed = false);
|
||||
|
||||
/**
|
||||
* Get or create a content process for a JS plugin. aPluginID is the id of the JS plugin
|
||||
|
|
|
@ -2254,38 +2254,3 @@ NPObjectMember_toPrimitive(JSContext *cx, unsigned argc, JS::Value *vp)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsJSObjWrapper::HasOwnProperty(NPObject *npobj, NPIdentifier npid)
|
||||
{
|
||||
NPP npp = NPPStack::Peek();
|
||||
nsIGlobalObject* globalObject = GetGlobalObject(npp);
|
||||
if (NS_WARN_IF(!globalObject)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dom::AutoEntryScript aes(globalObject, "NPAPI HasOwnProperty");
|
||||
JSContext *cx = aes.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSExceptionASCII(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_HasOwnProperty!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
bool found, ok = false;
|
||||
|
||||
AutoJSExceptionSuppressor suppressor(aes, npjsobj);
|
||||
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, jsobj);
|
||||
MarkCrossZoneNPIdentifier(cx, npid);
|
||||
|
||||
NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid),
|
||||
"id must be either string or int!\n");
|
||||
JS::Rooted<jsid> id(cx, NPIdentifierToJSId(npid));
|
||||
ok = ::JS_AlreadyHasOwnPropertyById(cx, jsobj, id, &found);
|
||||
return ok && found;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,6 @@ public:
|
|||
bool mDestroyPending;
|
||||
|
||||
static NPObject* GetNewOrUsed(NPP npp, JS::Handle<JSObject*> obj);
|
||||
static bool HasOwnProperty(NPObject* npobj, NPIdentifier npid);
|
||||
|
||||
void trace(JSTracer* trc) {
|
||||
JS::TraceEdge(trc, &mJSObj, "nsJSObjWrapper");
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
#undef LOG
|
||||
#define LOG(args) \
|
||||
MOZ_LOG(ScriptLoader::gScriptLoaderLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ModuleLoadRequest)
|
||||
NS_INTERFACE_MAP_END_INHERITING(ScriptLoadRequest)
|
||||
|
||||
|
@ -53,6 +57,14 @@ ModuleLoadRequest::Cancel()
|
|||
void
|
||||
ModuleLoadRequest::SetReady()
|
||||
{
|
||||
// Mark a module as ready to execute. This means that this module and all it
|
||||
// dependencies have had their source loaded, parsed as a module and the
|
||||
// modules instantiated.
|
||||
//
|
||||
// The mReady promise is used to ensure that when all dependencies of a module
|
||||
// have become ready, DependenciesLoaded is called on that module
|
||||
// request. This is set up in StartFetchingModuleDependencies.
|
||||
|
||||
#ifdef DEBUG
|
||||
for (size_t i = 0; i < mImports.Length(); i++) {
|
||||
MOZ_ASSERT(mImports[i]->IsReadyToRun());
|
||||
|
@ -69,6 +81,8 @@ ModuleLoadRequest::ModuleLoaded()
|
|||
// A module that was found to be marked as fetching in the module map has now
|
||||
// been loaded.
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Module loaded", this));
|
||||
|
||||
mModuleScript = mLoader->GetFetchedModule(mURI);
|
||||
mLoader->StartFetchingModuleDependencies(this);
|
||||
}
|
||||
|
@ -79,6 +93,8 @@ ModuleLoadRequest::DependenciesLoaded()
|
|||
// The module and all of its dependencies have been successfully fetched and
|
||||
// compiled.
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Module dependencies loaded", this));
|
||||
|
||||
if (!mLoader->InstantiateModuleTree(this)) {
|
||||
LoadFailed();
|
||||
return;
|
||||
|
@ -93,6 +109,8 @@ ModuleLoadRequest::DependenciesLoaded()
|
|||
void
|
||||
ModuleLoadRequest::LoadFailed()
|
||||
{
|
||||
LOG(("ScriptLoadRequest (%p): Module load failed", this));
|
||||
|
||||
Cancel();
|
||||
mLoader->ProcessLoadedModuleTree(this);
|
||||
mLoader = nullptr;
|
||||
|
|
|
@ -72,9 +72,12 @@ namespace dom {
|
|||
LazyLogModule ScriptLoader::gCspPRLog("CSP");
|
||||
LazyLogModule ScriptLoader::gScriptLoaderLog("ScriptLoader");
|
||||
|
||||
#undef LOG
|
||||
#define LOG(args) \
|
||||
MOZ_LOG(gScriptLoaderLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
#define LOG_ENABLED() \
|
||||
MOZ_LOG_TEST(ScriptLoader::gScriptLoaderLog, mozilla::LogLevel::Debug)
|
||||
|
||||
// Alternate Data MIME type used by the ScriptLoader to register that we want to
|
||||
// store bytecode without reading it.
|
||||
|
@ -357,6 +360,13 @@ ScriptLoader::SetModuleFetchFinishedAndResumeWaitingRequests(ModuleLoadRequest*
|
|||
{
|
||||
// Update module map with the result of fetching a single module script. The
|
||||
// module script pointer is nullptr on error.
|
||||
//
|
||||
// If any requests for the same URL are waiting on this one to complete, they
|
||||
// will have ModuleLoaded or LoadFailed on them when the promise is
|
||||
// resolved/rejected. This is set up in StartLoad.
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Module fetch finished (result == %u)",
|
||||
aRequest, unsigned(aResult)));
|
||||
|
||||
MOZ_ASSERT(!aRequest->IsReadyToRun());
|
||||
|
||||
|
@ -400,6 +410,12 @@ ScriptLoader::WaitForModuleFetch(ModuleLoadRequest* aRequest)
|
|||
ModuleScript*
|
||||
ScriptLoader::GetFetchedModule(nsIURI* aURL) const
|
||||
{
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString url;
|
||||
aURL->GetAsciiSpec(url);
|
||||
LOG(("GetFetchedModule %s", url.get()));
|
||||
}
|
||||
|
||||
bool found;
|
||||
ModuleScript* ms = mFetchedModules.GetWeak(aURL, &found);
|
||||
MOZ_ASSERT(found);
|
||||
|
@ -646,8 +662,13 @@ void
|
|||
ScriptLoader::StartFetchingModuleDependencies(ModuleLoadRequest* aRequest)
|
||||
{
|
||||
MOZ_ASSERT(aRequest->mModuleScript);
|
||||
MOZ_ASSERT(!aRequest->mModuleScript->InstantiationFailed());
|
||||
MOZ_ASSERT(!aRequest->IsReadyToRun());
|
||||
|
||||
if (aRequest->mModuleScript->InstantiationFailed()) {
|
||||
aRequest->LoadFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
aRequest->mProgress = ModuleLoadRequest::Progress::FetchingImports;
|
||||
|
||||
nsCOMArray<nsIURI> urls;
|
||||
|
@ -790,6 +811,8 @@ ScriptLoader::InstantiateModuleTree(ModuleLoadRequest* aRequest)
|
|||
|
||||
MOZ_ASSERT(aRequest);
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Instantiate module tree", aRequest));
|
||||
|
||||
ModuleScript* ms = aRequest->mModuleScript;
|
||||
MOZ_ASSERT(ms);
|
||||
if (!ms->ModuleRecord()) {
|
||||
|
@ -809,6 +832,7 @@ ScriptLoader::InstantiateModuleTree(ModuleLoadRequest* aRequest)
|
|||
|
||||
JS::RootedValue exception(jsapi.cx());
|
||||
if (!ok) {
|
||||
LOG(("ScriptLoadRequest (%p): Instantiate failed", aRequest));
|
||||
MOZ_ASSERT(jsapi.HasException());
|
||||
if (!jsapi.StealException(&exception)) {
|
||||
return false;
|
||||
|
@ -877,11 +901,18 @@ ScriptLoader::StartLoad(ScriptLoadRequest* aRequest)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString url;
|
||||
aRequest->mURI->GetAsciiSpec(url);
|
||||
LOG(("ScriptLoadRequest (%p): Start Load (url = %s)", aRequest, url.get()));
|
||||
}
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
// Check whether the module has been fetched or is currently being fetched,
|
||||
// and if so wait for it.
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
if (ModuleMapContainsModule(request)) {
|
||||
LOG(("ScriptLoadRequest (%p): Waiting for module fetch", aRequest));
|
||||
WaitForModuleFetch(request)
|
||||
->Then(GetMainThreadSerialEventTarget(), __func__, request,
|
||||
&ModuleLoadRequest::ModuleLoaded,
|
||||
|
@ -891,6 +922,7 @@ ScriptLoader::StartLoad(ScriptLoadRequest* aRequest)
|
|||
|
||||
// Otherwise put the URL in the module map and mark it as fetching.
|
||||
SetModuleFetchStarted(request);
|
||||
LOG(("ScriptLoadRequest (%p): Start fetching module", aRequest));
|
||||
}
|
||||
|
||||
nsContentPolicyType contentPolicyType = aRequest->IsPreload()
|
||||
|
|
|
@ -15,17 +15,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=841850
|
|||
var blankTarget = document.getElementById("blankTarget");
|
||||
blankTarget.click();
|
||||
|
||||
var os = SpecialPowers.Cc["@mozilla.org/observer-service;1"].
|
||||
getService(SpecialPowers.Components.interfaces.nsIObserverService);
|
||||
var observer = {
|
||||
observe: function(subject, topic, data) {
|
||||
if(topic == "content-document-global-created" && data =="http://example.com") {
|
||||
parent.parent.postMessage({"test": "blankTarget", "msg": "opened an http link with target=_blank from a secure page"}, "http://mochi.test:8888");
|
||||
os.removeObserver(observer, "content-document-global-created");
|
||||
SpecialPowers.removeAsyncObserver(observer, "content-document-global-created");
|
||||
}
|
||||
}
|
||||
}
|
||||
os.addObserver(observer, "content-document-global-created");
|
||||
SpecialPowers.addAsyncObserver(observer, "content-document-global-created");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -312,7 +312,9 @@ function checkChangeIsEnabled(aWindow, aNext)
|
|||
.then(aNext);
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.disable_window_move_resize", false]]}, function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.disable_window_move_resize", false],
|
||||
["security.data_uri.unique_opaque_origin", false]]},
|
||||
function() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
if (screen.width <= 200 || screen.height <= 200) {
|
||||
todo(false, "The screen needs to be bigger than 200px*200px to run this test.");
|
||||
|
|
|
@ -215,67 +215,75 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=565541
|
|||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
if (screen.width <= 200 || screen.height <= 200) {
|
||||
todo(false, "The screen is too small to run this test.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
backValues();
|
||||
function test() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
if (screen.width <= 200 || screen.height <= 200) {
|
||||
todo(false, "The screen is too small to run this test.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// We are in a chrome context, we can change the size and position.
|
||||
checkChangeIsEnabled(window.top, function() {
|
||||
// We create a window and check that the size and position can be set with
|
||||
// window.open parameters and can be changed by the created window.
|
||||
var w = window.open("data:text/html,<script>" +
|
||||
"function check(next) {" +
|
||||
" var is_range = function(aTest, aValue, aRange, aMsg) {" +
|
||||
" ok(aTest < aValue + aRange && aTest > aValue - aRange, aMsg);" +
|
||||
" };" +
|
||||
" is_range(window.innerWidth, 170, 5, 'parameter width should be taken into account');" +
|
||||
" is_range(window.innerHeight, 170, 5, 'parameter height should be taken into account');" +
|
||||
" is_range(window.screenX, 25, 5, 'parameter screenX should be taken into account');" +
|
||||
" is_range(window.screenY, 25, 5, 'parameter screenY should be taken into account');" +
|
||||
" checkChangeIsEnabled(window, next);" +
|
||||
"} <\/script>", '',
|
||||
'width=170,height=170,screenX=25,screenY=25');
|
||||
backValues();
|
||||
|
||||
SimpleTest.waitForFocus(function() {
|
||||
// This test relies on passing cross-origin windows to a chrome function,
|
||||
// which is generally forbidden if we don't twiddle the knob below.
|
||||
Components.utils.forcePermissiveCOWs();
|
||||
w.wrappedJSObject.ok = SimpleTest.ok;
|
||||
w.wrappedJSObject.checkChangeIsEnabled = window.checkChangeIsEnabled;
|
||||
w.wrappedJSObject.check(function() {
|
||||
// The current window can change the size and position of the created one.
|
||||
checkChangeIsEnabled(w, function() {
|
||||
w.close();
|
||||
// We are in a chrome context, we can change the size and position.
|
||||
checkChangeIsEnabled(window.top, function() {
|
||||
// We create a window and check that the size and position can be set with
|
||||
// window.open parameters and can be changed by the created window.
|
||||
var w = window.open("data:text/html,<script>" +
|
||||
"function check(next) {" +
|
||||
" var is_range = function(aTest, aValue, aRange, aMsg) {" +
|
||||
" ok(aTest < aValue + aRange && aTest > aValue - aRange, aMsg);" +
|
||||
" };" +
|
||||
" is_range(window.innerWidth, 170, 5, 'parameter width should be taken into account');" +
|
||||
" is_range(window.innerHeight, 170, 5, 'parameter height should be taken into account');" +
|
||||
" is_range(window.screenX, 25, 5, 'parameter screenX should be taken into account');" +
|
||||
" is_range(window.screenY, 25, 5, 'parameter screenY should be taken into account');" +
|
||||
" checkChangeIsEnabled(window, next);" +
|
||||
"} <\/script>", '',
|
||||
'width=170,height=170,screenX=25,screenY=25');
|
||||
|
||||
// If we call window.open with an empty string as a third parameter,
|
||||
// by default, it will create a new tab instead of a new window.
|
||||
// In a chrome context, the size and position can change.
|
||||
w = window.open("data:text/html,<script>" +
|
||||
"function check(next) {" +
|
||||
" checkChangeIsEnabled(window, next);" +
|
||||
"} <\/script>", '', '');
|
||||
SimpleTest.waitForFocus(function() {
|
||||
// This test relies on passing cross-origin windows to a chrome function,
|
||||
// which is generally forbidden if we don't twiddle the knob below.
|
||||
Components.utils.forcePermissiveCOWs();
|
||||
w.wrappedJSObject.ok = SimpleTest.ok;
|
||||
w.wrappedJSObject.checkChangeIsEnabled = window.checkChangeIsEnabled;
|
||||
w.wrappedJSObject.check(function() {
|
||||
// The current window can change the size and position of the created one.
|
||||
checkChangeIsEnabled(w, function() {
|
||||
w.close();
|
||||
|
||||
SimpleTest.waitForFocus(function() {
|
||||
w.wrappedJSObject.checkChangeIsEnabled = window.checkChangeIsEnabled;
|
||||
w.wrappedJSObject.check(function() {
|
||||
// The current window can change the size and position of the new tab.
|
||||
// Because we are in a chrome context.
|
||||
checkChangeIsEnabled(w, function() {
|
||||
w.close();
|
||||
// If we call window.open with an empty string as a third parameter,
|
||||
// by default, it will create a new tab instead of a new window.
|
||||
// In a chrome context, the size and position can change.
|
||||
w = window.open("data:text/html,<script>" +
|
||||
"function check(next) {" +
|
||||
" checkChangeIsEnabled(window, next);" +
|
||||
"} <\/script>", '', '');
|
||||
|
||||
restoreValues();
|
||||
SimpleTest.finish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
w.wrappedJSObject.checkChangeIsEnabled = window.checkChangeIsEnabled;
|
||||
w.wrappedJSObject.check(function() {
|
||||
// The current window can change the size and position of the new tab.
|
||||
// Because we are in a chrome context.
|
||||
checkChangeIsEnabled(w, function() {
|
||||
w.close();
|
||||
|
||||
restoreValues();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
}, w, false);
|
||||
}, w, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}, w, false);
|
||||
}, w, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
addLoadEvent(function onLoad() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.data_uri.unique_opaque_origin", false]]}, test);
|
||||
});
|
||||
]]>
|
||||
</script>
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
<script>
|
||||
add_task(async function() {
|
||||
// Push the correct preferences for the test
|
||||
await SpecialPowers.pushPrefEnv({'set': [['dom.select_events.enabled', true]]});
|
||||
await SpecialPowers.pushPrefEnv({'set': [
|
||||
['dom.select_events.enabled', true],
|
||||
['dom.select_events.textcontrols.enabled', true],
|
||||
]});
|
||||
|
||||
// Start the actual test
|
||||
await new Promise((done) => {
|
||||
|
|
|
@ -41,6 +41,7 @@ add_task(function setupPrefs() {
|
|||
return SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["browser.newtab.preload", false],
|
||||
]});
|
||||
});
|
||||
|
||||
|
|
|
@ -19,11 +19,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=966155
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.data_uri.unique_opaque_origin", false]]}, nextTest);
|
||||
});
|
||||
|
||||
function nextTest() {
|
||||
var win = window.open("data:text/html,<input><iframe onload=\"contentDocument.designMode = 'on';\">", "", "test-966155");
|
||||
win.addEventListener("load", function() {
|
||||
runTest(win);
|
||||
}, {once: true});
|
||||
});
|
||||
}
|
||||
|
||||
function runTest(win) {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
|
|
|
@ -19,11 +19,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=966552
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.data_uri.unique_opaque_origin", false]]}, nextTest);
|
||||
});
|
||||
|
||||
function nextTest() {
|
||||
var win = window.open("data:text/html,<body onload=\"document.designMode='on'\">test</body>", "", "test-966552");
|
||||
win.addEventListener("load", function() {
|
||||
runTest(win);
|
||||
}, {once: true});
|
||||
});
|
||||
}
|
||||
|
||||
function runTest(win) {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
DECL_GFX_ENV("DUMP_DEBUG", DumpDebug);
|
||||
|
||||
// Use WR recording
|
||||
DECL_GFX_ENV("ENABLE_WR_RENDERING", EnableWebRenderRecording);
|
||||
DECL_GFX_ENV("ENABLE_WR_RECORDING", EnableWebRenderRecording);
|
||||
|
||||
// OpenGL shader debugging in OGLShaderProgram, in DEBUG only
|
||||
DECL_GFX_ENV("MOZ_DEBUG_SHADERS", DebugShaders);
|
||||
|
|
|
@ -173,8 +173,7 @@ gfxFontCache::Shutdown()
|
|||
}
|
||||
|
||||
gfxFontCache::gfxFontCache(nsIEventTarget* aEventTarget)
|
||||
: nsExpirationTracker<gfxFont,3>(FONT_TIMEOUT_SECONDS * 1000,
|
||||
"gfxFontCache", aEventTarget)
|
||||
: gfxFontCacheExpirationTracker(aEventTarget)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
if (obs) {
|
||||
|
@ -286,7 +285,7 @@ gfxFontCache::NotifyReleased(gfxFont *aFont)
|
|||
}
|
||||
|
||||
void
|
||||
gfxFontCache::NotifyExpired(gfxFont *aFont)
|
||||
gfxFontCache::NotifyExpired(gfxFont* aFont)
|
||||
{
|
||||
aFont->ClearCachedWords();
|
||||
RemoveObject(aFont);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "harfbuzz/hb.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsColor.h"
|
||||
#include "mozilla/ServoUtils.h"
|
||||
|
||||
typedef struct _cairo cairo_t;
|
||||
typedef struct _cairo_scaled_font cairo_scaled_font_t;
|
||||
|
@ -255,12 +256,41 @@ struct FontCacheSizes {
|
|||
size_t mShapedWords; // memory used by the per-font shapedWord caches
|
||||
};
|
||||
|
||||
class gfxFontCache final : public nsExpirationTracker<gfxFont,3> {
|
||||
class gfxFontCacheExpirationTracker
|
||||
: public ExpirationTrackerImpl<gfxFont, 3,
|
||||
::detail::PlaceholderLock,
|
||||
::detail::PlaceholderAutoLock>
|
||||
{
|
||||
protected:
|
||||
typedef ::detail::PlaceholderLock Lock;
|
||||
typedef ::detail::PlaceholderAutoLock AutoLock;
|
||||
|
||||
Lock mLock;
|
||||
|
||||
AutoLock FakeLock()
|
||||
{
|
||||
return AutoLock(mLock);
|
||||
}
|
||||
|
||||
Lock& GetMutex() override
|
||||
{
|
||||
mozilla::AssertIsMainThreadOrServoFontMetricsLocked();
|
||||
return mLock;
|
||||
}
|
||||
|
||||
public:
|
||||
enum {
|
||||
FONT_TIMEOUT_SECONDS = 10,
|
||||
SHAPED_WORD_TIMEOUT_SECONDS = 60
|
||||
};
|
||||
enum { FONT_TIMEOUT_SECONDS = 10 };
|
||||
|
||||
gfxFontCacheExpirationTracker(nsIEventTarget* aEventTarget)
|
||||
: ExpirationTrackerImpl<gfxFont, 3, Lock, AutoLock>(
|
||||
FONT_TIMEOUT_SECONDS * 1000, "gfxFontCache", aEventTarget)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class gfxFontCache final : private gfxFontCacheExpirationTracker {
|
||||
public:
|
||||
enum { SHAPED_WORD_TIMEOUT_SECONDS = 60 };
|
||||
|
||||
explicit gfxFontCache(nsIEventTarget* aEventTarget);
|
||||
~gfxFontCache();
|
||||
|
@ -294,10 +324,6 @@ public:
|
|||
// amount of time.
|
||||
void NotifyReleased(gfxFont *aFont);
|
||||
|
||||
// This gets called when the timeout has expired on a zero-refcount
|
||||
// font; we just delete it.
|
||||
virtual void NotifyExpired(gfxFont *aFont) override;
|
||||
|
||||
// Cleans out the hashtable and removes expired fonts waiting for cleanup.
|
||||
// Other gfxFont objects may be still in use but they will be pushed
|
||||
// into the expiration queues and removed.
|
||||
|
@ -314,6 +340,16 @@ public:
|
|||
void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
|
||||
void AgeAllGenerations()
|
||||
{
|
||||
AgeAllGenerationsLocked(FakeLock());
|
||||
}
|
||||
|
||||
void RemoveObject(gfxFont* aFont)
|
||||
{
|
||||
RemoveObjectLocked(aFont, FakeLock());
|
||||
}
|
||||
|
||||
protected:
|
||||
class MemoryReporter final : public nsIMemoryReporter
|
||||
{
|
||||
|
@ -333,6 +369,20 @@ protected:
|
|||
NS_DECL_NSIOBSERVER
|
||||
};
|
||||
|
||||
nsresult AddObject(gfxFont* aFont)
|
||||
{
|
||||
return AddObjectLocked(aFont, FakeLock());
|
||||
}
|
||||
|
||||
// This gets called when the timeout has expired on a zero-refcount
|
||||
// font; we just delete it.
|
||||
virtual void NotifyExpiredLocked(gfxFont* aFont, const AutoLock&) override
|
||||
{
|
||||
NotifyExpired(aFont);
|
||||
}
|
||||
|
||||
void NotifyExpired(gfxFont* aFont);
|
||||
|
||||
void DestroyFont(gfxFont *aFont);
|
||||
|
||||
static gfxFontCache *gGlobalCache;
|
||||
|
|
|
@ -43,14 +43,9 @@ AnimationSurfaceProvider::DropImageReference()
|
|||
return; // Nothing to do.
|
||||
}
|
||||
|
||||
// RasterImage objects need to be destroyed on the main thread. We also need
|
||||
// to destroy them asynchronously, because if our surface cache entry is
|
||||
// destroyed and we were the only thing keeping |mImage| alive, RasterImage's
|
||||
// destructor may call into the surface cache while whatever code caused us to
|
||||
// get evicted is holding the surface cache lock, causing deadlock.
|
||||
RefPtr<RasterImage> image = mImage;
|
||||
mImage = nullptr;
|
||||
NS_ReleaseOnMainThreadSystemGroup(image.forget(), /* aAlwaysProxy = */ true);
|
||||
// RasterImage objects need to be destroyed on the main thread.
|
||||
NS_ReleaseOnMainThreadSystemGroup("AnimationSurfaceProvider::mImage",
|
||||
mImage.forget());
|
||||
}
|
||||
|
||||
DrawableFrameRef
|
||||
|
|
|
@ -253,12 +253,14 @@ public:
|
|||
return mSurfaces.Put(aSurface->GetSurfaceKey(), aSurface, fallible);
|
||||
}
|
||||
|
||||
void Remove(NotNull<CachedSurface*> aSurface)
|
||||
already_AddRefed<CachedSurface> Remove(NotNull<CachedSurface*> aSurface)
|
||||
{
|
||||
MOZ_ASSERT(mSurfaces.GetWeak(aSurface->GetSurfaceKey()),
|
||||
"Should not be removing a surface we don't have");
|
||||
|
||||
mSurfaces.Remove(aSurface->GetSurfaceKey());
|
||||
RefPtr<CachedSurface> surface;
|
||||
mSurfaces.Remove(aSurface->GetSurfaceKey(), getter_AddRefs(surface));
|
||||
return surface.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CachedSurface> Lookup(const SurfaceKey& aSurfaceKey)
|
||||
|
@ -515,10 +517,14 @@ public:
|
|||
}
|
||||
|
||||
StopTracking(aSurface, aAutoLock);
|
||||
cache->Remove(aSurface);
|
||||
|
||||
// Remove the per-image cache if it's unneeded now. (Keep it if the image is
|
||||
// locked, since the per-image cache is where we store that state.)
|
||||
// Individual surfaces must be freed outside the lock.
|
||||
mCachedSurfacesDiscard.AppendElement(cache->Remove(aSurface));
|
||||
|
||||
// Remove the per-image cache if it's unneeded now. Keep it if the image is
|
||||
// locked, since the per-image cache is where we store that state. Note that
|
||||
// we don't push it into mImageCachesDiscard because all of its surfaces
|
||||
// have been removed, so it is safe to free while holding the lock.
|
||||
if (cache->IsEmpty() && !cache->IsLocked()) {
|
||||
mImageCaches.Remove(imageKey);
|
||||
}
|
||||
|
@ -728,11 +734,12 @@ public:
|
|||
/* aStaticOnly = */ !gfxPrefs::ImageMemAnimatedDiscardable(), aAutoLock);
|
||||
}
|
||||
|
||||
void RemoveImage(const ImageKey aImageKey, const StaticMutexAutoLock& aAutoLock)
|
||||
already_AddRefed<ImageSurfaceCache>
|
||||
RemoveImage(const ImageKey aImageKey, const StaticMutexAutoLock& aAutoLock)
|
||||
{
|
||||
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
|
||||
if (!cache) {
|
||||
return; // No cached surfaces for this image, so nothing to do.
|
||||
return nullptr; // No cached surfaces for this image, so nothing to do.
|
||||
}
|
||||
|
||||
// Discard all of the cached surfaces for this image.
|
||||
|
@ -747,6 +754,10 @@ public:
|
|||
// The per-image cache isn't needed anymore, so remove it as well.
|
||||
// This implicitly unlocks the image if it was locked.
|
||||
mImageCaches.Remove(aImageKey);
|
||||
|
||||
// Since we did not actually remove any of the surfaces from the cache
|
||||
// itself, only stopped tracking them, we should free it outside the lock.
|
||||
return cache.forget();
|
||||
}
|
||||
|
||||
void DiscardAll(const StaticMutexAutoLock& aAutoLock)
|
||||
|
@ -785,6 +796,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void TakeDiscard(nsTArray<RefPtr<CachedSurface>>& aDiscard,
|
||||
const StaticMutexAutoLock& aAutoLock)
|
||||
{
|
||||
MOZ_ASSERT(aDiscard.IsEmpty());
|
||||
aDiscard = Move(mCachedSurfacesDiscard);
|
||||
}
|
||||
|
||||
void LockSurface(NotNull<CachedSurface*> aSurface,
|
||||
const StaticMutexAutoLock& aAutoLock)
|
||||
{
|
||||
|
@ -908,10 +926,12 @@ private:
|
|||
Remove(WrapNotNull(surface), aAutoLock);
|
||||
}
|
||||
|
||||
struct SurfaceTracker : public ExpirationTrackerImpl<CachedSurface, 2,
|
||||
StaticMutex,
|
||||
StaticMutexAutoLock>
|
||||
class SurfaceTracker final :
|
||||
public ExpirationTrackerImpl<CachedSurface, 2,
|
||||
StaticMutex,
|
||||
StaticMutexAutoLock>
|
||||
{
|
||||
public:
|
||||
explicit SurfaceTracker(uint32_t aSurfaceCacheExpirationTimeMS)
|
||||
: ExpirationTrackerImpl<CachedSurface, 2,
|
||||
StaticMutex, StaticMutexAutoLock>(
|
||||
|
@ -926,23 +946,40 @@ private:
|
|||
sInstance->Remove(WrapNotNull(aSurface), aAutoLock);
|
||||
}
|
||||
|
||||
void NotifyHandlerEndLocked(const StaticMutexAutoLock& aAutoLock) override
|
||||
{
|
||||
sInstance->TakeDiscard(mDiscard, aAutoLock);
|
||||
}
|
||||
|
||||
void NotifyHandlerEnd() override
|
||||
{
|
||||
nsTArray<RefPtr<CachedSurface>> discard(Move(mDiscard));
|
||||
}
|
||||
|
||||
StaticMutex& GetMutex() override
|
||||
{
|
||||
return sInstanceMutex;
|
||||
}
|
||||
|
||||
nsTArray<RefPtr<CachedSurface>> mDiscard;
|
||||
};
|
||||
|
||||
struct MemoryPressureObserver : public nsIObserver
|
||||
class MemoryPressureObserver final : public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Observe(nsISupports*,
|
||||
const char* aTopic,
|
||||
const char16_t*) override
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (sInstance && strcmp(aTopic, "memory-pressure") == 0) {
|
||||
sInstance->DiscardForMemoryPressure(lock);
|
||||
nsTArray<RefPtr<CachedSurface>> discard;
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (sInstance && strcmp(aTopic, "memory-pressure") == 0) {
|
||||
sInstance->DiscardForMemoryPressure(lock);
|
||||
sInstance->TakeDiscard(discard, lock);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -954,6 +991,7 @@ private:
|
|||
nsTArray<CostEntry> mCosts;
|
||||
nsRefPtrHashtable<nsPtrHashKey<Image>,
|
||||
ImageSurfaceCache> mImageCaches;
|
||||
nsTArray<RefPtr<CachedSurface>> mCachedSurfacesDiscard;
|
||||
SurfaceTracker mExpirationTracker;
|
||||
RefPtr<MemoryPressureObserver> mMemoryPressureObserver;
|
||||
const uint32_t mDiscardFactor;
|
||||
|
@ -1029,45 +1067,72 @@ SurfaceCache::Initialize()
|
|||
/* static */ void
|
||||
SurfaceCache::Shutdown()
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sInstance, "No singleton - was Shutdown() called twice?");
|
||||
sInstance = nullptr;
|
||||
RefPtr<SurfaceCacheImpl> cache;
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sInstance, "No singleton - was Shutdown() called twice?");
|
||||
cache = sInstance.forget();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ LookupResult
|
||||
SurfaceCache::Lookup(const ImageKey aImageKey,
|
||||
const SurfaceKey& aSurfaceKey)
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (!sInstance) {
|
||||
return LookupResult(MatchType::NOT_FOUND);
|
||||
nsTArray<RefPtr<CachedSurface>> discard;
|
||||
LookupResult rv(MatchType::NOT_FOUND);
|
||||
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (!sInstance) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = sInstance->Lookup(aImageKey, aSurfaceKey, lock);
|
||||
sInstance->TakeDiscard(discard, lock);
|
||||
}
|
||||
|
||||
return sInstance->Lookup(aImageKey, aSurfaceKey, lock);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */ LookupResult
|
||||
SurfaceCache::LookupBestMatch(const ImageKey aImageKey,
|
||||
const SurfaceKey& aSurfaceKey)
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (!sInstance) {
|
||||
return LookupResult(MatchType::NOT_FOUND);
|
||||
nsTArray<RefPtr<CachedSurface>> discard;
|
||||
LookupResult rv(MatchType::NOT_FOUND);
|
||||
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (!sInstance) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = sInstance->LookupBestMatch(aImageKey, aSurfaceKey, lock);
|
||||
sInstance->TakeDiscard(discard, lock);
|
||||
}
|
||||
|
||||
return sInstance->LookupBestMatch(aImageKey, aSurfaceKey, lock);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */ InsertOutcome
|
||||
SurfaceCache::Insert(NotNull<ISurfaceProvider*> aProvider)
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (!sInstance) {
|
||||
return InsertOutcome::FAILURE;
|
||||
nsTArray<RefPtr<CachedSurface>> discard;
|
||||
InsertOutcome rv(InsertOutcome::FAILURE);
|
||||
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (!sInstance) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = sInstance->Insert(aProvider, /* aSetAvailable = */ false, lock);
|
||||
sInstance->TakeDiscard(discard, lock);
|
||||
}
|
||||
|
||||
return sInstance->Insert(aProvider, /* aSetAvailable = */ false, lock);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
|
@ -1134,18 +1199,25 @@ SurfaceCache::UnlockEntries(const ImageKey aImageKey)
|
|||
/* static */ void
|
||||
SurfaceCache::RemoveImage(const ImageKey aImageKey)
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (sInstance) {
|
||||
sInstance->RemoveImage(aImageKey, lock);
|
||||
RefPtr<ImageSurfaceCache> discard;
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (sInstance) {
|
||||
discard = sInstance->RemoveImage(aImageKey, lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SurfaceCache::DiscardAll()
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (sInstance) {
|
||||
sInstance->DiscardAll(lock);
|
||||
nsTArray<RefPtr<CachedSurface>> discard;
|
||||
{
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (sInstance) {
|
||||
sInstance->DiscardAll(lock);
|
||||
sInstance->TakeDiscard(discard, lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -287,10 +287,27 @@ imgRequestProxy::GetEventTarget() const
|
|||
return target.forget();
|
||||
}
|
||||
|
||||
void
|
||||
imgRequestProxy::Dispatch(already_AddRefed<nsIRunnable> aEvent)
|
||||
nsresult
|
||||
imgRequestProxy::DispatchWithTargetIfAvailable(already_AddRefed<nsIRunnable> aEvent)
|
||||
{
|
||||
LOG_FUNC(gImgLog, "imgRequestProxy::Dispatch");
|
||||
LOG_FUNC(gImgLog, "imgRequestProxy::DispatchWithTargetIfAvailable");
|
||||
|
||||
// This method should only be used when it is *expected* that we are
|
||||
// dispatching an event (e.g. we want to handle an event asynchronously)
|
||||
// rather we need to (e.g. we are in the wrong scheduler group context).
|
||||
// As such, we do not set mHadDispatch for telemetry purposes.
|
||||
if (mEventTarget) {
|
||||
mEventTarget->Dispatch(Move(aEvent), NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_DispatchToMainThread(Move(aEvent));
|
||||
}
|
||||
|
||||
void
|
||||
imgRequestProxy::DispatchWithTarget(already_AddRefed<nsIRunnable> aEvent)
|
||||
{
|
||||
LOG_FUNC(gImgLog, "imgRequestProxy::DispatchWithTarget");
|
||||
|
||||
MOZ_ASSERT(mListener || mTabGroup);
|
||||
MOZ_ASSERT(mEventTarget);
|
||||
|
@ -410,7 +427,7 @@ imgRequestProxy::Cancel(nsresult status)
|
|||
mCanceled = true;
|
||||
|
||||
nsCOMPtr<nsIRunnable> ev = new imgCancelRunnable(this, status);
|
||||
return NS_DispatchToCurrentThread(ev);
|
||||
return DispatchWithTargetIfAvailable(ev.forget());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -451,8 +468,10 @@ imgRequestProxy::CancelAndForgetObserver(nsresult aStatus)
|
|||
mIsInLoadGroup = oldIsInLoadGroup;
|
||||
|
||||
if (mIsInLoadGroup) {
|
||||
NS_DispatchToCurrentThread(NewRunnableMethod("imgRequestProxy::DoRemoveFromLoadGroup",
|
||||
this, &imgRequestProxy::DoRemoveFromLoadGroup));
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
NewRunnableMethod("imgRequestProxy::DoRemoveFromLoadGroup",
|
||||
this, &imgRequestProxy::DoRemoveFromLoadGroup);
|
||||
DispatchWithTargetIfAvailable(ev.forget());
|
||||
}
|
||||
|
||||
NullOutListener();
|
||||
|
@ -929,12 +948,12 @@ imgRequestProxy::Notify(int32_t aType, const mozilla::gfx::IntRect* aRect)
|
|||
RefPtr<imgRequestProxy> self(this);
|
||||
if (aRect) {
|
||||
const mozilla::gfx::IntRect rect = *aRect;
|
||||
Dispatch(NS_NewRunnableFunction("imgRequestProxy::Notify",
|
||||
DispatchWithTarget(NS_NewRunnableFunction("imgRequestProxy::Notify",
|
||||
[self, rect, aType]() -> void {
|
||||
self->Notify(aType, &rect);
|
||||
}));
|
||||
} else {
|
||||
Dispatch(NS_NewRunnableFunction("imgRequestProxy::Notify",
|
||||
DispatchWithTarget(NS_NewRunnableFunction("imgRequestProxy::Notify",
|
||||
[self, aType]() -> void {
|
||||
self->Notify(aType, nullptr);
|
||||
}));
|
||||
|
@ -964,7 +983,7 @@ imgRequestProxy::OnLoadComplete(bool aLastPart)
|
|||
RefPtr<imgRequestProxy> self(this);
|
||||
|
||||
if (!IsOnEventTarget()) {
|
||||
Dispatch(NS_NewRunnableFunction("imgRequestProxy::OnLoadComplete",
|
||||
DispatchWithTarget(NS_NewRunnableFunction("imgRequestProxy::OnLoadComplete",
|
||||
[self, aLastPart]() -> void {
|
||||
self->OnLoadComplete(aLastPart);
|
||||
}));
|
||||
|
@ -1019,7 +1038,7 @@ imgRequestProxy::BlockOnload()
|
|||
|
||||
if (!IsOnEventTarget()) {
|
||||
RefPtr<imgRequestProxy> self(this);
|
||||
Dispatch(NS_NewRunnableFunction("imgRequestProxy::BlockOnload",
|
||||
DispatchWithTarget(NS_NewRunnableFunction("imgRequestProxy::BlockOnload",
|
||||
[self]() -> void {
|
||||
self->BlockOnload();
|
||||
}));
|
||||
|
@ -1046,7 +1065,7 @@ imgRequestProxy::UnblockOnload()
|
|||
|
||||
if (!IsOnEventTarget()) {
|
||||
RefPtr<imgRequestProxy> self(this);
|
||||
Dispatch(NS_NewRunnableFunction("imgRequestProxy::UnblockOnload",
|
||||
DispatchWithTarget(NS_NewRunnableFunction("imgRequestProxy::UnblockOnload",
|
||||
[self]() -> void {
|
||||
self->UnblockOnload();
|
||||
}));
|
||||
|
|
|
@ -214,7 +214,8 @@ private:
|
|||
|
||||
void AddToOwner(nsIDocument* aLoadingDocument);
|
||||
|
||||
void Dispatch(already_AddRefed<nsIRunnable> aEvent);
|
||||
nsresult DispatchWithTargetIfAvailable(already_AddRefed<nsIRunnable> aEvent);
|
||||
void DispatchWithTarget(already_AddRefed<nsIRunnable> aEvent);
|
||||
|
||||
// The URI of our request.
|
||||
RefPtr<ImageURL> mURI;
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
#include "gc/Heap.h"
|
||||
#include "vm/SelfHosting.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "vm/List-inl.h"
|
||||
#include "vm/NativeObject-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
@ -318,53 +317,13 @@ RejectNonGenericMethod(JSContext* cx, const CallArgs& args,
|
|||
inline static MOZ_MUST_USE NativeObject*
|
||||
SetNewList(JSContext* cx, HandleNativeObject container, uint32_t slot)
|
||||
{
|
||||
NativeObject* list = NewObjectWithNullTaggedProto<PlainObject>(cx);
|
||||
NativeObject* list = NewList(cx);
|
||||
if (!list)
|
||||
return nullptr;
|
||||
container->setFixedSlot(slot, ObjectValue(*list));
|
||||
return list;
|
||||
}
|
||||
|
||||
inline static MOZ_MUST_USE bool
|
||||
AppendToList(JSContext* cx, HandleNativeObject list, HandleValue value)
|
||||
{
|
||||
uint32_t length = list->getDenseInitializedLength();
|
||||
|
||||
if (!list->ensureElements(cx, length + 1))
|
||||
return false;
|
||||
|
||||
list->ensureDenseInitializedLength(cx, length, 1);
|
||||
list->setDenseElement(length, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline static MOZ_MUST_USE T*
|
||||
PeekList(NativeObject* list)
|
||||
{
|
||||
MOZ_ASSERT(list->getDenseInitializedLength() > 0);
|
||||
return &list->getDenseElement(0).toObject().as<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline static MOZ_MUST_USE T*
|
||||
ShiftFromList(JSContext* cx, HandleNativeObject list)
|
||||
{
|
||||
uint32_t length = list->getDenseInitializedLength();
|
||||
MOZ_ASSERT(length > 0);
|
||||
|
||||
Rooted<T*> entry(cx, &list->getDenseElement(0).toObject().as<T>());
|
||||
if (!list->tryShiftDenseElements(1)) {
|
||||
list->moveDenseElements(0, 1, length - 1);
|
||||
list->shrinkElements(cx, length - 1);
|
||||
}
|
||||
|
||||
list->setDenseInitializedLength(length - 1);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
class ByteStreamChunk : public NativeObject
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -3911,12 +3911,6 @@ Parser<ParseHandler, CharT>::functionStmt(uint32_t toStringStart, YieldHandling
|
|||
|
||||
GeneratorKind generatorKind = NotGenerator;
|
||||
if (tt == TOK_MUL) {
|
||||
if (!asyncIterationSupported()) {
|
||||
if (asyncKind != SyncFunction) {
|
||||
error(JSMSG_ASYNC_GENERATOR);
|
||||
return null();
|
||||
}
|
||||
}
|
||||
generatorKind = StarGenerator;
|
||||
if (!tokenStream.getToken(&tt))
|
||||
return null();
|
||||
|
@ -3986,12 +3980,6 @@ Parser<ParseHandler, CharT>::functionExpr(uint32_t toStringStart, InvokedPredict
|
|||
return null();
|
||||
|
||||
if (tt == TOK_MUL) {
|
||||
if (!asyncIterationSupported()) {
|
||||
if (asyncKind != SyncFunction) {
|
||||
error(JSMSG_ASYNC_GENERATOR);
|
||||
return null();
|
||||
}
|
||||
}
|
||||
generatorKind = StarGenerator;
|
||||
if (!tokenStream.getToken(&tt))
|
||||
return null();
|
||||
|
@ -6299,16 +6287,14 @@ Parser<ParseHandler, CharT>::forStatement(YieldHandling yieldHandling)
|
|||
}
|
||||
}
|
||||
|
||||
if (asyncIterationSupported()) {
|
||||
if (pc->isAsync()) {
|
||||
bool matched;
|
||||
if (!tokenStream.matchToken(&matched, TOK_AWAIT))
|
||||
return null();
|
||||
if (pc->isAsync()) {
|
||||
bool matched;
|
||||
if (!tokenStream.matchToken(&matched, TOK_AWAIT))
|
||||
return null();
|
||||
|
||||
if (matched) {
|
||||
iflags |= JSITER_FORAWAITOF;
|
||||
iterKind = IteratorKind::Async;
|
||||
}
|
||||
if (matched) {
|
||||
iflags |= JSITER_FORAWAITOF;
|
||||
iterKind = IteratorKind::Async;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9717,12 +9703,6 @@ Parser<ParseHandler, CharT>::propertyName(YieldHandling yieldHandling,
|
|||
}
|
||||
|
||||
if (ltok == TOK_MUL) {
|
||||
if (!asyncIterationSupported()) {
|
||||
if (isAsync) {
|
||||
error(JSMSG_ASYNC_GENERATOR);
|
||||
return null();
|
||||
}
|
||||
}
|
||||
isGenerator = true;
|
||||
if (!tokenStream.getToken(<ok))
|
||||
return null();
|
||||
|
|
|
@ -180,16 +180,6 @@ class ParserBase : public StrictModeGetter
|
|||
pc->isLegacyGenerator();
|
||||
}
|
||||
|
||||
bool asyncIterationSupported() {
|
||||
#ifdef RELEASE_OR_BETA
|
||||
return false;
|
||||
#else
|
||||
// Expose Async Iteration only to web content until the spec proposal
|
||||
// gets stable.
|
||||
return !options().isProbablySystemOrAddonCode;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual bool strictMode() { return pc->sc()->strict(); }
|
||||
bool setLocalStrictMode(bool strict) {
|
||||
MOZ_ASSERT(tokenStream.debugHasNoLookahead());
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
Object.defineProperty(Array.prototype, "2", {
|
||||
set: function () {}
|
||||
});
|
||||
async function* f() {
|
||||
yield {};
|
||||
}
|
||||
var x = f();
|
||||
x.next();
|
||||
x.next();
|
||||
x.next();
|
|
@ -0,0 +1,14 @@
|
|||
Object.prototype.set = function () {};
|
||||
let f = async function* () {
|
||||
yield;
|
||||
};
|
||||
let x = f();
|
||||
x.next();
|
||||
x.next().then(function () {
|
||||
x.next();
|
||||
});
|
||||
Object.defineProperty(Array.prototype, "0", {
|
||||
get: function () {
|
||||
return 1;
|
||||
}
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
if (helperThreadCount() === 0)
|
||||
quit();
|
||||
|
||||
setGCCallback({
|
||||
action: "majorGC"
|
||||
});
|
||||
gcparam("allocationThreshold", 1);
|
||||
offThreadCompileScript("");
|
||||
for (let i = 0; i < 40000; i++)
|
||||
Symbol.for(i);
|
||||
eval(0);
|
|
@ -0,0 +1,8 @@
|
|||
function f(x) {
|
||||
var count = 0;
|
||||
for (var i = 0; i < x.length; ++i)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
assertEq(f(Error()), 0);
|
||||
assertEq(f([[]]), 1);
|
|
@ -11367,8 +11367,13 @@ IonBuilder::getPropAddCache(MDefinition* obj, PropertyName* name,
|
|||
MOZ_TRY(resumeAfter(load));
|
||||
|
||||
MIRType rvalType = types->getKnownMIRType();
|
||||
if (barrier != BarrierKind::NoBarrier || IsNullOrUndefined(rvalType))
|
||||
if (barrier != BarrierKind::NoBarrier) {
|
||||
rvalType = MIRType::Value;
|
||||
} else {
|
||||
load->setResultTypeSet(types);
|
||||
if (IsNullOrUndefined(rvalType))
|
||||
rvalType = MIRType::Value;
|
||||
}
|
||||
load->setResultType(rvalType);
|
||||
|
||||
if (*pc != JSOP_CALLPROP || !IsNullOrUndefined(obj->type())) {
|
||||
|
|
|
@ -188,7 +188,6 @@ MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid array compre
|
|||
MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG, 0, JSEXN_INTERNALERR, "array initializer too large")
|
||||
MSG_DEF(JSMSG_AS_AFTER_IMPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'as' after import *")
|
||||
MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD, 1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'")
|
||||
MSG_DEF(JSMSG_ASYNC_GENERATOR, 0, JSEXN_SYNTAXERR, "generator function or method can't be async")
|
||||
MSG_DEF(JSMSG_AWAIT_IN_DEFAULT, 0, JSEXN_SYNTAXERR, "await can't be used in default expression")
|
||||
MSG_DEF(JSMSG_AWAIT_OUTSIDE_ASYNC, 0, JSEXN_SYNTAXERR, "await is only valid in async functions")
|
||||
MSG_DEF(JSMSG_BAD_ARROW_ARGS, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)")
|
||||
|
|
|
@ -6781,6 +6781,9 @@ GCRuntime::budgetIncrementalGC(bool nonincrementalByAPI, JS::gcreason::Reason re
|
|||
|
||||
bool reset = false;
|
||||
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
|
||||
if (!zone->canCollect())
|
||||
continue;
|
||||
|
||||
if (zone->usage.gcBytes() >= zone->threshold.gcTriggerBytes()) {
|
||||
MOZ_ASSERT(zone->isGCScheduled());
|
||||
budget.makeUnlimited();
|
||||
|
@ -6812,6 +6815,9 @@ class AutoScheduleZonesForGC
|
|||
public:
|
||||
explicit AutoScheduleZonesForGC(JSRuntime* rt) : rt_(rt) {
|
||||
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
|
||||
if (!zone->canCollect())
|
||||
continue;
|
||||
|
||||
if (rt->gc.gcMode() == JSGC_MODE_GLOBAL)
|
||||
zone->scheduleGC();
|
||||
|
||||
|
|
|
@ -41,10 +41,6 @@ skip-if(!Array.prototype.values) script test262/built-ins/Array/prototype/Symbol
|
|||
skip-if(!Array.prototype.values) include test262/built-ins/Array/prototype/values/jstests.list
|
||||
skip-if(!String.prototype.normalize) include test262/built-ins/String/prototype/normalize/jstests.list
|
||||
|
||||
# Async generator is non-release-or-beta only.
|
||||
skip-if(release_or_beta) include test262/language/expressions/async-generators/jstests.list
|
||||
skip-if(release_or_beta) include test262/language/statements/async-generator/jstests.list
|
||||
|
||||
# Requires ICU to detect Final_Sigma case mapping context
|
||||
skip-if(!this.hasOwnProperty("Intl")) script test262/built-ins/String/prototype/toLowerCase/Final_Sigma_U180E.js
|
||||
skip-if(!this.hasOwnProperty("Intl")) script test262/built-ins/String/prototype/toLowerCase/special_casing_conditional.js
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "jscntxtinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "vm/List-inl.h"
|
||||
#include "vm/NativeObject-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
@ -325,25 +326,24 @@ AsyncGeneratorObject::enqueueRequest(JSContext* cx, Handle<AsyncGeneratorObject*
|
|||
return true;
|
||||
}
|
||||
|
||||
RootedArrayObject queue(cx, NewDenseEmptyArray(cx));
|
||||
RootedNativeObject queue(cx, NewList(cx));
|
||||
if (!queue)
|
||||
return false;
|
||||
|
||||
if (!NewbornArrayPush(cx, queue, ObjectValue(*asyncGenObj->singleQueueRequest())))
|
||||
RootedValue requestVal(cx, ObjectValue(*asyncGenObj->singleQueueRequest()));
|
||||
if (!AppendToList(cx, queue, requestVal))
|
||||
return false;
|
||||
if (!NewbornArrayPush(cx, queue, ObjectValue(*request)))
|
||||
requestVal = ObjectValue(*request);
|
||||
if (!AppendToList(cx, queue, requestVal))
|
||||
return false;
|
||||
|
||||
asyncGenObj->setQueue(queue);
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedArrayObject queue(cx, asyncGenObj->queue());
|
||||
|
||||
FixedInvokeArgs<1> args(cx);
|
||||
args[0].setObject(*request);
|
||||
args.setThis(ObjectValue(*queue));
|
||||
return CallJSNative(cx, array_push, args);
|
||||
RootedNativeObject queue(cx, asyncGenObj->queue());
|
||||
RootedValue requestVal(cx, ObjectValue(*request));
|
||||
return AppendToList(cx, queue, requestVal);
|
||||
}
|
||||
|
||||
/* static */ AsyncGeneratorRequest*
|
||||
|
@ -355,14 +355,8 @@ AsyncGeneratorObject::dequeueRequest(JSContext* cx, Handle<AsyncGeneratorObject*
|
|||
return request;
|
||||
}
|
||||
|
||||
RootedArrayObject queue(cx, asyncGenObj->queue());
|
||||
|
||||
FixedInvokeArgs<0> args(cx);
|
||||
args.setThis(ObjectValue(*queue));
|
||||
if (!CallJSNative(cx, array_shift, args))
|
||||
return nullptr;
|
||||
|
||||
return &args.rval().toObject().as<AsyncGeneratorRequest>();
|
||||
RootedNativeObject queue(cx, asyncGenObj->queue());
|
||||
return ShiftFromList<AsyncGeneratorRequest>(cx, queue);
|
||||
}
|
||||
|
||||
/* static */ AsyncGeneratorRequest*
|
||||
|
@ -371,13 +365,7 @@ AsyncGeneratorObject::peekRequest(JSContext* cx, Handle<AsyncGeneratorObject*> a
|
|||
if (asyncGenObj->isSingleQueue())
|
||||
return asyncGenObj->singleQueueRequest();
|
||||
|
||||
RootedArrayObject queue(cx, asyncGenObj->queue());
|
||||
|
||||
RootedValue requestVal(cx);
|
||||
if (!GetElement(cx, queue, queue, 0, &requestVal))
|
||||
return nullptr;
|
||||
|
||||
return &requestVal.toObject().as<AsyncGeneratorRequest>();
|
||||
return PeekList<AsyncGeneratorRequest>(asyncGenObj->queue());
|
||||
}
|
||||
|
||||
const Class AsyncGeneratorRequest::class_ = {
|
||||
|
|
|
@ -146,8 +146,8 @@ class AsyncGeneratorObject : public NativeObject
|
|||
return &getFixedSlot(Slot_QueueOrRequest).toObject().as<AsyncGeneratorRequest>();
|
||||
}
|
||||
|
||||
ArrayObject* queue() const {
|
||||
return &getFixedSlot(Slot_QueueOrRequest).toObject().as<ArrayObject>();
|
||||
NativeObject* queue() const {
|
||||
return &getFixedSlot(Slot_QueueOrRequest).toObject().as<NativeObject>();
|
||||
}
|
||||
void setQueue(JSObject* queue_) {
|
||||
setFixedSlot(Slot_QueueOrRequest, ObjectValue(*queue_));
|
||||
|
@ -217,7 +217,7 @@ class AsyncGeneratorObject : public NativeObject
|
|||
bool isQueueEmpty() const {
|
||||
if (isSingleQueue())
|
||||
return isSingleQueueEmpty();
|
||||
return queue()->length() == 0;
|
||||
return queue()->getDenseInitializedLength() == 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* 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 vm_List_inl_h
|
||||
#define vm_List_inl_h
|
||||
|
||||
#include "jscntxt.h"
|
||||
|
||||
#include "gc/Rooting.h"
|
||||
#include "vm/NativeObject.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "vm/NativeObject-inl.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
inline MOZ_MUST_USE NativeObject*
|
||||
NewList(JSContext* cx)
|
||||
{
|
||||
return NewObjectWithNullTaggedProto<PlainObject>(cx);
|
||||
}
|
||||
|
||||
inline MOZ_MUST_USE bool
|
||||
AppendToList(JSContext* cx, HandleNativeObject list, HandleValue value)
|
||||
{
|
||||
uint32_t length = list->getDenseInitializedLength();
|
||||
|
||||
if (!list->ensureElements(cx, length + 1))
|
||||
return false;
|
||||
|
||||
list->ensureDenseInitializedLength(cx, length, 1);
|
||||
list->setDenseElement(length, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline MOZ_MUST_USE T*
|
||||
PeekList(NativeObject* list)
|
||||
{
|
||||
MOZ_ASSERT(list->getDenseInitializedLength() > 0);
|
||||
return &list->getDenseElement(0).toObject().as<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline MOZ_MUST_USE T*
|
||||
ShiftFromList(JSContext* cx, HandleNativeObject list)
|
||||
{
|
||||
uint32_t length = list->getDenseInitializedLength();
|
||||
MOZ_ASSERT(length > 0);
|
||||
|
||||
Rooted<T*> entry(cx, &list->getDenseElement(0).toObject().as<T>());
|
||||
if (!list->tryShiftDenseElements(1)) {
|
||||
list->moveDenseElements(0, 1, length - 1);
|
||||
list->shrinkElements(cx, length - 1);
|
||||
}
|
||||
|
||||
list->setDenseInitializedLength(length - 1);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* vm_List_inl_h */
|
|
@ -118,4 +118,3 @@ skip-if = os == 'win' || os == 'mac' || (os == 'linux' && !debug) # bug 1131110,
|
|||
[test_wrappers.xul]
|
||||
[test_xrayic.xul]
|
||||
[test_xrayToJS.xul]
|
||||
[test_asyncIteration.xul]
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1331092
|
||||
-->
|
||||
<window title="Mozilla Bug 1331092"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1331092"
|
||||
target="_blank">Mozilla Bug 1331092</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
try {
|
||||
eval(`
|
||||
async function* f() {
|
||||
}
|
||||
`);
|
||||
ok(false, "should throw");
|
||||
} catch (e) {
|
||||
ok(e instanceof SyntaxError, "Async Generator shouldn't be supported in chrome code");
|
||||
}
|
||||
|
||||
try {
|
||||
eval(`
|
||||
async function f() {
|
||||
for await (let x of []) {
|
||||
}
|
||||
}
|
||||
`);
|
||||
ok(false, "should throw");
|
||||
} catch (e) {
|
||||
ok(e instanceof SyntaxError, "for-await-of shouldn't be supported in chrome code");
|
||||
}
|
||||
]]></script>
|
||||
</window>
|
|
@ -90,16 +90,22 @@ public:
|
|||
// Removes all entries from the hash table
|
||||
void Clear();
|
||||
|
||||
protected:
|
||||
LinkedList<UndisplayedNode>* GetListFor(nsIContent* aParentContent);
|
||||
LinkedList<UndisplayedNode>* GetOrCreateListFor(nsIContent* aParentContent);
|
||||
void AppendNodeFor(UndisplayedNode* aNode, nsIContent* aParentContent);
|
||||
/**
|
||||
* Get the applicable parent for the map lookup. This is almost always the
|
||||
* provided argument, except if it's a <xbl:children> element, in which case
|
||||
* it's the parent of the children element.
|
||||
*
|
||||
* All functions that are entry points into code that handles "parent"
|
||||
* objects (used as the hash table keys) must ensure that the parent objects
|
||||
* that they act on (and pass to other code) have been normalized by calling
|
||||
* this method.
|
||||
*/
|
||||
nsIContent* GetApplicableParent(nsIContent* aParent);
|
||||
static nsIContent* GetApplicableParent(nsIContent* aParent);
|
||||
|
||||
protected:
|
||||
LinkedList<UndisplayedNode>* GetListFor(nsIContent* aParentContent);
|
||||
LinkedList<UndisplayedNode>* GetOrCreateListFor(nsIContent* aParentContent);
|
||||
void AppendNodeFor(UndisplayedNode* aNode, nsIContent* aParentContent);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -132,14 +138,17 @@ nsFrameManager::Destroy()
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static nsIContent*
|
||||
ParentForUndisplayedMap(const nsIContent* aContent)
|
||||
/* static */ nsIContent*
|
||||
nsFrameManager::ParentForUndisplayedMap(const nsIContent* aContent)
|
||||
{
|
||||
MOZ_ASSERT(aContent);
|
||||
|
||||
nsIContent* parent = aContent->GetParentElementCrossingShadowRoot();
|
||||
MOZ_ASSERT(parent || !aContent->GetParent(), "no non-elements");
|
||||
|
||||
// Normalize the parent:
|
||||
parent = UndisplayedMap::GetApplicableParent(parent);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
@ -158,7 +167,13 @@ nsFrameManager::GetUndisplayedNodeInMapFor(UndisplayedMap* aMap,
|
|||
if (!aContent) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This function is an entry point into UndisplayedMap handling code, so the
|
||||
// parent that we act on must be normalized by GetApplicableParent (as per
|
||||
// that function's documentation). We rely on ParentForUndisplayedMap to
|
||||
// have done that for us.
|
||||
nsIContent* parent = ParentForUndisplayedMap(aContent);
|
||||
|
||||
for (UndisplayedNode* node = aMap->GetFirstNode(parent);
|
||||
node; node = node->getNext()) {
|
||||
if (node->mContent == aContent)
|
||||
|
@ -198,7 +213,12 @@ nsFrameManager::SetStyleContextInMap(UndisplayedMap* aMap,
|
|||
MOZ_ASSERT(!GetStyleContextInMap(aMap, aContent),
|
||||
"Already have an entry for aContent");
|
||||
|
||||
// This function is an entry point into UndisplayedMap handling code, so the
|
||||
// parent that we act on must be normalized by GetApplicableParent (as per
|
||||
// that function's documentation). We rely on ParentForUndisplayedMap to
|
||||
// have done that for us.
|
||||
nsIContent* parent = ParentForUndisplayedMap(aContent);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsIPresShell* shell = aStyleContext->PresContext()->PresShell();
|
||||
NS_ASSERTION(parent || (shell && shell->GetDocument() &&
|
||||
|
@ -206,6 +226,16 @@ nsFrameManager::SetStyleContextInMap(UndisplayedMap* aMap,
|
|||
"undisplayed content must have a parent, unless it's the root "
|
||||
"element");
|
||||
#endif
|
||||
|
||||
// We set this bit as an optimization so that we can can know when a content
|
||||
// node may have |display:none| or |display:contents| children. This allows
|
||||
// other parts of the code to avoid checking for such children in
|
||||
// mDisplayNoneMap and mDisplayContentsMap if the bit isn't present on a node
|
||||
// that it's handling.
|
||||
if (parent) {
|
||||
parent->SetMayHaveChildrenWithLayoutBoxesDisabled();
|
||||
}
|
||||
|
||||
aMap->AddNodeFor(parent, aContent, aStyleContext);
|
||||
}
|
||||
|
||||
|
@ -231,7 +261,13 @@ nsFrameManager::ChangeStyleContextInMap(UndisplayedMap* aMap,
|
|||
printf("ChangeStyleContextInMap(%d): p=%p \n", i++, (void *)aContent);
|
||||
#endif
|
||||
|
||||
for (UndisplayedNode* node = aMap->GetFirstNode(aContent->GetParent());
|
||||
// This function is an entry point into UndisplayedMap handling code, so the
|
||||
// parent that we act on must be normalized by GetApplicableParent (as per
|
||||
// that function's documentation). We rely on ParentForUndisplayedMap to
|
||||
// have done that for us.
|
||||
nsIContent* parent = ParentForUndisplayedMap(aContent);
|
||||
|
||||
for (UndisplayedNode* node = aMap->GetFirstNode(parent);
|
||||
node; node = node->getNext()) {
|
||||
if (node->mContent == aContent) {
|
||||
node->mStyle = aStyleContext;
|
||||
|
@ -255,8 +291,23 @@ nsFrameManager::UnregisterDisplayNoneStyleFor(nsIContent* aContent,
|
|||
return;
|
||||
}
|
||||
|
||||
for (UndisplayedNode* node = mDisplayNoneMap->GetFirstNode(aParentContent);
|
||||
node; node = node->getNext()) {
|
||||
// This function is an entry point into UndisplayedMap handling code, so we
|
||||
// must call GetApplicableParent so the parent we pass around is correct.
|
||||
aParentContent = UndisplayedMap::GetApplicableParent(aParentContent);
|
||||
|
||||
if (aParentContent &&
|
||||
!aParentContent->MayHaveChildrenWithLayoutBoxesDisabled()) {
|
||||
MOZ_ASSERT(!mDisplayNoneMap->GetFirstNode(aParentContent),
|
||||
"MayHaveChildrenWithLayoutBoxesDisabled bit out of sync - "
|
||||
"may fail to remove node from mDisplayNoneMap");
|
||||
return;
|
||||
}
|
||||
|
||||
UndisplayedNode* node = mDisplayNoneMap->GetFirstNode(aParentContent);
|
||||
|
||||
const bool haveOneDisplayNoneChild = node && !node->getNext();
|
||||
|
||||
for (; node; node = node->getNext()) {
|
||||
if (node->mContent == aContent) {
|
||||
mDisplayNoneMap->RemoveNodeFor(aParentContent, node);
|
||||
|
||||
|
@ -266,6 +317,22 @@ nsFrameManager::UnregisterDisplayNoneStyleFor(nsIContent* aContent,
|
|||
// make sure that there are no more entries for the same content
|
||||
MOZ_ASSERT(!GetDisplayNoneStyleFor(aContent),
|
||||
"Found more undisplayed content data after removal");
|
||||
|
||||
if (haveOneDisplayNoneChild) {
|
||||
// There are no more children of aParentContent in mDisplayNoneMap.
|
||||
MOZ_ASSERT(!mDisplayNoneMap->GetFirstNode(aParentContent),
|
||||
"Bad UnsetMayHaveChildrenWithLayoutBoxesDisabled call");
|
||||
// If we also know that none of its children are in mDisplayContentsMap
|
||||
// then we can call UnsetMayHaveChildrenWithLayoutBoxesDisabled. We
|
||||
// don't want to check mDisplayContentsMap though since that involves a
|
||||
// hash table lookup in relatively hot code. Still, we know there are
|
||||
// no children in mDisplayContentsMap if the map is empty, so we do
|
||||
// check for that.
|
||||
if (aParentContent && !mDisplayContentsMap) {
|
||||
aParentContent->UnsetMayHaveChildrenWithLayoutBoxesDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -283,19 +350,37 @@ nsFrameManager::ClearAllMapsFor(nsIContent* aParentContent)
|
|||
printf("ClearAllMapsFor(%d): parent=%p \n", i++, aParentContent);
|
||||
#endif
|
||||
|
||||
if (mDisplayNoneMap) {
|
||||
mDisplayNoneMap->RemoveNodesFor(aParentContent);
|
||||
}
|
||||
if (mDisplayContentsMap) {
|
||||
nsAutoPtr<LinkedList<UndisplayedNode>> list =
|
||||
mDisplayContentsMap->UnlinkNodesFor(aParentContent);
|
||||
if (list) {
|
||||
while (UndisplayedNode* node = list->popFirst()) {
|
||||
ClearAllMapsFor(node->mContent);
|
||||
delete node;
|
||||
if (!aParentContent ||
|
||||
aParentContent->MayHaveChildrenWithLayoutBoxesDisabled()) {
|
||||
if (mDisplayNoneMap) {
|
||||
mDisplayNoneMap->RemoveNodesFor(aParentContent);
|
||||
}
|
||||
if (mDisplayContentsMap) {
|
||||
nsAutoPtr<LinkedList<UndisplayedNode>> list =
|
||||
mDisplayContentsMap->UnlinkNodesFor(aParentContent);
|
||||
if (list) {
|
||||
while (UndisplayedNode* node = list->popFirst()) {
|
||||
ClearAllMapsFor(node->mContent);
|
||||
delete node;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aParentContent) {
|
||||
aParentContent->UnsetMayHaveChildrenWithLayoutBoxesDisabled();
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
if (mDisplayNoneMap) {
|
||||
MOZ_ASSERT(!mDisplayNoneMap->GetFirstNode(aParentContent),
|
||||
"We failed to remove a node from mDisplayNoneMap");
|
||||
}
|
||||
if (mDisplayContentsMap) {
|
||||
MOZ_ASSERT(!mDisplayContentsMap->GetFirstNode(aParentContent),
|
||||
"We failed to remove a node from mDisplayContentsMap");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Need to look at aParentContent's content list due to XBL insertions.
|
||||
// Nodes in aParentContent's content list do not have aParentContent as a
|
||||
|
@ -342,8 +427,23 @@ nsFrameManager::UnregisterDisplayContentsStyleFor(nsIContent* aContent,
|
|||
return;
|
||||
}
|
||||
|
||||
for (UndisplayedNode* node = mDisplayContentsMap->GetFirstNode(aParentContent);
|
||||
node; node = node->getNext()) {
|
||||
// This function is an entry point into UndisplayedMap handling code, so we
|
||||
// must call GetApplicableParent so the parent we pass around is correct.
|
||||
aParentContent = UndisplayedMap::GetApplicableParent(aParentContent);
|
||||
|
||||
if (aParentContent &&
|
||||
!aParentContent->MayHaveChildrenWithLayoutBoxesDisabled()) {
|
||||
MOZ_ASSERT(!mDisplayContentsMap->GetFirstNode(aParentContent),
|
||||
"MayHaveChildrenWithLayoutBoxesDisabled bit out of sync - "
|
||||
"may fail to remove node from mDisplayContentsMap");
|
||||
return;
|
||||
}
|
||||
|
||||
UndisplayedNode* node = mDisplayContentsMap->GetFirstNode(aParentContent);
|
||||
|
||||
const bool haveOneDisplayContentsChild = node && !node->getNext();
|
||||
|
||||
for (; node; node = node->getNext()) {
|
||||
if (node->mContent == aContent) {
|
||||
mDisplayContentsMap->RemoveNodeFor(aParentContent, node);
|
||||
|
||||
|
@ -354,6 +454,22 @@ nsFrameManager::UnregisterDisplayContentsStyleFor(nsIContent* aContent,
|
|||
MOZ_ASSERT(!GetDisplayContentsStyleFor(aContent),
|
||||
"Found more entries for aContent after removal");
|
||||
ClearAllMapsFor(aContent);
|
||||
|
||||
if (haveOneDisplayContentsChild) {
|
||||
// There are no more children of aParentContent in mDisplayContentsMap.
|
||||
MOZ_ASSERT(!mDisplayContentsMap->GetFirstNode(aParentContent),
|
||||
"Bad UnsetMayHaveChildrenWithLayoutBoxesDisabled call");
|
||||
// If we also know that none of its children are in mDisplayNoneMap
|
||||
// then we can call UnsetMayHaveChildrenWithLayoutBoxesDisabled. We
|
||||
// don't want to check mDisplayNoneMap though since that involves a
|
||||
// hash table lookup in relatively hot code. Still, we know there are
|
||||
// no children in mDisplayNoneMap if the map is empty, so we do
|
||||
// check for that.
|
||||
if (aParentContent && !mDisplayNoneMap) {
|
||||
aParentContent->UnsetMayHaveChildrenWithLayoutBoxesDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -618,7 +734,8 @@ nsFrameManagerBase::UndisplayedMap::GetApplicableParent(nsIContent* aParent)
|
|||
LinkedList<UndisplayedNode>*
|
||||
nsFrameManagerBase::UndisplayedMap::GetListFor(nsIContent* aParent)
|
||||
{
|
||||
aParent = GetApplicableParent(aParent);
|
||||
MOZ_ASSERT(aParent == GetApplicableParent(aParent),
|
||||
"The parent that we use as the hash key must have been normalized");
|
||||
|
||||
LinkedList<UndisplayedNode>* list;
|
||||
if (Get(aParent, &list)) {
|
||||
|
@ -631,7 +748,9 @@ nsFrameManagerBase::UndisplayedMap::GetListFor(nsIContent* aParent)
|
|||
LinkedList<UndisplayedNode>*
|
||||
nsFrameManagerBase::UndisplayedMap::GetOrCreateListFor(nsIContent* aParent)
|
||||
{
|
||||
aParent = GetApplicableParent(aParent);
|
||||
MOZ_ASSERT(aParent == GetApplicableParent(aParent),
|
||||
"The parent that we use as the hash key must have been normalized");
|
||||
|
||||
return LookupOrAdd(aParent);
|
||||
}
|
||||
|
||||
|
|
|
@ -209,6 +209,8 @@ public:
|
|||
void RestoreFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState);
|
||||
|
||||
protected:
|
||||
static nsIContent* ParentForUndisplayedMap(const nsIContent* aContent);
|
||||
|
||||
void ClearAllMapsFor(nsIContent* aParentContent);
|
||||
|
||||
static nsStyleContext* GetStyleContextInMap(UndisplayedMap* aMap,
|
||||
|
|
|
@ -13913,15 +13913,15 @@ CSSParserImpl::ParseContent()
|
|||
// We need to divide the 'content' keywords into two classes for
|
||||
// ParseVariant's sake, so we can't just use nsCSSProps::kContentKTable.
|
||||
static const KTableEntry kContentListKWs[] = {
|
||||
{ eCSSKeyword_open_quote, NS_STYLE_CONTENT_OPEN_QUOTE },
|
||||
{ eCSSKeyword_close_quote, NS_STYLE_CONTENT_CLOSE_QUOTE },
|
||||
{ eCSSKeyword_no_open_quote, NS_STYLE_CONTENT_NO_OPEN_QUOTE },
|
||||
{ eCSSKeyword_no_close_quote, NS_STYLE_CONTENT_NO_CLOSE_QUOTE },
|
||||
{ eCSSKeyword_open_quote, uint8_t(StyleContent::OpenQuote) },
|
||||
{ eCSSKeyword_close_quote, uint8_t(StyleContent::CloseQuote) },
|
||||
{ eCSSKeyword_no_open_quote, uint8_t(StyleContent::NoOpenQuote) },
|
||||
{ eCSSKeyword_no_close_quote, uint8_t(StyleContent::NoCloseQuote) },
|
||||
{ eCSSKeyword_UNKNOWN, -1 }
|
||||
};
|
||||
|
||||
static const KTableEntry kContentSolitaryKWs[] = {
|
||||
{ eCSSKeyword__moz_alt_content, NS_STYLE_CONTENT_ALT_CONTENT },
|
||||
{ eCSSKeyword__moz_alt_content, uint8_t(StyleContent::AltContent) },
|
||||
{ eCSSKeyword_UNKNOWN, -1 }
|
||||
};
|
||||
|
||||
|
|
|
@ -1147,11 +1147,11 @@ const KTableEntry nsCSSProps::kColorKTable[] = {
|
|||
};
|
||||
|
||||
const KTableEntry nsCSSProps::kContentKTable[] = {
|
||||
{ eCSSKeyword_open_quote, NS_STYLE_CONTENT_OPEN_QUOTE },
|
||||
{ eCSSKeyword_close_quote, NS_STYLE_CONTENT_CLOSE_QUOTE },
|
||||
{ eCSSKeyword_no_open_quote, NS_STYLE_CONTENT_NO_OPEN_QUOTE },
|
||||
{ eCSSKeyword_no_close_quote, NS_STYLE_CONTENT_NO_CLOSE_QUOTE },
|
||||
{ eCSSKeyword__moz_alt_content, NS_STYLE_CONTENT_ALT_CONTENT },
|
||||
{ eCSSKeyword_open_quote, uint8_t(StyleContent::OpenQuote) },
|
||||
{ eCSSKeyword_close_quote, uint8_t(StyleContent::CloseQuote) },
|
||||
{ eCSSKeyword_no_open_quote, uint8_t(StyleContent::NoOpenQuote) },
|
||||
{ eCSSKeyword_no_close_quote, uint8_t(StyleContent::NoCloseQuote) },
|
||||
{ eCSSKeyword__moz_alt_content, uint8_t(StyleContent::AltContent) },
|
||||
{ eCSSKeyword_UNKNOWN, -1 }
|
||||
};
|
||||
|
||||
|
|
|
@ -1541,6 +1541,7 @@ struct SetEnumValueHelper
|
|||
DEFINE_ENUM_CLASS_SETTER(StyleBoxPack, Start, Justify)
|
||||
DEFINE_ENUM_CLASS_SETTER(StyleBoxSizing, Content, Border)
|
||||
DEFINE_ENUM_CLASS_SETTER(StyleClear, None, Both)
|
||||
DEFINE_ENUM_CLASS_SETTER(StyleContent, OpenQuote, AltContent)
|
||||
DEFINE_ENUM_CLASS_SETTER(StyleFillRule, Nonzero, Evenodd)
|
||||
DEFINE_ENUM_CLASS_SETTER(StyleFloat, None, InlineEnd)
|
||||
DEFINE_ENUM_CLASS_SETTER(StyleFloatEdge, ContentBox, MarginBox)
|
||||
|
@ -8971,7 +8972,7 @@ nsRuleNode::ComputeContentData(void* aStartStruct,
|
|||
break;
|
||||
|
||||
case eCSSUnit_Enumerated: {
|
||||
MOZ_ASSERT(contentValue->GetIntValue() == NS_STYLE_CONTENT_ALT_CONTENT,
|
||||
MOZ_ASSERT(contentValue->GetIntValue() == int32_t(StyleContent::AltContent),
|
||||
"unrecognized solitary content keyword");
|
||||
content->AllocateContents(1);
|
||||
content->ContentAt(0).SetKeyword(eStyleContentType_AltContent);
|
||||
|
@ -9036,16 +9037,16 @@ nsRuleNode::ComputeContentData(void* aStartStruct,
|
|||
}
|
||||
case eCSSUnit_Enumerated:
|
||||
switch (value.GetIntValue()) {
|
||||
case NS_STYLE_CONTENT_OPEN_QUOTE:
|
||||
case uint8_t(StyleContent::OpenQuote):
|
||||
data.SetKeyword(eStyleContentType_OpenQuote);
|
||||
break;
|
||||
case NS_STYLE_CONTENT_CLOSE_QUOTE:
|
||||
case uint8_t(StyleContent::CloseQuote):
|
||||
data.SetKeyword(eStyleContentType_CloseQuote);
|
||||
break;
|
||||
case NS_STYLE_CONTENT_NO_OPEN_QUOTE:
|
||||
case uint8_t(StyleContent::NoOpenQuote):
|
||||
data.SetKeyword(eStyleContentType_NoOpenQuote);
|
||||
break;
|
||||
case NS_STYLE_CONTENT_NO_CLOSE_QUOTE:
|
||||
case uint8_t(StyleContent::NoCloseQuote):
|
||||
data.SetKeyword(eStyleContentType_NoCloseQuote);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -406,11 +406,13 @@ enum class StyleImageLayerRepeat : uint8_t {
|
|||
#define NS_STYLE_BORDER_IMAGE_SLICE_FILL 1
|
||||
|
||||
// See nsStyleContent
|
||||
#define NS_STYLE_CONTENT_OPEN_QUOTE 0
|
||||
#define NS_STYLE_CONTENT_CLOSE_QUOTE 1
|
||||
#define NS_STYLE_CONTENT_NO_OPEN_QUOTE 2
|
||||
#define NS_STYLE_CONTENT_NO_CLOSE_QUOTE 3
|
||||
#define NS_STYLE_CONTENT_ALT_CONTENT 4
|
||||
enum class StyleContent : uint8_t {
|
||||
OpenQuote,
|
||||
CloseQuote,
|
||||
NoOpenQuote,
|
||||
NoCloseQuote,
|
||||
AltContent
|
||||
};
|
||||
|
||||
// See nsStyleColor
|
||||
#define NS_STYLE_CURSOR_AUTO 1
|
||||
|
|
|
@ -689,8 +689,12 @@ int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header,
|
|||
!decoder_database_->IsComfortNoise(main_payload_type)) {
|
||||
// The list can be empty here if we got nothing but DTMF payloads.
|
||||
AudioDecoder* decoder = decoder_database_->GetDecoder(main_payload_type);
|
||||
RTC_DCHECK(decoder); // Should always get a valid object, since we have
|
||||
// already checked that the payload types are known.
|
||||
// In Mozilla webrtc.org builds we can not assume a valid decoder for each
|
||||
// known payload type as some codecs are not built.
|
||||
if (!decoder) {
|
||||
LOG(LS_WARNING) << "Unsupported rtp payload type: " << main_payload_type;
|
||||
return kUnknownRtpPayloadType;
|
||||
}
|
||||
decoder->IncomingPacket(packet_list.front().payload.data(),
|
||||
packet_list.front().payload.size(),
|
||||
packet_list.front().sequence_number,
|
||||
|
|
|
@ -3493,7 +3493,7 @@ nsSocketTransport::CloseSocket(PRFileDesc *aFd, nsSocketTransportService *aSTS)
|
|||
int err = WSAGetLastError();
|
||||
SOCKET_LOG(("nsSocketTransport::CloseSocket - "
|
||||
"GetOverlappedResult err=%x\n", err));
|
||||
if (err != ERROR_IO_PENDING) {
|
||||
if (err != ERROR_IO_INCOMPLETE) {
|
||||
canClose = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1738,7 +1738,7 @@ nsSocketTransportService::CheckOverlappedPendingSocketsAreDone()
|
|||
int err = WSAGetLastError();
|
||||
SOCKET_LOG(("STS CheckOverlappedPendingSocketsAreDone "
|
||||
"GetOverlappedResult failed error=%x \n", err));
|
||||
if (err != ERROR_IO_PENDING) {
|
||||
if (err != ERROR_IO_INCOMPLETE) {
|
||||
canClose = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4351,6 +4351,12 @@ nsHalfOpenSocket::SetFastOpenConnected(nsresult aError, bool aWillRetry)
|
|||
// Check if we want to restart connection!
|
||||
if (aWillRetry &&
|
||||
((aError == NS_ERROR_CONNECTION_REFUSED) ||
|
||||
#if defined(_WIN64) && defined(WIN95)
|
||||
// On Windows PR_ContinueConnect can return NS_ERROR_FAILURE.
|
||||
// This will be fixed in bug 1386719 and this is just a temporary
|
||||
// work around.
|
||||
(aError == NS_ERROR_FAILURE) ||
|
||||
#endif
|
||||
(aError == NS_ERROR_NET_TIMEOUT))) {
|
||||
if (mEnt->mUseFastOpen) {
|
||||
gHttpHandler->IncrementFastOpenConsecutiveFailureCounter();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
# 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/.
|
||||
|
||||
import errno
|
||||
import os
|
||||
import tempfile
|
||||
import tarfile
|
||||
|
|
|
@ -178,7 +178,6 @@ HistoryStore.prototype = {
|
|||
|
||||
async applyIncomingBatch(records) {
|
||||
let failed = [];
|
||||
let blockers = [];
|
||||
|
||||
// Convert incoming records to mozIPlaceInfo objects. Some records can be
|
||||
// ignored or handled directly, so we're rewriting the array in-place.
|
||||
|
@ -189,9 +188,7 @@ HistoryStore.prototype = {
|
|||
|
||||
try {
|
||||
if (record.deleted) {
|
||||
let promise = this.remove(record);
|
||||
promise = promise.catch(ex => failed.push(record.id));
|
||||
blockers.push(promise);
|
||||
await this.remove(record);
|
||||
|
||||
// No further processing needed. Remove it from the list.
|
||||
shouldApply = false;
|
||||
|
@ -213,20 +210,9 @@ HistoryStore.prototype = {
|
|||
records.length = k; // truncate array
|
||||
|
||||
if (records.length) {
|
||||
blockers.push(new Promise(resolve => {
|
||||
let updatePlacesCallback = {
|
||||
handleResult: function handleResult() {},
|
||||
handleError: function handleError(resultCode, placeInfo) {
|
||||
failed.push(placeInfo.guid);
|
||||
},
|
||||
handleCompletion: resolve,
|
||||
};
|
||||
this._asyncHistory.updatePlaces(records, updatePlacesCallback);
|
||||
}));
|
||||
await PlacesUtils.history.insertMany(records)
|
||||
}
|
||||
|
||||
// failed is updated asynchronously, hence the await on blockers.
|
||||
await Promise.all(blockers);
|
||||
return failed;
|
||||
},
|
||||
|
||||
|
@ -239,11 +225,8 @@ HistoryStore.prototype = {
|
|||
*/
|
||||
async _recordToPlaceInfo(record) {
|
||||
// Sort out invalid URIs and ones Places just simply doesn't want.
|
||||
record.url = PlacesUtils.normalizeToURLOrGUID(record.histUri);
|
||||
record.uri = Utils.makeURI(record.histUri);
|
||||
if (!record.uri) {
|
||||
this._log.warn("Attempted to process invalid URI, skipping.");
|
||||
throw new Error("Invalid URI in record");
|
||||
}
|
||||
|
||||
if (!Utils.checkGUID(record.id)) {
|
||||
this._log.warn("Encountered record with invalid GUID: " + record.id);
|
||||
|
@ -300,8 +283,8 @@ HistoryStore.prototype = {
|
|||
continue;
|
||||
}
|
||||
|
||||
visit.visitDate = visit.date;
|
||||
visit.transitionType = visit.type;
|
||||
visit.date = PlacesUtils.toDate(visit.date);
|
||||
visit.transition = visit.type;
|
||||
k += 1;
|
||||
}
|
||||
record.visits.length = k; // truncate array
|
||||
|
|
|
@ -85,17 +85,17 @@ NS_INTERFACE_MAP_END
|
|||
|
||||
#define XPC_MAP_CLASSNAME AsyncStatementJSHelper
|
||||
#define XPC_MAP_QUOTED_CLASSNAME "AsyncStatementJSHelper"
|
||||
#define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_GETPROPERTY | \
|
||||
#define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
|
||||
XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
|
||||
#include "xpc_map_end.h"
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncStatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper,
|
||||
JSContext *aCtx,
|
||||
JSObject *aScopeObj,
|
||||
jsid aId,
|
||||
JS::Value *_result,
|
||||
bool *_retval)
|
||||
AsyncStatementJSHelper::Resolve(nsIXPConnectWrappedNative *aWrapper,
|
||||
JSContext *aCtx,
|
||||
JSObject *aScopeObj,
|
||||
jsid aId,
|
||||
bool *resolvedp,
|
||||
bool *_retval)
|
||||
{
|
||||
if (!JSID_IS_STRING(aId))
|
||||
return NS_OK;
|
||||
|
@ -115,8 +115,14 @@ AsyncStatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (::JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "params"))
|
||||
return getParams(stmt, aCtx, scope, _result);
|
||||
if (::JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "params")) {
|
||||
JS::RootedValue val(aCtx);
|
||||
nsresult rv = getParams(stmt, aCtx, scope, val.address());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
*_retval = ::JS_DefinePropertyById(aCtx, scope, id, val, JSPROP_RESOLVING);
|
||||
*resolvedp = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -184,18 +184,15 @@ NS_INTERFACE_MAP_END
|
|||
|
||||
#define XPC_MAP_CLASSNAME StatementJSHelper
|
||||
#define XPC_MAP_QUOTED_CLASSNAME "StatementJSHelper"
|
||||
#define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_GETPROPERTY | \
|
||||
XPC_SCRIPTABLE_WANT_RESOLVE | \
|
||||
#define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
|
||||
XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
|
||||
#include "xpc_map_end.h"
|
||||
|
||||
NS_IMETHODIMP
|
||||
StatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper,
|
||||
JSContext *aCtx,
|
||||
JSObject *aScopeObj,
|
||||
jsid aId,
|
||||
JS::Value *_result,
|
||||
bool *_retval)
|
||||
StatementJSHelper::Resolve(nsIXPConnectWrappedNative *aWrapper,
|
||||
JSContext *aCtx, JSObject *aScopeObj,
|
||||
jsid aId, bool *aResolvedp,
|
||||
bool *_retval)
|
||||
{
|
||||
if (!JSID_IS_STRING(aId))
|
||||
return NS_OK;
|
||||
|
@ -215,33 +212,32 @@ StatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper,
|
|||
static_cast<mozIStorageStatement *>(aWrapper->Native())
|
||||
);
|
||||
|
||||
JSFlatString *str = JSID_TO_FLAT_STRING(id);
|
||||
if (::JS_FlatStringEqualsAscii(str, "row"))
|
||||
return getRow(stmt, aCtx, scope, _result);
|
||||
|
||||
if (::JS_FlatStringEqualsAscii(str, "params"))
|
||||
return getParams(stmt, aCtx, scope, _result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
StatementJSHelper::Resolve(nsIXPConnectWrappedNative *aWrapper,
|
||||
JSContext *aCtx, JSObject *aScopeObj,
|
||||
jsid aId, bool *aResolvedp,
|
||||
bool *_retval)
|
||||
{
|
||||
if (!JSID_IS_STRING(aId))
|
||||
return NS_OK;
|
||||
|
||||
JS::RootedObject scope(aCtx, aScopeObj);
|
||||
if (::JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(aId), "step")) {
|
||||
JSFlatString* str = JSID_TO_FLAT_STRING(id);
|
||||
if (::JS_FlatStringEqualsAscii(str, "step")) {
|
||||
*_retval = ::JS_DefineFunction(aCtx, scope, "step", stepFunc,
|
||||
0, JSPROP_RESOLVING) != nullptr;
|
||||
*aResolvedp = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JS::RootedValue val(aCtx);
|
||||
|
||||
if (::JS_FlatStringEqualsAscii(str, "row")) {
|
||||
nsresult rv = getRow(stmt, aCtx, scope, val.address());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
*_retval = ::JS_DefinePropertyById(aCtx, scope, id, val, JSPROP_RESOLVING);
|
||||
*aResolvedp = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (::JS_FlatStringEqualsAscii(str, "params")) {
|
||||
nsresult rv = getParams(stmt, aCtx, scope, val.address());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
*_retval = ::JS_DefinePropertyById(aCtx, scope, id, val, JSPROP_RESOLVING);
|
||||
*aResolvedp = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@ only-for-attributes:
|
|||
- nightly
|
||||
|
||||
not-for-build-platforms:
|
||||
- linux-nightly/opt
|
||||
- linux64-nightly/opt
|
||||
- macosx64-nightly/opt
|
||||
- win32-nightly/opt
|
||||
- win64-nightly/opt
|
||||
- macosx64-nightly/opt
|
||||
- win32-nightly/opt
|
||||
- win64-nightly/opt
|
||||
|
|
|
@ -14,8 +14,6 @@ kind-dependencies:
|
|||
- repackage-signing
|
||||
|
||||
only-for-build-platforms:
|
||||
- linux-nightly/opt
|
||||
- linux64-nightly/opt
|
||||
- macosx64-nightly/opt
|
||||
- win32-nightly/opt
|
||||
- win64-nightly/opt
|
||||
|
|
|
@ -16,8 +16,6 @@ only-for-attributes:
|
|||
- nightly
|
||||
|
||||
not-for-build-platforms:
|
||||
- linux-nightly/opt
|
||||
- linux64-nightly/opt
|
||||
- macosx64-nightly/opt
|
||||
- win32-nightly/opt
|
||||
- win64-nightly/opt
|
||||
- macosx64-nightly/opt
|
||||
- win32-nightly/opt
|
||||
- win64-nightly/opt
|
||||
|
|
|
@ -15,8 +15,6 @@ kind-dependencies:
|
|||
- nightly-l10n-signing
|
||||
|
||||
only-for-build-platforms:
|
||||
- linux-nightly/opt
|
||||
- linux64-nightly/opt
|
||||
- macosx64-nightly/opt
|
||||
- win32-nightly/opt
|
||||
- win64-nightly/opt
|
||||
|
|
|
@ -15,10 +15,6 @@ kind-dependencies:
|
|||
- repackage-l10n
|
||||
|
||||
only-for-build-platforms:
|
||||
- linux-nightly/opt
|
||||
- linux-devedition-nightly/opt
|
||||
- linux64-nightly/opt
|
||||
- linux64-devedition-nightly/opt
|
||||
- macosx64-nightly/opt
|
||||
- macosx64-devedition-nightly/opt
|
||||
- win32-nightly/opt
|
||||
|
|
|
@ -15,10 +15,6 @@ kind-dependencies:
|
|||
- build-signing
|
||||
|
||||
only-for-build-platforms:
|
||||
- linux-nightly/opt
|
||||
- linux-devedition-nightly/opt
|
||||
- linux64-nightly/opt
|
||||
- linux64-devedition-nightly/opt
|
||||
- macosx64-nightly/opt
|
||||
- macosx64-devedition-nightly/opt
|
||||
- win32-nightly/opt
|
||||
|
|
|
@ -16,8 +16,6 @@ from taskgraph.transforms.task import task_description_schema
|
|||
from voluptuous import Any, Required, Optional
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -65,15 +63,21 @@ _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_L10N = [
|
|||
# with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
|
||||
# See example in bug 1348286
|
||||
UPSTREAM_ARTIFACT_UNSIGNED_PATHS = {
|
||||
r'^(linux(|64)|macosx64)-nightly$': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
|
||||
'host/bin/mar',
|
||||
'host/bin/mbsdiff',
|
||||
'macosx64-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
|
||||
"host/bin/mar",
|
||||
"host/bin/mbsdiff",
|
||||
],
|
||||
r'^win(32|64)-nightly$': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
|
||||
'macosx64-nightly-l10n': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_L10N,
|
||||
'win64-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
|
||||
"host/bin/mar.exe",
|
||||
"host/bin/mbsdiff.exe",
|
||||
],
|
||||
r'^(linux(|64)|macosx64|win(32|64))-nightly-l10n$': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_L10N,
|
||||
'win64-nightly-l10n': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_L10N,
|
||||
'win32-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
|
||||
"host/bin/mar.exe",
|
||||
"host/bin/mbsdiff.exe",
|
||||
],
|
||||
'win32-nightly-l10n': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_L10N,
|
||||
}
|
||||
|
||||
# Until bug 1331141 is fixed, if you are adding any new artifacts here that
|
||||
|
@ -81,8 +85,10 @@ UPSTREAM_ARTIFACT_UNSIGNED_PATHS = {
|
|||
# with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
|
||||
# See example in bug 1348286
|
||||
UPSTREAM_ARTIFACT_SIGNED_PATHS = {
|
||||
r'^linux(|64)-nightly(|-l10n)$': ['target.tar.bz2', 'target.tar.bz2.asc'],
|
||||
r'^win(32|64)-nightly(|-l10n)$': ['target.zip'],
|
||||
'win64-nightly': ['target.zip'],
|
||||
'win64-nightly-l10n': ['target.zip'],
|
||||
'win32-nightly': ['target.zip'],
|
||||
'win32-nightly-l10n': ['target.zip'],
|
||||
}
|
||||
|
||||
# Until bug 1331141 is fixed, if you are adding any new artifacts here that
|
||||
|
@ -90,32 +96,30 @@ UPSTREAM_ARTIFACT_SIGNED_PATHS = {
|
|||
# with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
|
||||
# See example in bug 1348286
|
||||
UPSTREAM_ARTIFACT_REPACKAGE_PATHS = {
|
||||
r'^macosx64-nightly(|-l10n)$': ['target.dmg'],
|
||||
'macosx64-nightly': ['target.dmg'],
|
||||
'macosx64-nightly-l10n': ['target.dmg'],
|
||||
}
|
||||
# Until bug 1331141 is fixed, if you are adding any new artifacts here that
|
||||
# need to be transfered to S3, please be aware you also need to follow-up
|
||||
# with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
|
||||
# See example in bug 1348286
|
||||
UPSTREAM_ARTIFACT_SIGNED_REPACKAGE_PATHS = {
|
||||
r'^(linux(|64)|macosx64)-nightly(|-l10n)$': ['target.complete.mar'],
|
||||
r'^win64-nightly(|-l10n)$': ['target.complete.mar', 'target.installer.exe'],
|
||||
r'^win32-nightly(|-l10n)$': [
|
||||
'macosx64-nightly': ['target.complete.mar'],
|
||||
'macosx64-nightly-l10n': ['target.complete.mar'],
|
||||
'win64-nightly': ['target.complete.mar', 'target.installer.exe'],
|
||||
'win64-nightly-l10n': ['target.complete.mar', 'target.installer.exe'],
|
||||
'win32-nightly': [
|
||||
'target.complete.mar',
|
||||
'target.installer.exe',
|
||||
'target.stub-installer.exe'
|
||||
],
|
||||
'win32-nightly-l10n': [
|
||||
'target.complete.mar',
|
||||
'target.installer.exe',
|
||||
'target.stub-installer.exe'
|
||||
],
|
||||
}
|
||||
|
||||
# Compile every regex once at import time
|
||||
for dict_ in (
|
||||
UPSTREAM_ARTIFACT_UNSIGNED_PATHS, UPSTREAM_ARTIFACT_SIGNED_PATHS,
|
||||
UPSTREAM_ARTIFACT_REPACKAGE_PATHS, UPSTREAM_ARTIFACT_SIGNED_REPACKAGE_PATHS,
|
||||
):
|
||||
for uncompiled_regex, value in dict_.iteritems():
|
||||
compiled_regex = re.compile(uncompiled_regex)
|
||||
del dict_[uncompiled_regex]
|
||||
dict_[compiled_regex] = value
|
||||
|
||||
# Voluptuous uses marker objects as dictionary *keys*, but they are not
|
||||
# comparable, so we cast all of the keys back to regular strings
|
||||
task_description_schema = {str(k): v for k, v in task_description_schema.schema.iteritems()}
|
||||
|
@ -267,37 +271,18 @@ def generate_upstream_artifacts(build_task_ref, build_signing_task_ref,
|
|||
]
|
||||
|
||||
for ref, tasktype, mapping in zip(task_refs, tasktypes, mapping):
|
||||
plarform_was_previously_matched_by_regex = None
|
||||
for platform_regex, paths in mapping.iteritems():
|
||||
if platform_regex.match(platform) is not None:
|
||||
_check_platform_matched_only_one_regex(
|
||||
tasktype, platform, plarform_was_previously_matched_by_regex, platform_regex
|
||||
)
|
||||
|
||||
upstream_artifacts.append({
|
||||
"taskId": {"task-reference": ref},
|
||||
"taskType": tasktype,
|
||||
"paths": ["{}/{}".format(artifact_prefix, path) for path in paths],
|
||||
"locale": locale or "en-US",
|
||||
})
|
||||
plarform_was_previously_matched_by_regex = platform_regex
|
||||
if platform in mapping:
|
||||
upstream_artifacts.append({
|
||||
"taskId": {"task-reference": ref},
|
||||
"taskType": tasktype,
|
||||
"paths": ["{}/{}".format(artifact_prefix, p)
|
||||
for p in mapping[platform]],
|
||||
"locale": locale or "en-US",
|
||||
})
|
||||
|
||||
return upstream_artifacts
|
||||
|
||||
|
||||
def _check_platform_matched_only_one_regex(
|
||||
task_type, platform, plarform_was_previously_matched_by_regex, platform_regex
|
||||
):
|
||||
if plarform_was_previously_matched_by_regex is not None:
|
||||
raise Exception('In task type "{task_type}", platform "{platform}" matches at \
|
||||
least 2 regular expressions. First matched: "{first_matched}". Second matched: \
|
||||
"{second_matched}"'.format(
|
||||
task_type=task_type, platform=platform,
|
||||
first_matched=plarform_was_previously_matched_by_regex.pattern,
|
||||
second_matched=platform_regex.pattern
|
||||
))
|
||||
|
||||
|
||||
def is_valid_beetmover_job(job):
|
||||
# windows builds don't have docker-image, so fewer dependencies
|
||||
if any(b in job['attributes']['build_platform'] for b in _WINDOWS_BUILD_PLATFORMS):
|
||||
|
|
|
@ -8,8 +8,6 @@ Transform the signing task into an actual task description.
|
|||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.signed_artifacts import generate_specifications_of_artifacts_to_sign
|
||||
|
||||
|
||||
transforms = TransformSequence()
|
||||
|
||||
|
@ -36,26 +34,66 @@ def add_signed_routes(config, jobs):
|
|||
|
||||
|
||||
@transforms.add
|
||||
def define_upstream_artifacts(config, jobs):
|
||||
def make_signing_description(config, jobs):
|
||||
for job in jobs:
|
||||
dep_job = job['dependent-task']
|
||||
build_platform = dep_job.attributes.get('build_platform')
|
||||
|
||||
artifacts_specifications = generate_specifications_of_artifacts_to_sign(
|
||||
build_platform,
|
||||
dep_job.attributes.get('nightly'),
|
||||
keep_locale_template=False
|
||||
job['upstream-artifacts'] = _generate_upstream_artifacts(
|
||||
dep_job.attributes.get('build_platform'),
|
||||
dep_job.attributes.get('nightly')
|
||||
)
|
||||
|
||||
if 'android' in build_platform:
|
||||
# We're in the job that creates both multilocale and en-US APKs
|
||||
artifacts_specifications[0]['artifacts'].append('public/build/en-US/target.apk')
|
||||
|
||||
job['upstream-artifacts'] = [{
|
||||
'taskId': {'task-reference': '<build>'},
|
||||
'taskType': 'build',
|
||||
'paths': spec['artifacts'],
|
||||
'formats': spec['formats'],
|
||||
} for spec in artifacts_specifications]
|
||||
|
||||
yield job
|
||||
|
||||
|
||||
def _generate_upstream_artifacts(build_platform, is_nightly=False):
|
||||
if 'android' in build_platform:
|
||||
artifacts_specificities = [{
|
||||
'artifacts': [
|
||||
'public/build/target.apk',
|
||||
'public/build/en-US/target.apk'
|
||||
],
|
||||
'format': 'jar',
|
||||
}]
|
||||
# XXX: Mac and Windows don't sign mars because internal aren't signed at
|
||||
# this stage of the release
|
||||
elif 'macosx' in build_platform:
|
||||
artifacts_specificities = [{
|
||||
'artifacts': ['public/build/target.dmg'],
|
||||
'format': 'macapp',
|
||||
}]
|
||||
elif 'win64' in build_platform:
|
||||
artifacts_specificities = [{
|
||||
'artifacts': [
|
||||
'public/build/target.zip',
|
||||
'public/build/setup.exe'
|
||||
],
|
||||
'format': 'sha2signcode',
|
||||
}]
|
||||
elif 'win32' in build_platform:
|
||||
artifacts_specificities = [{
|
||||
'artifacts': [
|
||||
'public/build/target.zip',
|
||||
'public/build/setup.exe',
|
||||
],
|
||||
'format': 'sha2signcode',
|
||||
}]
|
||||
if is_nightly:
|
||||
artifacts_specificities[0]['artifacts'] += ['public/build/setup-stub.exe']
|
||||
elif 'linux' in build_platform:
|
||||
artifacts_specificities = [{
|
||||
'artifacts': ['public/build/target.tar.bz2'],
|
||||
'format': 'gpg',
|
||||
}, {
|
||||
'artifacts': ['public/build/update/target.complete.mar'],
|
||||
'format': 'mar_sha384',
|
||||
}]
|
||||
else:
|
||||
raise Exception("Platform not implemented for signing")
|
||||
|
||||
return [{
|
||||
'taskId': {'task-reference': '<build>'},
|
||||
'taskType': 'build',
|
||||
'paths': specificity['artifacts'],
|
||||
'formats': [specificity['format']],
|
||||
} for specificity in artifacts_specificities]
|
||||
|
|
|
@ -31,10 +31,6 @@ JOB_NAME_WHITELIST = set([
|
|||
'browser-haz-debug',
|
||||
'linux-debug',
|
||||
'linux-devedition',
|
||||
'linux-devedition-nightly-repackage',
|
||||
'linux-devedition-nightly-repackage-signing',
|
||||
'linux-nightly-repackage',
|
||||
'linux-nightly-repackage-signing',
|
||||
'linux-opt',
|
||||
'linux-pgo',
|
||||
'linux64-add-on-devel',
|
||||
|
@ -48,11 +44,7 @@ JOB_NAME_WHITELIST = set([
|
|||
'linux64-clang-tidy',
|
||||
'linux64-debug',
|
||||
'linux64-devedition',
|
||||
'linux64-devedition-nightly-repackage',
|
||||
'linux64-devedition-nightly-repackage-signing',
|
||||
'linux64-jsdcov-opt',
|
||||
'linux64-nightly-repackage',
|
||||
'linux64-nightly-repackage-signing',
|
||||
'linux64-noopt-debug',
|
||||
'linux64-opt',
|
||||
'linux64-pgo',
|
||||
|
|
|
@ -8,7 +8,6 @@ Transform the signing task into an actual task description.
|
|||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.signed_artifacts import generate_specifications_of_artifacts_to_sign
|
||||
from taskgraph.util.treeherder import join_symbol
|
||||
|
||||
transforms = TransformSequence()
|
||||
|
@ -20,6 +19,72 @@ def make_signing_description(config, jobs):
|
|||
job['depname'] = 'unsigned-repack'
|
||||
|
||||
dep_job = job['dependent-task']
|
||||
dep_platform = dep_job.attributes.get('build_platform')
|
||||
|
||||
job['upstream-artifacts'] = []
|
||||
if 'android' in dep_platform:
|
||||
job_specs = [
|
||||
{
|
||||
'artifacts': ['public/build/{locale}/target.apk'],
|
||||
'format': 'jar',
|
||||
},
|
||||
]
|
||||
elif 'macosx' in dep_platform:
|
||||
job_specs = [
|
||||
{
|
||||
'artifacts': ['public/build/{locale}/target.dmg'],
|
||||
'format': 'macapp',
|
||||
}
|
||||
]
|
||||
elif 'win32' in dep_platform:
|
||||
job_specs = [
|
||||
{
|
||||
'artifacts': [
|
||||
'public/build/{locale}/target.zip',
|
||||
'public/build/{locale}/setup.exe',
|
||||
'public/build/{locale}/setup-stub.exe'
|
||||
],
|
||||
'format': 'sha2signcode',
|
||||
}
|
||||
]
|
||||
elif 'win64' in dep_platform:
|
||||
job_specs = [
|
||||
{
|
||||
'artifacts': [
|
||||
'public/build/{locale}/target.zip',
|
||||
'public/build/{locale}/setup.exe',
|
||||
],
|
||||
'format': 'sha2signcode',
|
||||
}
|
||||
]
|
||||
elif 'linux' in dep_platform:
|
||||
job_specs = [
|
||||
{
|
||||
'artifacts': ['public/build/{locale}/target.tar.bz2'],
|
||||
'format': 'gpg',
|
||||
}, {
|
||||
'artifacts': ['public/build/{locale}/target.complete.mar'],
|
||||
'format': 'mar_sha384',
|
||||
}
|
||||
]
|
||||
else:
|
||||
raise Exception("Platform not implemented for signing")
|
||||
|
||||
upstream_artifacts = []
|
||||
for spec in job_specs:
|
||||
fmt = spec['format']
|
||||
upstream_artifacts.append({
|
||||
"taskId": {"task-reference": "<unsigned-repack>"},
|
||||
"taskType": "l10n",
|
||||
# Set paths based on artifacts in the specs (above) one per
|
||||
# locale present in the chunk this is signing stuff for.
|
||||
"paths": [f.format(locale=l)
|
||||
for l in dep_job.attributes.get('chunk_locales', [])
|
||||
for f in spec['artifacts']],
|
||||
"formats": [fmt]
|
||||
})
|
||||
|
||||
job['upstream-artifacts'] = upstream_artifacts
|
||||
|
||||
# add the chunk number to the TH symbol
|
||||
symbol = 'Ns{}'.format(dep_job.attributes.get('l10n_chunk'))
|
||||
|
@ -30,34 +95,3 @@ def make_signing_description(config, jobs):
|
|||
}
|
||||
|
||||
yield job
|
||||
|
||||
|
||||
@transforms.add
|
||||
def define_upstream_artifacts(config, jobs):
|
||||
for job in jobs:
|
||||
dep_job = job['dependent-task']
|
||||
|
||||
locale_specifications = generate_specifications_of_artifacts_to_sign(
|
||||
dep_job.attributes.get('build_platform'),
|
||||
is_nightly=True,
|
||||
keep_locale_template=True
|
||||
)
|
||||
|
||||
upstream_artifacts = []
|
||||
for spec in locale_specifications:
|
||||
upstream_artifacts.append({
|
||||
'taskId': {'task-reference': '<unsigned-repack>'},
|
||||
'taskType': 'l10n',
|
||||
# Set paths based on artifacts in the specs (above) one per
|
||||
# locale present in the chunk this is signing stuff for.
|
||||
'paths': [
|
||||
path_template.format(locale=locale)
|
||||
for locale in dep_job.attributes.get('chunk_locales', [])
|
||||
for path_template in spec['artifacts']
|
||||
],
|
||||
'formats': spec['formats']
|
||||
})
|
||||
|
||||
job['upstream-artifacts'] = upstream_artifacts
|
||||
|
||||
yield job
|
||||
|
|
|
@ -148,15 +148,8 @@ def make_job_description(config, jobs):
|
|||
if build_platform.startswith('win'):
|
||||
worker_type = 'aws-provisioner-v1/gecko-%s-b-win2012' % level
|
||||
run['use-magic-mh-args'] = False
|
||||
else:
|
||||
if build_platform.startswith('macosx'):
|
||||
worker_type = 'aws-provisioner-v1/gecko-%s-b-macosx64' % level
|
||||
elif build_platform.startswith('linux'):
|
||||
worker_type = 'aws-provisioner-v1/gecko-%s-b-linux' % level
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
'Unsupported build_platform: "{}"'.format(build_platform)
|
||||
)
|
||||
elif build_platform.startswith('macosx'):
|
||||
worker_type = 'aws-provisioner-v1/gecko-%s-b-macosx64' % level
|
||||
|
||||
run['tooltool-downloads'] = 'internal'
|
||||
worker['docker-image'] = {"in-tree": "desktop-build"}
|
||||
|
@ -192,26 +185,20 @@ def make_job_description(config, jobs):
|
|||
def _generate_task_mozharness_config(build_platform):
|
||||
if build_platform.startswith('macosx'):
|
||||
return ['repackage/osx_signed.py']
|
||||
elif build_platform.startswith('win'):
|
||||
return ['repackage/win32_signed.py'] if '32' in build_platform \
|
||||
else ['repackage/win64_signed.py']
|
||||
else:
|
||||
bits = 32 if '32' in build_platform else 64
|
||||
if build_platform.startswith('linux'):
|
||||
return ['repackage/linux{}_signed.py'.format(bits)]
|
||||
elif build_platform.startswith('win'):
|
||||
return ['repackage/win{}_signed.py'.format(bits)]
|
||||
|
||||
raise NotImplementedError('Unsupported build_platform: "{}"'.format(build_platform))
|
||||
raise NotImplemented('Unsupported build_platform: "{}"'.format(build_platform))
|
||||
|
||||
|
||||
def _generate_task_env(build_platform, build_task_ref, signing_task_ref, locale=None):
|
||||
mar_prefix = _generate_taskcluster_prefix(build_task_ref, postfix='host/bin/', locale=None)
|
||||
signed_prefix = _generate_taskcluster_prefix(signing_task_ref, locale=locale)
|
||||
|
||||
if build_platform.startswith('linux') or build_platform.startswith('macosx'):
|
||||
tarball_extension = 'bz2' if build_platform.startswith('linux') else 'gz'
|
||||
if build_platform.startswith('macosx'):
|
||||
return {
|
||||
'SIGNED_INPUT': {'task-reference': '{}target.tar.{}'.format(
|
||||
signed_prefix, tarball_extension
|
||||
)},
|
||||
'SIGNED_INPUT': {'task-reference': '{}target.tar.gz'.format(signed_prefix)},
|
||||
'UNSIGNED_MAR': {'task-reference': '{}mar'.format(mar_prefix)},
|
||||
}
|
||||
elif build_platform.startswith('win'):
|
||||
|
@ -228,7 +215,8 @@ def _generate_task_env(build_platform, build_task_ref, signing_task_ref, locale=
|
|||
}
|
||||
return task_env
|
||||
|
||||
raise NotImplementedError('Unsupported build_platform: "{}"'.format(build_platform))
|
||||
else:
|
||||
raise NotImplemented('Unsupported build_platform: "{}"'.format(build_platform))
|
||||
|
||||
|
||||
def _generate_taskcluster_prefix(task_id, postfix='', locale=None):
|
||||
|
@ -240,23 +228,18 @@ def _generate_taskcluster_prefix(task_id, postfix='', locale=None):
|
|||
|
||||
def _generate_task_output_files(build_platform, locale=None):
|
||||
locale_output_path = '{}/'.format(locale) if locale else ''
|
||||
|
||||
if build_platform.startswith('linux') or build_platform.startswith('macosx'):
|
||||
output_files = [{
|
||||
if build_platform.startswith('macosx'):
|
||||
return [{
|
||||
'type': 'file',
|
||||
'path': '/home/worker/workspace/build/artifacts/{}target.dmg'
|
||||
.format(locale_output_path),
|
||||
'name': 'public/build/{}target.dmg'.format(locale_output_path),
|
||||
}, {
|
||||
'type': 'file',
|
||||
'path': '/home/worker/workspace/build/artifacts/{}target.complete.mar'
|
||||
.format(locale_output_path),
|
||||
'name': 'public/build/{}target.complete.mar'.format(locale_output_path),
|
||||
}]
|
||||
|
||||
if build_platform.startswith('macosx'):
|
||||
output_files.append({
|
||||
'type': 'file',
|
||||
'path': '/home/worker/workspace/build/artifacts/{}target.dmg'
|
||||
.format(locale_output_path),
|
||||
'name': 'public/build/{}target.dmg'.format(locale_output_path),
|
||||
})
|
||||
|
||||
elif build_platform.startswith('win'):
|
||||
output_files = [{
|
||||
'type': 'file',
|
||||
|
@ -276,7 +259,6 @@ def _generate_task_output_files(build_platform, locale=None):
|
|||
'name': 'public/build/{}target.stub-installer.exe'.format(locale_output_path),
|
||||
})
|
||||
|
||||
if output_files:
|
||||
return output_files
|
||||
|
||||
raise NotImplementedError('Unsupported build_platform: "{}"'.format(build_platform))
|
||||
else:
|
||||
raise NotImplemented('Unsupported build_platform: "{}"'.format(build_platform))
|
||||
|
|
|
@ -130,8 +130,6 @@ def make_repackage_signing_description(config, jobs):
|
|||
}
|
||||
|
||||
funsize_platforms = [
|
||||
'linux-nightly',
|
||||
'linux64-nightly',
|
||||
'macosx64-nightly',
|
||||
'win32-nightly',
|
||||
'win64-nightly'
|
||||
|
|
|
@ -136,6 +136,11 @@ def make_task_description(config, jobs):
|
|||
'routes': job.get('routes', []),
|
||||
}
|
||||
|
||||
if 'linux' in dep_job.attributes.get('build_platform') and \
|
||||
dep_job.attributes.get('nightly'):
|
||||
task['routes'].append("project.releng.funsize.level-{level}.{project}".format(
|
||||
project=config.params['project'], level=config.params['level']))
|
||||
|
||||
yield task
|
||||
|
||||
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче