Merge mozilla-central to autoland. a=merge on a CLOSED TREE

This commit is contained in:
Andreea Pavel 2018-03-15 00:10:23 +02:00
commit 46575fad3b
112 changed files with 52962 additions and 53795 deletions

View File

@ -5144,6 +5144,7 @@ var TabsProgressListener = {
// or history.push/pop/replaceState.
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
// Reader mode cares about history.pushState and friends.
// FIXME: The content process should manage this directly (bug 1445351).
aBrowser.messageManager.sendAsyncMessage("Reader:PushState", {
isArticle: aBrowser.isArticle,
});

View File

@ -960,29 +960,20 @@ var PageInfoListener = {
};
if (computedStyle) {
let addImgFunc = (label, val) => {
if (val.primitiveType == content.CSSPrimitiveValue.CSS_URI) {
addImage(val.getStringValue(), label, strings.notSet, elem, true);
} else if (val.primitiveType == content.CSSPrimitiveValue.CSS_STRING) {
// This is for -moz-image-rect.
// TODO: Reimplement once bug 714757 is fixed.
let strVal = val.getStringValue();
if (strVal.search(/^.*url\(\"?/) > -1) {
let url = strVal.replace(/^.*url\(\"?/, "").replace(/\"?\).*$/, "");
addImage(url, label, strings.notSet, elem, true);
}
} else if (val.cssValueType == content.CSSValue.CSS_VALUE_LIST) {
// Recursively resolve multiple nested CSS value lists.
for (let i = 0; i < val.length; i++) {
addImgFunc(label, val.item(i));
}
let addImgFunc = (label, urls) => {
for (let url of urls) {
addImage(url, label, strings.notSet, elem, true);
}
};
addImgFunc(strings.mediaBGImg, computedStyle.getPropertyCSSValue("background-image"));
addImgFunc(strings.mediaBorderImg, computedStyle.getPropertyCSSValue("border-image-source"));
addImgFunc(strings.mediaListImg, computedStyle.getPropertyCSSValue("list-style-image"));
addImgFunc(strings.mediaCursor, computedStyle.getPropertyCSSValue("cursor"));
// FIXME: This is missing properties. See the implementation of
// getCSSImageURLs for a list of properties.
//
// If you don't care about the message you can also pass "all" here and
// get all the ones the browser knows about.
addImgFunc(strings.mediaBGImg, computedStyle.getCSSImageURLs("background-image"));
addImgFunc(strings.mediaBorderImg, computedStyle.getCSSImageURLs("border-image-source"));
addImgFunc(strings.mediaListImg, computedStyle.getCSSImageURLs("list-style-image"));
addImgFunc(strings.mediaCursor, computedStyle.getCSSImageURLs("cursor"));
}
// One swi^H^H^Hif-else to rule them all.

View File

@ -162,6 +162,7 @@ skip-if = toolkit == "cocoa"
[browser_bug491431.js]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_bug495058.js]
skip-if = jsdcov # Bug 1439493
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_bug519216.js]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.

View File

@ -129,9 +129,6 @@ let propNameWhitelist = [
// Bug 1441878
{propName: "--theme-codemirror-gutter-background",
isFromDevTools: true},
// Bug 1441879
{propName: "--arrow-width",
isFromDevTools: true},
// Bug 1442300
{propName: "--in-content-category-background",
isFromDevTools: false},

View File

@ -170,6 +170,7 @@ class BrowserErrorReporter {
{
type: errorName,
value: errorMessage,
module: message.sourceName,
stacktrace: {
frames,
}

View File

@ -376,18 +376,17 @@ class ContextMenu {
// Returns a "url"-type computed style attribute value, with the url() stripped.
_getComputedURL(aElem, aProp) {
let url = aElem.ownerGlobal.getComputedStyle(aElem).getPropertyCSSValue(aProp);
let urls = aElem.ownerGlobal.getComputedStyle(aElem).getCSSImageURLs(aProp);
if (url instanceof this.content.CSSValueList) {
if (url.length != 1) {
throw "found multiple URLs";
}
url = url[0];
if (!urls.length) {
return null;
}
return url.primitiveType == this.content.CSSPrimitiveValue.CSS_URI ?
url.getStringValue() : null;
if (urls.length != 1) {
throw "found multiple URLs";
}
return urls[0];
}
_makeURLAbsolute(aBase, aUrl) {

View File

@ -366,6 +366,7 @@ add_task(async function testFetchArguments() {
{
type: "Error",
value: "testFetchArguments error",
module: testPageUrl,
stacktrace: {
frames: [
{

View File

@ -66,6 +66,8 @@ included_inclnames_to_ignore = set([
'frontend/ReservedWordsGenerated.h', # generated in $OBJDIR
'gc/StatsPhasesGenerated.h', # generated in $OBJDIR
'gc/StatsPhasesGenerated.cpp', # generated in $OBJDIR
'jit/LOpcodes.h', # generated in $OBJDIR
'jit/MOpcodes.h', # generated in $OBJDIR
'jscustomallocator.h', # provided by embedders; allowed to be missing
'js-config.h', # generated in $OBJDIR
'fdlibm.h', # fdlibm

View File

@ -1,12 +1,13 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Version 20.0
Comparison: https://github.com/devtools-html/debugger.html/compare/release-19-2...release-20
Version 21.0
Comparison: https://github.com/devtools-html/debugger.html/compare/release-20...release-21
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.0
- babel-preset-react @6.24.1
- react @15.6.2
- react-dom @15.6.2
- webpack @3.10.0
- react @16.2.0
- react-dom @16.2.0
- webpack @3.11.0

View File

@ -512,19 +512,16 @@ body {
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
:root {
--arrow-width: 10px;
--icon-size: 13px;
}
:root.theme-light,
:root .theme-light {
--search-overlays-semitransparent: rgba(221, 225, 228, 0.66);
--popup-shadow-color: #d0d0d0;
}
:root.theme-dark,
:root .theme-dark {
--search-overlays-semitransparent: rgba(42, 46, 56, 0.66);
--popup-shadow-color: #5c667b;
}
/* This Source Code Form is subject to the terms of the Mozilla Public
@ -1466,7 +1463,7 @@ html[dir="rtl"] .arrow svg,
.project-text-search .line-match {
display: "flex";
grow: 1;
flex-grow: 1;
}
.project-text-search .search-field {
@ -1652,7 +1649,9 @@ html[dir="rtl"] .arrow svg,
background-color: white;
}
.tree:not(.object-inspector) .tree-node[data-expandable="false"] .tree-indent:last-of-type {
.tree:not(.object-inspector)
.tree-node[data-expandable="false"]
.tree-indent:last-of-type {
margin-inline-end: 4px;
}
/* This Source Code Form is subject to the terms of the Mozilla Public
@ -1758,7 +1757,6 @@ html[dir="rtl"] .arrow svg,
text-align: center;
position: relative;
padding: 0px 5px;
margin-inline-end: 0.3em;
fill: currentColor;
}
@ -3439,7 +3437,6 @@ html .breakpoints-list .breakpoint.paused {
overflow: hidden;
z-index: 1;
background-color: var(--theme-toolbar-background);
align-items: center;
}
html[dir="rtl"] .command-bar {
@ -3544,7 +3541,8 @@ img.resume {
.command-bar .step-position {
color: var(--theme-comment-alt);
margin-inline-end: 1em;
padding-top: 8px;
margin-inline-end: 4px;
}
.command-bar .replay-active {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -47,6 +47,8 @@ support-files =
examples/babel/fixtures/webpack-modules/output.js.map
examples/babel/fixtures/webpack-modules-es6/output.js
examples/babel/fixtures/webpack-modules-es6/output.js.map
examples/babel/fixtures/webpack-standalone/output.js
examples/babel/fixtures/webpack-standalone/output.js.map
examples/sourcemaps/bundle.js
examples/sourcemaps/bundle.js.map
examples/sourcemaps2/main.min.js
@ -119,6 +121,7 @@ support-files =
[browser_dbg-async-stepping.js]
[browser_dbg-babel-scopes.js]
[browser_dbg-babel-stepping.js]
skip-if = true
[browser_dbg-breaking.js]
[browser_dbg-breaking-from-console.js]
[browser_dbg-breakpoints.js]

View File

@ -317,4 +317,28 @@ add_task(async function() {
["aNamespace3", "{\u2026}"],
"root()"
]);
await breakpointScopes(dbg, "webpack-standalone", { line: 11, column: 0 }, [
"Block",
["<this>", '"this-value"'],
["arg", '"arg-value"'],
["arguments", "Arguments"],
["inner", "undefined"],
"Block",
["someName", "(optimized away)"],
"Block",
["two", "2"],
"Block",
["one", "1"],
"root",
["arguments", "Arguments"],
"fn:someName()",
"webpackStandalone",
["__webpack_exports__", "(optimized away)"],
["__WEBPACK_IMPORTED_MODULE_0__src_mod1__", "{\u2026}"],
["__webpack_require__", "(optimized away)"],
["arguments", "(unavailable)"],
["module", "(optimized away)"],
"root()"
]);
});

View File

@ -18,6 +18,7 @@ async function breakpointSteps(dbg, fixture, { line, column }, steps) {
await addBreakpoint(dbg, source, line);
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
ok(
getBreakpoint(getState(), { sourceId: source.id, line, column }),
"Breakpoint has correct line"
@ -78,12 +79,8 @@ async function runSteps(dbg, source, steps) {
}
}
add_task(async function() {
requestLongerTimeout(4);
const dbg = await initDebugger("doc-babel.html");
await breakpointSteps(dbg, "step-over-for-of", { line: 4, column: 2 }, [
function testStepOverForOf(dbg) {
return breakpointSteps(dbg, "step-over-for-of", { line: 4, column: 2 }, [
["stepOver", { line: 6, column: 2 }],
["stepOver", { line: 7, column: 4 }],
["stepOver", { line: 6, column: 2 }],
@ -91,10 +88,12 @@ add_task(async function() {
["stepOver", { line: 6, column: 2 }],
["stepOver", { line: 10, column: 2 }]
]);
}
// This codifies the current behavior, but stepping twice over the for
// header isn't ideal.
await breakpointSteps(dbg, "step-over-for-of-array", { line: 3, column: 2 }, [
// This codifies the current behavior, but stepping twice over the for
// header isn't ideal.
function testStepOverForOfArray(dbg) {
return breakpointSteps(dbg, "step-over-for-of-array", { line: 3, column: 2 }, [
["stepOver", { line: 5, column: 2 }],
["stepOver", { line: 5, column: 7 }],
["stepOver", { line: 6, column: 4 }],
@ -104,23 +103,29 @@ add_task(async function() {
["stepOver", { line: 5, column: 2 }],
["stepOver", { line: 9, column: 2 }]
]);
}
// The closure means it isn't actually possible to step into the for body,
// and Babel doesn't map the _loop() call, so we step past it automatically.
await breakpointSteps(
// The closure means it isn't actually possible to step into the for body,
// and Babel doesn't map the _loop() call, so we step past it automatically.
function testStepOveForOfClosure(dbg) {
return breakpointSteps(
dbg,
"step-over-for-of-closure",
{ line: 6, column: 2 },
[
["stepOver", { line: 8, column: 2 }],
["stepOver", { line: 8, column: 2 }],
["stepOver", { line: 8, column: 2 }],
["stepOver", { line: 12, column: 2 }]
]
);
}
// Same as the previous, not possible to step into the body. The less
// complicated array logic makes it possible to step into the header at least,
// but this does end up double-visiting the for head.
await breakpointSteps(
// Same as the previous, not possible to step into the body. The less
// complicated array logic makes it possible to step into the header at least,
// but this does end up double-visiting the for head.
function testStepOverForOfArrayClosure(dbg) {
return breakpointSteps(
dbg,
"step-over-for-of-array-closure",
{ line: 3, column: 2 },
@ -133,15 +138,19 @@ add_task(async function() {
["stepOver", { line: 9, column: 2 }]
]
);
}
await breakpointSteps(
function testStepOverFunctionParams(dbg) {
return breakpointSteps(
dbg,
"step-over-function-params",
{ line: 6, column: 2 },
[["stepOver", { line: 7, column: 2 }], ["stepIn", { line: 2, column: 2 }]]
);
}
await breakpointSteps(
function testStepOverRegeneratorAwait(dbg) {
return breakpointSteps(
dbg,
"step-over-regenerator-await",
{ line: 2, column: 2 },
@ -151,4 +160,17 @@ add_task(async function() {
// ["stepOver", { line: 4, column: 2 }],
]
);
}
add_task(async function() {
requestLongerTimeout(4);
const dbg = await initDebugger("doc-babel.html");
await testStepOverForOf(dbg);
await testStepOverForOfArray(dbg);
await testStepOveForOfClosure(dbg);
await testStepOverForOfArrayClosure(dbg);
await testStepOverFunctionParams(dbg);
await testStepOverRegeneratorAwait(dbg);
});

View File

@ -24,11 +24,22 @@ function assertEditorBreakpoint(dbg, line, shouldExist) {
);
}
function waitForElementFocus(dbg, el) {
const doc = dbg.win.document;
return waitFor(() => doc.activeElement == el && doc.hasFocus());
}
async function assertConditionalBreakpointIsFocused(dbg) {
const input = findElement(dbg, "conditionalPanelInput");
await waitForElementFocus(dbg, input);
}
async function setConditionalBreakpoint(dbg, index, condition) {
rightClickElement(dbg, "gutter", index);
selectMenuItem(dbg, 2);
await waitForElementWithSelector(dbg, ".conditional-breakpoint-panel input");
findElementWithSelector(dbg, ".conditional-breakpoint-panel input").focus();
await waitForElement(dbg, "conditionalPanelInput");
await assertConditionalBreakpointIsFocused(dbg);
// Position cursor reliably at the end of the text.
pressKey(dbg, "End");
type(dbg, condition);
@ -39,21 +50,18 @@ add_task(async function() {
const dbg = await initDebugger("doc-scripts.html");
await selectSource(dbg, "simple2");
dump("Adding a conditional Breakpoint\n");
await setConditionalBreakpoint(dbg, 5, "1");
await waitForDispatch(dbg, "ADD_BREAKPOINT");
let bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, "1", "breakpoint is created with the condition");
assertEditorBreakpoint(dbg, 5, true);
dump("Editing a conditional breakpoint\n");
await setConditionalBreakpoint(dbg, 5, "2");
await waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION");
bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, "12", "breakpoint is created with the condition");
assertEditorBreakpoint(dbg, 5, true);
dump("Removing a conditional breakpoint\n");
clickElement(dbg, "gutter", 5);
await waitForDispatch(dbg, "REMOVE_BREAKPOINT");
bp = findBreakpoint(dbg, "simple2", 5);

View File

@ -0,0 +1,23 @@
import aDefault from "./src/mod1";
export default function root() {
let one = 1;
{
const two = 2;
var fn = function someName(arg) {
console.log(this, arguments);
console.log("pause here", aDefault, one, two, fn, arg);
var inner = (arg) => { var body = "42"; console.log("pause here", body); };
inner();
};
fn.call("this-value", "arg-value");
}
}
// The build harness sets the wrong global, so just override it.
Promise.resolve().then(() => {
window.webpackStandalone = root;
});

View File

@ -0,0 +1,110 @@
var webpackStandalone =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony export (immutable) */ __webpack_exports__["default"] = root;
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__src_mod1__ = __webpack_require__(1);
function root() {
let one = 1;
{
const two = 2;
var fn = function someName(arg) {
console.log(this, arguments);
console.log("pause here", __WEBPACK_IMPORTED_MODULE_0__src_mod1__["a" /* default */], one, two, fn, arg);
var inner = (arg) => { var body = "42"; console.log("pause here", body); };
inner();
};
fn.call("this-value", "arg-value");
}
}
// The build harness sets the wrong global, so just override it.
Promise.resolve().then(() => {
window.webpackStandalone = root;
});
/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("a-default");
/***/ })
/******/ ]);
//# sourceMappingURL=output.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["webpack:///webpack/bootstrap c097356c0822da643365","webpack:///./fixtures/webpack-standalone/input.js","webpack:///./fixtures/webpack-standalone/src/mod1.js"],"names":[],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;AC7DA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,4BAA4B,iBAAiB,iCAAiC;AAC9E;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,CAAC;;;;;;;;ACtBD","file":"fixtures/webpack-standalone/output.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap c097356c0822da643365","import aDefault from \"./src/mod1\";\n\nexport default function root() {\n let one = 1;\n\n {\n const two = 2;\n\n var fn = function someName(arg) {\n console.log(this, arguments);\n console.log(\"pause here\", aDefault, one, two, fn, arg);\n\n var inner = (arg) => { var body = \"42\"; console.log(\"pause here\", body); };\n inner();\n };\n fn.call(\"this-value\", \"arg-value\");\n }\n}\n\n// The build harness sets the wrong global, so just override it.\nPromise.resolve().then(() => {\n window.webpackStandalone = root;\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./fixtures/webpack-standalone/input.js\n// module id = 0\n// module chunks = 0","export default \"a-default\";\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./fixtures/webpack-standalone/src/mod1.js\n// module id = 1\n// module chunks = 0"],"sourceRoot":""}

View File

@ -0,0 +1 @@
export default "a-default";

View File

@ -48,6 +48,7 @@ module.exports = [
}
].concat(
tests.map(({ name, dirname, input, output }) => {
const babelEnabled = name !== "webpackStandalone";
const babelEnv = name !== "webpackModulesEs6";
const babelModules = name !== "webpackModules";
@ -63,20 +64,23 @@ module.exports = [
},
devtool: "sourcemap",
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
babelrc: false,
presets: babelEnv
? [["env", { modules: babelModules ? "commonjs" : false }]]
: [],
plugins: babelEnv && babelModules ? ["add-module-exports"] : []
}
}
]
loaders: babelEnabled
? [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
babelrc: false,
presets: babelEnv
? [["env", { modules: babelModules ? "commonjs" : false }]]
: [],
plugins:
babelEnv && babelModules ? ["add-module-exports"] : []
}
}
]
: []
}
};
})

View File

@ -53,6 +53,8 @@
<button onclick="webpackModules()">Run webpackModules</button>
<script src="babel/fixtures/webpack-modules-es6/output.js"></script>
<button onclick="webpackModulesEs6()">Run webpackModulesEs6</button>
<script src="babel/fixtures/webpack-standalone/output.js"></script>
<button onclick="webpackStandalone()">Run webpackStandalone</button>
<!-- INJECTED-END -->
</body>
</html>

View File

@ -951,7 +951,8 @@ const selectors = {
tooltip: ".tooltip",
outlineItem: i =>
`.outline-list__element:nth-child(${i}) .function-signature`,
outlineItems: ".outline-list__element"
outlineItems: ".outline-list__element",
conditionalPanelInput: ".conditional-breakpoint-panel input"
};
function getSelector(elementName, ...args) {

View File

@ -89,7 +89,7 @@ public:
, mEncodeCompleteCallback(aEncodeCompleteCallback)
, mFailed(false)
{
if (!NS_IsMainThread() && GetCurrentThreadWorkerPrivate()) {
if (!NS_IsMainThread() && IsCurrentThreadRunningWorker()) {
mCreationEventTarget = GetCurrentThreadEventTarget();
} else {
mCreationEventTarget = GetMainThreadEventTarget();

View File

@ -112,6 +112,25 @@ ShadowRoot::CloneInternalDataFrom(ShadowRoot* aOther)
}
}
void
ShadowRoot::InvalidateStyleAndLayoutOnSubtree(Element* aElement)
{
MOZ_ASSERT(aElement);
if (!IsComposedDocParticipant()) {
return;
}
MOZ_ASSERT(GetComposedDoc() == OwnerDoc());
nsIPresShell* shell = OwnerDoc()->GetShell();
if (!shell) {
return;
}
shell->DestroyFramesForAndRestyle(aElement);
}
void
ShadowRoot::AddSlot(HTMLSlotElement* aSlot)
{
@ -134,10 +153,11 @@ ShadowRoot::AddSlot(HTMLSlotElement* aSlot)
return;
}
bool doEnqueueSlotChange = false;
if (oldSlot && oldSlot != currentSlot) {
// Move assigned nodes from old slot to new slot.
InvalidateStyleAndLayoutOnSubtree(oldSlot);
const nsTArray<RefPtr<nsINode>>& assignedNodes = oldSlot->AssignedNodes();
bool doEnqueueSlotChange = false;
while (assignedNodes.Length() > 0) {
nsINode* assignedNode = assignedNodes[0];
@ -151,6 +171,7 @@ ShadowRoot::AddSlot(HTMLSlotElement* aSlot)
currentSlot->EnqueueSlotChangeEvent();
}
} else {
bool doEnqueueSlotChange = false;
// Otherwise add appropriate nodes to this slot from the host.
for (nsIContent* child = GetHost()->GetFirstChild();
child;
@ -159,10 +180,11 @@ ShadowRoot::AddSlot(HTMLSlotElement* aSlot)
if (child->IsElement()) {
child->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::slot, slotName);
}
if (child->IsSlotable() && slotName.Equals(name)) {
currentSlot->AppendAssignedNode(child);
doEnqueueSlotChange = true;
if (!child->IsSlotable() || !slotName.Equals(name)) {
continue;
}
doEnqueueSlotChange = true;
currentSlot->AppendAssignedNode(child);
}
if (doEnqueueSlotChange) {
@ -343,8 +365,8 @@ ShadowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor)
return NS_OK;
}
const HTMLSlotElement*
ShadowRoot::AssignSlotFor(nsIContent* aContent)
ShadowRoot::SlotAssignment
ShadowRoot::SlotAssignmentFor(nsIContent* aContent)
{
nsAutoString slotName;
// Note that if slot attribute is missing, assign it to the first default
@ -355,7 +377,7 @@ ShadowRoot::AssignSlotFor(nsIContent* aContent)
nsTArray<HTMLSlotElement*>* slots = mSlotMap.Get(slotName);
if (!slots) {
return nullptr;
return { };
}
HTMLSlotElement* slot = slots->ElementAt(0);
@ -383,58 +405,48 @@ ShadowRoot::AssignSlotFor(nsIContent* aContent)
}
}
if (insertionIndex) {
slot->InsertAssignedNode(*insertionIndex, aContent);
} else {
slot->AppendAssignedNode(aContent);
}
return slot;
return { slot, insertionIndex };
}
const HTMLSlotElement*
ShadowRoot::UnassignSlotFor(nsIContent* aNode, const nsAString& aSlotName)
void
ShadowRoot::MaybeReassignElement(Element* aElement)
{
// Find the insertion point to which the content belongs. Note that if slot
// attribute is missing, unassign it from the first default slot, if exists.
nsTArray<HTMLSlotElement*>* slots = mSlotMap.Get(aSlotName);
if (!slots) {
return nullptr;
MOZ_ASSERT(aElement->GetParent() == GetHost());
HTMLSlotElement* oldSlot = aElement->GetAssignedSlot();
SlotAssignment assignment = SlotAssignmentFor(aElement);
if (assignment.mSlot == oldSlot) {
// Nothing to do here.
return;
}
HTMLSlotElement* slot = slots->ElementAt(0);
MOZ_ASSERT(slot);
if (!slot->AssignedNodes().Contains(aNode)) {
return nullptr;
// If the old slot is about to become empty, let layout know that it needs to
// do work.
if (oldSlot && oldSlot->AssignedNodes().Length() == 1) {
InvalidateStyleAndLayoutOnSubtree(oldSlot);
}
// Ditto if the new slot will stop showing fallback content.
if (assignment.mSlot && assignment.mSlot->AssignedNodes().IsEmpty()) {
InvalidateStyleAndLayoutOnSubtree(assignment.mSlot);
}
slot->RemoveAssignedNode(aNode);
return slot;
}
// Otherwise we only need to care about the reassigned element. Note that this
// is a no-op if we hit the `oldSlot` path above.
InvalidateStyleAndLayoutOnSubtree(aElement);
bool
ShadowRoot::MaybeReassignElement(Element* aElement,
const nsAttrValue* aOldValue)
{
nsIContent* parent = aElement->GetParent();
if (parent && parent == GetHost()) {
const HTMLSlotElement* oldSlot = UnassignSlotFor(aElement,
aOldValue ? aOldValue->GetStringValue() : EmptyString());
const HTMLSlotElement* newSlot = AssignSlotFor(aElement);
if (oldSlot) {
oldSlot->RemoveAssignedNode(aElement);
oldSlot->EnqueueSlotChangeEvent();
}
if (oldSlot != newSlot) {
if (oldSlot) {
oldSlot->EnqueueSlotChangeEvent();
}
if (newSlot) {
newSlot->EnqueueSlotChangeEvent();
}
return true;
if (assignment.mSlot) {
if (assignment.mIndex) {
assignment.mSlot->InsertAssignedNode(*assignment.mIndex, aElement);
} else {
assignment.mSlot->AppendAssignedNode(aElement);
}
assignment.mSlot->EnqueueSlotChangeEvent();
}
return false;
}
Element*
@ -466,22 +478,11 @@ ShadowRoot::AttributeChanged(Element* aElement,
return;
}
// Attributes may change insertion point matching, find its new distribution.
if (!MaybeReassignElement(aElement, aOldValue)) {
if (aElement->GetParent() != GetHost()) {
return;
}
if (!aElement->IsInComposedDoc()) {
return;
}
auto* shell = OwnerDoc()->GetShell();
if (!shell) {
return;
}
// FIXME(emilio): We could be more granular in a bunch of cases.
shell->DestroyFramesForAndRestyle(aElement);
MaybeReassignElement(aElement);
}
void
@ -509,9 +510,22 @@ ShadowRoot::ContentInserted(nsIContent* aChild)
}
if (aChild->GetParent() == GetHost()) {
if (const HTMLSlotElement* slot = AssignSlotFor(aChild)) {
slot->EnqueueSlotChangeEvent();
SlotAssignment assignment = SlotAssignmentFor(aChild);
if (!assignment.mSlot) {
return;
}
// Fallback content will go away, let layout know.
if (assignment.mSlot->AssignedNodes().IsEmpty()) {
InvalidateStyleAndLayoutOnSubtree(assignment.mSlot);
}
if (assignment.mIndex) {
assignment.mSlot->InsertAssignedNode(*assignment.mIndex, aChild);
} else {
assignment.mSlot->AppendAssignedNode(aChild);
}
assignment.mSlot->EnqueueSlotChangeEvent();
return;
}
@ -539,11 +553,13 @@ ShadowRoot::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling)
}
if (aChild->GetParent() == GetHost()) {
nsAutoString slotName;
if (aChild->IsElement()) {
aChild->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::slot, slotName);
}
if (const HTMLSlotElement* slot = UnassignSlotFor(aChild, slotName)) {
if (HTMLSlotElement* slot = aChild->GetAssignedSlot()) {
// If the slot is going to start showing fallback content, we need to tell
// layout about it.
if (slot->AssignedNodes().Length() == 1) {
InvalidateStyleAndLayoutOnSubtree(slot);
}
slot->RemoveAssignedNode(aChild);
slot->EnqueueSlotChangeEvent();
}
return;

View File

@ -99,23 +99,47 @@ private:
* Try to reassign an element to a slot and returns whether the assignment
* changed.
*/
bool MaybeReassignElement(Element* aElement, const nsAttrValue* aOldValue);
void MaybeReassignElement(Element* aElement);
/**
* Try to assign aContent to a slot in the shadow tree, returns the assigned
* slot if found.
* Represents the insertion point in a slot for a given node.
*/
const HTMLSlotElement* AssignSlotFor(nsIContent* aContent);
struct SlotAssignment
{
HTMLSlotElement* mSlot = nullptr;
Maybe<uint32_t> mIndex;
SlotAssignment() = default;
SlotAssignment(HTMLSlotElement* aSlot, const Maybe<uint32_t>& aIndex)
: mSlot(aSlot)
, mIndex(aIndex)
{ }
};
/**
* Unassign aContent from the assigned slot in the shadow tree, returns the
* assigned slot if found.
* Return the assignment corresponding to the content node at this particular
* point in time.
*
* Note: slot attribute of aContent may have changed already, so pass slot
* name explicity here.
* It's the caller's responsibility to actually call InsertAssignedNode /
* AppendAssignedNode in the slot as needed.
*/
const HTMLSlotElement* UnassignSlotFor(nsIContent* aContent,
const nsAString& aSlotName);
SlotAssignment SlotAssignmentFor(nsIContent* aContent);
/**
* Explicitly invalidates the style and layout of the flattened-tree subtree
* rooted at the element.
*
* You need to use this whenever the flat tree is going to be shuffled in a
* way that layout doesn't understand via the usual ContentInserted /
* ContentAppended / ContentRemoved notifications. For example, if removing an
* element will cause a change in the flat tree such that other element will
* start showing up (like fallback content), this method needs to be called on
* an ancestor of that element.
*
* It is important that this runs _before_ actually shuffling the flat tree
* around, so that layout knows the actual tree that it needs to invalidate.
*/
void InvalidateStyleAndLayoutOnSubtree(Element*);
public:
void AddSlot(HTMLSlotElement* aSlot);
@ -163,8 +187,6 @@ public:
protected:
virtual ~ShadowRoot();
void SyncServoStyles();
const ShadowRootMode mMode;
// The computed data from the style sheets.

View File

@ -1255,7 +1255,13 @@ StructuredCloneHolder::CustomWriteTransferHandler(JSContext* aCx,
*aExtraData = 0;
*aTag = SCTAG_DOM_IMAGEBITMAP;
*aOwnership = JS::SCTAG_TMO_CUSTOM;
*aContent = bitmap->ToCloneData().release();
UniquePtr<ImageBitmapCloneData> clonedBitmap = bitmap->ToCloneData();
if (!clonedBitmap) {
return false;
}
*aContent = clonedBitmap.release();
MOZ_ASSERT(*aContent);
bitmap->Close();

View File

@ -1501,6 +1501,15 @@ nsIDocument::nsIDocument()
mDelayFrameLoaderInitialization(false),
mSynchronousDOMContentLoaded(false),
mMaybeServiceWorkerControlled(false),
mValidWidth(false),
mValidHeight(false),
mAutoSize(false),
mAllowZoom(false),
mAllowDoubleTapZoom(false),
mValidScaleFloat(false),
mValidMaxScale(false),
mScaleStrEmpty(false),
mWidthStrEmpty(false),
mPendingFullscreenRequests(0),
mXMLDeclarationBits(0),
mCompatMode(eCompatibility_FullStandards),
@ -1560,15 +1569,6 @@ nsDocument::nsDocument(const char* aContentType)
, mReportedUseCounters(false)
, mOnloadBlockCount(0)
, mAsyncOnloadBlockCount(0)
, mValidWidth(false)
, mValidHeight(false)
, mAutoSize(false)
, mAllowZoom(false)
, mAllowDoubleTapZoom(false)
, mValidScaleFloat(false)
, mValidMaxScale(false)
, mScaleStrEmpty(false)
, mWidthStrEmpty(false)
#ifdef DEBUG
, mWillReparent(false)
#endif
@ -1619,7 +1619,7 @@ nsIDocument::~nsIDocument()
}
bool
nsDocument::IsAboutPage() const
nsIDocument::IsAboutPage() const
{
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
nsCOMPtr<nsIURI> uri;
@ -7332,7 +7332,7 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
}
nsViewportInfo
nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
nsIDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
{
MOZ_ASSERT(mPresShell);
@ -7352,8 +7352,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
// Special behaviour for desktop mode, provided we are not on an about: page
nsPIDOMWindowOuter* win = GetWindow();
if (win && win->IsDesktopModeViewport() && !IsAboutPage())
{
if (win && win->IsDesktopModeViewport() && !IsAboutPage()) {
CSSCoord viewportWidth = gfxPrefs::DesktopViewportWidth() / fullZoom;
CSSToScreenScale scaleToFit(aDisplaySize.width / viewportWidth);
float aspectRatio = (float)aDisplaySize.height / aDisplaySize.width;
@ -7406,8 +7405,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
if (handheldFriendly.EqualsLiteral("true")) {
mViewportType = DisplayWidthHeight;
return nsViewportInfo(aDisplaySize,
defaultScale,
return nsViewportInfo(aDisplaySize, defaultScale,
/*allowZoom*/true);
}
}

View File

@ -227,8 +227,6 @@ public:
nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const;
nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName);
virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) override;
enum class UseCounterReportKind {
// Flush the document's use counters only; the use counters for any
// external resource documents will be flushed when the external
@ -412,9 +410,6 @@ private:
void ClearAllBoxObjects();
// Returns true if the scheme for the url for this document is "about"
bool IsAboutPage() const;
// These are not implemented and not supported.
nsDocument(const nsDocument& aOther);
nsDocument& operator=(const nsDocument& aOther);
@ -427,16 +422,6 @@ private:
nsCOMPtr<nsIRunnable> mMaybeEndOutermostXBLUpdateRunner;
// These member variables cache information about the viewport so we don't have to
// recalculate it each time.
bool mValidWidth, mValidHeight;
mozilla::LayoutDeviceToScreenScale mScaleMinFloat;
mozilla::LayoutDeviceToScreenScale mScaleMaxFloat;
mozilla::LayoutDeviceToScreenScale mScaleFloat;
mozilla::CSSToLayoutDeviceScale mPixelRatio;
bool mAutoSize, mAllowZoom, mAllowDoubleTapZoom, mValidScaleFloat, mValidMaxScale, mScaleStrEmpty, mWidthStrEmpty;
mozilla::CSSSize mViewportSize;
#ifdef DEBUG
public:
bool mWillReparent;

View File

@ -1307,7 +1307,7 @@ public:
* NOTE: If the site is optimized for mobile (via the doctype), this
* will return viewport information that specifies default information.
*/
virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) = 0;
nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize);
/**
* True iff this doc will ignore manual character encoding overrides.
@ -3631,6 +3631,8 @@ public:
nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
protected:
// Returns true if the scheme for the url for this document is "about".
bool IsAboutPage() const;
bool ContainsEMEContent();
bool ContainsMSEContent();
@ -4127,6 +4129,18 @@ protected:
// Used to prevent multiple requests to ServiceWorkerManager.
bool mMaybeServiceWorkerControlled: 1;
// These member variables cache information about the viewport so we don't
// have to recalculate it each time.
bool mValidWidth: 1;
bool mValidHeight: 1;
bool mAutoSize: 1;
bool mAllowZoom: 1;
bool mAllowDoubleTapZoom: 1;
bool mValidScaleFloat: 1;
bool mValidMaxScale: 1;
bool mScaleStrEmpty: 1;
bool mWidthStrEmpty: 1;
uint8_t mPendingFullscreenRequests;
uint8_t mXMLDeclarationBits;
@ -4442,6 +4456,14 @@ protected:
// 2) We haven't had Destroy() called on us yet.
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
// These member variables cache information about the viewport so we don't
// have to recalculate it each time.
mozilla::LayoutDeviceToScreenScale mScaleMinFloat;
mozilla::LayoutDeviceToScreenScale mScaleMaxFloat;
mozilla::LayoutDeviceToScreenScale mScaleFloat;
mozilla::CSSToLayoutDeviceScale mPixelRatio;
mozilla::CSSSize mViewportSize;
nsTArray<RefPtr<mozilla::StyleSheet>> mOnDemandBuiltInUASheets;
nsTArray<RefPtr<mozilla::StyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];

View File

@ -792,6 +792,11 @@ ImageBitmap::TransferAsImage()
UniquePtr<ImageBitmapCloneData>
ImageBitmap::ToCloneData() const
{
if (!mData) {
// A closed image cannot be cloned.
return nullptr;
}
UniquePtr<ImageBitmapCloneData> result(new ImageBitmapCloneData());
result->mPictureRect = mPictureRect;
result->mAlphaType = mAlphaType;

View File

@ -114,6 +114,7 @@ public:
already_AddRefed<layers::Image>
TransferAsImage();
// This method returns null if the image has been already closed.
UniquePtr<ImageBitmapCloneData>
ToCloneData() const;

View File

@ -224,10 +224,14 @@ FromPboOffset(WebGLContext* webgl, const char* funcName, TexImageTarget target,
static UniquePtr<webgl::TexUnpackBlob>
FromImageBitmap(WebGLContext* webgl, const char* funcName, TexImageTarget target,
uint32_t width, uint32_t height, uint32_t depth,
const dom::ImageBitmap& imageBitmap)
uint32_t width, uint32_t height, uint32_t depth,
const dom::ImageBitmap& imageBitmap)
{
UniquePtr<dom::ImageBitmapCloneData> cloneData = Move(imageBitmap.ToCloneData());
if (!cloneData) {
return nullptr;
}
const RefPtr<gfx::DataSourceSurface> surf = cloneData->mSurface;
if (!width) {

View File

@ -15,10 +15,6 @@ support-files =
[test_bug1315862.html]
[test_bug1323158.html]
[test_bug1403055.html]
[test_bug1414336.html]
support-files =
../../../../gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
../../../../gfx/layers/apz/test/mochitest/apz_test_utils.js
[test_bug1420589_1.html]
support-files =
bug_1420589_iframe1.html

View File

@ -104,13 +104,13 @@ public:
// ControlRunnable used to complete the releasing of resources on the worker
// thread when already shutting down.
template <class Derived>
class ContinueConsumeBodyControlRunnable final : public MainThreadWorkerControlRunnable
class AbortConsumeBodyControlRunnable final : public MainThreadWorkerControlRunnable
{
RefPtr<FetchBodyConsumer<Derived>> mFetchBodyConsumer;
public:
ContinueConsumeBodyControlRunnable(FetchBodyConsumer<Derived>* aFetchBodyConsumer,
uint8_t* aResult)
AbortConsumeBodyControlRunnable(FetchBodyConsumer<Derived>* aFetchBodyConsumer,
uint8_t* aResult)
: MainThreadWorkerControlRunnable(aFetchBodyConsumer->GetWorkerPrivate())
, mFetchBodyConsumer(aFetchBodyConsumer)
{
@ -127,27 +127,6 @@ public:
}
};
template <class Derived>
class FailConsumeBodyWorkerRunnable : public MainThreadWorkerControlRunnable
{
RefPtr<FetchBodyConsumer<Derived>> mBodyConsumer;
public:
explicit FailConsumeBodyWorkerRunnable(FetchBodyConsumer<Derived>* aBodyConsumer)
: MainThreadWorkerControlRunnable(aBodyConsumer->GetWorkerPrivate())
, mBodyConsumer(aBodyConsumer)
{
AssertIsOnMainThread();
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
mBodyConsumer->ContinueConsumeBody(NS_ERROR_FAILURE, 0, nullptr);
return true;
}
};
/*
* In case of failure to create a stream pump or dispatch stream completion to
* worker, ensure we cleanup properly. Thread agnostic.
@ -168,8 +147,8 @@ public:
if (mBodyConsumer) {
if (mBodyConsumer->GetWorkerPrivate()) {
RefPtr<FailConsumeBodyWorkerRunnable<Derived>> r =
new FailConsumeBodyWorkerRunnable<Derived>(mBodyConsumer);
RefPtr<AbortConsumeBodyControlRunnable<Derived>> r =
new AbortConsumeBodyControlRunnable<Derived>(mBodyConsumer, nullptr);
if (!r->Dispatch()) {
MOZ_CRASH("We are going to leak");
}
@ -217,13 +196,13 @@ public:
// ControlRunnable used to complete the releasing of resources on the worker
// thread when already shutting down.
template <class Derived>
class ContinueConsumeBlobBodyControlRunnable final
class AbortConsumeBlobBodyControlRunnable final
: public MainThreadWorkerControlRunnable
{
RefPtr<FetchBodyConsumer<Derived>> mFetchBodyConsumer;
public:
explicit ContinueConsumeBlobBodyControlRunnable(FetchBodyConsumer<Derived>* aFetchBodyConsumer)
explicit AbortConsumeBlobBodyControlRunnable(FetchBodyConsumer<Derived>* aFetchBodyConsumer)
: MainThreadWorkerControlRunnable(aFetchBodyConsumer->GetWorkerPrivate())
, mFetchBodyConsumer(aFetchBodyConsumer)
{
@ -288,9 +267,9 @@ public:
// The worker is shutting down. Let's use a control runnable to complete the
// shutting down procedure.
RefPtr<ContinueConsumeBodyControlRunnable<Derived>> r =
new ContinueConsumeBodyControlRunnable<Derived>(mFetchBodyConsumer,
nonconstResult);
RefPtr<AbortConsumeBodyControlRunnable<Derived>> r =
new AbortConsumeBodyControlRunnable<Derived>(mFetchBodyConsumer,
nonconstResult);
if (NS_WARN_IF(!r->Dispatch())) {
return NS_ERROR_FAILURE;
}
@ -333,8 +312,8 @@ public:
// The worker is shutting down. Let's use a control runnable to complete the
// shutting down procedure.
RefPtr<ContinueConsumeBlobBodyControlRunnable<Derived>> r =
new ContinueConsumeBlobBodyControlRunnable<Derived>(mFetchBodyConsumer);
RefPtr<AbortConsumeBlobBodyControlRunnable<Derived>> r =
new AbortConsumeBlobBodyControlRunnable<Derived>(mFetchBodyConsumer);
Unused << NS_WARN_IF(!r->Dispatch());
}
@ -612,16 +591,13 @@ FetchBodyConsumer<Derived>::ContinueConsumeBody(nsresult aStatus,
// sync with a body read.
MOZ_ASSERT(mBody->BodyUsed());
auto autoFree = mozilla::MakeScopeExit([&] {
free(aResult);
});
MOZ_ASSERT(mConsumePromise);
RefPtr<Promise> localPromise = mConsumePromise.forget();
RefPtr<FetchBodyConsumer<Derived>> self = this;
auto autoReleaseObject = mozilla::MakeScopeExit([&] {
self->ReleaseObject();
free(aResult);
});
if (aShuttingDown) {
@ -726,10 +702,10 @@ FetchBodyConsumer<Derived>::ContinueConsumeBlobBody(BlobImpl* aBlobImpl,
// sync with a body read.
MOZ_ASSERT(mBody->BodyUsed());
if (!aShuttingDown) {
MOZ_ASSERT(mConsumePromise);
RefPtr<Promise> localPromise = mConsumePromise.forget();
MOZ_ASSERT(mConsumePromise);
RefPtr<Promise> localPromise = mConsumePromise.forget();
if (!aShuttingDown) {
RefPtr<dom::Blob> blob = dom::Blob::Create(mGlobal, aBlobImpl);
MOZ_ASSERT(blob);

View File

@ -11,6 +11,7 @@
#include "nsIDocument.h"
#include "mozilla/dom/InternalRequest.h"
#include "mozilla/dom/WorkerRef.h"
namespace mozilla {
namespace dom {
@ -266,36 +267,43 @@ public:
NS_IMPL_ISUPPORTS(WindowStreamOwner, nsIObserver, nsISupportsWeakReference)
class WorkerStreamOwner final : public WorkerHolder
class WorkerStreamOwner final
{
// Read from any thread but only set/cleared on the worker thread. The
// lifecycle of WorkerStreamOwner prevents concurrent read/clear.
nsCOMPtr<nsIAsyncInputStream> mStream;
public:
NS_INLINE_DECL_REFCOUNTING(WorkerStreamOwner)
explicit WorkerStreamOwner(nsIAsyncInputStream* aStream)
: WorkerHolder("WorkerStreamOwner",
WorkerHolder::Behavior::AllowIdleShutdownStart)
, mStream(aStream)
: mStream(aStream)
{}
static UniquePtr<WorkerStreamOwner>
static already_AddRefed<WorkerStreamOwner>
Create(nsIAsyncInputStream* aStream, WorkerPrivate* aWorker)
{
auto self = MakeUnique<WorkerStreamOwner>(aStream);
RefPtr<WorkerStreamOwner> self = new WorkerStreamOwner(aStream);
if (!self->HoldWorker(aWorker, Closing)) {
self->mWorkerRef = WeakWorkerRef::Create(aWorker, [self]() {
if (self->mStream) {
// If this Close() calls JSStreamConsumer::OnInputStreamReady and drops
// the last reference to the JSStreamConsumer, 'this' will not be
// destroyed since ~JSStreamConsumer() only enqueues a Destroyer.
self->mStream->Close();
self->mStream = nullptr;
self->mWorkerRef = nullptr;
}
});
if (!self->mWorkerRef) {
return nullptr;
}
return self;
return self.forget();
}
struct Destroyer final : CancelableRunnable
{
UniquePtr<WorkerStreamOwner> mDoomed;
RefPtr<WorkerStreamOwner> mDoomed;
explicit Destroyer(UniquePtr<WorkerStreamOwner>&& aDoomed)
explicit Destroyer(already_AddRefed<WorkerStreamOwner>&& aDoomed)
: CancelableRunnable("WorkerStreamOwner::Destroyer")
, mDoomed(Move(aDoomed))
{}
@ -314,29 +322,21 @@ public:
}
};
// WorkerHolder:
private:
~WorkerStreamOwner() = default;
bool Notify(WorkerStatus aStatus) override
{
if (!mStream) {
return true;
}
// Read from any thread but only set/cleared on the worker thread. The
// lifecycle of WorkerStreamOwner prevents concurrent read/clear.
nsCOMPtr<nsIAsyncInputStream> mStream;
RefPtr<WeakWorkerRef> mWorkerRef;
// If this Close() calls JSStreamConsumer::OnInputStreamReady and drops the
// last reference to the JSStreamConsumer, 'this' will not be destroyed
// since ~JSStreamConsumer() only enqueues a Destroyer.
mStream->Close();
mStream = nullptr;
ReleaseWorker();
return true;
}
};
class JSStreamConsumer final : public nsIInputStreamCallback
{
nsCOMPtr<nsIEventTarget> mOwningEventTarget;
RefPtr<WindowStreamOwner> mWindowStreamOwner;
UniquePtr<WorkerStreamOwner> mWorkerStreamOwner;
RefPtr<WorkerStreamOwner> mWorkerStreamOwner;
JS::StreamConsumer* mConsumer;
bool mConsumerAborted;
@ -352,7 +352,7 @@ class JSStreamConsumer final : public nsIInputStreamCallback
MOZ_DIAGNOSTIC_ASSERT(mConsumer);
}
JSStreamConsumer(UniquePtr<WorkerStreamOwner> aWorkerStreamOwner,
JSStreamConsumer(RefPtr<WorkerStreamOwner> aWorkerStreamOwner,
nsIGlobalObject* aGlobal,
JS::StreamConsumer* aConsumer)
: mOwningEventTarget(aGlobal->EventTargetFor(TaskCategory::Other))
@ -375,7 +375,7 @@ class JSStreamConsumer final : public nsIInputStreamCallback
destroyer = new WindowStreamOwner::Destroyer(mWindowStreamOwner.forget());
} else {
MOZ_DIAGNOSTIC_ASSERT(mWorkerStreamOwner);
destroyer = new WorkerStreamOwner::Destroyer(Move(mWorkerStreamOwner));
destroyer = new WorkerStreamOwner::Destroyer(mWorkerStreamOwner.forget());
}
MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget->Dispatch(destroyer.forget()));
@ -440,7 +440,7 @@ public:
RefPtr<JSStreamConsumer> consumer;
if (aMaybeWorker) {
UniquePtr<WorkerStreamOwner> owner =
RefPtr<WorkerStreamOwner> owner =
WorkerStreamOwner::Create(asyncStream, aMaybeWorker);
if (!owner) {
return false;

View File

@ -8,9 +8,8 @@
#include "IPCBlobInputStreamThread.h"
#include "mozilla/ipc/IPCStreamUtils.h"
#include "mozilla/dom/WorkerHolder.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/dom/WorkerRunnable.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/dom/WorkerRef.h"
namespace mozilla {
namespace dom {
@ -90,45 +89,6 @@ private:
nsCOMPtr<nsIInputStream> mCreatedStream;
};
class IPCBlobInputStreamWorkerHolder final : public WorkerHolder
{
public:
IPCBlobInputStreamWorkerHolder()
: WorkerHolder("IPCBlobInputStreamWorkerHolder")
{}
bool Notify(WorkerStatus aStatus) override
{
// We must keep the worker alive until the migration is completed.
return true;
}
};
class ReleaseWorkerHolderRunnable final : public CancelableRunnable
{
public:
explicit ReleaseWorkerHolderRunnable(UniquePtr<WorkerHolder>&& aWorkerHolder)
: CancelableRunnable("dom::ReleaseWorkerHolderRunnable")
, mWorkerHolder(Move(aWorkerHolder))
{}
NS_IMETHOD
Run() override
{
mWorkerHolder = nullptr;
return NS_OK;
}
nsresult
Cancel() override
{
return Run();
}
private:
UniquePtr<WorkerHolder> mWorkerHolder;
};
} // anonymous
IPCBlobInputStreamChild::IPCBlobInputStreamChild(const nsID& aID,
@ -143,13 +103,18 @@ IPCBlobInputStreamChild::IPCBlobInputStreamChild(const nsID& aID,
// before the thread is released.
if (!NS_IsMainThread()) {
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
if (workerPrivate) {
UniquePtr<WorkerHolder> workerHolder(
new IPCBlobInputStreamWorkerHolder());
if (workerHolder->HoldWorker(workerPrivate, Canceling)) {
mWorkerHolder.swap(workerHolder);
}
if (!workerPrivate) {
return;
}
RefPtr<StrongWorkerRef> workerRef =
StrongWorkerRef::Create(workerPrivate, "IPCBlobInputStreamChild");
if (!workerRef) {
return;
}
// We must keep the worker alive until the migration is completed.
mWorkerRef = new ThreadSafeWorkerRef(workerRef);
}
}
@ -163,7 +128,7 @@ IPCBlobInputStreamChild::Shutdown()
RefPtr<IPCBlobInputStreamChild> kungFuDeathGrip = this;
mWorkerHolder = nullptr;
mWorkerRef = nullptr;
mPendingOperations.Clear();
if (mState == eActive) {
@ -195,7 +160,7 @@ IPCBlobInputStreamChild::ActorDestroy(IProtocol::ActorDestroyReason aReason)
return;
}
// Let's cleanup the workerHolder and the pending operation queue.
// Let's cleanup the workerRef and the pending operation queue.
Shutdown();
}
@ -339,11 +304,7 @@ IPCBlobInputStreamChild::Migrated()
MutexAutoLock lock(mMutex);
MOZ_ASSERT(mState == eInactiveMigrating);
if (mWorkerHolder) {
RefPtr<ReleaseWorkerHolderRunnable> runnable =
new ReleaseWorkerHolderRunnable(Move(mWorkerHolder));
mOwningEventTarget->Dispatch(runnable, NS_DISPATCH_NORMAL);
}
mWorkerRef = nullptr;
mOwningEventTarget = GetCurrentThreadSerialEventTarget();
MOZ_ASSERT(IPCBlobInputStreamThread::IsOnFileEventTarget(mOwningEventTarget));

View File

@ -17,7 +17,7 @@ namespace mozilla {
namespace dom {
class IPCBlobInputStream;
class WorkerHolder;
class ThreadSafeWorkerRef;
class IPCBlobInputStreamChild final
: public mozilla::ipc::PIPCBlobInputStreamChild
@ -107,7 +107,7 @@ private:
nsCOMPtr<nsISerialEventTarget> mOwningEventTarget;
UniquePtr<WorkerHolder> mWorkerHolder;
RefPtr<ThreadSafeWorkerRef> mWorkerRef;
};
} // namespace dom

View File

@ -101,7 +101,7 @@ skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulato
[test_peerConnection_audioCodecs.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_transceivers.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
skip-if = (android_version == '18') || (os == 'linux' && debug) # android(Bug 1189784, timeouts on 4.3 emulator), Bug 1432025
[test_peerConnection_basicAudio.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_audioSynchronizationSources.html]

View File

@ -5,7 +5,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PerformanceStorageWorker.h"
#include "mozilla/dom/WorkerHolder.h"
#include "mozilla/dom/WorkerRef.h"
#include "mozilla/dom/WorkerRunnable.h"
#include "mozilla/dom/WorkerPrivate.h"
namespace mozilla {
@ -29,47 +30,6 @@ public:
namespace {
// This runnable calls InitializeOnWorker() on the worker thread. Here a
// workerHolder is used to monitor when the worker thread is starting the
// shutdown procedure.
// Here we use control runnable because this code must be executed also when in
// a sync event loop.
class PerformanceStorageInitializer final : public WorkerControlRunnable
{
RefPtr<PerformanceStorageWorker> mStorage;
public:
PerformanceStorageInitializer(WorkerPrivate* aWorkerPrivate,
PerformanceStorageWorker* aStorage)
: WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
, mStorage(aStorage)
{}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
mStorage->InitializeOnWorker();
return true;
}
nsresult
Cancel() override
{
mStorage->ShutdownOnWorker();
return WorkerRunnable::Cancel();
}
bool
PreDispatch(WorkerPrivate* aWorkerPrivate) override
{
return true;
}
void
PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override
{}
};
// Here we use control runnable because this code must be executed also when in
// a sync event loop
class PerformanceEntryAdder final : public WorkerControlRunnable
@ -141,24 +101,23 @@ public:
/* static */ already_AddRefed<PerformanceStorageWorker>
PerformanceStorageWorker::Create(WorkerPrivate* aWorkerPrivate)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
RefPtr<PerformanceStorageWorker> storage =
new PerformanceStorageWorker(aWorkerPrivate);
RefPtr<PerformanceStorageWorker> storage = new PerformanceStorageWorker();
RefPtr<PerformanceStorageInitializer> r =
new PerformanceStorageInitializer(aWorkerPrivate, storage);
if (NS_WARN_IF(!r->Dispatch())) {
return nullptr;
}
storage->mWorkerRef = WeakWorkerRef::Create(aWorkerPrivate, [storage]() {
storage->ShutdownOnWorker();
});
// PerformanceStorageWorker is created at the creation time of the worker.
MOZ_ASSERT(storage->mWorkerRef);
return storage.forget();
}
PerformanceStorageWorker::PerformanceStorageWorker(WorkerPrivate* aWorkerPrivate)
PerformanceStorageWorker::PerformanceStorageWorker()
: mMutex("PerformanceStorageWorker::mMutex")
, mWorkerPrivate(aWorkerPrivate)
, mState(eInitializing)
{
}
@ -172,10 +131,15 @@ PerformanceStorageWorker::AddEntry(nsIHttpChannel* aChannel,
MutexAutoLock lock(mMutex);
if (mState == eTerminated) {
if (!mWorkerRef) {
return;
}
// If we have mWorkerRef, we haven't received the WorkerRef notification and
// we haven't yet call ShutdownOnWorker, which uses the mutex.
WorkerPrivate* workerPrivate = mWorkerRef->GetUnsafePrivate();
MOZ_ASSERT(workerPrivate);
nsAutoString initiatorType;
nsAutoString entryName;
@ -191,44 +155,22 @@ PerformanceStorageWorker::AddEntry(nsIHttpChannel* aChannel,
entryName));
RefPtr<PerformanceEntryAdder> r =
new PerformanceEntryAdder(mWorkerPrivate, this, Move(data));
new PerformanceEntryAdder(workerPrivate, this, Move(data));
Unused << NS_WARN_IF(!r->Dispatch());
}
void
PerformanceStorageWorker::InitializeOnWorker()
{
MutexAutoLock lock(mMutex);
MOZ_ASSERT(mState == eInitializing);
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
mWorkerHolder.reset(new PerformanceStorageWorkerHolder(this));
if (!mWorkerHolder->HoldWorker(mWorkerPrivate, Canceling)) {
MutexAutoUnlock lock(mMutex);
ShutdownOnWorker();
return;
}
// We are ready to accept entries.
mState = eReady;
}
void
PerformanceStorageWorker::ShutdownOnWorker()
{
MutexAutoLock lock(mMutex);
if (mState == eTerminated) {
if (!mWorkerRef) {
return;
}
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
MOZ_ASSERT(IsCurrentThreadRunningWorker());
mState = eTerminated;
mWorkerHolder = nullptr;
mWorkerPrivate = nullptr;
mWorkerRef = nullptr;
}
void
@ -240,16 +182,16 @@ PerformanceStorageWorker::AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aDa
{
MutexAutoLock lock(mMutex);
if (mState == eTerminated) {
if (!mWorkerRef) {
return;
}
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
// We must have the workerPrivate because it is available until a notification
// is received by WorkerRef and we use mutex to make the code protected.
WorkerPrivate* workerPrivate = mWorkerRef->GetPrivate();
MOZ_ASSERT(workerPrivate);
MOZ_ASSERT(mState == eReady);
WorkerGlobalScope* scope = mWorkerPrivate->GlobalScope();
WorkerGlobalScope* scope = workerPrivate->GlobalScope();
performance = scope->GetPerformance();
}

View File

@ -12,7 +12,7 @@
namespace mozilla {
namespace dom {
class WorkerHolder;
class WeakWorkerRef;
class WorkerPrivate;
class PerformanceProxyData;
@ -25,8 +25,6 @@ public:
static already_AddRefed<PerformanceStorageWorker>
Create(WorkerPrivate* aWorkerPrivate);
void InitializeOnWorker();
void ShutdownOnWorker();
void AddEntry(nsIHttpChannel* aChannel,
@ -35,25 +33,14 @@ public:
void AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aData);
private:
explicit PerformanceStorageWorker(WorkerPrivate* aWorkerPrivate);
PerformanceStorageWorker();
~PerformanceStorageWorker();
Mutex mMutex;
// Protected by mutex.
// This raw pointer is nullified when the WorkerHolder communicates the
// shutting down of the worker thread.
WorkerPrivate* mWorkerPrivate;
// Protected by mutex.
enum {
eInitializing,
eReady,
eTerminated,
} mState;
// Touched on worker-thread only.
UniquePtr<WorkerHolder> mWorkerHolder;
// Created and released on worker-thread. Used also on main-thread.
RefPtr<WeakWorkerRef> mWorkerRef;
};
} // namespace dom

View File

@ -21,6 +21,7 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/dom/WorkerRunnable.h"
#include "mozilla/dom/WorkerRef.h"
#include "jsfriendapi.h"
#include "js/StructuredClone.h"
@ -494,7 +495,7 @@ Promise::ReportRejectedPromise(JSContext* aCx, JS::HandleObject aPromise)
RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
bool isMainThread = MOZ_LIKELY(NS_IsMainThread());
bool isChrome = isMainThread ? nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(aPromise))
: GetCurrentThreadWorkerPrivate()->IsChromeWorker();
: IsCurrentThreadRunningChromeWorker();
nsGlobalWindowInner* win = isMainThread
? xpc::WindowGlobalOrNull(aPromise)
: nullptr;
@ -572,30 +573,6 @@ private:
PromiseWorkerProxy::RunCallbackFunc mFunc;
};
class PromiseWorkerHolder final : public WorkerHolder
{
// RawPointer because this proxy keeps alive the holder.
PromiseWorkerProxy* mProxy;
public:
explicit PromiseWorkerHolder(PromiseWorkerProxy* aProxy)
: WorkerHolder("PromiseWorkerHolder")
, mProxy(aProxy)
{
MOZ_ASSERT(aProxy);
}
bool
Notify(WorkerStatus aStatus) override
{
if (aStatus >= Canceling) {
mProxy->CleanUp();
}
return true;
}
};
/* static */
already_AddRefed<PromiseWorkerProxy>
PromiseWorkerProxy::Create(WorkerPrivate* aWorkerPrivate,
@ -608,27 +585,36 @@ PromiseWorkerProxy::Create(WorkerPrivate* aWorkerPrivate,
MOZ_ASSERT_IF(aCb, !!aCb->Write && !!aCb->Read);
RefPtr<PromiseWorkerProxy> proxy =
new PromiseWorkerProxy(aWorkerPrivate, aWorkerPromise, aCb);
new PromiseWorkerProxy(aWorkerPromise, aCb);
// We do this to make sure the worker thread won't shut down before the
// promise is resolved/rejected on the worker thread.
if (!proxy->AddRefObject()) {
RefPtr<StrongWorkerRef> workerRef =
StrongWorkerRef::Create(aWorkerPrivate, "PromiseWorkerProxy", [proxy]() {
proxy->CleanUp();
});
if (NS_WARN_IF(!workerRef)) {
// Probably the worker is terminating. We cannot complete the operation
// and we have to release all the resources.
proxy->CleanProperties();
return nullptr;
}
proxy->mWorkerRef = new ThreadSafeWorkerRef(workerRef);
// Maintain a reference so that we have a valid object to clean up when
// removing the feature.
proxy.get()->AddRef();
return proxy.forget();
}
NS_IMPL_ISUPPORTS0(PromiseWorkerProxy)
PromiseWorkerProxy::PromiseWorkerProxy(WorkerPrivate* aWorkerPrivate,
Promise* aWorkerPromise,
PromiseWorkerProxy::PromiseWorkerProxy(Promise* aWorkerPromise,
const PromiseWorkerProxyStructuredCloneCallbacks* aCallbacks)
: mWorkerPrivate(aWorkerPrivate)
, mWorkerPromise(aWorkerPromise)
: mWorkerPromise(aWorkerPromise)
, mCleanedUp(false)
, mCallbacks(aCallbacks)
, mCleanUpLock("cleanUpLock")
@ -638,48 +624,25 @@ PromiseWorkerProxy::PromiseWorkerProxy(WorkerPrivate* aWorkerPrivate,
PromiseWorkerProxy::~PromiseWorkerProxy()
{
MOZ_ASSERT(mCleanedUp);
MOZ_ASSERT(!mWorkerHolder);
MOZ_ASSERT(!mWorkerPromise);
MOZ_ASSERT(!mWorkerPrivate);
MOZ_ASSERT(!mWorkerRef);
}
void
PromiseWorkerProxy::CleanProperties()
{
#ifdef DEBUG
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
worker->AssertIsOnWorkerThread();
#endif
MOZ_ASSERT(IsCurrentThreadRunningWorker());
// Ok to do this unprotected from Create().
// CleanUp() holds the lock before calling this.
mCleanedUp = true;
mWorkerPromise = nullptr;
mWorkerPrivate = nullptr;
mWorkerRef = nullptr;
// Clear the StructuredCloneHolderBase class.
Clear();
}
bool
PromiseWorkerProxy::AddRefObject()
{
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
MOZ_ASSERT(!mWorkerHolder);
mWorkerHolder.reset(new PromiseWorkerHolder(this));
if (NS_WARN_IF(!mWorkerHolder->HoldWorker(mWorkerPrivate, Canceling))) {
mWorkerHolder = nullptr;
return false;
}
// Maintain a reference so that we have a valid object to clean up when
// removing the feature.
AddRef();
return true;
}
WorkerPrivate*
PromiseWorkerProxy::GetWorkerPrivate() const
{
@ -691,19 +654,15 @@ PromiseWorkerProxy::GetWorkerPrivate() const
// Safe to check this without a lock since we assert lock ownership on the
// main thread above.
MOZ_ASSERT(!mCleanedUp);
MOZ_ASSERT(mWorkerHolder);
MOZ_ASSERT(mWorkerRef);
return mWorkerPrivate;
return mWorkerRef->Private();
}
Promise*
PromiseWorkerProxy::WorkerPromise() const
{
#ifdef DEBUG
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
worker->AssertIsOnWorkerThread();
#endif
MOZ_ASSERT(IsCurrentThreadRunningWorker());
MOZ_ASSERT(mWorkerPromise);
return mWorkerPromise;
}
@ -754,21 +713,17 @@ PromiseWorkerProxy::CleanUp()
{
MutexAutoLock lock(Lock());
// |mWorkerPrivate| is not safe to use anymore if we have already
// cleaned up and RemoveWorkerHolder(), so we need to check |mCleanedUp|
// first.
if (CleanedUp()) {
return;
}
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
MOZ_ASSERT(mWorkerRef);
mWorkerRef->Private()->AssertIsOnWorkerThread();
// Release the Promise and remove the PromiseWorkerProxy from the holders of
// the worker thread since the Promise has been resolved/rejected or the
// worker thread has been cancelled.
MOZ_ASSERT(mWorkerHolder);
mWorkerHolder = nullptr;
mWorkerRef = nullptr;
CleanProperties();
}

View File

@ -11,7 +11,6 @@
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/dom/StructuredCloneHolder.h"
#include "mozilla/dom/WorkerHolder.h"
#include "mozilla/dom/WorkerRunnable.h"
#include "nsProxyRelease.h"
@ -19,6 +18,7 @@ namespace mozilla {
namespace dom {
class Promise;
class ThreadSafeWorkerRef;
class WorkerPrivate;
// A proxy to (eventually) mirror a resolved/rejected Promise's result from the
@ -179,14 +179,11 @@ protected:
JS::Handle<JS::Value> aValue) override;
private:
PromiseWorkerProxy(WorkerPrivate* aWorkerPrivate,
Promise* aWorkerPromise,
const PromiseWorkerProxyStructuredCloneCallbacks* aCallbacks = nullptr);
explicit PromiseWorkerProxy(Promise* aWorkerPromise,
const PromiseWorkerProxyStructuredCloneCallbacks* aCallbacks = nullptr);
virtual ~PromiseWorkerProxy();
bool AddRefObject();
// If not called from Create(), be sure to hold Lock().
void CleanProperties();
@ -199,7 +196,7 @@ private:
RunCallbackFunc aFunc);
// Any thread with appropriate checks.
WorkerPrivate* mWorkerPrivate;
RefPtr<ThreadSafeWorkerRef> mWorkerRef;
// Worker thread only.
RefPtr<Promise> mWorkerPromise;
@ -213,8 +210,6 @@ private:
// Ensure the worker and the main thread won't race to access |mCleanedUp|.
Mutex mCleanUpLock;
UniquePtr<WorkerHolder> mWorkerHolder;
};
} // namespace dom
} // namespace mozilla

View File

@ -18,12 +18,13 @@ static nsIThread* gPBackgroundThread;
static void
u2f_register_callback(uint64_t aTransactionId, rust_u2f_result* aResult)
{
UniquePtr<U2FResult> rv = MakeUnique<U2FResult>(aTransactionId, aResult);
StaticMutexAutoLock lock(gInstanceMutex);
if (!gInstance || NS_WARN_IF(!gPBackgroundThread)) {
return;
}
UniquePtr<U2FResult> rv = MakeUnique<U2FResult>(aTransactionId, aResult);
nsCOMPtr<nsIRunnable> r(NewRunnableMethod<UniquePtr<U2FResult>&&>(
"U2FHIDTokenManager::HandleRegisterResult", gInstance,
&U2FHIDTokenManager::HandleRegisterResult, Move(rv)));
@ -35,12 +36,13 @@ u2f_register_callback(uint64_t aTransactionId, rust_u2f_result* aResult)
static void
u2f_sign_callback(uint64_t aTransactionId, rust_u2f_result* aResult)
{
UniquePtr<U2FResult> rv = MakeUnique<U2FResult>(aTransactionId, aResult);
StaticMutexAutoLock lock(gInstanceMutex);
if (!gInstance || NS_WARN_IF(!gPBackgroundThread)) {
return;
}
UniquePtr<U2FResult> rv = MakeUnique<U2FResult>(aTransactionId, aResult);
nsCOMPtr<nsIRunnable> r(NewRunnableMethod<UniquePtr<U2FResult>&&>(
"U2FHIDTokenManager::HandleSignResult", gInstance,
&U2FHIDTokenManager::HandleSignResult, Move(rv)));
@ -218,6 +220,11 @@ U2FHIDTokenManager::HandleRegisterResult(UniquePtr<U2FResult>&& aResult)
MOZ_ASSERT(!mRegisterPromise.IsEmpty());
if (aResult->IsError()) {
mRegisterPromise.Reject(aResult->GetError(), __func__);
return;
}
nsTArray<uint8_t> registration;
if (!aResult->CopyRegistration(registration)) {
mRegisterPromise.Reject(NS_ERROR_DOM_UNKNOWN_ERR, __func__);
@ -241,6 +248,11 @@ U2FHIDTokenManager::HandleSignResult(UniquePtr<U2FResult>&& aResult)
MOZ_ASSERT(!mSignPromise.IsEmpty());
if (aResult->IsError()) {
mSignPromise.Reject(aResult->GetError(), __func__);
return;
}
nsTArray<uint8_t> appId;
if (!aResult->CopyAppId(appId)) {
mSignPromise.Reject(NS_ERROR_DOM_UNKNOWN_ERR, __func__);

View File

@ -64,12 +64,32 @@ public:
explicit U2FResult(uint64_t aTransactionId, rust_u2f_result* aResult)
: mTransactionId(aTransactionId)
, mResult(aResult)
{ }
{
MOZ_ASSERT(mResult);
}
~U2FResult() { rust_u2f_res_free(mResult); }
uint64_t GetTransactionId() { return mTransactionId; }
bool IsError() { return NS_FAILED(GetError()); }
nsresult GetError() {
switch (rust_u2f_result_error(mResult)) {
case U2F_ERROR_UKNOWN:
case U2F_ERROR_CONSTRAINT:
return NS_ERROR_DOM_UNKNOWN_ERR;
case U2F_ERROR_NOT_SUPPORTED:
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
case U2F_ERROR_INVALID_STATE:
return NS_ERROR_DOM_INVALID_STATE_ERR;
case U2F_ERROR_NOT_ALLOWED:
return NS_ERROR_DOM_NOT_ALLOWED_ERR;
default:
return NS_OK;
}
}
bool CopyRegistration(nsTArray<uint8_t>& aBuffer)
{
return CopyBuffer(U2F_RESBUF_ID_REGISTRATION, aBuffer);
@ -92,10 +112,6 @@ public:
private:
bool CopyBuffer(uint8_t aResBufID, nsTArray<uint8_t>& aBuffer) {
if (!mResult) {
return false;
}
size_t len;
if (!rust_u2f_resbuf_length(mResult, aResBufID, &len)) {
return false;

View File

@ -11,9 +11,13 @@ use U2FManager;
type U2FAppIds = Vec<::AppId>;
type U2FKeyHandles = Vec<::KeyHandle>;
type U2FResult = HashMap<u8, Vec<u8>>;
type U2FCallback = extern "C" fn(u64, *mut U2FResult);
pub enum U2FResult {
Success(HashMap<u8, Vec<u8>>),
Error(::Error),
}
const RESBUF_ID_REGISTRATION: u8 = 0;
const RESBUF_ID_KEYHANDLE: u8 = 1;
const RESBUF_ID_SIGNATURE: u8 = 2;
@ -90,6 +94,19 @@ pub unsafe extern "C" fn rust_u2f_khs_free(khs: *mut U2FKeyHandles) {
}
}
#[no_mangle]
pub unsafe extern "C" fn rust_u2f_result_error(res: *const U2FResult) -> u8 {
if res.is_null() {
return ::Error::Unknown as u8;
}
if let U2FResult::Error(ref err) = *res {
return *err as u8;
}
return 0; /* No error, the request succeeded. */
}
#[no_mangle]
pub unsafe extern "C" fn rust_u2f_resbuf_length(
res: *const U2FResult,
@ -100,9 +117,11 @@ pub unsafe extern "C" fn rust_u2f_resbuf_length(
return false;
}
if let Some(buf) = (*res).get(&bid) {
*len = buf.len();
return true;
if let U2FResult::Success(ref bufs) = *res {
if let Some(buf) = bufs.get(&bid) {
*len = buf.len();
return true;
}
}
false
@ -118,9 +137,11 @@ pub unsafe extern "C" fn rust_u2f_resbuf_copy(
return false;
}
if let Some(buf) = (*res).get(&bid) {
ptr::copy_nonoverlapping(buf.as_ptr(), dst, buf.len());
return true;
if let U2FResult::Success(ref bufs) = *res {
if let Some(buf) = bufs.get(&bid) {
ptr::copy_nonoverlapping(buf.as_ptr(), dst, buf.len());
return true;
}
}
false
@ -167,13 +188,16 @@ pub unsafe extern "C" fn rust_u2f_mgr_register(
application,
key_handles,
move |rv| {
if let Ok(registration) = rv {
let mut result = U2FResult::new();
result.insert(RESBUF_ID_REGISTRATION, registration);
callback(tid, Box::into_raw(Box::new(result)));
} else {
callback(tid, ptr::null_mut());
let result = match rv {
Ok(registration) => {
let mut bufs = HashMap::new();
bufs.insert(RESBUF_ID_REGISTRATION, registration);
U2FResult::Success(bufs)
}
Err(e) => U2FResult::Error(e),
};
callback(tid, Box::into_raw(Box::new(result)));
},
);
@ -216,15 +240,18 @@ pub unsafe extern "C" fn rust_u2f_mgr_sign(
let tid = new_tid();
let res = (*mgr).sign(flags, timeout, challenge, app_ids, key_handles, move |rv| {
if let Ok((app_id, key_handle, signature)) = rv {
let mut result = U2FResult::new();
result.insert(RESBUF_ID_KEYHANDLE, key_handle);
result.insert(RESBUF_ID_SIGNATURE, signature);
result.insert(RESBUF_ID_APPID, app_id);
callback(tid, Box::into_raw(Box::new(result)));
} else {
callback(tid, ptr::null_mut());
let result = match rv {
Ok((app_id, key_handle, signature)) => {
let mut bufs = HashMap::new();
bufs.insert(RESBUF_ID_KEYHANDLE, key_handle);
bufs.insert(RESBUF_ID_SIGNATURE, signature);
bufs.insert(RESBUF_ID_APPID, app_id);
U2FResult::Success(bufs)
}
Err(e) => U2FResult::Error(e),
};
callback(tid, Box::into_raw(Box::new(result)));
});
if res.is_ok() {

View File

@ -79,6 +79,15 @@ pub type AppId = Vec<u8>;
pub type RegisterResult = Vec<u8>;
pub type SignResult = (AppId, Vec<u8>, Vec<u8>);
#[derive(Debug, Clone, Copy)]
pub enum Error {
Unknown = 1,
NotSupported = 2,
InvalidState = 3,
ConstraintError = 4,
NotAllowed = 5,
}
#[cfg(fuzzing)]
pub use u2fprotocol::*;
#[cfg(fuzzing)]

View File

@ -11,7 +11,7 @@ use std::os::unix::prelude::*;
use consts::CID_BROADCAST;
use platform::hidraw;
use util::{from_unix_result, to_io_err};
use util::from_unix_result;
use u2ftypes::U2FDevice;
#[derive(Debug)]
@ -23,7 +23,7 @@ pub struct Device {
impl Device {
pub fn new(path: OsString) -> io::Result<Self> {
let cstr = CString::new(path.as_bytes()).map_err(to_io_err)?;
let cstr = CString::new(path.as_bytes())?;
let fd = unsafe { libc::open(cstr.as_ptr(), libc::O_RDWR) };
let fd = from_unix_result(fd)?;
Ok(Self {

View File

@ -5,8 +5,7 @@
use platform::monitor::Monitor;
use runloop::RunLoop;
use std::ffi::OsString;
use std::io;
use util::{io_err, OnceCallback};
use util::OnceCallback;
pub struct Transaction {
// Handle to the thread loop.
@ -14,7 +13,11 @@ pub struct Transaction {
}
impl Transaction {
pub fn new<F, T>(timeout: u64, callback: OnceCallback<T>, new_device_cb: F) -> io::Result<Self>
pub fn new<F, T>(
timeout: u64,
callback: OnceCallback<T>,
new_device_cb: F,
) -> Result<Self, ::Error>
where
F: Fn(OsString, &Fn() -> bool) + Sync + Send + 'static,
T: 'static,
@ -25,13 +28,13 @@ impl Transaction {
let mut monitor = Monitor::new(new_device_cb);
// Start polling for new devices.
try_or!(monitor.run(alive), |e| callback.call(Err(e)));
try_or!(monitor.run(alive), |_| callback.call(Err(::Error::Unknown)));
// Send an error, if the callback wasn't called already.
callback.call(Err(io_err("aborted or timed out")));
callback.call(Err(::Error::NotAllowed));
},
timeout,
)?;
).map_err(|_| ::Error::Unknown)?;
Ok(Self {
thread: Some(thread),

View File

@ -8,10 +8,9 @@ use core_foundation_sys::runloop::*;
use libc::c_void;
use platform::iokit::{CFRunLoopEntryObserver, IOHIDDeviceRef, SendableRunLoop};
use platform::monitor::Monitor;
use std::io;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread;
use util::{io_err, to_io_err, OnceCallback};
use util::OnceCallback;
// A transaction will run the given closure in a new thread, thereby using a
// separate per-thread state machine for each HID. It will either complete or
@ -23,7 +22,11 @@ pub struct Transaction {
}
impl Transaction {
pub fn new<F, T>(timeout: u64, callback: OnceCallback<T>, new_device_cb: F) -> io::Result<Self>
pub fn new<F, T>(
timeout: u64,
callback: OnceCallback<T>,
new_device_cb: F,
) -> Result<Self, ::Error>
where
F: Fn((IOHIDDeviceRef, Receiver<Vec<u8>>), &Fn() -> bool) + Sync + Send + 'static,
T: 'static,
@ -32,31 +35,33 @@ impl Transaction {
let timeout = (timeout as f64) / 1000.0;
let builder = thread::Builder::new();
let thread = builder.spawn(move || {
// Add a runloop observer that will be notified when we enter the
// runloop and tx.send() the current runloop to the owning thread.
// We need to ensure the runloop was entered before unblocking
// Transaction::new(), so we can always properly cancel.
let context = &tx as *const _ as *mut c_void;
let obs = CFRunLoopEntryObserver::new(Transaction::observe, context);
obs.add_to_current_runloop();
let thread = builder
.spawn(move || {
// Add a runloop observer that will be notified when we enter the
// runloop and tx.send() the current runloop to the owning thread.
// We need to ensure the runloop was entered before unblocking
// Transaction::new(), so we can always properly cancel.
let context = &tx as *const _ as *mut c_void;
let obs = CFRunLoopEntryObserver::new(Transaction::observe, context);
obs.add_to_current_runloop();
// Create a new HID device monitor and start polling.
let mut monitor = Monitor::new(new_device_cb);
try_or!(monitor.start(), |e| callback.call(Err(e)));
// Create a new HID device monitor and start polling.
let mut monitor = Monitor::new(new_device_cb);
try_or!(monitor.start(), |_| callback.call(Err(::Error::Unknown)));
// This will block until completion, abortion, or timeout.
unsafe { CFRunLoopRunInMode(kCFRunLoopDefaultMode, timeout, 0) };
// This will block until completion, abortion, or timeout.
unsafe { CFRunLoopRunInMode(kCFRunLoopDefaultMode, timeout, 0) };
// Close the monitor and its devices.
monitor.stop();
// Close the monitor and its devices.
monitor.stop();
// Send an error, if the callback wasn't called already.
callback.call(Err(io_err("aborted or timed out")));
})?;
// Send an error, if the callback wasn't called already.
callback.call(Err(::Error::NotAllowed));
})
.map_err(|_| ::Error::Unknown)?;
// Block until we enter the CFRunLoop.
let runloop = rx.recv().map_err(to_io_err)?;
let runloop = rx.recv().map_err(|_| ::Error::Unknown)?;
Ok(Self {
runloop: Some(runloop),

View File

@ -9,7 +9,7 @@ use std::time::Duration;
use consts::PARAMETER_SIZE;
use statemachine::StateMachine;
use runloop::RunLoop;
use util::{to_io_err, OnceCallback};
use util::OnceCallback;
enum QueueAction {
Register {
@ -105,24 +105,18 @@ impl U2FManager {
application: ::AppId,
key_handles: Vec<::KeyHandle>,
callback: F,
) -> io::Result<()>
) -> Result<(), ::Error>
where
F: FnOnce(io::Result<::RegisterResult>),
F: FnOnce(Result<::RegisterResult, ::Error>),
F: Send + 'static,
{
if challenge.len() != PARAMETER_SIZE || application.len() != PARAMETER_SIZE {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid parameter sizes",
));
return Err(::Error::Unknown);
}
for key_handle in &key_handles {
if key_handle.credential.len() > 256 {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Key handle too large",
));
return Err(::Error::Unknown);
}
}
@ -135,7 +129,7 @@ impl U2FManager {
key_handles,
callback,
};
self.tx.send(action).map_err(to_io_err)
self.tx.send(action).map_err(|_| ::Error::Unknown)
}
pub fn sign<F>(
@ -146,40 +140,28 @@ impl U2FManager {
app_ids: Vec<::AppId>,
key_handles: Vec<::KeyHandle>,
callback: F,
) -> io::Result<()>
) -> Result<(), ::Error>
where
F: FnOnce(io::Result<::SignResult>),
F: FnOnce(Result<::SignResult, ::Error>),
F: Send + 'static,
{
if challenge.len() != PARAMETER_SIZE {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid parameter sizes",
));
return Err(::Error::Unknown);
}
if app_ids.len() < 1 {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"No app IDs given",
));
return Err(::Error::Unknown);
}
for app_id in &app_ids {
if app_id.len() != PARAMETER_SIZE {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid app_id size",
));
return Err(::Error::Unknown);
}
}
for key_handle in &key_handles {
if key_handle.credential.len() > 256 {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Key handle too large",
));
return Err(::Error::Unknown);
}
}
@ -192,11 +174,13 @@ impl U2FManager {
key_handles,
callback,
};
self.tx.send(action).map_err(to_io_err)
self.tx.send(action).map_err(|_| ::Error::Unknown)
}
pub fn cancel(&self) -> io::Result<()> {
self.tx.send(QueueAction::Cancel).map_err(to_io_err)
pub fn cancel(&self) -> Result<(), ::Error> {
self.tx
.send(QueueAction::Cancel)
.map_err(|_| ::Error::Unknown)
}
}

View File

@ -7,7 +7,7 @@ use platform::device::Device;
use platform::transaction::Transaction;
use std::thread;
use std::time::Duration;
use util::{io_err, OnceCallback};
use util::OnceCallback;
use u2fprotocol::{u2f_init_device, u2f_is_keyhandle_valid, u2f_register, u2f_sign};
fn is_valid_transport(transports: ::AuthenticatorTransports) -> bool {
@ -99,7 +99,7 @@ impl StateMachine {
if excluded {
let blank = vec![0u8; PARAMETER_SIZE];
if let Ok(_) = u2f_register(dev, &blank, &blank) {
callback.call(Err(io_err("duplicate registration")));
callback.call(Err(::Error::InvalidState));
break;
}
} else {
@ -114,9 +114,7 @@ impl StateMachine {
}
});
self.transaction = Some(try_or!(transaction, |_| cbc.call(Err(io_err(
"couldn't create transaction"
)))));
self.transaction = Some(try_or!(transaction, |e| cbc.call(Err(e))));
}
pub fn sign(
@ -183,7 +181,7 @@ impl StateMachine {
if valid_handles.is_empty() {
let blank = vec![0u8; PARAMETER_SIZE];
if let Ok(_) = u2f_register(dev, &blank, &blank) {
callback.call(Err(io_err("invalid key")));
callback.call(Err(::Error::InvalidState));
break;
}
} else {
@ -206,9 +204,7 @@ impl StateMachine {
}
});
self.transaction = Some(try_or!(transaction, |_| cbc.call(Err(io_err(
"couldn't create transaction"
)))));
self.transaction = Some(try_or!(transaction, |e| cbc.call(Err(e))));
}
// This blocks.

View File

@ -2,18 +2,21 @@
* 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/. */
use std::io;
use util::{io_err, OnceCallback};
use util::OnceCallback;
pub struct Transaction {}
impl Transaction {
pub fn new<F, T>(timeout: u64, callback: OnceCallback<T>, new_device_cb: F) -> io::Result<Self>
pub fn new<F, T>(
timeout: u64,
callback: OnceCallback<T>,
new_device_cb: F,
) -> Result<Self, ::Error>
where
F: Fn(String, &Fn() -> bool),
{
callback.call(Err(io_err("not implemented")));
Err(io_err("not implemented"))
callback.call(Err(::Error::NotSupported));
Err(::Error::NotSupported)
}
pub fn cancel(&mut self) {

View File

@ -24,6 +24,12 @@ const uint8_t U2F_AUTHENTICATOR_TRANSPORT_USB = 1;
const uint8_t U2F_AUTHENTICATOR_TRANSPORT_NFC = 2;
const uint8_t U2F_AUTHENTICATOR_TRANSPORT_BLE = 4;
const uint8_t U2F_ERROR_UKNOWN = 1;
const uint8_t U2F_ERROR_NOT_SUPPORTED = 2;
const uint8_t U2F_ERROR_INVALID_STATE = 3;
const uint8_t U2F_ERROR_CONSTRAINT = 4;
const uint8_t U2F_ERROR_NOT_ALLOWED = 5;
// NOTE: Preconditions
// * All rust_u2f_mgr* pointers must refer to pointers which are returned
// by rust_u2f_mgr_new, and must be freed with rust_u2f_mgr_free.
@ -96,6 +102,9 @@ void rust_u2f_khs_add(rust_u2f_key_handles* khs,
/// U2FResult functions.
// Returns 0 for success, or the U2F_ERROR error code >= 1.
uint8_t rust_u2f_result_error(const rust_u2f_result *res);
// Call this before `[..]_copy()` to allocate enough space.
bool rust_u2f_resbuf_length(const rust_u2f_result *res, uint8_t bid, size_t* len);
bool rust_u2f_resbuf_copy(const rust_u2f_result *res, uint8_t bid, uint8_t* dst);

View File

@ -4,7 +4,6 @@
extern crate libc;
use std::error::Error;
use std::io;
use std::sync::{Arc, Mutex};
@ -49,18 +48,14 @@ pub fn io_err(msg: &str) -> io::Error {
io::Error::new(io::ErrorKind::Other, msg)
}
pub fn to_io_err<T: Error>(err: T) -> io::Error {
io_err(err.description())
}
pub struct OnceCallback<T> {
callback: Arc<Mutex<Option<SendBoxFnOnce<(io::Result<T>,)>>>>,
callback: Arc<Mutex<Option<SendBoxFnOnce<(Result<T, ::Error>,)>>>>,
}
impl<T> OnceCallback<T> {
pub fn new<F>(cb: F) -> Self
where
F: FnOnce(io::Result<T>),
F: FnOnce(Result<T, ::Error>),
F: Send + 'static,
{
let cb = Some(SendBoxFnOnce::from(cb));
@ -69,7 +64,7 @@ impl<T> OnceCallback<T> {
}
}
pub fn call(&self, rv: io::Result<T>) {
pub fn call(&self, rv: Result<T, ::Error>) {
if let Ok(mut cb) = self.callback.lock() {
if let Some(cb) = cb.take() {
cb.call(rv);

View File

@ -4,8 +4,7 @@
use platform::monitor::Monitor;
use runloop::RunLoop;
use std::io;
use util::{io_err, OnceCallback};
use util::OnceCallback;
pub struct Transaction {
// Handle to the thread loop.
@ -13,7 +12,11 @@ pub struct Transaction {
}
impl Transaction {
pub fn new<F, T>(timeout: u64, callback: OnceCallback<T>, new_device_cb: F) -> io::Result<Self>
pub fn new<F, T>(
timeout: u64,
callback: OnceCallback<T>,
new_device_cb: F,
) -> Result<Self, ::Error>
where
F: Fn(String, &Fn() -> bool) + Sync + Send + 'static,
T: 'static,
@ -24,13 +27,13 @@ impl Transaction {
let mut monitor = Monitor::new(new_device_cb);
// Start polling for new devices.
try_or!(monitor.run(alive), |e| callback.call(Err(e)));
try_or!(monitor.run(alive), |_| callback.call(Err(::Error::Unknown)));
// Send an error, if the callback wasn't called already.
callback.call(Err(io_err("aborted or timed out")));
callback.call(Err(::Error::NotAllowed));
},
timeout,
)?;
).map_err(|_| ::Error::Unknown)?;
Ok(Self {
thread: Some(thread),

View File

@ -14,6 +14,9 @@ interface CSSStyleDeclaration {
readonly attribute unsigned long length;
getter DOMString item(unsigned long index);
[Throws, ChromeOnly]
sequence<DOMString> getCSSImageURLs(DOMString property);
[Throws]
DOMString getPropertyValue(DOMString property);
// Mozilla extension, sort of

View File

@ -423,6 +423,11 @@ private:
return false;
}
// PerformanceStorage needs to be initialized on the worker thread before
// being used on main-thread. Let's be sure that it is created before any
// content loading.
aWorkerPrivate->EnsurePerformanceStorage();
ErrorResult rv;
workerinternals::LoadMainScript(aWorkerPrivate, mScriptURL, WorkerScript, rv);
rv.WouldReportJSException();
@ -3442,6 +3447,16 @@ WorkerPrivate::EnsureClientSource()
return true;
}
void
WorkerPrivate::EnsurePerformanceStorage()
{
AssertIsOnWorkerThread();
if (!mPerformanceStorage) {
mPerformanceStorage = PerformanceStorageWorker::Create(this);
}
}
const ClientInfo&
WorkerPrivate::GetClientInfo() const
{
@ -5268,11 +5283,7 @@ PerformanceStorage*
WorkerPrivate::GetPerformanceStorage()
{
AssertIsOnMainThread();
if (!mPerformanceStorage) {
mPerformanceStorage = PerformanceStorageWorker::Create(this);
}
MOZ_ASSERT(mPerformanceStorage);
return mPerformanceStorage;
}

View File

@ -559,6 +559,9 @@ public:
bool
EnsureClientSource();
void
EnsurePerformanceStorage();
const ClientInfo&
GetClientInfo() const;

View File

@ -23,7 +23,7 @@ class ReleaseRefControlRunnable final : public WorkerControlRunnable
public:
ReleaseRefControlRunnable(WorkerPrivate* aWorkerPrivate,
already_AddRefed<StrongWorkerRef> aRef)
: WorkerControlRunnable(aWorkerPrivate,WorkerThreadUnchangedBusyCount)
: WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
, mRef(Move(aRef))
{
MOZ_ASSERT(mRef);
@ -68,7 +68,13 @@ public:
bool
Notify(WorkerStatus aStatus) override
{
mWorkerRef->Notify();
MOZ_ASSERT(mWorkerRef);
// Let's keep this object alive for the whole Notify() execution.
RefPtr<WorkerRef> workerRef;
workerRef = mWorkerRef;
workerRef->Notify();
return true;
}
@ -150,11 +156,16 @@ WeakWorkerRef::Notify()
WorkerPrivate*
WeakWorkerRef::GetPrivate() const
{
MOZ_ASSERT(mHolder);
NS_ASSERT_OWNINGTHREAD(WeakWorkerRef);
return mWorkerPrivate;
}
WorkerPrivate*
WeakWorkerRef::GetUnsafePrivate() const
{
return mWorkerPrivate;
}
// ----------------------------------------------------------------------------
// StrongWorkerRef
@ -206,8 +217,9 @@ ThreadSafeWorkerRef::~ThreadSafeWorkerRef()
{
// Let's release the StrongWorkerRef on the correct thread.
if (!mRef->mWorkerPrivate->IsOnWorkerThread()) {
WorkerPrivate* workerPrivate = mRef->mWorkerPrivate;
RefPtr<ReleaseRefControlRunnable> r =
new ReleaseRefControlRunnable(mRef->mWorkerPrivate, mRef.forget());
new ReleaseRefControlRunnable(workerPrivate, mRef.forget());
r->Dispatch();
return;
}

View File

@ -115,6 +115,11 @@ public:
WorkerPrivate*
GetPrivate() const;
// This can be called on any thread. It's racy and, in general, the wrong
// choice.
WorkerPrivate*
GetUnsafePrivate() const;
private:
explicit WeakWorkerRef(WorkerPrivate* aWorkerPrivate);
~WeakWorkerRef();

View File

@ -1,4 +1,4 @@
52537
52547
0/nm
0th/pt
1/n1
@ -23236,8 +23236,10 @@ distinguishable/I
distinguished/U
distort/GDR
distortion/MS
distract/DG
distract/DGB
distractability
distracted/Y
distractible
distraction/S
distrait
distraught
@ -29829,6 +29831,7 @@ horizontal/SMY
hormonal
hormone/SM
horn/MDS
hornbeam/S
hornblende/M
hornet/MS
hornless
@ -30504,6 +30507,7 @@ immutable
immutably
imp/SMR
impact/SMDG
impactful
impair/SDGL
impaired/U
impairment/MS
@ -32194,6 +32198,8 @@ keratitis
kerbside
kerchief/SM
kerfuffle/S
kern/G
kerne
kernel/SM
kerosene/M
kestrel/MS
@ -36058,6 +36064,7 @@ neat/NRYPXT
neaten/GD
neath
neatness/M
neato
nebula/M
nebulae
nebular
@ -41860,6 +41867,7 @@ recognizably
recognize/DRSGB
recognized/U
recombination
recommender/S
recompense/DSMG
recompile/GD
recon/S
@ -42321,6 +42329,7 @@ repurchase/GDS
reputability/M
reputably/E
reputation/MS
reputational
repute/DSMGB
reputed/Y
request/GDR
@ -51994,6 +52003,7 @@ wizardry/M
wizened
wk/Y
woad/M
woah
wobble/MGDS
wobbliness/M
wobbly/RTP

View File

@ -143,9 +143,8 @@ CopyableCanvasRenderer::ReadbackSurface()
SharedSurface* frontbuffer = nullptr;
if (mGLFrontbuffer) {
frontbuffer = mGLFrontbuffer.get();
} else {
GLScreenBuffer* screen = mGLContext->Screen();
const auto& front = screen->Front();
} else if (mGLContext->Screen()) {
const auto& front = mGLContext->Screen()->Front();
if (front) {
frontbuffer = front->Surf();
}

View File

@ -59,42 +59,33 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1414336
</div>
<script type="text/javascript">
/** Test for Bug 1414336 **/
if (isApzEnabled()) {
SimpleTest.waitForExplicitFinish();
waitUntilApzStable().then(() => {
let target0 = window.document.getElementById("target0");
let target0_events = ["pointerdown", "pointermove"];
waitUntilApzStable().then(() => {
let isWindows = (getPlatform() == "windows");
SpecialPowers.pushPrefEnv({"set": [["dom.w3c_pointer_events.enabled", true],
["apz.test.fails_with_native_injection", isWindows]]}, () => {
let target0 = window.document.getElementById("target0");
let target0_events = ["pointerdown", "pointermove"];
target0_events.forEach((elem, index, arr) => {
target0.addEventListener(elem, (event) => {
is(event.type, target0_events[0], "receive " + event.type + " on target0");
target0_events.shift();
}, { once: true });
});
target0.addEventListener("pointercancel", (event) => {
ok(false, "Shouldn't receive pointercancel when content prevents default on touchstart");
SimpleTest.finish();
}, { once: true });
target0.addEventListener("touchstart", (event) => {
event.preventDefault();
}, { once: true });
target0.addEventListener("pointerup", (event) => {
ok(target0_events.length == 0, " should receive " + target0_events + " on target0");
SimpleTest.finish();
}, { once: true });
synthesizeNativeTouchDrag(target0, 2, 2, 0, 80);
});
target0_events.forEach((elem, index, arr) => {
target0.addEventListener(elem, (event) => {
is(event.type, target0_events[0], "receive " + event.type + " on target0");
target0_events.shift();
}, { once: true });
});
}
target0.addEventListener("pointercancel", (event) => {
ok(false, "Shouldn't receive pointercancel when content prevents default on touchstart");
subtestDone();
}, { once: true });
target0.addEventListener("touchstart", (event) => {
event.preventDefault();
}, { once: true });
target0.addEventListener("pointerup", (event) => {
ok(target0_events.length == 0, " should receive " + target0_events + " on target0");
subtestDone();
}, { once: true });
synthesizeNativeTouchDrag(target0, 2, 2, 0, 80);
});
</script>
</body>

View File

@ -12,6 +12,7 @@
helper_bug1285070.html
helper_bug1299195.html
helper_bug1346632.html
helper_bug1414336.html
helper_click.html
helper_div_pan.html
helper_drag_click.html

View File

@ -11,9 +11,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1285070
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
let isWindows = navigator.platform.indexOf("Win") == 0;
var subtests = [
{'file': 'helper_bug1285070.html', 'prefs': [["dom.w3c_pointer_events.enabled", true]]},
{'file': 'helper_bug1299195.html', 'prefs': [["dom.w3c_pointer_events.enabled", true]]}
{'file': 'helper_bug1299195.html', 'prefs': [["dom.w3c_pointer_events.enabled", true]]},
{'file': 'helper_bug1414336.html', 'prefs': [
["dom.w3c_pointer_events.enabled", true],
["apz.test.fails_with_native_injection", isWindows]
]}
];
if (isApzEnabled()) {

View File

@ -319,7 +319,9 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable,
static uint64_t sNextID = 1;
uint64_t id = sNextID++;
{
// ImageClient of ImageContainer provides aImageContainer.
// But offscreen canvas does not provide it.
if (aImageContainer) {
MutexAutoLock lock(mContainerMapLock);
MOZ_ASSERT(!mImageContainerListeners.Contains(id));
mImageContainerListeners.Put(id, aImageContainer->GetImageContainerListener());

View File

@ -154,12 +154,6 @@ WebRenderLayerManager::GetCompositorBridgeChild()
return WrBridge()->GetCompositorBridgeChild();
}
int32_t
WebRenderLayerManager::GetMaxTextureSize() const
{
return WrBridge()->GetMaxTextureSize();
}
bool
WebRenderLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
{

View File

@ -63,7 +63,8 @@ public:
WebRenderLayerManager* AsWebRenderLayerManager() override { return this; }
virtual CompositorBridgeChild* GetCompositorBridgeChild() override;
virtual int32_t GetMaxTextureSize() const override;
// WebRender can handle images larger than the max texture size via tiling.
virtual int32_t GetMaxTextureSize() const override { return INT32_MAX; }
virtual bool BeginTransactionWithTarget(gfxContext* aTarget) override;
virtual bool BeginTransaction() override;

View File

@ -228,7 +228,6 @@ def generate_separated_sources(platform_sources):
'SkDumpCanvas',
'SkFrontBufferedStream',
'SkInterpolator',
'SkMD5',
'SkMultiPictureDocument',
'SkNullCanvas',
'SkNWayCanvas',
@ -281,9 +280,7 @@ def generate_separated_sources(platform_sources):
'arm': set(),
'arm64': set(),
'none': set(),
'pdf': {
'skia/src/core/SkMD5.cpp',
},
'pdf': set(),
'gpu': set()
})

View File

@ -108,6 +108,7 @@ UNIFIED_SOURCES += [
'skia/src/core/SkMaskGamma.cpp',
'skia/src/core/SkMath.cpp',
'skia/src/core/SkMatrixImageFilter.cpp',
'skia/src/core/SkMD5.cpp',
'skia/src/core/SkMetaData.cpp',
'skia/src/core/SkMipMap.cpp',
'skia/src/core/SkModeColorFilter.cpp',
@ -335,7 +336,6 @@ SOURCES['skia/src/jumper/SkJumper_stages.cpp'].flags += skia_opt_flags
SOURCES['skia/src/jumper/SkJumper_stages_lowp.cpp'].flags += skia_opt_flags
if CONFIG['MOZ_ENABLE_SKIA_PDF']:
UNIFIED_SOURCES += [
'skia/src/core/SkMD5.cpp',
'skia/src/pdf/SkDeflate.cpp',
'skia/src/pdf/SkJpegInfo.cpp',
'skia/src/pdf/SkKeyedImage.cpp',

View File

@ -15,7 +15,6 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Tuple.h"
#include "nsIDOMEvent.h"
@ -860,13 +859,20 @@ VectorImage::GetImageContainerSize(LayerManager* aManager,
NS_IMETHODIMP_(bool)
VectorImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
{
return false;
if (mError || !mIsFullyLoaded || mHaveAnimations ||
aManager->GetBackendType() != LayersBackend::LAYERS_WR) {
return false;
}
return true;
}
//******************************************************************************
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
VectorImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
{
MOZ_ASSERT(aManager->GetBackendType() != LayersBackend::LAYERS_WR,
"WebRender should always use GetImageContainerAvailableAtSize!");
return nullptr;
}
@ -876,14 +882,9 @@ VectorImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
const IntSize& aSize,
uint32_t aFlags)
{
if (mError || !mIsFullyLoaded || aSize.IsEmpty() ||
mHaveAnimations || !gfxVars::GetUseWebRenderOrDefault()) {
return false;
}
int32_t maxTextureSize = aManager->GetMaxTextureSize();
return aSize.width <= maxTextureSize &&
aSize.height <= maxTextureSize;
// Since we only support image containers with WebRender, and it can handle
// textures larger than the hw max texture size, we don't need to check aSize.
return !aSize.IsEmpty() && IsImageContainerAvailable(aManager, aFlags);
}
//******************************************************************************

View File

@ -18,6 +18,7 @@
#include "GeckoProfiler.h"
#include "MainThreadUtils.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/Tools.h"
#include "mozilla/gfx/SourceSurfaceRawData.h"
#include "mozilla/layers/SourceSurfaceSharedData.h"

View File

@ -26,12 +26,12 @@
# RUN TESTS NOT AFFECTED BY DOWNSCALE-DURING-DECODE:
# ==================================================
fuzzy-if(skiaContent,14,416) fails-if(webrender) == downscale-svg-1a.html downscale-svg-1-ref.html?80
fuzzy(80,468) == downscale-svg-1b.html downscale-svg-1-ref.html?72
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),1,62) fuzzy-if(skiaContent,8,292) == downscale-svg-1c.html downscale-svg-1-ref.html?64
fuzzy(17,208) == downscale-svg-1d.html downscale-svg-1-ref.html?53
fuzzy(80,216) fuzzy-if(skiaContent,110,181) == downscale-svg-1e.html downscale-svg-1-ref.html?40
fuzzy(51,90) fuzzy-if(skiaContent,142,77) == downscale-svg-1f.html downscale-svg-1-ref.html?24
fuzzy-if(skiaContent,14,416) fuzzy-if(webrender,102-102,396-396) == downscale-svg-1a.html downscale-svg-1-ref.html?80
fuzzy(80,468) fuzzy-if(webrender,65-65,579-579) == downscale-svg-1b.html downscale-svg-1-ref.html?72
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),1,62) fuzzy-if(skiaContent,8,292) fuzzy-if(webrender,14-14,316-316) == downscale-svg-1c.html downscale-svg-1-ref.html?64
fuzzy(17,208) fuzzy-if(webrender,83-83,325-325) == downscale-svg-1d.html downscale-svg-1-ref.html?53
fuzzy(80,216) fuzzy-if(skiaContent,110,181) fuzzy-if(webrender,84-84,216-216) == downscale-svg-1e.html downscale-svg-1-ref.html?40
fuzzy(51,90) fuzzy-if(skiaContent,142,77) fuzzy-if(webrender,62-62,98-98) == downscale-svg-1f.html downscale-svg-1-ref.html?24
# RUN TESTS WITH DOWNSCALE-DURING-DECODE DISABLED:
# ================================================

View File

@ -0,0 +1,57 @@
# 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/.
# This script generates jit/LOpcodes.h (list of LIR instructions) and
# jit/MOpcodes.h (list of MIR instructions) from MIR.h and LIR files.
import re
HEADER_TEMPLATE = """\
/* 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 %(includeguard)s
#define %(includeguard)s
/* This file is generated by jit/GenerateOpcodeFiles.py. Do not edit! */
#define %(listname)s(_) \\
%(ops)s
#endif // %(includeguard)s
"""
def get_opcodes(inputs, pat):
# Preserve the original order. Use a set to detect duplicates.
ops = []
ops_set = set()
for inputfile in inputs:
for line in open(inputfile):
match = pat.match(line)
if match:
op = match.group('name')
if op in ops_set:
raise Exception("Duplicate opcode {} in {}".format(op, inputfile))
ops.append(op)
ops_set.add(op)
assert len(ops) == len(ops_set)
return ops
def generate_header(c_out, inputs, pat, includeguard, listname):
ops = get_opcodes(inputs, pat)
ops_string = '\\\n'.join(['_(' + op + ')' for op in ops])
c_out.write(HEADER_TEMPLATE % {
'ops': ops_string,
'includeguard': includeguard,
'listname': listname,
})
def generate_mir_header(c_out, *inputs):
pat = re.compile(r"^\s*INSTRUCTION_HEADER(_WITHOUT_TYPEPOLICY)?\((?P<name>\w+)\);?$")
generate_header(c_out, inputs, pat, 'jit_MOpcodes_h', 'MIR_OPCODE_LIST')
def generate_lir_header(c_out, *inputs):
pat = re.compile(r"^\s*LIR_HEADER\((?P<name>\w+)\);?$")
generate_header(c_out, inputs, pat, 'jit_LOpcodes_h', 'LIR_OPCODE_LIST')

View File

@ -800,6 +800,7 @@ class LNode
LIR_OPCODE_LIST(LIROP)
#undef LIROP
// Note: GenerateOpcodeFiles.py generates LOpcodes.h based on this macro.
#define LIR_HEADER(opcode) \
static constexpr LNode::Opcode classOpcode = LNode::Opcode::opcode;
};

View File

@ -1,32 +0,0 @@
/* -*- 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 jit_LOpcodes_h
#define jit_LOpcodes_h
#if defined(JS_CODEGEN_X86)
# include "jit/x86/LOpcodes-x86.h"
#elif defined(JS_CODEGEN_X64)
# include "jit/x64/LOpcodes-x64.h"
#elif defined(JS_CODEGEN_ARM)
# include "jit/arm/LOpcodes-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/LOpcodes-arm64.h"
#elif defined(JS_CODEGEN_MIPS32)
# include "jit/mips32/LOpcodes-mips32.h"
#elif defined(JS_CODEGEN_MIPS64)
# include "jit/mips64/LOpcodes-mips64.h"
#elif defined(JS_CODEGEN_NONE)
# include "jit/none/LOpcodes-none.h"
#else
# error "Unknown architecture!"
#endif
#define LIR_OPCODE_LIST(_) \
LIR_COMMON_OPCODE_LIST(_) \
LIR_CPU_OPCODE_LIST(_)
#endif /* jit_LOpcodes_h */

View File

@ -41,6 +41,20 @@ class StringObject;
namespace jit {
// Forward declarations of MIR types.
#define FORWARD_DECLARE(op) class M##op;
MIR_OPCODE_LIST(FORWARD_DECLARE)
#undef FORWARD_DECLARE
// MDefinition visitor which ignores non-overloaded visit functions.
class MDefinitionVisitorDefaultNoop
{
public:
#define VISIT_INS(op) void visit##op(M##op*) { }
MIR_OPCODE_LIST(VISIT_INS)
#undef VISIT_INS
};
class BaselineInspector;
class Range;
@ -1208,6 +1222,8 @@ class MInstruction
virtual MIRType typePolicySpecialization() = 0;
};
// Note: GenerateOpcodeFiles.py generates MOpcodes.h based on the
// INSTRUCTION_HEADER* macros.
#define INSTRUCTION_HEADER_WITHOUT_TYPEPOLICY(opcode) \
static const Opcode classOpcode = Opcode::opcode; \
using MThisOpcode = M##opcode;

View File

@ -1,353 +0,0 @@
/* -*- 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 jit_MOpcodes_h
#define jit_MOpcodes_h
namespace js {
namespace jit {
#define MIR_OPCODE_LIST(_) \
_(Constant) \
_(SimdBox) \
_(SimdUnbox) \
_(SimdValueX4) \
_(SimdSplat) \
_(SimdConstant) \
_(SimdConvert) \
_(SimdReinterpretCast) \
_(SimdExtractElement) \
_(SimdInsertElement) \
_(SimdSwizzle) \
_(SimdGeneralShuffle) \
_(SimdShuffle) \
_(SimdUnaryArith) \
_(SimdBinaryComp) \
_(SimdBinaryArith) \
_(SimdBinarySaturating) \
_(SimdBinaryBitwise) \
_(SimdShift) \
_(SimdSelect) \
_(SimdAllTrue) \
_(SimdAnyTrue) \
_(CloneLiteral) \
_(Parameter) \
_(Callee) \
_(IsConstructing) \
_(TableSwitch) \
_(Goto) \
_(Test) \
_(GotoWithFake) \
_(ObjectGroupDispatch) \
_(FunctionDispatch) \
_(Compare) \
_(SameValue) \
_(Phi) \
_(Beta) \
_(NaNToZero) \
_(OsrValue) \
_(OsrEnvironmentChain) \
_(OsrReturnValue) \
_(OsrArgumentsObject) \
_(ReturnFromCtor) \
_(BinarySharedStub) \
_(UnarySharedStub) \
_(NullarySharedStub) \
_(CheckOverRecursed) \
_(DefVar) \
_(DefLexical) \
_(DefFun) \
_(CreateThis) \
_(CreateThisWithProto) \
_(CreateThisWithTemplate) \
_(CreateArgumentsObject) \
_(GetArgumentsObjectArg) \
_(SetArgumentsObjectArg) \
_(ComputeThis) \
_(ImplicitThis) \
_(Call) \
_(ApplyArgs) \
_(ApplyArray) \
_(Bail) \
_(Unreachable) \
_(EncodeSnapshot) \
_(AssertFloat32) \
_(AssertRecoveredOnBailout) \
_(GetDynamicName) \
_(CallDirectEval) \
_(BitNot) \
_(TypeOf) \
_(ToAsync) \
_(ToAsyncGen) \
_(ToAsyncIter) \
_(ToId) \
_(BitAnd) \
_(BitOr) \
_(BitXor) \
_(Lsh) \
_(Rsh) \
_(Ursh) \
_(SignExtendInt32) \
_(SignExtendInt64) \
_(MinMax) \
_(Abs) \
_(Clz) \
_(Ctz) \
_(Popcnt) \
_(Sqrt) \
_(Atan2) \
_(Hypot) \
_(Pow) \
_(PowHalf) \
_(Random) \
_(MathFunction) \
_(Add) \
_(Sub) \
_(Mul) \
_(Div) \
_(Mod) \
_(Concat) \
_(CharCodeAt) \
_(FromCharCode) \
_(FromCodePoint) \
_(StringConvertCase) \
_(SinCos) \
_(StringSplit) \
_(Substr) \
_(Return) \
_(Throw) \
_(Box) \
_(Unbox) \
_(GuardObject) \
_(GuardString) \
_(PolyInlineGuard) \
_(AssertRange) \
_(ToDouble) \
_(ToFloat32) \
_(ToNumberInt32) \
_(TruncateToInt32) \
_(WrapInt64ToInt32) \
_(ExtendInt32ToInt64) \
_(Int64ToFloatingPoint) \
_(ToString) \
_(ToObject) \
_(ToObjectOrNull) \
_(NewArray) \
_(NewArrayCopyOnWrite) \
_(NewArrayDynamicLength) \
_(NewIterator) \
_(NewTypedArray) \
_(NewTypedArrayDynamicLength) \
_(NewObject) \
_(NewTypedObject) \
_(NewNamedLambdaObject) \
_(NewCallObject) \
_(NewSingletonCallObject) \
_(NewStringObject) \
_(ObjectState) \
_(ArrayState) \
_(ArgumentState) \
_(InitElem) \
_(InitElemGetterSetter) \
_(MutateProto) \
_(InitPropGetterSetter) \
_(Start) \
_(OsrEntry) \
_(Nop) \
_(LimitedTruncate) \
_(RegExp) \
_(RegExpMatcher) \
_(RegExpSearcher) \
_(RegExpTester) \
_(RegExpPrototypeOptimizable) \
_(RegExpInstanceOptimizable) \
_(GetFirstDollarIndex) \
_(StringReplace) \
_(ClassConstructor) \
_(Lambda) \
_(LambdaArrow) \
_(SetFunName) \
_(KeepAliveObject) \
_(Slots) \
_(Elements) \
_(ConstantElements) \
_(ConvertElementsToDoubles) \
_(MaybeToDoubleElement) \
_(MaybeCopyElementsForWrite) \
_(LoadSlot) \
_(StoreSlot) \
_(FunctionEnvironment) \
_(NewLexicalEnvironmentObject) \
_(CopyLexicalEnvironmentObject) \
_(HomeObject) \
_(HomeObjectSuperBase) \
_(FilterTypeSet) \
_(TypeBarrier) \
_(PostWriteBarrier) \
_(PostWriteElementBarrier) \
_(GetPropSuperCache) \
_(GetPropertyCache) \
_(GetPropertyPolymorphic) \
_(SetPropertyPolymorphic) \
_(BindNameCache) \
_(CallBindVar) \
_(GuardShape) \
_(GuardReceiverPolymorphic) \
_(GuardObjectGroup) \
_(GuardObjectIdentity) \
_(GuardUnboxedExpando) \
_(LoadUnboxedExpando) \
_(ArrayLength) \
_(SetArrayLength) \
_(GetNextEntryForIterator) \
_(TypedArrayLength) \
_(TypedArrayElements) \
_(SetDisjointTypedElements) \
_(TypedObjectDescr) \
_(TypedObjectElements) \
_(SetTypedObjectOffset) \
_(InitializedLength) \
_(SetInitializedLength) \
_(Not) \
_(BoundsCheck) \
_(BoundsCheckLower) \
_(SpectreMaskIndex) \
_(InArray) \
_(LoadElement) \
_(LoadElementHole) \
_(LoadUnboxedScalar) \
_(LoadUnboxedObjectOrNull) \
_(LoadUnboxedString) \
_(LoadElementFromState) \
_(StoreElement) \
_(StoreElementHole) \
_(FallibleStoreElement) \
_(StoreUnboxedScalar) \
_(StoreUnboxedObjectOrNull) \
_(StoreUnboxedString) \
_(ConvertUnboxedObjectToNative) \
_(ArrayPopShift) \
_(ArrayPush) \
_(ArraySlice) \
_(ArrayJoin) \
_(LoadTypedArrayElementHole) \
_(LoadTypedArrayElementStatic) \
_(StoreTypedArrayElementHole) \
_(StoreTypedArrayElementStatic) \
_(AtomicIsLockFree) \
_(GuardSharedTypedArray) \
_(CompareExchangeTypedArrayElement) \
_(AtomicExchangeTypedArrayElement) \
_(AtomicTypedArrayElementBinop) \
_(EffectiveAddress) \
_(ClampToUint8) \
_(LoadFixedSlot) \
_(LoadFixedSlotAndUnbox) \
_(StoreFixedSlot) \
_(CallGetProperty) \
_(GetNameCache) \
_(CallGetIntrinsicValue) \
_(CallGetElement) \
_(CallSetElement) \
_(CallSetProperty) \
_(CallInitElementArray) \
_(DeleteProperty) \
_(DeleteElement) \
_(SetPropertyCache) \
_(GetIteratorCache) \
_(IteratorMore) \
_(IsNoIter) \
_(IteratorEnd) \
_(StringLength) \
_(ArgumentsLength) \
_(GetFrameArgument) \
_(SetFrameArgument) \
_(RunOncePrologue) \
_(Rest) \
_(Floor) \
_(Ceil) \
_(Round) \
_(NearbyInt) \
_(InCache) \
_(HasOwnCache) \
_(InstanceOf) \
_(InstanceOfCache) \
_(InterruptCheck) \
_(GetDOMProperty) \
_(GetDOMMember) \
_(SetDOMProperty) \
_(IsConstructor) \
_(IsCallable) \
_(IsArray) \
_(IsTypedArray) \
_(IsObject) \
_(HasClass) \
_(ObjectClassToString) \
_(CopySign) \
_(Rotate) \
_(NewDerivedTypedObject) \
_(RecompileCheck) \
_(UnknownValue) \
_(LexicalCheck) \
_(ThrowRuntimeLexicalError) \
_(GlobalNameConflictsCheck) \
_(Debugger) \
_(NewTarget) \
_(ArrowNewTarget) \
_(CheckReturn) \
_(CheckIsObj) \
_(CheckIsCallable) \
_(CheckObjCoercible) \
_(DebugCheckSelfHosted) \
_(FinishBoundFunctionInit) \
_(IsPackedArray) \
_(GetPrototypeOf) \
_(AsmJSLoadHeap) \
_(AsmJSStoreHeap) \
_(WasmCompareExchangeHeap) \
_(WasmAtomicExchangeHeap) \
_(WasmAtomicBinopHeap) \
_(WasmNeg) \
_(WasmBoundsCheck) \
_(WasmAlignmentCheck) \
_(WasmLoadTls) \
_(WasmAddOffset) \
_(WasmLoad) \
_(WasmStore) \
_(WasmTrap) \
_(WasmTruncateToInt32) \
_(WasmUnsignedToDouble) \
_(WasmUnsignedToFloat32) \
_(WasmLoadGlobalVar) \
_(WasmStoreGlobalVar) \
_(WasmReturn) \
_(WasmReturnVoid) \
_(WasmParameter) \
_(WasmStackArg) \
_(WasmCall) \
_(WasmSelect) \
_(WasmReinterpret) \
_(WasmFloatConstant) \
_(WasmTruncateToInt64)
// Forward declarations of MIR types.
#define FORWARD_DECLARE(op) class M##op;
MIR_OPCODE_LIST(FORWARD_DECLARE)
#undef FORWARD_DECLARE
// MDefinition visitor which ignores non-overloaded visit functions.
class MDefinitionVisitorDefaultNoop
{
public:
#define VISIT_INS(op) void visit##op(M##op*) { }
MIR_OPCODE_LIST(VISIT_INS)
#undef VISIT_INS
};
} // namespace jit
} // namespace js
#endif /* jit_MOpcodes_h */

View File

@ -1,34 +0,0 @@
/* -*- 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 jit_arm_LOpcodes_arm_h
#define jit_arm_LOpcodes_arm_h
#include "jit/shared/LOpcodes-shared.h"
#define LIR_CPU_OPCODE_LIST(_) \
_(BoxFloatingPoint) \
_(SoftDivI) \
_(SoftModI) \
_(ModMaskI) \
_(UDiv) \
_(UMod) \
_(SoftUDivOrMod) \
_(DivOrModI64) \
_(UDivOrModI64) \
_(WasmTruncateToInt64) \
_(WasmAtomicLoadI64) \
_(WasmAtomicStoreI64) \
_(WasmCompareExchangeI64) \
_(WasmAtomicBinopI64) \
_(WasmAtomicExchangeI64) \
_(WasmUnalignedLoad) \
_(WasmUnalignedStore) \
_(WasmUnalignedLoadI64) \
_(WasmUnalignedStoreI64) \
_(Int64ToFloatingPointCall)
#endif /* jit_arm_LOpcodes_arm_h */

View File

@ -1,20 +0,0 @@
/* -*- 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 jit_arm64_LOpcodes_arm64_h
#define jit_arm64_LOpcodes_arm64_h
#include "jit/shared/LOpcodes-shared.h"
#define LIR_CPU_OPCODE_LIST(_) \
_(SoftDivI) \
_(SoftModI) \
_(ModMaskI) \
_(UDiv) \
_(UMod) \
_(SoftUDivOrMod)
#endif /* jit_arm64_LOpcodes_arm64_h */

View File

@ -2824,3 +2824,11 @@ MacroAssembler::atomicEffectOpJS(Scalar::Type arrayType, const Synchronization&
atomicEffectOp(arrayType, sync, op, value, mem, valueTemp, offsetTemp, maskTemp);
}
// ========================================================================
// Spectre Mitigations.
void
MacroAssembler::speculationBarrier()
{
MOZ_CRASH();
}

View File

@ -1,30 +0,0 @@
/* -*- 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 jit_mips32_LOpcodes_mips32_h__
#define jit_mips32_LOpcodes_mips32_h__
#include "jit/shared/LOpcodes-shared.h"
#define LIR_CPU_OPCODE_LIST(_) \
_(BoxFloatingPoint) \
_(ModMaskI) \
_(UDivOrMod) \
_(DivOrModI64) \
_(UDivOrModI64) \
_(WasmUnalignedLoad) \
_(WasmUnalignedStore) \
_(WasmUnalignedLoadI64) \
_(WasmUnalignedStoreI64) \
_(WasmTruncateToInt64) \
_(Int64ToFloatingPoint) \
_(WasmCompareExchangeI64) \
_(WasmAtomicExchangeI64) \
_(WasmAtomicBinopI64) \
_(WasmAtomicLoadI64) \
_(WasmAtomicStoreI64) \
#endif // jit_mips32_LOpcodes_mips32_h__

View File

@ -1,27 +0,0 @@
/* -*- 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 jit_mips64_LOpcodes_mips64_h__
#define jit_mips64_LOpcodes_mips64_h__
#include "jit/shared/LOpcodes-shared.h"
#define LIR_CPU_OPCODE_LIST(_) \
_(ModMaskI) \
_(DivOrModI64) \
_(UDivOrMod) \
_(UDivOrModI64) \
_(WasmUnalignedLoad) \
_(WasmUnalignedStore) \
_(WasmUnalignedLoadI64) \
_(WasmUnalignedStoreI64) \
_(WasmTruncateToInt64) \
_(Int64ToFloatingPoint) \
_(WasmCompareExchangeI64) \
_(WasmAtomicExchangeI64) \
_(WasmAtomicBinopI64) \
#endif // jit_mips64_LOpcodes_mips64_h__

View File

@ -1,14 +0,0 @@
/* -*- 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 jit_none_LOpcodes_none_h__
#define jit_none_LOpcodes_none_h__
#include "jit/shared/LOpcodes-shared.h"
#define LIR_CPU_OPCODE_LIST(_)
#endif // jit_none_LOpcodes_none_h__

View File

@ -1,468 +0,0 @@
/* -*- 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 jit_shared_LOpcodes_shared_h
#define jit_shared_LOpcodes_shared_h
#define LIR_COMMON_OPCODE_LIST(_) \
_(Unbox) \
_(Box) \
_(UnboxFloatingPoint) \
_(OsiPoint) \
_(MoveGroup) \
_(Integer) \
_(Integer64) \
_(Pointer) \
_(Double) \
_(Float32) \
_(SimdBox) \
_(SimdUnbox) \
_(SimdSplatX16) \
_(SimdSplatX8) \
_(SimdSplatX4) \
_(Simd128Int) \
_(Simd128Float) \
_(SimdAllTrue) \
_(SimdAnyTrue) \
_(SimdReinterpretCast) \
_(SimdExtractElementI) \
_(SimdExtractElementU2D) \
_(SimdExtractElementB) \
_(SimdExtractElementF) \
_(SimdInsertElementI) \
_(SimdInsertElementF) \
_(SimdGeneralShuffleI) \
_(SimdGeneralShuffleF) \
_(SimdSwizzleI) \
_(SimdSwizzleF) \
_(SimdShuffle) \
_(SimdShuffleX4) \
_(SimdUnaryArithIx16) \
_(SimdUnaryArithIx8) \
_(SimdUnaryArithIx4) \
_(SimdUnaryArithFx4) \
_(SimdBinaryCompIx16) \
_(SimdBinaryCompIx8) \
_(SimdBinaryCompIx4) \
_(SimdBinaryCompFx4) \
_(SimdBinaryArithIx16) \
_(SimdBinaryArithIx8) \
_(SimdBinaryArithIx4) \
_(SimdBinaryArithFx4) \
_(SimdBinarySaturating) \
_(SimdBinaryBitwise) \
_(SimdShift) \
_(SimdSelect) \
_(Value) \
_(CloneLiteral) \
_(Parameter) \
_(Callee) \
_(IsConstructing) \
_(TableSwitch) \
_(TableSwitchV) \
_(Goto) \
_(NewArray) \
_(NewArrayCopyOnWrite) \
_(NewArrayDynamicLength) \
_(NewIterator) \
_(NewTypedArray) \
_(NewTypedArrayDynamicLength) \
_(NewObject) \
_(NewTypedObject) \
_(NewNamedLambdaObject) \
_(NewCallObject) \
_(NewSingletonCallObject) \
_(NewStringObject) \
_(NewDerivedTypedObject) \
_(InitElem) \
_(InitElemGetterSetter) \
_(MutateProto) \
_(InitPropGetterSetter) \
_(CheckOverRecursed) \
_(DefVar) \
_(DefLexical) \
_(DefFun) \
_(CallKnown) \
_(CallGeneric) \
_(CallNative) \
_(ApplyArgsGeneric) \
_(ApplyArrayGeneric) \
_(Bail) \
_(Unreachable) \
_(EncodeSnapshot) \
_(GetDynamicName) \
_(CallDirectEval) \
_(StackArgT) \
_(StackArgV) \
_(CreateThis) \
_(CreateThisWithProto) \
_(CreateThisWithTemplate) \
_(CreateArgumentsObject) \
_(GetArgumentsObjectArg) \
_(SetArgumentsObjectArg) \
_(ReturnFromCtor) \
_(ComputeThis) \
_(ImplicitThis) \
_(BitNotI) \
_(BitNotV) \
_(BitOpI) \
_(BitOpI64) \
_(BitOpV) \
_(ShiftI) \
_(ShiftI64) \
_(SignExtendInt32) \
_(SignExtendInt64) \
_(UrshD) \
_(Return) \
_(Throw) \
_(Phi) \
_(TestIAndBranch) \
_(TestI64AndBranch) \
_(TestDAndBranch) \
_(TestFAndBranch) \
_(TestVAndBranch) \
_(TestOAndBranch) \
_(FunctionDispatch) \
_(ObjectGroupDispatch) \
_(Compare) \
_(CompareAndBranch) \
_(CompareI64) \
_(CompareI64AndBranch) \
_(CompareD) \
_(CompareDAndBranch) \
_(CompareF) \
_(CompareFAndBranch) \
_(CompareS) \
_(CompareStrictS) \
_(CompareB) \
_(CompareBAndBranch) \
_(CompareBitwise) \
_(CompareBitwiseAndBranch) \
_(CompareVM) \
_(BitAndAndBranch) \
_(IsNullOrLikeUndefinedV) \
_(IsNullOrLikeUndefinedT) \
_(IsNullOrLikeUndefinedAndBranchV)\
_(IsNullOrLikeUndefinedAndBranchT)\
_(SameValueD) \
_(SameValueV) \
_(SameValueVM) \
_(MinMaxI) \
_(MinMaxD) \
_(MinMaxF) \
_(NegI) \
_(NegD) \
_(NegF) \
_(AbsI) \
_(AbsD) \
_(AbsF) \
_(ClzI) \
_(ClzI64) \
_(CtzI) \
_(CtzI64) \
_(PopcntI) \
_(PopcntI64) \
_(SqrtD) \
_(SqrtF) \
_(CopySignD) \
_(CopySignF) \
_(Atan2D) \
_(Hypot) \
_(PowI) \
_(PowD) \
_(PowV) \
_(PowHalfD) \
_(Random) \
_(MathFunctionD) \
_(MathFunctionF) \
_(NotI) \
_(NotI64) \
_(NotD) \
_(NotF) \
_(NotO) \
_(NotV) \
_(AddI) \
_(AddI64) \
_(SubI) \
_(SubI64) \
_(MulI) \
_(MulI64) \
_(MathD) \
_(MathF) \
_(DivI) \
_(DivPowTwoI) \
_(ModI) \
_(ModPowTwoI) \
_(ModD) \
_(BinaryV) \
_(Concat) \
_(CharCodeAt) \
_(FromCharCode) \
_(FromCodePoint) \
_(StringConvertCase) \
_(SinCos) \
_(StringSplit) \
_(Int32ToDouble) \
_(Float32ToDouble) \
_(DoubleToFloat32) \
_(Int32ToFloat32) \
_(ValueToDouble) \
_(ValueToInt32) \
_(ValueToFloat32) \
_(DoubleToInt32) \
_(Float32ToInt32) \
_(TruncateDToInt32) \
_(TruncateFToInt32) \
_(WrapInt64ToInt32) \
_(ExtendInt32ToInt64) \
_(BooleanToString) \
_(IntToString) \
_(DoubleToString) \
_(ValueToString) \
_(ValueToObject) \
_(ValueToObjectOrNull) \
_(Int32x4ToFloat32x4) \
_(Float32x4ToInt32x4) \
_(Float32x4ToUint32x4) \
_(Start) \
_(NaNToZero) \
_(OsrEntry) \
_(OsrValue) \
_(OsrEnvironmentChain) \
_(OsrReturnValue) \
_(OsrArgumentsObject) \
_(RegExp) \
_(RegExpMatcher) \
_(RegExpSearcher) \
_(RegExpTester) \
_(RegExpPrototypeOptimizable) \
_(RegExpInstanceOptimizable) \
_(GetFirstDollarIndex) \
_(StringReplace) \
_(Substr) \
_(BinarySharedStub) \
_(UnarySharedStub) \
_(NullarySharedStub) \
_(ClassConstructor) \
_(Lambda) \
_(LambdaArrow) \
_(LambdaForSingleton) \
_(SetFunName) \
_(KeepAliveObject) \
_(Slots) \
_(Elements) \
_(ConvertElementsToDoubles) \
_(MaybeToDoubleElement) \
_(MaybeCopyElementsForWrite) \
_(LoadSlotV) \
_(LoadSlotT) \
_(StoreSlotV) \
_(StoreSlotT) \
_(GuardShape) \
_(GuardReceiverPolymorphic) \
_(GuardObjectGroup) \
_(GuardObjectIdentity) \
_(GuardUnboxedExpando) \
_(LoadUnboxedExpando) \
_(TypeBarrierV) \
_(TypeBarrierO) \
_(PostWriteBarrierO) \
_(PostWriteBarrierS) \
_(PostWriteBarrierV) \
_(PostWriteElementBarrierO) \
_(PostWriteElementBarrierS) \
_(PostWriteElementBarrierV) \
_(InitializedLength) \
_(SetInitializedLength) \
_(BoundsCheck) \
_(BoundsCheckRange) \
_(BoundsCheckLower) \
_(SpectreMaskIndex) \
_(LoadElementV) \
_(LoadElementT) \
_(LoadElementHole) \
_(LoadUnboxedScalar) \
_(LoadUnboxedPointerV) \
_(LoadUnboxedPointerT) \
_(LoadElementFromStateV) \
_(UnboxObjectOrNull) \
_(StoreElementV) \
_(StoreElementT) \
_(StoreUnboxedScalar) \
_(StoreUnboxedPointer) \
_(ConvertUnboxedObjectToNative) \
_(ArrayPopShiftV) \
_(ArrayPopShiftT) \
_(ArrayPushV) \
_(ArrayPushT) \
_(ArraySlice) \
_(ArrayJoin) \
_(StoreElementHoleV) \
_(StoreElementHoleT) \
_(FallibleStoreElementV) \
_(FallibleStoreElementT) \
_(LoadTypedArrayElementHole) \
_(LoadTypedArrayElementStatic) \
_(StoreTypedArrayElementHole) \
_(StoreTypedArrayElementStatic) \
_(AtomicIsLockFree) \
_(GuardSharedTypedArray) \
_(CompareExchangeTypedArrayElement) \
_(AtomicExchangeTypedArrayElement) \
_(AtomicTypedArrayElementBinop) \
_(AtomicTypedArrayElementBinopForEffect) \
_(EffectiveAddress) \
_(ClampIToUint8) \
_(ClampDToUint8) \
_(ClampVToUint8) \
_(LoadFixedSlotV) \
_(LoadFixedSlotT) \
_(LoadFixedSlotAndUnbox) \
_(StoreFixedSlotV) \
_(StoreFixedSlotT) \
_(FunctionEnvironment) \
_(NewLexicalEnvironmentObject) \
_(CopyLexicalEnvironmentObject) \
_(HomeObject) \
_(HomeObjectSuperBase) \
_(GetPropSuperCacheV) \
_(GetPropertyCacheV) \
_(GetPropertyCacheT) \
_(GetPropertyPolymorphicV) \
_(GetPropertyPolymorphicT) \
_(BindNameCache) \
_(CallBindVar) \
_(CallGetProperty) \
_(GetNameCache) \
_(CallGetIntrinsicValue) \
_(CallGetElement) \
_(CallSetElement) \
_(CallInitElementArray) \
_(CallSetProperty) \
_(CallDeleteProperty) \
_(CallDeleteElement) \
_(SetPropertyCache) \
_(SetPropertyPolymorphicV) \
_(SetPropertyPolymorphicT) \
_(GetIteratorCache) \
_(IteratorMore) \
_(IsNoIterAndBranch) \
_(IteratorEnd) \
_(ArrayLength) \
_(SetArrayLength) \
_(GetNextEntryForIterator) \
_(TypedArrayLength) \
_(TypedArrayElements) \
_(SetDisjointTypedElements) \
_(TypedObjectDescr) \
_(TypedObjectElements) \
_(SetTypedObjectOffset) \
_(StringLength) \
_(ArgumentsLength) \
_(GetFrameArgument) \
_(SetFrameArgumentT) \
_(SetFrameArgumentC) \
_(SetFrameArgumentV) \
_(RunOncePrologue) \
_(Rest) \
_(TypeOfV) \
_(ToAsync) \
_(ToAsyncGen) \
_(ToAsyncIter) \
_(ToIdV) \
_(Floor) \
_(FloorF) \
_(Ceil) \
_(CeilF) \
_(Round) \
_(RoundF) \
_(NearbyInt) \
_(NearbyIntF) \
_(InCache) \
_(InArray) \
_(HasOwnCache) \
_(InstanceOfO) \
_(InstanceOfV) \
_(InstanceOfCache) \
_(InterruptCheck) \
_(Rotate) \
_(RotateI64) \
_(GetDOMProperty) \
_(GetDOMMemberV) \
_(GetDOMMemberT) \
_(SetDOMProperty) \
_(CallDOMNative) \
_(IsCallableO) \
_(IsCallableV) \
_(IsConstructor) \
_(IsArrayO) \
_(IsArrayV) \
_(IsTypedArray) \
_(IsObject) \
_(IsObjectAndBranch) \
_(HasClass) \
_(ObjectClassToString) \
_(RecompileCheck) \
_(MemoryBarrier) \
_(AssertRangeI) \
_(AssertRangeD) \
_(AssertRangeF) \
_(AssertRangeV) \
_(AssertResultV) \
_(AssertResultT) \
_(LexicalCheck) \
_(ThrowRuntimeLexicalError) \
_(GlobalNameConflictsCheck) \
_(Debugger) \
_(NewTarget) \
_(ArrowNewTarget) \
_(CheckReturn) \
_(CheckIsObj) \
_(CheckIsCallable) \
_(CheckObjCoercible) \
_(DebugCheckSelfHosted) \
_(FinishBoundFunctionInit) \
_(IsPackedArray) \
_(GetPrototypeOf) \
_(AsmJSLoadHeap) \
_(AsmJSStoreHeap) \
_(WasmCompareExchangeHeap) \
_(WasmAtomicExchangeHeap) \
_(WasmAtomicBinopHeap) \
_(WasmAtomicBinopHeapForEffect) \
_(WasmTruncateToInt32) \
_(WasmTrap) \
_(WasmReinterpret) \
_(WasmReinterpretToI64) \
_(WasmReinterpretFromI64) \
_(WasmSelect) \
_(WasmSelectI64) \
_(WasmBoundsCheck) \
_(WasmAlignmentCheck) \
_(WasmLoadTls) \
_(WasmAddOffset) \
_(WasmLoad) \
_(WasmLoadI64) \
_(WasmStore) \
_(WasmStoreI64) \
_(WasmLoadGlobalVar) \
_(WasmLoadGlobalVarI64) \
_(WasmStoreGlobalVar) \
_(WasmStoreGlobalVarI64) \
_(WasmParameter) \
_(WasmParameterI64) \
_(WasmReturn) \
_(WasmReturnI64) \
_(WasmReturnVoid) \
_(WasmStackArg) \
_(WasmStackArgI64) \
_(WasmCall) \
_(WasmCallVoid) \
_(WasmCallI64) \
_(WasmUint32ToDouble) \
_(WasmUint32ToFloat32)
#endif /* jit_shared_LOpcodes_shared_h */

View File

@ -1,23 +0,0 @@
/* -*- 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 jit_x64_LOpcodes_x64_h
#define jit_x64_LOpcodes_x64_h
#include "jit/shared/LOpcodes-shared.h"
#define LIR_CPU_OPCODE_LIST(_) \
_(DivOrModConstantI) \
_(DivOrModI64) \
_(UDivOrModI64) \
_(WasmTruncateToInt64) \
_(Int64ToFloatingPoint) \
_(SimdValueInt32x4) \
_(SimdValueFloat32x4) \
_(UDivOrMod) \
_(UDivOrModConstant)
#endif /* jit_x64_LOpcodes_x64_h */

View File

@ -1,29 +0,0 @@
/* -*- 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 jit_x86_LOpcodes_x86_h
#define jit_x86_LOpcodes_x86_h
#include "jit/shared/LOpcodes-shared.h"
#define LIR_CPU_OPCODE_LIST(_) \
_(BoxFloatingPoint) \
_(DivOrModConstantI) \
_(SimdValueInt32x4) \
_(SimdValueFloat32x4) \
_(UDivOrMod) \
_(UDivOrModConstant) \
_(UDivOrModI64) \
_(DivOrModI64) \
_(WasmTruncateToInt64) \
_(WasmAtomicLoadI64) \
_(WasmAtomicStoreI64) \
_(WasmCompareExchangeI64) \
_(WasmAtomicExchangeI64) \
_(WasmAtomicBinopI64) \
_(Int64ToFloatingPoint)
#endif /* jit_x86_LOpcodes_x86_h */

View File

@ -80,6 +80,19 @@ if CONFIG['HAVE_DTRACE']:
EXPORTS += ['!javascript-trace.h']
# Generate jit/MOpcodes.h from jit/MIR.h
GENERATED_FILES += ['jit/MOpcodes.h']
MOpcodesGenerated = GENERATED_FILES['jit/MOpcodes.h']
MOpcodesGenerated.script = 'jit/GenerateOpcodeFiles.py:generate_mir_header'
MOpcodesGenerated.inputs = ['jit/MIR.h']
# Generate jit/LOpcodes.h from jit/LIR.h, jit/shared/LIR-shared.h, and
# platform-specific LIR files.
GENERATED_FILES += ['jit/LOpcodes.h']
LOpcodesGenerated = GENERATED_FILES['jit/LOpcodes.h']
LOpcodesGenerated.script = 'jit/GenerateOpcodeFiles.py:generate_lir_header'
LOpcodesGenerated.inputs = ['jit/LIR.h', 'jit/shared/LIR-shared.h']
# Changes to internal header files, used externally, massively slow down
# browser builds. Don't add new files here unless you know what you're
# doing!
@ -450,6 +463,7 @@ if not CONFIG['ENABLE_ION']:
'jit/none/Trampoline-none.cpp'
]
elif CONFIG['JS_CODEGEN_X86'] or CONFIG['JS_CODEGEN_X64']:
LOpcodesGenerated.inputs += ['jit/x86-shared/LIR-x86-shared.h']
UNIFIED_SOURCES += [
'jit/x86-shared/Architecture-x86-shared.cpp',
'jit/x86-shared/Assembler-x86-shared.cpp',
@ -465,6 +479,7 @@ elif CONFIG['JS_CODEGEN_X86'] or CONFIG['JS_CODEGEN_X64']:
'jit/x86-shared/Disassembler-x86-shared.cpp', # using namespace js::jit::X86Encoding;
]
if CONFIG['JS_CODEGEN_X64']:
LOpcodesGenerated.inputs += ['jit/x64/LIR-x64.h']
UNIFIED_SOURCES += [
'jit/x64/Assembler-x64.cpp',
'jit/x64/Bailouts-x64.cpp',
@ -477,6 +492,7 @@ elif CONFIG['JS_CODEGEN_X86'] or CONFIG['JS_CODEGEN_X64']:
'jit/x64/Trampoline-x64.cpp',
]
else:
LOpcodesGenerated.inputs += ['jit/x86/LIR-x86.h']
UNIFIED_SOURCES += [
'jit/x86/Assembler-x86.cpp',
'jit/x86/Bailouts-x86.cpp',
@ -489,6 +505,7 @@ elif CONFIG['JS_CODEGEN_X86'] or CONFIG['JS_CODEGEN_X64']:
'jit/x86/Trampoline-x86.cpp',
]
elif CONFIG['JS_CODEGEN_ARM']:
LOpcodesGenerated.inputs += ['jit/arm/LIR-arm.h']
UNIFIED_SOURCES += [
'jit/arm/Architecture-arm.cpp',
'jit/arm/Assembler-arm.cpp',
@ -514,6 +531,7 @@ elif CONFIG['JS_CODEGEN_ARM']:
'jit/arm/llvm-compiler-rt/arm/aeabi_uidivmod.S',
]
elif CONFIG['JS_CODEGEN_ARM64']:
LOpcodesGenerated.inputs += ['jit/arm64/LIR-arm64.h']
UNIFIED_SOURCES += [
'jit/arm64/Architecture-arm64.cpp',
'jit/arm64/Assembler-arm64.cpp',
@ -545,6 +563,7 @@ elif CONFIG['JS_CODEGEN_ARM64']:
'jit/arm64/vixl/Simulator-vixl.cpp'
]
elif CONFIG['JS_CODEGEN_MIPS32'] or CONFIG['JS_CODEGEN_MIPS64']:
LOpcodesGenerated.inputs += ['jit/mips-shared/LIR-mips-shared.h']
UNIFIED_SOURCES += [
'jit/mips-shared/Architecture-mips-shared.cpp',
'jit/mips-shared/Assembler-mips-shared.cpp',
@ -557,6 +576,7 @@ elif CONFIG['JS_CODEGEN_MIPS32'] or CONFIG['JS_CODEGEN_MIPS64']:
'jit/mips-shared/MoveEmitter-mips-shared.cpp',
]
if CONFIG['JS_CODEGEN_MIPS32']:
LOpcodesGenerated.inputs += ['jit/mips32/LIR-mips32.h']
UNIFIED_SOURCES += [
'jit/mips32/Architecture-mips32.cpp',
'jit/mips32/Assembler-mips32.cpp',
@ -575,6 +595,7 @@ elif CONFIG['JS_CODEGEN_MIPS32'] or CONFIG['JS_CODEGEN_MIPS64']:
'jit/mips32/Simulator-mips32.cpp'
]
elif CONFIG['JS_CODEGEN_MIPS64']:
LOpcodesGenerated.inputs += ['jit/mips64/LIR-mips64.h']
UNIFIED_SOURCES += [
'jit/mips64/Architecture-mips64.cpp',
'jit/mips64/Assembler-mips64.cpp',

View File

@ -329,14 +329,15 @@ GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe, const Maybe<ImmP
// Save the return address if it wasn't already saved by the call insn.
#ifdef JS_USE_LINK_REGISTER
# if defined(JS_CODEGEN_ARM)
# if defined(JS_CODEGEN_ARM) || \
defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
masm.pushReturnAddress();
# elif defined(JS_CODEGEN_ARM64)
// WasmPush updates framePushed() unlike pushReturnAddress(), but that's
// cancelled by the setFramePushed() below.
WasmPush(masm, lr);
# else
# MOZ_CRASH("Implement this");
MOZ_CRASH("Implement this");
# endif
#endif

View File

@ -7181,22 +7181,24 @@ nsLayoutUtils::ComputeImageContainerDrawingParameters(imgIContainer*
SamplingFilter samplingFilter =
nsLayoutUtils::GetSamplingFilterForFrame(aForFrame);
// Compute our SVG context parameters, if any.
// Compute our SVG context parameters, if any. Don't replace the viewport
// size if it was already set, prefer what the caller gave.
SVGImageContext::MaybeStoreContextPaint(aSVGContext, aForFrame, aImage);
if ((scaleFactors.width != 1.0 || scaleFactors.height != 1.0) &&
aImage->GetType() == imgIContainer::TYPE_VECTOR) {
if (!aSVGContext) {
aSVGContext.emplace();
}
aImage->GetType() == imgIContainer::TYPE_VECTOR &&
(!aSVGContext || !aSVGContext->GetViewportSize())) {
gfxSize gfxDestSize(aDestRect.Width(), aDestRect.Height());
IntSize viewportSize =
aImage->OptimalImageSizeForDest(gfxDestSize,
imgIContainer::FRAME_CURRENT,
samplingFilter, aFlags);
aSVGContext->SetViewportSize(Some(CSSIntSize(viewportSize.width,
viewportSize.height)));
CSSIntSize cssViewportSize(viewportSize.width, viewportSize.height);
if (!aSVGContext) {
aSVGContext.emplace(Some(cssViewportSize));
} else {
aSVGContext->SetViewportSize(Some(cssViewportSize));
}
}
// Attempt to snap pixels, the same as ComputeSnappedImageDrawingParameters.

View File

@ -600,10 +600,13 @@ nsImageRenderer::BuildWebRenderDisplayItems(nsPresContext* aPresContext,
containerFlags |= imgIContainer::FLAG_SYNC_DECODE;
}
CSSIntSize imageSize(nsPresContext::AppUnitsToIntCSSPixels(mSize.width),
nsPresContext::AppUnitsToIntCSSPixels(mSize.height));
Maybe<SVGImageContext> svgContext(Some(SVGImageContext(Some(imageSize))));
const int32_t appUnitsPerDevPixel = mForFrame->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
aDest, appUnitsPerDevPixel);
Maybe<SVGImageContext> svgContext;
gfx::IntSize decodeSize =
nsLayoutUtils::ComputeImageContainerDrawingParameters(mImageContainer, mForFrame, destRect,
aSc, containerFlags, svgContext);

View File

@ -181,8 +181,8 @@ include empty/reftest.list
== wide--contain--percent-width-percent-height.html ref-wide-lime768x128-aqua768x128.html
== wide--contain--percent-width-percent-height-viewbox.html ref-wide-lime16x128-aqua16x128.html
== wide--cover--nonpercent-width-nonpercent-height.html ref-wide-lime768x256.html
== wide--cover--nonpercent-width-nonpercent-height-viewbox.html ref-wide-lime768x256.html
fuzzy-if(webrender,127-127,768-768) == wide--cover--nonpercent-width-nonpercent-height.html ref-wide-lime768x256.html
fuzzy-if(webrender,127-127,768-768) == wide--cover--nonpercent-width-nonpercent-height-viewbox.html ref-wide-lime768x256.html
== wide--cover--nonpercent-width-omitted-height.html ref-wide-lime768x128-aqua768x128.html
== wide--cover--nonpercent-width-omitted-height-viewbox.html ref-wide-lime768x256.html
== wide--cover--nonpercent-width-percent-height.html ref-wide-lime768x128-aqua768x128.html

View File

@ -36,6 +36,7 @@
#include "nsCSSPseudoElements.h"
#include "mozilla/EffectSet.h"
#include "mozilla/IntegerRange.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#ifdef MOZ_OLD_STYLE
@ -859,6 +860,137 @@ nsComputedDOMStyle::GetAdjustedValuesForBoxSizing()
return adjustment;
}
static void
AddImageURL(nsIURI& aURI, nsTArray<nsString>& aURLs)
{
nsAutoCString spec;
nsresult rv = aURI.GetSpec(spec);
if (NS_FAILED(rv)) {
return;
}
aURLs.AppendElement(NS_ConvertUTF8toUTF16(spec));
}
static void
AddImageURL(const css::URLValueData& aURL, nsTArray<nsString>& aURLs)
{
if (aURL.IsLocalRef()) {
return;
}
if (nsIURI* uri = aURL.GetURI()) {
AddImageURL(*uri, aURLs);
}
}
static void
AddImageURL(const nsStyleImageRequest& aRequest, nsTArray<nsString>& aURLs)
{
if (auto* value = aRequest.GetImageValue()) {
AddImageURL(*value, aURLs);
}
}
static void
AddImageURL(const nsStyleImage& aImage, nsTArray<nsString>& aURLs)
{
if (auto* urlValue = aImage.GetURLValue()) {
AddImageURL(*urlValue, aURLs);
}
}
static void
AddImageURL(const StyleShapeSource& aShapeSource, nsTArray<nsString>& aURLs)
{
switch (aShapeSource.GetType()) {
case StyleShapeSourceType::URL:
AddImageURL(*aShapeSource.GetURL(), aURLs);
break;
case StyleShapeSourceType::Image:
AddImageURL(*aShapeSource.GetShapeImage(), aURLs);
break;
default:
break;
}
}
static void
AddImageURLs(const nsStyleImageLayers& aLayers, nsTArray<nsString>& aURLs)
{
for (auto i : IntegerRange(aLayers.mLayers.Length())) {
AddImageURL(aLayers.mLayers[i].mImage, aURLs);
}
}
// FIXME(stylo-everywhere): This should be `const ServoStyleContext&`.
static void
CollectImageURLsForProperty(nsCSSPropertyID aProp,
nsStyleContext& aStyle,
nsTArray<nsString>& aURLs)
{
if (nsCSSProps::IsShorthand(aProp)) {
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProp, CSSEnabledState::eInChrome) {
CollectImageURLsForProperty(*p, aStyle, aURLs);
}
return;
}
switch (aProp) {
case eCSSProperty_cursor:
for (auto& image : aStyle.StyleUserInterface()->mCursorImages) {
AddImageURL(*image.mImage, aURLs);
}
break;
case eCSSProperty_background_image:
AddImageURLs(aStyle.StyleBackground()->mImage, aURLs);
break;
case eCSSProperty_mask_clip:
AddImageURLs(aStyle.StyleSVGReset()->mMask, aURLs);
break;
case eCSSProperty_list_style_image:
if (nsStyleImageRequest* image = aStyle.StyleList()->mListStyleImage) {
AddImageURL(*image, aURLs);
}
break;
case eCSSProperty_border_image_source:
AddImageURL(aStyle.StyleBorder()->mBorderImageSource, aURLs);
break;
case eCSSProperty_clip_path:
AddImageURL(aStyle.StyleSVGReset()->mClipPath, aURLs);
break;
case eCSSProperty_shape_outside:
AddImageURL(aStyle.StyleDisplay()->mShapeOutside, aURLs);
break;
default:
break;
}
}
void
nsComputedDOMStyle::GetCSSImageURLs(const nsAString& aPropertyName,
nsTArray<nsString>& aImageURLs,
mozilla::ErrorResult& aRv)
{
nsCSSPropertyID prop =
nsCSSProps::LookupProperty(aPropertyName, CSSEnabledState::eInChrome);
if (prop == eCSSProperty_UNKNOWN) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
UpdateCurrentStyleSources(false);
if (!mStyleContext) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
CollectImageURLsForProperty(prop, *mStyleContext, aImageURLs);
}
// nsDOMCSSDeclaration abstract methods which should never be called
// on a nsComputedDOMStyle object, but must be defined to avoid
// compile errors.

View File

@ -130,6 +130,11 @@ public:
mExposeVisitedStyle = aExpose;
}
void GetCSSImageURLs(const nsAString& aPropertyName,
nsTArray<nsString>& aImageURLs,
mozilla::ErrorResult& aRv) final;
// nsDOMCSSDeclaration abstract methods which should never be called
// on a nsComputedDOMStyle object, but must be defined to avoid
// compile errors.

View File

@ -71,6 +71,14 @@ public:
}
}
virtual void
GetCSSImageURLs(const nsAString& aPropertyName,
nsTArray<nsString>& aImageURLs,
mozilla::ErrorResult& aRv)
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
// WebIDL interface for CSSStyleDeclaration
virtual void SetCssText(const nsAString& aString,
nsIPrincipal* aSubjectPrincipal,

View File

@ -451,8 +451,10 @@ SandboxBroker::SetSecurityLevelForContentProcess(int32_t aSandboxLevel,
if (aSandboxLevel > 4) {
result = mPolicy->SetAlternateDesktop(false);
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
"Failed to create alternate desktop for sandbox.");
if (NS_WARN_IF(result != sandbox::SBOX_ALL_OK)) {
LOG_W("SetAlternateDesktop failed, result: %i, last error: %x",
result, ::GetLastError());
}
}
if (aSandboxLevel > 3) {
@ -849,8 +851,10 @@ SandboxBroker::SetSecurityLevelForPDFiumProcess()
"SetTokenLevel should never fail with these arguments, what happened?");
result = mPolicy->SetAlternateDesktop(true);
SANDBOX_ENSURE_SUCCESS(result,
"Failed to create alternate desktop for sandbox.");
if (NS_WARN_IF(result != sandbox::SBOX_ALL_OK)) {
LOG_W("SetAlternateDesktop failed, result: %i, last error: %x",
result, ::GetLastError());
}
result = mPolicy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
MOZ_ASSERT(sandbox::SBOX_ALL_OK == result,
@ -928,8 +932,10 @@ SandboxBroker::SetSecurityLevelForGMPlugin(SandboxLevel aLevel)
"SetTokenLevel should never fail with these arguments, what happened?");
result = mPolicy->SetAlternateDesktop(true);
SANDBOX_ENSURE_SUCCESS(result,
"Failed to create alternate desktop for sandbox.");
if (NS_WARN_IF(result != sandbox::SBOX_ALL_OK)) {
LOG_W("SetAlternateDesktop failed, result: %i, last error: %x",
result, ::GetLastError());
}
result = mPolicy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
MOZ_ASSERT(sandbox::SBOX_ALL_OK == result,

View File

@ -302,6 +302,20 @@ def fix_init_url(config):
config['init_url'] = convert_url(config, config['init_url'])
@validator
def determine_local_symbols_path(config):
if 'symbols_path' not in config:
return
# use objdir/dist/crashreporter-symbols for symbolsPath if none provided
if not config['symbols_path'] and \
config['develop'] and \
'MOZ_DEVELOPER_OBJ_DIR' in os.environ:
config['symbols_path'] = os.path.join(os.environ['MOZ_DEVELOPER_OBJ_DIR'],
'dist',
'crashreporter-symbols')
def get_counters(config):
counters = set()
return counters

Some files were not shown because too many files have changed in this diff Show More