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

This commit is contained in:
shindli 2018-02-01 00:37:57 +02:00
Родитель 3a1892a89a a9ac1e44cc
Коммит f713c5d75e
139 изменённых файлов: 3896 добавлений и 2564 удалений

Просмотреть файл

@ -429,11 +429,15 @@ DownloadsPlacesView.prototype = {
xblFields.set(key, value);
}
let oldActiveElement = document.activeElement;
let parentNode = this._richlistbox.parentNode;
let nextSibling = this._richlistbox.nextSibling;
parentNode.removeChild(this._richlistbox);
this._richlistbox.prepend(this.batchFragment);
parentNode.insertBefore(this._richlistbox, nextSibling);
if (oldActiveElement && oldActiveElement != document.activeElement) {
oldActiveElement.focus();
}
for (let [key, value] of xblFields) {
this._richlistbox[key] = value;

Просмотреть файл

@ -202,7 +202,6 @@ def old_configure_options(*options):
'--enable-nfc',
'--enable-nspr-build',
'--enable-official-branding',
'--enable-oom-breakpoint',
'--enable-parental-controls',
'--enable-pie',
'--enable-posix-nspr-emulation',

Просмотреть файл

@ -1,9 +1,9 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Version v11.0
Comparison: https://github.com/devtools-html/debugger.html/compare/release-10...release-11
Commit: https://github.com/devtools-html/debugger.html/commit/4ef9b879ef7b51430e4acdadfd24a8d7e9f64c82
Version 12.0
Comparison: https://github.com/devtools-html/debugger.html/compare/release-11...release-12
Commit: https://github.com/devtools-html/debugger.html/commit/5f7ecfe
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.0

Просмотреть файл

@ -1122,6 +1122,95 @@ html[dir="rtl"] .managed-tree .tree .node > div {
.managed-tree .tree-node button {
position: fixed;
}
/* 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/. */
.tree {
overflow: auto;
}
.tree.inline {
display: inline-block;
}
.tree.nowrap {
white-space: nowrap;
}
.tree.noselect {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.tree button {
display: block;
}
.tree .tree-node {
display: flex;
}
.tree .tree-node:not(.focused):hover {
background-color: var(--theme-selection-background-hover);
}
.tree-indent {
display: inline-block;
width: 12px;
margin-inline-start: 5px;
border-inline-start: 1px solid #A2D1FF;
flex-shrink: 0;
}
/* Align with expandables siblings (where we have the arrow) */
.tree-node[data-expandable="false"] .tree-indent:last-of-type {
margin-inline-end: 15px;
}
/* For non expandable root nodes, we don't have .tree-indent elements, so we declare
the margin on the start of the node */
.tree-node[data-expandable="false"][aria-level="0"] {
padding-inline-start: 15px
}
.tree .tree-node[data-expandable="true"] {
cursor: default;
}
.tree .tree-node.focused {
color: white;
background-color: var(--theme-selection-background, #0a84ff);
}
.tree-node.focused .arrow svg {
fill: currentColor;
}
.tree-node:hover img {
background-color: var(--theme-content-color3);
}
.arrow svg {
fill: var(--theme-splitter-color, #9B9B9B);
transition: transform 0.125s ease;
width: 10px;
margin-inline-end: 5px;
transform: rotate(-90deg);
}
html[dir="rtl"] .arrow svg,
.arrow svg:dir(rtl),
.arrow svg:-moz-locale-dir(rtl) {
transform: rotate(90deg);
}
.arrow.expanded.expanded svg {
transform: rotate(0deg);
}
/* 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/>. */
@ -1409,6 +1498,10 @@ html[dir="rtl"] .managed-tree .tree .node > div {
overflow-y: auto;
}
.sources-list .tree:focus {
outline: none;
}
.sources-list .managed-tree {
flex: 1;
display: flex;
@ -2060,6 +2153,13 @@ html .toggle-button.end.vertical svg {
color: var(--theme-body-color);
}
/******************************************************************************/
/* Length bubble for arraylikes and maplikes */
.objectLengthBubble {
color: var(--null-color);
}
/******************************************************************************/
.objectLeftBrace,
@ -2070,7 +2170,7 @@ html .toggle-button.end.vertical svg {
}
/******************************************************************************/
/* Cycle reference*/
/* Cycle reference */
.objectBox-Reference {
font-weight: bold;
@ -2149,91 +2249,6 @@ html .toggle-button.end.vertical svg {
* 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/. */
.tree {
overflow: auto;
}
.tree.inline {
display: inline-block;
}
.tree.nowrap {
white-space: nowrap;
}
.tree.noselect {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.tree button {
display: block;
}
.tree .tree-node {
display: flex;
}
.tree-indent {
display: inline-block;
width: 12px;
margin-inline-start: 5px;
border-inline-start: 1px solid #A2D1FF;
flex-shrink: 0;
}
/* Align with expandables siblings (where we have the arrow) */
.tree-node[data-expandable="false"] .tree-indent:last-of-type {
margin-inline-end: 15px;
}
/* For non expandable root nodes, we don't have .tree-indent elements, so we declare
the margin on the start of the node */
.tree-node[data-expandable="false"][aria-level="0"] {
padding-inline-start: 15px
}
.tree .tree-node[data-expandable="true"] {
cursor: default;
}
.tree .tree-node:not(.focused):hover {
background-color: #F0F9FE;
}
.tree .tree-node.focused {
color: white;
background-color: var(--theme-selection-background, #0a84ff);
}
.tree-node.focused .arrow svg {
fill: currentColor;
}
.arrow svg {
fill: var(--theme-splitter-color, #9B9B9B);
transition: transform 0.125s ease;
width: 10px;
margin-inline-end: 5px;
transform: rotate(-90deg);
}
html[dir="rtl"] .arrow svg,
.arrow svg:dir(rtl),
.arrow svg:-moz-locale-dir(rtl) {
transform: rotate(90deg);
}
.arrow.expanded.expanded svg {
transform: rotate(0deg);
}
/* 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/. */
.tree.object-inspector .node.object-node {
display: inline-block;
}
@ -3025,6 +3040,10 @@ html .breakpoints-list .breakpoint.paused {
.expression-input {
max-width: 50%;
}
.expressions-list .tree:focus {
outline: none;
}
/* 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/>. */
@ -3614,6 +3633,10 @@ img.ignore-exceptions {
padding-inline-start: 4px;
}
.scopes-list .tree:focus {
outline: none;
}
.scopes-list .function-signature {
display: inline-block;
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -15,6 +15,14 @@ support-files =
examples/sourcemaps3/bundle.js.map
examples/sourcemaps3/sorted.js
examples/sourcemaps3/test.js
examples/sourcemaps-reload/v1.bundle.js
examples/sourcemaps-reload/v1.bundle.js.map
examples/sourcemaps-reload/v2.bundle.js
examples/sourcemaps-reload/v2.bundle.js.map
examples/sourcemaps-reload/v3.bundle.js
examples/sourcemaps-reload/v3.bundle.js.map
examples/sourcemaps-reload/doc-sourcemaps-reload.html
examples/sourcemaps-reload/sjs_code_reload.sjs
examples/wasm-sourcemaps/average.js
examples/wasm-sourcemaps/average.wasm
examples/wasm-sourcemaps/average.wasm.map
@ -25,7 +33,8 @@ support-files =
examples/sum/sum.min.js.map
examples/reload/code_reload_1.js
examples/reload/code_reload_2.js
examples/reload/doc_reload.html
examples/reload/doc-reload.html
examples/reload/sjs_code_reload.sjs
examples/doc-async.html
examples/doc-asm.html
examples/doc-content-script-sources.html
@ -63,7 +72,6 @@ support-files =
examples/script-switching-02.js
examples/script-switching-01.js
examples/times2.js
examples/reload/sjs_code_reload.sjs
[browser_dbg-asm.js]
[browser_dbg-async-stepping.js]
@ -115,6 +123,7 @@ skip-if = os == "win" # Bug 1393121
skip-if = true # regular failures during release in Bug 1415300
[browser_dbg-search-project.js]
[browser_dbg-sourcemaps.js]
[browser_dbg-sourcemaps-reload.js]
[browser_dbg-sourcemaps-reloading.js]
[browser_dbg-sourcemaps2.js]
[browser_dbg-sourcemaps3.js]

Просмотреть файл

@ -18,10 +18,11 @@ async function waitForBreakpoint(dbg, location) {
}
add_task(async function() {
const dbg = await initDebugger("reload/doc_reload.html", "sjs_code_reload");
const dbg = await initDebugger("reload/doc-reload.html");
await waitForSource(dbg, "sjs_code_reload");
await selectSource(dbg, "sjs_code_reload");
await waitForSelectedSource(dbg, "sjs_code_reload");
await addBreakpoint(dbg, "sjs_code_reload", 2);
await reload(dbg, "sjs_code_reload");

Просмотреть файл

@ -0,0 +1,59 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* Test reloading:
* 1. reload the source
* 2. re-sync breakpoints
*/
async function waitForBreakpoint(dbg, location) {
return waitForState(
dbg,
state => {
return dbg.selectors.getBreakpoint(dbg.getState(), location);
},
"Waiting for breakpoint"
);
}
function getBreakpoints(dbg) {
const breakpoints = dbg.selectors.getBreakpoints(dbg.getState());
return breakpoints.valueSeq().toJS();
}
add_task(async function() {
const dbg = await initDebugger("doc-minified.html");
await navigate(dbg, "sourcemaps-reload/doc-sourcemaps-reload.html", "v1");
await waitForSource(dbg, "v1");
await selectSource(dbg, "v1");
await addBreakpoint(dbg, "v1", 6);
let breakpoint = getBreakpoints(dbg)[0];
is(breakpoint.location.line, 6);
let syncBp = waitForDispatch(dbg, "SYNC_BREAKPOINT");
await reload(dbg);
await waitForPaused(dbg);
await syncBp;
assertDebugLine(dbg, 72);
breakpoint = getBreakpoints(dbg)[0];
is(breakpoint.location.line, 9);
is(breakpoint.generatedLocation.line, 73);
await resume(dbg);
syncBp = waitForDispatch(dbg, "SYNC_BREAKPOINT", 2);
await selectSource(dbg, "v1");
await addBreakpoint(dbg, "v1", 13);
await reload(dbg);
await waitForSource(dbg, "v1");
await syncBp;
await waitForSelectedSource(dbg, "v1");
is(getBreakpoints(dbg).length, 0, "No breakpoints");
});

Просмотреть файл

@ -1,6 +1,10 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
async function waitForBreakpointCount(dbg, count) {
return waitForState(dbg, state => dbg.selectors.getBreakpoints(state).size === count)
}
add_task(async function() {
// NOTE: the CORS call makes the test run times inconsistent
requestLongerTimeout(2);
@ -22,12 +26,14 @@ add_task(async function() {
// should not move anywhere.
await addBreakpoint(dbg, entrySrc, 13);
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
ok(
getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }),
"Breakpoint has correct line"
);
await addBreakpoint(dbg, entrySrc, 5);
await addBreakpoint(dbg, entrySrc, 15);
await disableBreakpoint(dbg, entrySrc, 15);
@ -38,6 +44,7 @@ add_task(async function() {
await waitForPaused(dbg);
assertPausedLocation(dbg);
await waitForBreakpointCount(dbg, 3);
is(getBreakpoints(getState()).size, 3, "Three breakpoints exist");
ok(

Просмотреть файл

@ -12,7 +12,9 @@ async function waitForSourceCount(dbg, i) {
}
function getLabel(dbg, index) {
return findElement(dbg, "sourceNode", index).textContent.trim();
return findElement(dbg, "sourceNode", index)
.textContent.trim()
.replace(/^[\s\u200b]*/g, "");
}
add_task(async function() {
@ -27,5 +29,5 @@ add_task(async function() {
await waitForSourceCount(dbg, 3);
is(getLabel(dbg, 3), "evaled.js", "the eval script exists");
is(getLabel(dbg, 3), "evaled.js", "evaled exists");
});

Просмотреть файл

@ -17,7 +17,9 @@ async function assertSourceCount(dbg, count) {
}
function getLabel(dbg, index) {
return findElement(dbg, "sourceNode", index).textContent.trim();
return findElement(dbg, "sourceNode", index)
.textContent.trim()
.replace(/^[\s\u200b]*/g, "");
}
add_task(async function() {
@ -62,5 +64,9 @@ add_task(async function() {
});
await waitForSourceCount(dbg, 9);
is(getLabel(dbg, 7), "math.min.js", "The dynamic script exists");
is(
getLabel(dbg, 7),
"math.min.js",
"math.min.js - The dynamic script exists"
);
});

Просмотреть файл

@ -0,0 +1,3 @@
{
"plugins": ["transform-async-to-generator"]
}

Просмотреть файл

@ -0,0 +1,7 @@
### Steps to Rebuild
1. make changes to v1.js, v2.js, v3.js
2. run `yarn` to install webpack & babel
3. run `webpack`
4. change `sources` reference in `v2.bundle.js.map` to `v1.js`
5. change `sources` reference in `v3.bundle.js.map` to `v1.js`

Просмотреть файл

@ -0,0 +1,15 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<script src="sjs_code_reload.sjs?foo"></script>
<head>
<meta charset="utf-8"/>
<title>Empty test page 1</title>
</head>
<body>
</body>
</html>

Просмотреть файл

@ -0,0 +1,19 @@
{
"name": "sourcemaps-reload",
"version": "1.0.0",
"description": "",
"main": "sorted.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"webpack": "^3.7.1"
}
}

Просмотреть файл

@ -0,0 +1,36 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* globals getState, setState */
/* exported handleRequest */
"use strict";
const NUM_FILES = 3;
function _getUrl(request, counter) {
const { scheme, host, path } = request;
const index = Math.ceil(counter / 2);
const showMap = false ;//(counter % 2) === 1
const newPath = path.substr(0, path.lastIndexOf("/") + 1);
const url = `${scheme}://${host}${newPath}/v${index}.bundle.js${showMap ? '.map' : ''}`;
return url
}
function handleRequest(request, response) {
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
response.setHeader("Access-Control-Allow-Origin", "*", false);
response.setHeader("Content-Type", "text/javascript", false);
// Redirect to a different file each time.
let counter = (+getState("counter") || 1) % ( 2 * NUM_FILES + 1);
const newUrl = _getUrl(request, counter);
response.setStatusLine(request.httpVersion, 302, "Found");
response.setHeader("Location", newUrl);
setState("counter", "" + ++counter);
}

Просмотреть файл

@ -0,0 +1,89 @@
/******/ (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, exports) {
let foo = (() => {
var _ref = _asyncToGenerator(function* () {
yield bar();
console.log("YO");
});
return function foo() {
return _ref.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function bar() {
return new Promise(resolve => setTimeout(resolve, 100));
}
/***/ })
/******/ ]);
//# sourceMappingURL=v1.bundle.js.map

Просмотреть файл

@ -0,0 +1 @@
{"version":3,"sources":["webpack:///webpack/bootstrap 8bcf0d04c821a99f6859","webpack:///./v1.js"],"names":["bar","console","log","foo","Promise","resolve","setTimeout"],"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;;;;;;;;+BCzDA,aAAqB;AACnB,UAAMA,KAAN;AACAC,YAAQC,GAAR,CAAY,IAAZ;AACD,G;;kBAHcC,G;;;;;;;AAJf,SAASH,GAAT,GAAe;AACb,SAAO,IAAII,OAAJ,CAAYC,WAAWC,WAAWD,OAAX,EAAoB,GAApB,CAAvB,CAAP;AACD,C","file":"v1.bundle.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 8bcf0d04c821a99f6859","function bar() {\n return new Promise(resolve => setTimeout(resolve, 100))\n}\n\nasync function foo() {\n await bar();\n console.log(\"YO\")\n}\n\n\n\n// WEBPACK FOOTER //\n// ./v1.js"],"sourceRoot":""}

Просмотреть файл

@ -0,0 +1,8 @@
function bar() {
return new Promise(resolve => setTimeout(resolve, 100))
}
async function foo() {
await bar();
console.log("YO")
}

Просмотреть файл

@ -0,0 +1,92 @@
/******/ (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 = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */,
/* 1 */
/***/ (function(module, exports) {
let foo = (() => {
var _ref = _asyncToGenerator(function* () {
yield bar();
console.log("YO");
});
return function foo() {
return _ref.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function bar() {
return new Promise(resolve => setTimeout(resolve, 100));
}
console.log("HEY");
/***/ })
/******/ ]);
//# sourceMappingURL=v2.bundle.js.map

Просмотреть файл

@ -0,0 +1 @@
{"version":3,"sources":["webpack:///webpack/bootstrap 8bcf0d04c821a99f6859","webpack:///./v1.js"],"names":["bar","console","log","foo","Promise","resolve","setTimeout"],"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;;;;;;;;;+BCtDA,aAAqB;AACnB,UAAMA,KAAN;AACAC,YAAQC,GAAR,CAAY,IAAZ;AACD,G;;kBAHcC,G;;;;;;;AAPf,SAASH,GAAT,GAAe;AACb,SAAO,IAAII,OAAJ,CAAYC,WAAWC,WAAWD,OAAX,EAAoB,GAApB,CAAvB,CAAP;AACD;;AAUDJ,QAAQC,GAAR,CAAY,KAAZ,E","file":"v2.bundle.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 = 1);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 8bcf0d04c821a99f6859","function bar() {\n return new Promise(resolve => setTimeout(resolve, 100))\n}\n\n\n\n\nasync function foo() {\n await bar();\n console.log(\"YO\")\n}\n\nconsole.log(\"HEY\")\n\n\n\n// WEBPACK FOOTER //\n// ./v2.js"],"sourceRoot":""}

Просмотреть файл

@ -0,0 +1,13 @@
function bar() {
return new Promise(resolve => setTimeout(resolve, 100))
}
async function foo() {
await bar();
console.log("YO")
}
console.log("HEY")

Просмотреть файл

@ -0,0 +1,78 @@
/******/ (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 = 2);
/******/ })
/************************************************************************/
/******/ ({
/***/ 2:
/***/ (function(module, exports) {
function bar() {
return new Promise(resolve => setTimeout(resolve, 100));
}
/***/ })
/******/ });
//# sourceMappingURL=v3.bundle.js.map

Просмотреть файл

@ -0,0 +1 @@
{"version":3,"sources":["webpack:///webpack/bootstrap 8bcf0d04c821a99f6859","webpack:///./v1.js"],"names":["bar","Promise","resolve","setTimeout"],"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,SAASA,GAAT,GAAe;AACb,SAAO,IAAIC,OAAJ,CAAYC,WAAWC,WAAWD,OAAX,EAAoB,GAApB,CAAvB,CAAP;AACD,C","file":"v3.bundle.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 = 2);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 8bcf0d04c821a99f6859","function bar() {\n return new Promise(resolve => setTimeout(resolve, 100))\n}\n\n\n\n// WEBPACK FOOTER //\n// ./v3.js"],"sourceRoot":""}

Просмотреть файл

@ -0,0 +1,3 @@
function bar() {
return new Promise(resolve => setTimeout(resolve, 100))
}

Просмотреть файл

@ -0,0 +1,26 @@
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: {
v1: "./v1.js",
v2: "./v2.js",
v3: "./v3.js"
},
output: {
path: __dirname,
filename: "[name].bundle.js"
},
devtool: "sourcemap",
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}
]
},
plugins: [
]
};

Просмотреть файл

@ -29,6 +29,10 @@ copySourceUri2.accesskey=u
setDirectoryRoot.label=Set directory root
setDirectoryRoot.accesskey=r
# LOCALIZATION NOTE (removeDirectoryRoot): This is the text that appears in the
# context menu to remove a directory as root directory
removeDirectoryRoot.label=Remove directory root
# LOCALIZATION NOTE (copyFunction): This is the text that appears in the
# context menu to copy the function the user selected
copyFunction.label=Copy function

Просмотреть файл

@ -246,6 +246,7 @@
#include "mozilla/dom/NavigatorBinding.h"
#include "mozilla/dom/ImageBitmap.h"
#include "mozilla/dom/ImageBitmapBinding.h"
#include "mozilla/dom/ServiceWorker.h"
#include "mozilla/dom/ServiceWorkerRegistration.h"
#include "mozilla/dom/U2F.h"
#include "mozilla/dom/WebIDLGlobalNameHash.h"
@ -2395,6 +2396,12 @@ nsPIDOMWindowInner::GetController() const
return Move(nsGlobalWindowInner::Cast(this)->GetController());
}
RefPtr<mozilla::dom::ServiceWorker>
nsPIDOMWindowInner::GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor)
{
return Move(nsGlobalWindowInner::Cast(this)->GetOrCreateServiceWorker(aDescriptor));
}
void
nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope)
{
@ -6371,6 +6378,39 @@ nsGlobalWindowInner::GetController() const
return Move(controller);
}
RefPtr<ServiceWorker>
nsGlobalWindowInner::GetOrCreateServiceWorker(const ServiceWorkerDescriptor& aDescriptor)
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<ServiceWorker> ref;
for (auto sw : mServiceWorkerList) {
if (sw->MatchesDescriptor(aDescriptor)) {
ref = sw;
return ref.forget();
}
}
ref = ServiceWorker::Create(this, aDescriptor);
return ref.forget();
}
void
nsGlobalWindowInner::AddServiceWorker(ServiceWorker* aServiceWorker)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(aServiceWorker);
MOZ_ASSERT(!mServiceWorkerList.Contains(aServiceWorker));
mServiceWorkerList.AppendElement(aServiceWorker);
}
void
nsGlobalWindowInner::RemoveServiceWorker(ServiceWorker* aServiceWorker)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(aServiceWorker);
MOZ_ASSERT(mServiceWorkerList.Contains(aServiceWorker));
mServiceWorkerList.RemoveElement(aServiceWorker);
}
nsresult
nsGlobalWindowInner::FireDelayedDOMEvents()
{

Просмотреть файл

@ -351,6 +351,15 @@ public:
mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const override;
virtual RefPtr<mozilla::dom::ServiceWorker>
GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor) override;
virtual void
AddServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker) override;
virtual void
RemoveServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker) override;
void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
virtual nsresult FireDelayedDOMEvents() override;
@ -1442,6 +1451,10 @@ protected:
mozilla::UniquePtr<mozilla::dom::ClientSource> mClientSource;
// Weak references added by AddServiceWorker() and cleared by
// RemoveServiceWorker() when the ServiceWorker is destroyed.
nsTArray<mozilla::dom::ServiceWorker*> mServiceWorkerList;
nsTArray<RefPtr<mozilla::dom::Promise>> mPendingPromises;
static InnerWindowByIdTable* sInnerWindowsById;

Просмотреть файл

@ -5,12 +5,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIGlobalObject.h"
#include "mozilla/dom/ServiceWorker.h"
#include "nsContentUtils.h"
#include "nsThreadUtils.h"
#include "nsHostObjectProtocolHandler.h"
using mozilla::Maybe;
using mozilla::dom::ClientInfo;
using mozilla::dom::ServiceWorker;
using mozilla::dom::ServiceWorkerDescriptor;
nsIGlobalObject::~nsIGlobalObject()
@ -132,3 +135,22 @@ nsIGlobalObject::GetController() const
// window and worker globals can currently be controlled as a client.
return Maybe<ServiceWorkerDescriptor>();
}
RefPtr<ServiceWorker>
nsIGlobalObject::GetOrCreateServiceWorker(const ServiceWorkerDescriptor& aDescriptor)
{
MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service workers");
return nullptr;
}
void
nsIGlobalObject::AddServiceWorker(ServiceWorker* aServiceWorker)
{
MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service workers");
}
void
nsIGlobalObject::RemoveServiceWorker(ServiceWorker* aServiceWorker)
{
MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service workers");
}

Просмотреть файл

@ -24,6 +24,12 @@
class nsCycleCollectionTraversalCallback;
class nsIPrincipal;
namespace mozilla {
namespace dom {
class ServiceWorker;
} // namespace dom
} // namespace mozilla
class nsIGlobalObject : public nsISupports,
public mozilla::dom::DispatcherTrait
{
@ -86,6 +92,21 @@ public:
virtual mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>
GetController() const;
// Get the DOM object for the given descriptor or attempt to create one.
// Creation can still fail and return nullptr during shutdown, etc.
virtual RefPtr<mozilla::dom::ServiceWorker>
GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor);
// These methods allow the ServiceWorker instances to note their existence
// so that the global can use weak references to them. The global should
// not hold a strong reference to the ServiceWorker.
virtual void
AddServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker);
// This method must be called by the ServiceWorker before it is destroyed.
virtual void
RemoveServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker);
protected:
virtual ~nsIGlobalObject();

Просмотреть файл

@ -53,6 +53,7 @@ class TabGroup;
class Element;
class Navigator;
class Performance;
class ServiceWorker;
class ServiceWorkerDescriptor;
class ServiceWorkerRegistration;
class Timeout;
@ -334,6 +335,9 @@ public:
mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const;
RefPtr<mozilla::dom::ServiceWorker>
GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor);
void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
mozilla::dom::TabGroup* TabGroup();

Просмотреть файл

@ -572,8 +572,9 @@ ClientSource::PostMessage(const ClientPostMessageArgs& aArgs)
if (reg) {
RefPtr<ServiceWorkerInfo> serviceWorker = reg->GetByID(source.Id());
if (serviceWorker) {
init.mSource.SetValue().SetAsServiceWorker() =
serviceWorker->GetOrCreateInstance(GetInnerWindow());
RefPtr<ServiceWorker> instance =
globalObject->GetOrCreateServiceWorker(source);
init.mSource.SetValue().SetAsServiceWorker() = instance;
}
}

Просмотреть файл

@ -17,6 +17,7 @@ struct IPCServiceWorkerDescriptor
uint64_t id;
PrincipalInfo principalInfo;
nsCString scope;
nsCString scriptURL;
ServiceWorkerState state;
};

Просмотреть файл

@ -0,0 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include PBackgroundSharedTypes;
include IPCServiceWorkerDescriptor;
using ServiceWorkerUpdateViaCache from "mozilla/dom/ServiceWorkerIPCUtils.h";
namespace mozilla {
namespace dom {
// IPC type with enough information to create a ServiceWorker DOM object
// in a child process. Note that the state may be slightly out-of-sync
// with the parent and should be updated dynamically if necessary.
struct IPCServiceWorkerRegistrationDescriptor
{
// These values should match the principal and scope in each
// associated worker. It may be possible to optimize in the future,
// but for now we duplicate the information here to ensure correctness.
// Its possible we may need to reference a registration before the
// worker is installed yet, etc.
PrincipalInfo principalInfo;
nsCString scope;
ServiceWorkerUpdateViaCache updateViaCache;
OptionalIPCServiceWorkerDescriptor installing;
OptionalIPCServiceWorkerDescriptor waiting;
OptionalIPCServiceWorkerDescriptor active;
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -38,22 +38,58 @@ ServiceWorkerVisible(JSContext* aCx, JSObject* aObj)
return IS_INSTANCE_OF(ServiceWorkerGlobalScope, aObj);
}
ServiceWorker::ServiceWorker(nsPIDOMWindowInner* aWindow,
ServiceWorkerInfo* aInfo)
: DOMEventTargetHelper(aWindow),
mInfo(aInfo)
// static
already_AddRefed<ServiceWorker>
ServiceWorker::Create(nsIGlobalObject* aOwner,
const ServiceWorkerDescriptor& aDescriptor)
{
RefPtr<ServiceWorker> ref;
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (!swm) {
return ref.forget();
}
RefPtr<ServiceWorkerRegistrationInfo> reg =
swm->GetRegistration(aDescriptor.PrincipalInfo(), aDescriptor.Scope());
if (!reg) {
return ref.forget();
}
RefPtr<ServiceWorkerInfo> info = reg->GetByID(aDescriptor.Id());
if (!info) {
return ref.forget();
}
ref = new ServiceWorker(aOwner, aDescriptor, info);
return ref.forget();
}
ServiceWorker::ServiceWorker(nsIGlobalObject* aGlobal,
const ServiceWorkerDescriptor& aDescriptor,
ServiceWorker::Inner* aInner)
: DOMEventTargetHelper(aGlobal)
, mDescriptor(aDescriptor)
, mInner(aInner)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aInfo);
MOZ_DIAGNOSTIC_ASSERT(aGlobal);
MOZ_DIAGNOSTIC_ASSERT(mInner);
aGlobal->AddServiceWorker(this);
// This will update our state too.
mInfo->AppendWorker(this);
mInner->AddServiceWorker(this);
}
ServiceWorker::~ServiceWorker()
{
MOZ_ASSERT(NS_IsMainThread());
mInfo->RemoveWorker(this);
mInner->RemoveServiceWorker(this);
nsIGlobalObject* global = GetParentObject();
if (global) {
global->RemoveServiceWorker(this);
}
}
NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper)
@ -70,10 +106,26 @@ ServiceWorker::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return ServiceWorkerBinding::Wrap(aCx, this, aGivenProto);
}
ServiceWorkerState
ServiceWorker::State() const
{
return mDescriptor.State();
}
void
ServiceWorker::SetState(ServiceWorkerState aState)
{
ServiceWorkerState oldState = mDescriptor.State();
mDescriptor.SetState(aState);
if (oldState != aState) {
DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));
}
}
void
ServiceWorker::GetScriptURL(nsString& aURL) const
{
CopyUTF8toUTF16(mInfo->ScriptSpec(), aURL);
CopyUTF8toUTF16(mDescriptor.ScriptURL(), aURL);
}
void
@ -86,33 +138,28 @@ ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
return;
}
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetParentObject());
if (!window || !window->GetExtantDoc()) {
NS_WARNING("Trying to call post message from an invalid dom object.");
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
mInner->PostMessage(GetParentObject(), aCx, aMessage, aTransferable, aRv);
}
auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
if (storageAllowed != nsContentUtils::StorageAccess::eAllow) {
ServiceWorkerManager::LocalizeAndReportToAllClients(
mInfo->Scope(), "ServiceWorkerPostMessageStorageError",
nsTArray<nsString> { NS_ConvertUTF8toUTF16(mInfo->Scope()) });
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
bool
ServiceWorker::MatchesDescriptor(const ServiceWorkerDescriptor& aDescriptor) const
{
// Compare everything in the descriptor except the state. That is mutable
// and may not exactly match.
return mDescriptor.PrincipalInfo() == aDescriptor.PrincipalInfo() &&
mDescriptor.Scope() == aDescriptor.Scope() &&
mDescriptor.ScriptURL() == aDescriptor.ScriptURL() &&
mDescriptor.Id() == aDescriptor.Id();
}
Maybe<ClientInfo> clientInfo = window->GetClientInfo();
Maybe<ClientState> clientState = window->GetClientState();
if (clientInfo.isNothing() || clientState.isNothing()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
void
ServiceWorker::DisconnectFromOwner()
{
nsIGlobalObject* global = GetParentObject();
if (global) {
global->RemoveServiceWorker(this);
}
ServiceWorkerPrivate* workerPrivate = mInfo->WorkerPrivate();
aRv = workerPrivate->SendMessageEvent(aCx, aMessage, aTransferable,
ClientInfoAndState(clientInfo.ref().ToIPC(),
clientState.ref().ToIPC()));
DOMEventTargetHelper::DisconnectFromOwner();
}
} // namespace dom

Просмотреть файл

@ -9,70 +9,96 @@
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ServiceWorkerBinding.h" // For ServiceWorkerState.
#include "mozilla/dom/ServiceWorkerDescriptor.h"
class nsPIDOMWindowInner;
#ifdef XP_WIN
#undef PostMessage
#endif
class nsIGlobalObject;
namespace mozilla {
namespace dom {
class ServiceWorkerInfo;
class ServiceWorkerManager;
class SharedWorker;
bool
ServiceWorkerVisible(JSContext* aCx, JSObject* aObj);
class ServiceWorker final : public DOMEventTargetHelper
{
friend class ServiceWorkerInfo;
public:
// Abstract interface for the internal representation of the
// ServiceWorker object.
class Inner
{
public:
// This will be called when a DOM ServiceWorker object is
// created and takes a strong ref to the Inner object.
// RemoveServiceWorker() is guaranteed to be called on the
// current thread before the ServiceWorker is destroyed.
//
// In addition, the Inner object should check to see if
// the ServiceWorker's state is correct. If not, it should
// be updated automatically by calling SetState(). This is
// necessary to handle race conditions where the DOM
// ServiceWorker object is created while the state is being
// updated in another process.
virtual void
AddServiceWorker(ServiceWorker* aWorker) = 0;
// This is called when the DOM ServiceWorker object is
// destroyed and drops its ref to the Inner object.
virtual void
RemoveServiceWorker(ServiceWorker* aWorker) = 0;
virtual void
PostMessage(nsIGlobalObject* aGlobal,
JSContext* aCx, JS::Handle<JS::Value> aMessage,
const Sequence<JSObject*>& aTransferable,
ErrorResult& aRv) = 0;
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
};
NS_DECL_ISUPPORTS_INHERITED
IMPL_EVENT_HANDLER(statechange)
IMPL_EVENT_HANDLER(error)
static already_AddRefed<ServiceWorker>
Create(nsIGlobalObject* aOwner, const ServiceWorkerDescriptor& aDescriptor);
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
ServiceWorkerState
State() const
{
return mState;
}
State() const;
void
SetState(ServiceWorkerState aState)
{
mState = aState;
}
SetState(ServiceWorkerState aState);
void
GetScriptURL(nsString& aURL) const;
void
DispatchStateChange(ServiceWorkerState aState)
{
DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));
}
#ifdef XP_WIN
#undef PostMessage
#endif
void
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
bool
MatchesDescriptor(const ServiceWorkerDescriptor& aDescriptor) const;
void
DisconnectFromOwner() override;
private:
// This class can only be created from ServiceWorkerInfo::GetOrCreateInstance().
ServiceWorker(nsPIDOMWindowInner* aWindow, ServiceWorkerInfo* aInfo);
ServiceWorker(nsIGlobalObject* aWindow,
const ServiceWorkerDescriptor& aDescriptor,
Inner* aInner);
// This class is reference-counted and will be destroyed from Release().
~ServiceWorker();
ServiceWorkerState mState;
const RefPtr<ServiceWorkerInfo> mInfo;
ServiceWorkerDescriptor mDescriptor;
const RefPtr<Inner> mInner;
};
} // namespace dom

Просмотреть файл

@ -251,7 +251,7 @@ ServiceWorkerContainer::GetController()
// Right now we only know how to create ServiceWorker DOM objects on
// the main thread with a window. In the future this should operate
// on only nsIGlobalObject somehow.
mControllerWorker = info->GetOrCreateInstance(inner);
mControllerWorker = inner->GetOrCreateServiceWorker(info->Descriptor());
}
RefPtr<ServiceWorker> ref = mControllerWorker;

Просмотреть файл

@ -15,6 +15,7 @@ namespace dom {
ServiceWorkerDescriptor::ServiceWorkerDescriptor(uint64_t aId,
nsIPrincipal* aPrincipal,
const nsACString& aScope,
const nsACString& aScriptURL,
ServiceWorkerState aState)
: mData(MakeUnique<IPCServiceWorkerDescriptor>())
{
@ -23,14 +24,17 @@ ServiceWorkerDescriptor::ServiceWorkerDescriptor(uint64_t aId,
mData->id() = aId;
mData->scope() = aScope;
mData->scriptURL() = aScriptURL;
mData->state() = aState;
}
ServiceWorkerDescriptor::ServiceWorkerDescriptor(uint64_t aId,
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
const nsACString& aScope,
const nsACString& aScriptURL,
ServiceWorkerState aState)
: mData(MakeUnique<IPCServiceWorkerDescriptor>(aId, aPrincipalInfo,
nsCString(aScriptURL),
nsCString(aScope), aState))
{
}
@ -94,6 +98,12 @@ ServiceWorkerDescriptor::Scope() const
return mData->scope();
}
const nsCString&
ServiceWorkerDescriptor::ScriptURL() const
{
return mData->scriptURL();
}
ServiceWorkerState
ServiceWorkerDescriptor::State() const
{

Просмотреть файл

@ -25,7 +25,7 @@ enum class ServiceWorkerState : uint8_t;
// accurate. Currently the only variable field is the ServiceWorkerState.
class ServiceWorkerDescriptor final
{
// This class is largely a wrapper wround an IPDL generated struct. We
// This class is largely a wrapper around an IPDL generated struct. We
// need the wrapper class since IPDL generated code includes windows.h
// which is in turn incompatible with bindings code.
UniquePtr<IPCServiceWorkerDescriptor> mData;
@ -34,11 +34,13 @@ public:
ServiceWorkerDescriptor(uint64_t aId,
nsIPrincipal* aPrincipal,
const nsACString& aScope,
const nsACString& aScriptURL,
ServiceWorkerState aState);
ServiceWorkerDescriptor(uint64_t aId,
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
const nsACString& aScope,
const nsACString& aScriptURL,
ServiceWorkerState aState);
explicit ServiceWorkerDescriptor(const IPCServiceWorkerDescriptor& aDescriptor);
@ -67,6 +69,9 @@ public:
const nsCString&
Scope() const;
const nsCString&
ScriptURL() const;
ServiceWorkerState
State() const;

Просмотреть файл

@ -7,7 +7,12 @@
#define _mozilla_dom_ServiceWorkerIPCUtils_h
#include "ipc/IPCMessageUtils.h"
// Undo X11/X.h's definition of None
#undef None
#include "mozilla/dom/ServiceWorkerBinding.h"
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
namespace IPC {
@ -18,6 +23,13 @@ namespace IPC {
mozilla::dom::ServiceWorkerState::EndGuard_>
{};
template<>
struct ParamTraits<mozilla::dom::ServiceWorkerUpdateViaCache> :
public ContiguousEnumSerializer<mozilla::dom::ServiceWorkerUpdateViaCache,
mozilla::dom::ServiceWorkerUpdateViaCache::Imports,
mozilla::dom::ServiceWorkerUpdateViaCache::EndGuard_>
{};
} // namespace IPC
#endif // _mozilla_dom_ServiceWorkerIPCUtils_h

Просмотреть файл

@ -34,7 +34,7 @@ NS_IMETHODIMP
ServiceWorkerInfo::GetScriptSpec(nsAString& aScriptSpec)
{
MOZ_ASSERT(NS_IsMainThread());
CopyUTF8toUTF16(mScriptSpec, aScriptSpec);
CopyUTF8toUTF16(mDescriptor.ScriptURL(), aScriptSpec);
return NS_OK;
}
@ -113,35 +113,6 @@ ServiceWorkerInfo::DetachDebugger()
return mServiceWorkerPrivate->DetachDebugger();
}
void
ServiceWorkerInfo::AppendWorker(ServiceWorker* aWorker)
{
MOZ_ASSERT(aWorker);
#ifdef DEBUG
nsAutoString workerURL;
aWorker->GetScriptURL(workerURL);
MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mScriptSpec)));
#endif
MOZ_ASSERT(!mInstances.Contains(aWorker));
mInstances.AppendElement(aWorker);
aWorker->SetState(State());
}
void
ServiceWorkerInfo::RemoveWorker(ServiceWorker* aWorker)
{
MOZ_ASSERT(aWorker);
#ifdef DEBUG
nsAutoString workerURL;
aWorker->GetScriptURL(workerURL);
MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mScriptSpec)));
#endif
MOZ_ASSERT(mInstances.Contains(aWorker));
mInstances.RemoveElement(aWorker);
}
namespace {
class ChangeStateUpdater final : public Runnable
@ -159,16 +130,9 @@ public:
NS_IMETHOD Run() override
{
// We need to update the state of all instances atomically before notifying
// them to make sure that the observed state for all instances inside
// statechange event handlers is correct.
for (size_t i = 0; i < mInstances.Length(); ++i) {
mInstances[i]->SetState(mState);
}
for (size_t i = 0; i < mInstances.Length(); ++i) {
mInstances[i]->DispatchStateChange(mState);
}
return NS_OK;
}
@ -221,8 +185,8 @@ ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
const nsAString& aCacheName,
nsLoadFlags aImportsLoadFlags)
: mPrincipal(aPrincipal)
, mDescriptor(GetNextID(), aPrincipal, aScope, ServiceWorkerState::Parsed)
, mScriptSpec(aScriptSpec)
, mDescriptor(GetNextID(), aPrincipal, aScope, aScriptSpec,
ServiceWorkerState::Parsed)
, mCacheName(aCacheName)
, mImportsLoadFlags(aImportsLoadFlags)
, mCreationTime(PR_Now())
@ -237,7 +201,7 @@ ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
MOZ_ASSERT(mPrincipal);
// cache origin attributes so we can use them off main thread
mOriginAttributes = mPrincipal->OriginAttributesRef();
MOZ_ASSERT(!mScriptSpec.IsEmpty());
MOZ_ASSERT(!mDescriptor.ScriptURL().IsEmpty());
MOZ_ASSERT(!mCacheName.IsEmpty());
// Scripts of a service worker should always be loaded bypass service workers.
@ -260,27 +224,70 @@ ServiceWorkerInfo::GetNextID() const
return ++gServiceWorkerInfoCurrentID;
}
already_AddRefed<ServiceWorker>
ServiceWorkerInfo::GetOrCreateInstance(nsPIDOMWindowInner* aWindow)
void
ServiceWorkerInfo::AddServiceWorker(ServiceWorker* aWorker)
{
MOZ_DIAGNOSTIC_ASSERT(aWorker);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
nsAutoString workerURL;
aWorker->GetScriptURL(workerURL);
MOZ_DIAGNOSTIC_ASSERT(
workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
#endif
MOZ_ASSERT(!mInstances.Contains(aWorker));
mInstances.AppendElement(aWorker);
aWorker->SetState(State());
}
void
ServiceWorkerInfo::RemoveServiceWorker(ServiceWorker* aWorker)
{
MOZ_DIAGNOSTIC_ASSERT(aWorker);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
nsAutoString workerURL;
aWorker->GetScriptURL(workerURL);
MOZ_DIAGNOSTIC_ASSERT(
workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
#endif
MOZ_ASSERT(mInstances.Contains(aWorker));
mInstances.RemoveElement(aWorker);
}
void
ServiceWorkerInfo::PostMessage(nsIGlobalObject* aGlobal,
JSContext* aCx, JS::Handle<JS::Value> aMessage,
const Sequence<JSObject*>& aTransferable,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aWindow);
RefPtr<ServiceWorker> ref;
for (uint32_t i = 0; i < mInstances.Length(); ++i) {
MOZ_ASSERT(mInstances[i]);
if (mInstances[i]->GetOwner() == aWindow) {
ref = mInstances[i];
break;
}
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
if (NS_WARN_IF(!window || !window->GetExtantDoc())) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (!ref) {
ref = new ServiceWorker(aWindow, this);
auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
if (storageAllowed != nsContentUtils::StorageAccess::eAllow) {
ServiceWorkerManager::LocalizeAndReportToAllClients(
Scope(), "ServiceWorkerPostMessageStorageError",
nsTArray<nsString> { NS_ConvertUTF8toUTF16(Scope()) });
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
return ref.forget();
Maybe<ClientInfo> clientInfo = window->GetClientInfo();
Maybe<ClientState> clientState = window->GetClientState();
if (NS_WARN_IF(clientInfo.isNothing() || clientState.isNothing())) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
aRv = mServiceWorkerPrivate->SendMessageEvent(aCx, aMessage, aTransferable,
ClientInfoAndState(clientInfo.ref().ToIPC(),
clientState.ref().ToIPC()));
}
void

Просмотреть файл

@ -12,11 +12,11 @@
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/OriginAttributes.h"
#include "nsIServiceWorkerManager.h"
#include "ServiceWorker.h"
namespace mozilla {
namespace dom {
class ServiceWorker;
class ServiceWorkerPrivate;
/*
@ -26,11 +26,11 @@ class ServiceWorkerPrivate;
* by this class and spawn a ServiceWorker in the right global when required.
*/
class ServiceWorkerInfo final : public nsIServiceWorkerInfo
, public ServiceWorker::Inner
{
private:
nsCOMPtr<nsIPrincipal> mPrincipal;
ServiceWorkerDescriptor mDescriptor;
const nsCString mScriptSpec;
const nsString mCacheName;
OriginAttributes mOriginAttributes;
@ -76,6 +76,19 @@ private:
uint64_t
GetNextID() const;
// ServiceWorker::Inner implementation
virtual void
AddServiceWorker(ServiceWorker* aWorker) override;
virtual void
RemoveServiceWorker(ServiceWorker* aWorker) override;
virtual void
PostMessage(nsIGlobalObject* aGlobal,
JSContext* aCx, JS::Handle<JS::Value> aMessage,
const Sequence<JSObject*>& aTransferable,
ErrorResult& aRv) override;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISERVICEWORKERINFO
@ -96,7 +109,7 @@ public:
const nsCString&
ScriptSpec() const
{
return mScriptSpec;
return mDescriptor.ScriptURL();
}
const nsCString&
@ -186,15 +199,6 @@ public:
return mHandlesFetch != Disabled;
}
void
AppendWorker(ServiceWorker* aWorker);
void
RemoveWorker(ServiceWorker* aWorker);
already_AddRefed<ServiceWorker>
GetOrCreateInstance(nsPIDOMWindowInner* aWindow);
void
UpdateInstalledTime();

Просмотреть файл

@ -192,7 +192,7 @@ PopulateRegistrationData(nsIPrincipal* aPrincipal,
return rv;
}
aData.scope() = aRegistration->mScope;
aData.scope() = aRegistration->Scope();
RefPtr<ServiceWorkerInfo> newest = aRegistration->Newest();
if (NS_WARN_IF(!newest)) {
@ -465,7 +465,7 @@ class ServiceWorkerResolveWindowPromiseOnRegisterCallback final : public Service
RefPtr<ServiceWorkerRegistrationInfo> reg = registerJob->GetRegistration();
RefPtr<ServiceWorkerRegistration> swr =
window->GetServiceWorkerRegistration(NS_ConvertUTF8toUTF16(reg->mScope));
window->GetServiceWorkerRegistration(NS_ConvertUTF8toUTF16(reg->Scope()));
promise->MaybeResolve(swr);
}
@ -1003,7 +1003,7 @@ public:
for (uint32_t i = 0; i < data->mOrderedScopes.Length(); ++i) {
RefPtr<ServiceWorkerRegistrationInfo> info =
data->mInfos.GetWeak(data->mOrderedScopes[i]);
if (info->mPendingUninstall) {
if (info->IsPendingUninstall()) {
continue;
}
@ -1146,7 +1146,7 @@ public:
return NS_OK;
}
NS_ConvertUTF8toUTF16 scope(registration->mScope);
NS_ConvertUTF8toUTF16 scope(registration->Scope());
RefPtr<ServiceWorkerRegistration> swr =
mWindow->GetServiceWorkerRegistration(scope);
mPromise->MaybeResolve(swr);
@ -1463,7 +1463,7 @@ ServiceWorkerManager::CheckReadyPromise(nsPIDOMWindowInner* aWindow,
GetServiceWorkerRegistrationInfo(principal, aURI);
if (registration && registration->GetActive()) {
NS_ConvertUTF8toUTF16 scope(registration->mScope);
NS_ConvertUTF8toUTF16 scope(registration->Scope());
RefPtr<ServiceWorkerRegistration> swr =
aWindow->GetServiceWorkerRegistration(scope);
aPromise->MaybeResolve(swr);
@ -1651,7 +1651,7 @@ ServiceWorkerManager::WorkerIsIdle(ServiceWorkerInfo* aWorker)
return;
}
if (!reg->IsControllingClients() && reg->mPendingUninstall) {
if (!reg->IsControllingClients() && reg->IsPendingUninstall()) {
RemoveRegistration(reg);
return;
}
@ -1840,8 +1840,8 @@ ServiceWorkerManager::LoadRegistration(
const nsCString& currentWorkerURL = aRegistration.currentWorkerURL();
if (!currentWorkerURL.IsEmpty()) {
registration->SetActive(
new ServiceWorkerInfo(registration->mPrincipal,
registration->mScope,
new ServiceWorkerInfo(registration->Principal(),
registration->Scope(),
currentWorkerURL,
aRegistration.cacheName(),
importsLoadFlags));
@ -1962,12 +1962,12 @@ ServiceWorkerManager::GetServiceWorkerRegistrationInfo(const nsACString& aScopeK
#ifdef DEBUG
nsAutoCString origin;
rv = registration->mPrincipal->GetOrigin(origin);
rv = registration->Principal()->GetOrigin(origin);
MOZ_ASSERT(NS_SUCCEEDED(rv));
MOZ_ASSERT(origin.Equals(aScopeKey));
#endif
if (registration->mPendingUninstall) {
if (registration->IsPendingUninstall()) {
return nullptr;
}
return registration.forget();
@ -2015,7 +2015,7 @@ ServiceWorkerManager::AddScopeAndRegistration(const nsACString& aScope,
ServiceWorkerRegistrationInfo* aInfo)
{
MOZ_ASSERT(aInfo);
MOZ_ASSERT(aInfo->mPrincipal);
MOZ_ASSERT(aInfo->Principal());
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (!swm) {
@ -2024,7 +2024,7 @@ ServiceWorkerManager::AddScopeAndRegistration(const nsACString& aScope,
}
nsAutoCString scopeKey;
nsresult rv = swm->PrincipalToScopeKey(aInfo->mPrincipal, scopeKey);
nsresult rv = swm->PrincipalToScopeKey(aInfo->Principal(), scopeKey);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@ -2118,7 +2118,7 @@ ServiceWorkerManager::RemoveScopeAndRegistration(ServiceWorkerRegistrationInfo*
}
nsAutoCString scopeKey;
nsresult rv = swm->PrincipalToScopeKey(aRegistration->mPrincipal, scopeKey);
nsresult rv = swm->PrincipalToScopeKey(aRegistration->Principal(), scopeKey);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@ -2128,7 +2128,7 @@ ServiceWorkerManager::RemoveScopeAndRegistration(ServiceWorkerRegistrationInfo*
return;
}
if (auto entry = data->mUpdateTimers.Lookup(aRegistration->mScope)) {
if (auto entry = data->mUpdateTimers.Lookup(aRegistration->Scope())) {
entry.Data()->Cancel();
entry.Remove();
}
@ -2136,8 +2136,8 @@ ServiceWorkerManager::RemoveScopeAndRegistration(ServiceWorkerRegistrationInfo*
// Verify there are no controlled clients for the purged registration.
for (auto iter = swm->mControlledClients.Iter(); !iter.Done(); iter.Next()) {
auto& reg = iter.UserData()->mRegistrationInfo;
if (reg->mScope.Equals(aRegistration->mScope) &&
reg->mPrincipal->Equals(aRegistration->mPrincipal)) {
if (reg->Scope().Equals(aRegistration->Scope()) &&
reg->Principal()->Equals(aRegistration->Principal())) {
MOZ_DIAGNOSTIC_ASSERT(false,
"controlled client when removing registration");
iter.Remove();
@ -2146,8 +2146,8 @@ ServiceWorkerManager::RemoveScopeAndRegistration(ServiceWorkerRegistrationInfo*
}
RefPtr<ServiceWorkerRegistrationInfo> info;
data->mInfos.Remove(aRegistration->mScope, getter_AddRefs(info));
data->mOrderedScopes.RemoveElement(aRegistration->mScope);
data->mInfos.Remove(aRegistration->Scope(), getter_AddRefs(info));
data->mOrderedScopes.RemoveElement(aRegistration->Scope());
swm->NotifyListenersOnUnregister(info);
swm->MaybeRemoveRegistrationInfo(scopeKey);
@ -2216,7 +2216,7 @@ ServiceWorkerManager::StopControllingRegistration(ServiceWorkerRegistrationInfo*
return;
}
if (aRegistration->mPendingUninstall) {
if (aRegistration->IsPendingUninstall()) {
RemoveRegistration(aRegistration);
return;
}
@ -2246,7 +2246,7 @@ ServiceWorkerManager::GetScopeForUrl(nsIPrincipal* aPrincipal,
return NS_ERROR_FAILURE;
}
aScope = NS_ConvertUTF8toUTF16(r->mScope);
aScope = NS_ConvertUTF8toUTF16(r->Scope());
return NS_OK;
}
@ -2302,7 +2302,7 @@ ServiceWorkerManager::FireUpdateFoundOnServiceWorkerRegistrations(
MOZ_ASSERT(!regScope.IsEmpty());
NS_ConvertUTF16toUTF8 utf8Scope(regScope);
if (utf8Scope.Equals(aRegistration->mScope)) {
if (utf8Scope.Equals(aRegistration->Scope())) {
target->UpdateFound();
}
}
@ -2366,7 +2366,8 @@ ServiceWorkerManager::GetServiceWorkerForScope(nsPIDOMWindowInner* aWindow,
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
RefPtr<ServiceWorker> serviceWorker = info->GetOrCreateInstance(aWindow);
RefPtr<ServiceWorker> serviceWorker =
aWindow->GetOrCreateServiceWorker(info->Descriptor());
serviceWorker->SetState(info->State());
serviceWorker.forget(aServiceWorker);
@ -2669,7 +2670,7 @@ ServiceWorkerManager::TransitionServiceWorkerRegistrationWorker(ServiceWorkerReg
NS_ConvertUTF16toUTF8 utf8Scope(regScope);
if (utf8Scope.Equals(aRegistration->mScope)) {
if (utf8Scope.Equals(aRegistration->Scope())) {
target->TransitionWorker(aWhichOne);
}
}
@ -2689,7 +2690,7 @@ ServiceWorkerManager::InvalidateServiceWorkerRegistrationWorker(ServiceWorkerReg
NS_ConvertUTF16toUTF8 utf8Scope(regScope);
if (utf8Scope.Equals(aRegistration->mScope)) {
if (utf8Scope.Equals(aRegistration->Scope())) {
target->InvalidateWorkers(aWhichOnes);
}
}
@ -2708,7 +2709,7 @@ ServiceWorkerManager::NotifyServiceWorkerRegistrationRemoved(ServiceWorkerRegist
NS_ConvertUTF16toUTF8 utf8Scope(regScope);
if (utf8Scope.Equals(aRegistration->mScope)) {
if (utf8Scope.Equals(aRegistration->Scope())) {
target->RegistrationRemoved();
}
}
@ -2816,7 +2817,7 @@ ServiceWorkerManager::SoftUpdateInternal(const OriginAttributes& aOriginAttribut
}
// "If registration's uninstalling flag is set, abort these steps."
if (registration->mPendingUninstall) {
if (registration->IsPendingUninstall()) {
return;
}
@ -2841,7 +2842,7 @@ ServiceWorkerManager::SoftUpdateInternal(const OriginAttributes& aOriginAttribut
aScope);
RefPtr<ServiceWorkerUpdateJob> job =
new ServiceWorkerUpdateJob(principal, registration->mScope,
new ServiceWorkerUpdateJob(principal, registration->Scope(),
newest->ScriptSpec(), nullptr,
registration->GetUpdateViaCache());
@ -2916,7 +2917,7 @@ ServiceWorkerManager::UpdateInternal(nsIPrincipal* aPrincipal,
// "Invoke Update algorithm, or its equivalent, with client, registration as
// its argument."
RefPtr<ServiceWorkerUpdateJob> job =
new ServiceWorkerUpdateJob(aPrincipal, registration->mScope,
new ServiceWorkerUpdateJob(aPrincipal, registration->Scope(),
newest->ScriptSpec(), nullptr,
registration->GetUpdateViaCache());
@ -2936,7 +2937,7 @@ ServiceWorkerManager::MaybeClaimClient(nsIDocument* aDocument,
RefPtr<GenericPromise> ref;
// Same origin check
if (!aWorkerRegistration->mPrincipal->Equals(aDocument->NodePrincipal())) {
if (!aWorkerRegistration->Principal()->Equals(aDocument->NodePrincipal())) {
ref = GenericPromise::CreateAndReject(NS_ERROR_DOM_SECURITY_ERR, __func__);
return ref.forget();
}
@ -3144,7 +3145,7 @@ ServiceWorkerManager::MaybeRemoveRegistration(ServiceWorkerRegistrationInfo* aRe
{
MOZ_ASSERT(aRegistration);
RefPtr<ServiceWorkerInfo> newest = aRegistration->Newest();
if (!newest && HasScope(aRegistration->mPrincipal, aRegistration->mScope)) {
if (!newest && HasScope(aRegistration->Principal(), aRegistration->Scope())) {
RemoveRegistration(aRegistration);
}
}
@ -3165,10 +3166,10 @@ ServiceWorkerManager::RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistr
// null workers (case 3).
#ifdef DEBUG
RefPtr<ServiceWorkerInfo> newest = aRegistration->Newest();
MOZ_ASSERT(aRegistration->mPendingUninstall || !newest);
MOZ_ASSERT(aRegistration->IsPendingUninstall() || !newest);
#endif
MOZ_ASSERT(HasScope(aRegistration->mPrincipal, aRegistration->mScope));
MOZ_ASSERT(HasScope(aRegistration->Principal(), aRegistration->Scope()));
// When a registration is removed, we must clear its contents since the DOM
// object may be held by content script.
@ -3236,7 +3237,7 @@ ServiceWorkerManager::GetAllRegistrations(nsIArray** aResult)
ServiceWorkerRegistrationInfo* reg = it2.UserData();
MOZ_ASSERT(reg);
if (reg->mPendingUninstall) {
if (reg->IsPendingUninstall()) {
continue;
}
@ -3257,18 +3258,18 @@ ServiceWorkerManager::ForceUnregister(RegistrationDataPerPrincipal* aRegistratio
MOZ_ASSERT(aRegistration);
RefPtr<ServiceWorkerJobQueue> queue;
aRegistrationData->mJobQueues.Get(aRegistration->mScope, getter_AddRefs(queue));
aRegistrationData->mJobQueues.Get(aRegistration->Scope(), getter_AddRefs(queue));
if (queue) {
queue->CancelAll();
}
if (auto entry = aRegistrationData->mUpdateTimers.Lookup(aRegistration->mScope)) {
if (auto entry = aRegistrationData->mUpdateTimers.Lookup(aRegistration->Scope())) {
entry.Data()->Cancel();
entry.Remove();
}
// Since Unregister is async, it is ok to call it in an enumeration.
Unregister(aRegistration->mPrincipal, nullptr, NS_ConvertUTF8toUTF16(aRegistration->mScope));
Unregister(aRegistration->Principal(), nullptr, NS_ConvertUTF8toUTF16(aRegistration->Scope()));
}
NS_IMETHODIMP
@ -3345,10 +3346,10 @@ ServiceWorkerManager::RemoveAllRegistrations(OriginAttributesPattern* aPattern)
ServiceWorkerRegistrationInfo* reg = it2.UserData();
MOZ_ASSERT(reg);
MOZ_ASSERT(reg->mPrincipal);
MOZ_ASSERT(reg->Principal());
bool matches =
aPattern->Matches(reg->mPrincipal->OriginAttributesRef());
aPattern->Matches(reg->Principal()->OriginAttributesRef());
if (!matches) {
continue;
}

Просмотреть файл

@ -1854,10 +1854,7 @@ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
rv = PrincipalToPrincipalInfo(mInfo->Principal(), &principalInfo);
NS_ENSURE_SUCCESS(rv, rv);
info.mServiceWorkerDescriptor.emplace(ServiceWorkerDescriptor(mInfo->ID(),
principalInfo,
mInfo->Scope(),
mInfo->State()));
info.mServiceWorkerDescriptor.emplace(mInfo->Descriptor());
info.mLoadGroup = aLoadGroup;
info.mLoadFailedAsyncRunnable = aLoadFailedRunnable;

Просмотреть файл

@ -44,8 +44,8 @@ ServiceWorkerRegisterJob::AsyncExecute()
// it to disk again. We preemptively removed it earlier during
// unregister so that closing the window by shutting down the browser
// results in the registration being gone on restart.
if (registration->mPendingUninstall) {
registration->mPendingUninstall = false;
if (registration->IsPendingUninstall()) {
registration->ClearPendingUninstall();
swm->StoreRegistration(mPrincipal, registration);
// Its possible that a ready promise is created between when the
// uninstalling flag is set and when we resurrect the registration

Просмотреть файл

@ -0,0 +1,269 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "ServiceWorkerInfo.h"
namespace mozilla {
namespace dom {
Maybe<IPCServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::NewestInternal() const
{
Maybe<IPCServiceWorkerDescriptor> result;
if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(mData->installing().get_IPCServiceWorkerDescriptor());
} else if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(mData->waiting().get_IPCServiceWorkerDescriptor());
} else if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(mData->active().get_IPCServiceWorkerDescriptor());
}
return Move(result);
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
nsIPrincipal* aPrincipal,
const nsACString& aScope,
ServiceWorkerUpdateViaCache aUpdateViaCache)
: mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>())
{
MOZ_ALWAYS_SUCCEEDS(
PrincipalToPrincipalInfo(aPrincipal, &mData->principalInfo()));
mData->scope() = aScope;
mData->updateViaCache() = aUpdateViaCache;
mData->installing() = void_t();
mData->waiting() = void_t();
mData->active() = void_t();
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
const nsACString& aScope,
ServiceWorkerUpdateViaCache aUpdateViaCache)
: mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(aPrincipalInfo,
nsCString(aScope),
aUpdateViaCache,
void_t(),
void_t(),
void_t()))
{
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(const IPCServiceWorkerRegistrationDescriptor& aDescriptor)
: mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(aDescriptor))
{
MOZ_DIAGNOSTIC_ASSERT(IsValid());
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(const ServiceWorkerRegistrationDescriptor& aRight)
{
// UniquePtr doesn't have a default copy constructor, so we can't rely
// on default copy construction. Use the assignment operator to
// minimize duplication.
operator=(aRight);
}
ServiceWorkerRegistrationDescriptor&
ServiceWorkerRegistrationDescriptor::operator=(const ServiceWorkerRegistrationDescriptor& aRight)
{
mData.reset();
mData = MakeUnique<IPCServiceWorkerRegistrationDescriptor>(*aRight.mData);
MOZ_DIAGNOSTIC_ASSERT(IsValid());
return *this;
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(ServiceWorkerRegistrationDescriptor&& aRight)
: mData(Move(aRight.mData))
{
MOZ_DIAGNOSTIC_ASSERT(IsValid());
}
ServiceWorkerRegistrationDescriptor&
ServiceWorkerRegistrationDescriptor::operator=(ServiceWorkerRegistrationDescriptor&& aRight)
{
mData.reset();
mData = Move(aRight.mData);
MOZ_DIAGNOSTIC_ASSERT(IsValid());
return *this;
}
bool
ServiceWorkerRegistrationDescriptor::operator==(const ServiceWorkerRegistrationDescriptor& aRight) const
{
return *mData == *aRight.mData;
}
ServiceWorkerUpdateViaCache
ServiceWorkerRegistrationDescriptor::UpdateViaCache() const
{
return mData->updateViaCache();
}
const mozilla::ipc::PrincipalInfo&
ServiceWorkerRegistrationDescriptor::PrincipalInfo() const
{
return mData->principalInfo();
}
const nsCString&
ServiceWorkerRegistrationDescriptor::Scope() const
{
return mData->scope();
}
Maybe<ServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::GetInstalling() const
{
Maybe<ServiceWorkerDescriptor> result;
if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(ServiceWorkerDescriptor(
mData->installing().get_IPCServiceWorkerDescriptor()));
}
return Move(result);
}
Maybe<ServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::GetWaiting() const
{
Maybe<ServiceWorkerDescriptor> result;
if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(ServiceWorkerDescriptor(
mData->waiting().get_IPCServiceWorkerDescriptor()));
}
return Move(result);
}
Maybe<ServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::GetActive() const
{
Maybe<ServiceWorkerDescriptor> result;
if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(ServiceWorkerDescriptor(
mData->active().get_IPCServiceWorkerDescriptor()));
}
return Move(result);
}
Maybe<ServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::Newest() const
{
Maybe<ServiceWorkerDescriptor> result;
Maybe<IPCServiceWorkerDescriptor> newest(NewestInternal());
if (newest.isSome()) {
result.emplace(ServiceWorkerDescriptor(newest.ref()));
}
return Move(result);
}
namespace {
bool
IsValidWorker(const OptionalIPCServiceWorkerDescriptor& aWorker,
const nsACString& aScope,
const mozilla::ipc::ContentPrincipalInfo& aContentPrincipal)
{
if (aWorker.type() == OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
return true;
}
auto& worker = aWorker.get_IPCServiceWorkerDescriptor();
if (worker.scope() != aScope) {
return false;
}
auto& principalInfo = worker.principalInfo();
if (principalInfo.type() != mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
return false;
}
auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
if (contentPrincipal.originNoSuffix() != aContentPrincipal.originNoSuffix() ||
contentPrincipal.attrs() != aContentPrincipal.attrs()) {
return false;
}
return true;
}
} // anonymous namespace
bool
ServiceWorkerRegistrationDescriptor::IsValid() const
{
auto& principalInfo = PrincipalInfo();
if (principalInfo.type() != mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
return false;
}
auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
if (!IsValidWorker(mData->installing(), Scope(), contentPrincipal) ||
!IsValidWorker(mData->waiting(), Scope(), contentPrincipal) ||
!IsValidWorker(mData->active(), Scope(), contentPrincipal)) {
return false;
}
return true;
}
void
ServiceWorkerRegistrationDescriptor::SetUpdateViaCache(ServiceWorkerUpdateViaCache aUpdateViaCache)
{
mData->updateViaCache() = aUpdateViaCache;
}
void
ServiceWorkerRegistrationDescriptor::SetWorkers(ServiceWorkerInfo* aInstalling,
ServiceWorkerInfo* aWaiting,
ServiceWorkerInfo* aActive)
{
if (aInstalling) {
mData->installing() = aInstalling->Descriptor().ToIPC();
} else {
mData->installing() = void_t();
}
if (aWaiting) {
mData->waiting() = aWaiting->Descriptor().ToIPC();
} else {
mData->waiting() = void_t();
}
if (aActive) {
mData->active() = aActive->Descriptor().ToIPC();
} else {
mData->active() = void_t();
}
MOZ_DIAGNOSTIC_ASSERT(IsValid());
}
void
ServiceWorkerRegistrationDescriptor::SetWorkers(OptionalIPCServiceWorkerDescriptor& aInstalling,
OptionalIPCServiceWorkerDescriptor& aWaiting,
OptionalIPCServiceWorkerDescriptor& aActive)
{
mData->installing() = aInstalling;
mData->waiting() = aWaiting;
mData->active() = aActive;
MOZ_DIAGNOSTIC_ASSERT(IsValid());
}
const IPCServiceWorkerRegistrationDescriptor&
ServiceWorkerRegistrationDescriptor::ToIPC() const
{
return *mData;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,110 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _mozilla_dom_ServiceWorkerRegistrationDescriptor_h
#define _mozilla_dom_ServiceWorkerRegistrationDescriptor_h
#include "mozilla/Maybe.h"
#include "mozilla/dom/IPCServiceWorkerRegistrationDescriptor.h"
#include "mozilla/dom/ServiceWorkerDescriptor.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
namespace ipc {
class PrincipalInfo;
} // namespace ipc
namespace dom {
class IPCServiceWorkerRegistrationDescriptor;
class ServiceWorkerInfo;
enum class ServiceWorkerUpdateViaCache : uint8_t;
// This class represents a snapshot of a particular
// ServiceWorkerRegistrationInfo object. It is threadsafe and can be
// transferred across processes.
class ServiceWorkerRegistrationDescriptor final
{
// This class is largely a wrapper wround an IPDL generated struct. We
// need the wrapper class since IPDL generated code includes windows.h
// which is in turn incompatible with bindings code.
UniquePtr<IPCServiceWorkerRegistrationDescriptor> mData;
Maybe<IPCServiceWorkerDescriptor>
NewestInternal() const;
public:
ServiceWorkerRegistrationDescriptor(nsIPrincipal* aPrincipal,
const nsACString& aScope,
ServiceWorkerUpdateViaCache aUpdateViaCache);
ServiceWorkerRegistrationDescriptor(const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
const nsACString& aScope,
ServiceWorkerUpdateViaCache aUpdateViaCache);
explicit ServiceWorkerRegistrationDescriptor(const IPCServiceWorkerRegistrationDescriptor& aDescriptor);
ServiceWorkerRegistrationDescriptor(const ServiceWorkerRegistrationDescriptor& aRight);
ServiceWorkerRegistrationDescriptor&
operator=(const ServiceWorkerRegistrationDescriptor& aRight);
ServiceWorkerRegistrationDescriptor(ServiceWorkerRegistrationDescriptor&& aRight);
ServiceWorkerRegistrationDescriptor&
operator=(ServiceWorkerRegistrationDescriptor&& aRight);
~ServiceWorkerRegistrationDescriptor() = default;
bool
operator==(const ServiceWorkerRegistrationDescriptor& aRight) const;
ServiceWorkerUpdateViaCache
UpdateViaCache() const;
const mozilla::ipc::PrincipalInfo&
PrincipalInfo() const;
const nsCString&
Scope() const;
Maybe<ServiceWorkerDescriptor>
GetInstalling() const;
Maybe<ServiceWorkerDescriptor>
GetWaiting() const;
Maybe<ServiceWorkerDescriptor>
GetActive() const;
Maybe<ServiceWorkerDescriptor>
Newest() const;
bool
IsValid() const;
void
SetUpdateViaCache(ServiceWorkerUpdateViaCache aUpdateViaCache);
void
SetWorkers(ServiceWorkerInfo* aInstalling,
ServiceWorkerInfo* aWaiting,
ServiceWorkerInfo* aActive);
void
SetWorkers(OptionalIPCServiceWorkerDescriptor& aInstalling,
OptionalIPCServiceWorkerDescriptor& aWaiting,
OptionalIPCServiceWorkerDescriptor& aActive);
// Expose the underlying IPC type so that it can be passed via IPC.
const IPCServiceWorkerRegistrationDescriptor&
ToIPC() const;
};
} // namespace dom
} // namespace mozilla
#endif // _mozilla_dom_ServiceWorkerRegistrationDescriptor_h

Просмотреть файл

@ -78,6 +78,8 @@ ServiceWorkerRegistrationInfo::Clear()
mActiveWorker = nullptr;
}
mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
NotifyChromeRegistrationListeners();
}
@ -85,14 +87,13 @@ ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
const nsACString& aScope,
nsIPrincipal* aPrincipal,
ServiceWorkerUpdateViaCache aUpdateViaCache)
: mControlledClientsCounter(0)
: mPrincipal(aPrincipal)
, mDescriptor(aPrincipal, aScope, aUpdateViaCache)
, mControlledClientsCounter(0)
, mUpdateState(NoUpdate)
, mCreationTime(PR_Now())
, mCreationTimeStamp(TimeStamp::Now())
, mLastUpdateTime(0)
, mUpdateViaCache(aUpdateViaCache)
, mScope(aScope)
, mPrincipal(aPrincipal)
, mPendingUninstall(false)
{}
@ -101,6 +102,36 @@ ServiceWorkerRegistrationInfo::~ServiceWorkerRegistrationInfo()
MOZ_DIAGNOSTIC_ASSERT(!IsControllingClients());
}
const nsCString&
ServiceWorkerRegistrationInfo::Scope() const
{
return mDescriptor.Scope();
}
nsIPrincipal*
ServiceWorkerRegistrationInfo::Principal() const
{
return mPrincipal;
}
bool
ServiceWorkerRegistrationInfo::IsPendingUninstall() const
{
return mPendingUninstall;
}
void
ServiceWorkerRegistrationInfo::SetPendingUninstall()
{
mPendingUninstall = true;
}
void
ServiceWorkerRegistrationInfo::ClearPendingUninstall()
{
mPendingUninstall = false;
}
NS_IMPL_ISUPPORTS(ServiceWorkerRegistrationInfo, nsIServiceWorkerRegistrationInfo)
NS_IMETHODIMP
@ -115,7 +146,7 @@ NS_IMETHODIMP
ServiceWorkerRegistrationInfo::GetScope(nsAString& aScope)
{
MOZ_ASSERT(NS_IsMainThread());
CopyUTF8toUTF16(mScope, aScope);
CopyUTF8toUTF16(Scope(), aScope);
return NS_OK;
}
@ -311,6 +342,9 @@ ServiceWorkerRegistrationInfo::FinishActivate(bool aSuccess)
// Activation never fails, so aSuccess is ignored.
mActiveWorker->UpdateState(ServiceWorkerState::Activated);
mActiveWorker->UpdateActivatedTime();
mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
NotifyChromeRegistrationListeners();
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
@ -420,7 +454,7 @@ ServiceWorkerRegistrationInfo::MaybeScheduleTimeCheckAndUpdate()
mUpdateState = NeedTimeCheckAndUpdate;
}
swm->ScheduleUpdateTimer(mPrincipal, mScope);
swm->ScheduleUpdateTimer(mPrincipal, Scope());
}
void
@ -436,7 +470,7 @@ ServiceWorkerRegistrationInfo::MaybeScheduleUpdate()
mUpdateState = NeedUpdate;
swm->ScheduleUpdateTimer(mPrincipal, mScope);
swm->ScheduleUpdateTimer(mPrincipal, Scope());
}
bool
@ -542,6 +576,8 @@ ServiceWorkerRegistrationInfo::ClearInstalling()
mInstallingWorker->UpdateRedundantTime();
mInstallingWorker = nullptr;
mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
NotifyChromeRegistrationListeners();
}
@ -554,6 +590,9 @@ ServiceWorkerRegistrationInfo::TransitionEvaluatingToInstalling()
mInstallingWorker = mEvaluatingWorker.forget();
mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
NotifyChromeRegistrationListeners();
}
@ -574,6 +613,9 @@ ServiceWorkerRegistrationInfo::TransitionInstallingToWaiting()
TransitionToNextState);
mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
mWaitingWorker->UpdateInstalledTime();
mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
NotifyChromeRegistrationListeners();
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
@ -612,6 +654,9 @@ ServiceWorkerRegistrationInfo::SetActive(ServiceWorkerInfo* aServiceWorker)
// We don't need to update activated time when we load registration from
// registrar.
UpdateRegistrationStateProperties(WhichServiceWorker::ACTIVE_WORKER, Invalidate);
mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
NotifyChromeRegistrationListeners();
}
@ -633,6 +678,9 @@ ServiceWorkerRegistrationInfo::TransitionWaitingToActive()
UpdateRegistrationStateProperties(WhichServiceWorker::WAITING_WORKER,
TransitionToNextState);
mActiveWorker->UpdateState(ServiceWorkerState::Activating);
mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
NotifyChromeRegistrationListeners();
}
@ -645,14 +693,14 @@ ServiceWorkerRegistrationInfo::IsIdle() const
ServiceWorkerUpdateViaCache
ServiceWorkerRegistrationInfo::GetUpdateViaCache() const
{
return mUpdateViaCache;
return mDescriptor.UpdateViaCache();
}
void
ServiceWorkerRegistrationInfo::SetUpdateViaCache(
ServiceWorkerUpdateViaCache aUpdateViaCache)
{
mUpdateViaCache = aUpdateViaCache;
mDescriptor.SetUpdateViaCache(aUpdateViaCache);
}
int64_t
@ -671,5 +719,11 @@ ServiceWorkerRegistrationInfo::SetLastUpdateTime(const int64_t aTime)
mLastUpdateTime = aTime;
}
const ServiceWorkerRegistrationDescriptor&
ServiceWorkerRegistrationInfo::Descriptor() const
{
return mDescriptor;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/dom/ServiceWorkerInfo.h"
#include "mozilla/dom/ServiceWorkerCommon.h"
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
#include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
#include "nsProxyRelease.h"
namespace mozilla {
@ -18,6 +19,10 @@ namespace dom {
class ServiceWorkerRegistrationInfo final
: public nsIServiceWorkerRegistrationInfo
{
nsCOMPtr<nsIPrincipal> mPrincipal;
ServiceWorkerRegistrationDescriptor mDescriptor;
nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
uint32_t mControlledClientsCounter;
enum
@ -33,8 +38,6 @@ class ServiceWorkerRegistrationInfo final
// The time of update is 0, if SWR've never been updated yet.
PRTime mLastUpdateTime;
ServiceWorkerUpdateViaCache mUpdateViaCache;
RefPtr<ServiceWorkerInfo> mEvaluatingWorker;
RefPtr<ServiceWorkerInfo> mActiveWorker;
RefPtr<ServiceWorkerInfo> mWaitingWorker;
@ -42,25 +45,34 @@ class ServiceWorkerRegistrationInfo final
virtual ~ServiceWorkerRegistrationInfo();
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
const nsCString mScope;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
// When unregister() is called on a registration, it is not immediately
// removed since documents may be controlled. It is marked as
// pendingUninstall and when all controlling documents go away, removed.
bool mPendingUninstall;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
ServiceWorkerRegistrationInfo(const nsACString& aScope,
nsIPrincipal* aPrincipal,
ServiceWorkerUpdateViaCache aUpdateViaCache);
const nsCString&
Scope() const;
nsIPrincipal*
Principal() const;
bool
IsPendingUninstall() const;
void
SetPendingUninstall();
void
ClearPendingUninstall();
already_AddRefed<ServiceWorkerInfo>
Newest() const
{
@ -197,6 +209,9 @@ public:
void
SetLastUpdateTime(const int64_t aTime);
const ServiceWorkerRegistrationDescriptor&
Descriptor() const;
private:
enum TransitionType {
TransitionToNextState = 0,

Просмотреть файл

@ -981,8 +981,8 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext
statusAsText.AppendInt(status);
ServiceWorkerManager::LocalizeAndReportToAllClients(
mRegistration->mScope, "ServiceWorkerRegisterNetworkError",
nsTArray<nsString> { NS_ConvertUTF8toUTF16(mRegistration->mScope),
mRegistration->Scope(), "ServiceWorkerRegisterNetworkError",
nsTArray<nsString> { NS_ConvertUTF8toUTF16(mRegistration->Scope()),
statusAsText, mURL });
rv = NS_ERROR_FAILURE;
@ -1016,8 +1016,8 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext
!mimeType.LowerCaseEqualsLiteral("application/x-javascript") &&
!mimeType.LowerCaseEqualsLiteral("application/javascript")) {
ServiceWorkerManager::LocalizeAndReportToAllClients(
mRegistration->mScope, "ServiceWorkerRegisterMimeTypeError",
nsTArray<nsString> { NS_ConvertUTF8toUTF16(mRegistration->mScope),
mRegistration->Scope(), "ServiceWorkerRegisterMimeTypeError",
nsTArray<nsString> { NS_ConvertUTF8toUTF16(mRegistration->Scope()),
NS_ConvertUTF8toUTF16(mimeType), mURL });
rv = NS_ERROR_DOM_SECURITY_ERR;
return rv;

Просмотреть файл

@ -120,17 +120,17 @@ ServiceWorkerUnregisterJob::Unregister()
}
// Note, we send the message to remove the registration from disk now even
// though we may only set the mPendingUninstall flag below. This is
// though we may only set the pending uninstall flag below. This is
// necessary to ensure the registration is removed if the controlled
// clients are closed by shutting down the browser. If the registration
// is resurrected by clearing mPendingUninstall then it should be saved
// is resurrected by clearing pending uninstall then it should be saved
// to disk again.
if (mSendToParent && !registration->mPendingUninstall) {
if (mSendToParent && !registration->IsPendingUninstall()) {
swm->MaybeSendUnregister(mPrincipal, mScope);
}
// "Set registration's uninstalling flag."
registration->mPendingUninstall = true;
registration->SetPendingUninstall();
// "Resolve promise with true"
mResult = true;

Просмотреть файл

@ -260,7 +260,7 @@ ServiceWorkerUpdateJob::AsyncExecute()
RefPtr<ServiceWorkerRegistrationInfo> registration =
swm->GetRegistration(mPrincipal, mScope);
if (!registration || registration->mPendingUninstall) {
if (!registration || registration->IsPendingUninstall()) {
ErrorResult rv;
rv.ThrowTypeError<MSG_SW_UPDATE_BAD_REGISTRATION>(NS_ConvertUTF8toUTF16(mScope),
NS_LITERAL_STRING("uninstalled"));
@ -399,9 +399,9 @@ ServiceWorkerUpdateJob::ComparisonResult(nsresult aStatus,
}
}
if (!StringBeginsWith(mRegistration->mScope, maxPrefix)) {
if (!StringBeginsWith(mRegistration->Scope(), maxPrefix)) {
nsAutoString message;
NS_ConvertUTF8toUTF16 reportScope(mRegistration->mScope);
NS_ConvertUTF8toUTF16 reportScope(mRegistration->Scope());
NS_ConvertUTF8toUTF16 reportMaxPrefix(maxPrefix);
const char16_t* params[] = { reportScope.get(), reportMaxPrefix.get() };
@ -434,8 +434,8 @@ ServiceWorkerUpdateJob::ComparisonResult(nsresult aStatus,
}
RefPtr<ServiceWorkerInfo> sw =
new ServiceWorkerInfo(mRegistration->mPrincipal,
mRegistration->mScope,
new ServiceWorkerInfo(mRegistration->Principal(),
mRegistration->Scope(),
mScriptSpec,
aNewCacheName,
flags);
@ -475,7 +475,7 @@ ServiceWorkerUpdateJob::ContinueUpdateAfterScriptEval(bool aScriptEvaluationResu
ErrorResult error;
NS_ConvertUTF8toUTF16 scriptSpec(mScriptSpec);
NS_ConvertUTF8toUTF16 scope(mRegistration->mScope);
NS_ConvertUTF8toUTF16 scope(mRegistration->Scope());
error.ThrowTypeError<MSG_SW_SCRIPT_THREW>(scriptSpec, scope);
FailUpdateJob(error);
return;

Просмотреть файл

@ -22,6 +22,7 @@ EXPORTS.mozilla.dom += [
'ServiceWorkerManagerParent.h',
'ServiceWorkerRegistrar.h',
'ServiceWorkerRegistration.h',
'ServiceWorkerRegistrationDescriptor.h',
'ServiceWorkerRegistrationInfo.h',
'ServiceWorkerUtils.h',
]
@ -43,6 +44,7 @@ UNIFIED_SOURCES += [
'ServiceWorkerRegisterJob.cpp',
'ServiceWorkerRegistrar.cpp',
'ServiceWorkerRegistration.cpp',
'ServiceWorkerRegistrationDescriptor.cpp',
'ServiceWorkerRegistrationInfo.cpp',
'ServiceWorkerScriptCache.cpp',
'ServiceWorkerUnregisterJob.cpp',
@ -54,6 +56,7 @@ UNIFIED_SOURCES += [
IPDL_SOURCES += [
'IPCServiceWorkerDescriptor.ipdlh',
'IPCServiceWorkerRegistrationDescriptor.ipdlh',
'PServiceWorkerManager.ipdl',
'PServiceWorkerUpdater.ipdl',
'ServiceWorkerRegistrarTypes.ipdlh',

Просмотреть файл

@ -320,6 +320,15 @@ set_define('JS_TRACE_LOGGING',
depends_if('--enable-trace-logging')(lambda x: True))
# Enable breakpoint for artificial OOMs
# =======================================================
js_option('--enable-oom-breakpoint',
help='Enable a breakpoint function for artificial OOMs')
set_define('JS_OOM_BREAKPOINT',
depends_if('--enable-oom-breakpoint')(lambda _: True))
js_option('--enable-perf', env='JS_ION_PERF',
help='Enable Linux perf integration')

Просмотреть файл

@ -1988,7 +1988,7 @@ static const JSFunctionSpec object_static_methods[] = {
JS_FN("keys", obj_keys, 1, 0),
JS_FN("values", obj_values, 1, 0),
JS_FN("entries", obj_entries, 1, 0),
JS_FN("is", obj_is, 2, 0),
JS_INLINABLE_FN("is", obj_is, 2, 0, ObjectIs),
JS_SELF_HOSTED_FN("defineProperty", "ObjectDefineProperty", 3, 0),
JS_FN("defineProperties", obj_defineProperties, 2, 0),
JS_INLINABLE_FN("create", obj_create, 2, 0, ObjectCreate),

Просмотреть файл

@ -0,0 +1,48 @@
function SameValue(x, y) {
if (x === y) {
return (x !== 0) || (1 / x === 1 / y);
}
return (x !== x && y !== y);
}
function* cartesian(a, b = a) {
for (var pa of a) {
for (var pb of b) {
yield [pa, pb];
}
}
}
var testValues = {
Double: `[-0.0, +0.0, 1.0, NaN]`,
Int32: `[-1, 0, 1, 2]`,
Value: `[-0.0, +0.0, "", NaN]`,
};
for (var [xs, ys] of cartesian(Object.values(testValues))) {
var fn = Function(`
var xs = ${xs};
var ys = ${ys};
assertEq(xs.length, 4);
assertEq(ys.length, 4);
// Compare each entry in xs with each entry in ys and ensure Object.is
// computes the same result as SameValue.
var actual = 0, expected = 0;
for (var i = 0; i < 1000; ++i) {
// 0 1 2 3
var xi = i & 3;
// 0 1 2 3 1 2 3 0 2 3 0 1 3 0 1 2
var yi = (i + ((i >> 2) & 3)) & 3;
actual += Object.is(xs[xi], ys[yi]) ? 1 : 0;
expected += SameValue(xs[xi], ys[yi]) ? 1 : 0;
}
assertEq(actual, expected);
`);
for (var i = 0; i < 3; ++i) {
fn();
}
}

Просмотреть файл

@ -0,0 +1,95 @@
var success = 0;
var expected_bool = 0;
var expected_int = 0;
var expected_double = 0;
var expected_string = 0;
var expected_object = 0;
var expected_symbol = 0;
function test_type_stable_ic() {
// Initialize as falsy where possible.
var a = undefined; // No Change, never succeeds
var b = null; // No Change, never succeeds
var c = false; // Alternate between true and false.
var d = 0; // Int32 cache checker, change int values
var e = ""; // String cache checker, change string values
var f = Symbol(); // No change, always succeed, no cache.
var g = {}; // Change objects, always succeed.
var h = -0; // Double cache checker, change double values.
for (var i =0; i < 30; i++) {
// Switch between values to ensure the caches fire.
switch (i % 3) {
case 0:
d = 0;
e = "hi"; expected_string++;
c = true; expected_bool++;
h = 0;
break;
case 1:
d = 1; expected_int++;
e = "";
c = false;
h = NaN;
break;
case 2:
d = 2; expected_int++;
h = 1.234; expected_double++;
g = {};
break;
}
if (a) { success++; }
if (b) { success++; }
if (c) { success++; }
if (d) { success++; }
if (e) { success++; }
if (f) { success++; } expected_symbol++; // Symbol succeed
if (g) { success++; } expected_object++; // Object success
if (h) { success++; }
}
}
test_type_stable_ic();
assertEq(success, expected_bool + expected_double + expected_int + expected_object + expected_string + expected_symbol);
// Test cache failures.
function helper(fun, arg, n)
{
var r = 0;
for (var i = 0; i < n; i++) {
r = fun(arg);
}
return r ? 1 : 0;
}
function test_transition(fun, load, test, before, after) {
var a = helper(fun, load, 30);
var x = helper(fun, test, 5)
assertEq(a, before);
assertEq(x, after)
}
var fun1 = (x) => { if (x) return true; else return false; };
var fun2 = (x) => { if (x) return true; else return false; };
var fun3 = (x) => { if (x) return true; else return false; };
var fun4 = (x) => { if (x) return true; else return false; };
var fun5 = (x) => { if (x) return true; else return false; };
var fun6 = (x) => { if (x) return true; else return false; };
var fun7 = (x) => { if (x) return true; else return false; };
var fun8 = (x) => { if (x) return true; else return false; };
// NaN -> Int32
test_transition(fun1, NaN, 1, 0, 1);
test_transition(fun2, 1, NaN, 1, 0);
// NaN -> Object / Object -> NaN
test_transition(fun3, NaN, {}, 0, 1);
test_transition(fun4, {}, NaN, 1, 0);
// Object -> null / null -> Object
test_transition(fun5, {}, null, 1, 0);
test_transition(fun6, null, {}, 0, 1);
// Symbol -> null, null -> Symbol
test_transition(fun7, Symbol('hi'), null, 1, 0);
test_transition(fun8, null, Symbol('lo'), 0, 1);

Просмотреть файл

@ -0,0 +1,6 @@
// |jit-test| --spectre-mitigations=on
function f() {
return arguments[arguments.length];
}
for (var i = 0; i < 10; i++)
assertEq(f(), undefined);

Просмотреть файл

@ -2095,6 +2095,7 @@ BaselineCacheIRCompiler::init(CacheKind kind)
case CacheKind::GetProp:
case CacheKind::TypeOf:
case CacheKind::GetIterator:
case CacheKind::ToBool:
MOZ_ASSERT(numInputs == 1);
allocator.initInputLocation(0, R0);
break;

Просмотреть файл

@ -461,74 +461,33 @@ DoToBoolFallback(JSContext* cx, BaselineFrame* frame, ICToBool_Fallback* stub, H
{
FallbackICSpew(cx, stub, "ToBool");
bool cond = ToBoolean(arg);
ret.setBoolean(cond);
// Check to see if a new stub should be generated.
if (stub->numOptimizedStubs() >= ICToBool_Fallback::MAX_OPTIMIZED_STUBS) {
// TODO: Discard all stubs in this IC and replace with inert megamorphic stub.
// But for now we just bail.
return true;
}
MOZ_ASSERT(!arg.isBoolean());
JSScript* script = frame->script();
if (stub->state().maybeTransition())
stub->discardStubs(cx);
// Try to generate new stubs.
if (arg.isInt32()) {
JitSpew(JitSpew_BaselineIC, " Generating ToBool(Int32) stub.");
ICToBool_Int32::Compiler compiler(cx);
ICStub* int32Stub = compiler.getStub(compiler.getStubSpace(script));
if (!int32Stub)
return false;
if (stub->state().canAttachStub()) {
stub->addNewStub(int32Stub);
return true;
RootedScript script(cx, frame->script());
jsbytecode* pc = stub->icEntry()->pc(script);
ICStubEngine engine = ICStubEngine::Baseline;
ToBoolIRGenerator gen(cx, script, pc, stub->state().mode(),
arg);
bool attached = false;
if (gen.tryAttachStub()) {
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
BaselineCacheIRStubKind::Regular,
engine, script, stub, &attached);
if (newStub)
JitSpew(JitSpew_BaselineIC, " Attached ToBool CacheIR stub, attached is now %d", attached);
}
if (!attached)
stub->state().trackNotAttached();
}
if (arg.isDouble() && cx->runtime()->jitSupportsFloatingPoint) {
JitSpew(JitSpew_BaselineIC, " Generating ToBool(Double) stub.");
ICToBool_Double::Compiler compiler(cx);
ICStub* doubleStub = compiler.getStub(compiler.getStubSpace(script));
if (!doubleStub)
return false;
stub->addNewStub(doubleStub);
return true;
}
if (arg.isString()) {
JitSpew(JitSpew_BaselineIC, " Generating ToBool(String) stub");
ICToBool_String::Compiler compiler(cx);
ICStub* stringStub = compiler.getStub(compiler.getStubSpace(script));
if (!stringStub)
return false;
stub->addNewStub(stringStub);
return true;
}
if (arg.isNull() || arg.isUndefined()) {
ICToBool_NullUndefined::Compiler compiler(cx);
ICStub* nilStub = compiler.getStub(compiler.getStubSpace(script));
if (!nilStub)
return false;
stub->addNewStub(nilStub);
return true;
}
if (arg.isObject()) {
JitSpew(JitSpew_BaselineIC, " Generating ToBool(Object) stub.");
ICToBool_Object::Compiler compiler(cx);
ICStub* objStub = compiler.getStub(compiler.getStubSpace(script));
if (!objStub)
return false;
stub->addNewStub(objStub);
return true;
}
bool cond = ToBoolean(arg);
ret.setBoolean(cond);
return true;
}
@ -554,150 +513,6 @@ ICToBool_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
return tailCallVM(fun, masm);
}
//
// ToBool_Int32
//
bool
ICToBool_Int32::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(engine_ == Engine::Baseline);
Label failure;
masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
Label ifFalse;
masm.branchTestInt32Truthy(false, R0, &ifFalse);
masm.moveValue(BooleanValue(true), R0);
EmitReturnFromIC(masm);
masm.bind(&ifFalse);
masm.moveValue(BooleanValue(false), R0);
EmitReturnFromIC(masm);
// Failure case - jump to next stub
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
//
// ToBool_String
//
bool
ICToBool_String::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(engine_ == Engine::Baseline);
Label failure;
masm.branchTestString(Assembler::NotEqual, R0, &failure);
Label ifFalse;
masm.branchTestStringTruthy(false, R0, &ifFalse);
masm.moveValue(BooleanValue(true), R0);
EmitReturnFromIC(masm);
masm.bind(&ifFalse);
masm.moveValue(BooleanValue(false), R0);
EmitReturnFromIC(masm);
// Failure case - jump to next stub
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
//
// ToBool_NullUndefined
//
bool
ICToBool_NullUndefined::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(engine_ == Engine::Baseline);
Label failure, ifFalse;
masm.branchTestNull(Assembler::Equal, R0, &ifFalse);
masm.branchTestUndefined(Assembler::NotEqual, R0, &failure);
masm.bind(&ifFalse);
masm.moveValue(BooleanValue(false), R0);
EmitReturnFromIC(masm);
// Failure case - jump to next stub
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
//
// ToBool_Double
//
bool
ICToBool_Double::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(engine_ == Engine::Baseline);
Label failure, ifTrue;
masm.branchTestDouble(Assembler::NotEqual, R0, &failure);
masm.unboxDouble(R0, FloatReg0);
masm.branchTestDoubleTruthy(true, FloatReg0, &ifTrue);
masm.moveValue(BooleanValue(false), R0);
EmitReturnFromIC(masm);
masm.bind(&ifTrue);
masm.moveValue(BooleanValue(true), R0);
EmitReturnFromIC(masm);
// Failure case - jump to next stub
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
//
// ToBool_Object
//
bool
ICToBool_Object::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(engine_ == Engine::Baseline);
Label failure, emulatesUndefined, slowPath;
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
Register objReg = masm.extractObject(R0, ExtractTemp0);
Register scratch = R1.scratchReg();
masm.branchIfObjectEmulatesUndefined(objReg, scratch, &slowPath, &emulatesUndefined);
// If object doesn't emulate undefined, it evaulates to true.
masm.moveValue(BooleanValue(true), R0);
EmitReturnFromIC(masm);
masm.bind(&emulatesUndefined);
masm.moveValue(BooleanValue(false), R0);
EmitReturnFromIC(masm);
masm.bind(&slowPath);
masm.setupUnalignedABICall(scratch);
masm.passABIArg(objReg);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, js::EmulatesUndefined));
masm.convertBoolToInt32(ReturnReg, ReturnReg);
masm.xor32(Imm32(1), ReturnReg);
masm.tagValue(JSVAL_TYPE_BOOLEAN, ReturnReg, R0);
EmitReturnFromIC(masm);
// Failure case - jump to next stub
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
//
// ToNumber_Fallback

Просмотреть файл

@ -242,121 +242,6 @@ class ICToBool_Fallback : public ICFallbackStub
};
};
class ICToBool_Int32 : public ICStub
{
friend class ICStubSpace;
explicit ICToBool_Int32(JitCode* stubCode)
: ICStub(ICStub::ToBool_Int32, stubCode) {}
public:
// Compiler for this stub kind.
class Compiler : public ICStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
explicit Compiler(JSContext* cx)
: ICStubCompiler(cx, ICStub::ToBool_Int32, Engine::Baseline) {}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICToBool_Int32>(space, getStubCode());
}
};
};
class ICToBool_String : public ICStub
{
friend class ICStubSpace;
explicit ICToBool_String(JitCode* stubCode)
: ICStub(ICStub::ToBool_String, stubCode) {}
public:
// Compiler for this stub kind.
class Compiler : public ICStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
explicit Compiler(JSContext* cx)
: ICStubCompiler(cx, ICStub::ToBool_String, Engine::Baseline) {}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICToBool_String>(space, getStubCode());
}
};
};
class ICToBool_NullUndefined : public ICStub
{
friend class ICStubSpace;
explicit ICToBool_NullUndefined(JitCode* stubCode)
: ICStub(ICStub::ToBool_NullUndefined, stubCode) {}
public:
// Compiler for this stub kind.
class Compiler : public ICStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
explicit Compiler(JSContext* cx)
: ICStubCompiler(cx, ICStub::ToBool_NullUndefined, Engine::Baseline) {}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICToBool_NullUndefined>(space, getStubCode());
}
};
};
class ICToBool_Double : public ICStub
{
friend class ICStubSpace;
explicit ICToBool_Double(JitCode* stubCode)
: ICStub(ICStub::ToBool_Double, stubCode) {}
public:
// Compiler for this stub kind.
class Compiler : public ICStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
explicit Compiler(JSContext* cx)
: ICStubCompiler(cx, ICStub::ToBool_Double, Engine::Baseline) {}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICToBool_Double>(space, getStubCode());
}
};
};
class ICToBool_Object : public ICStub
{
friend class ICStubSpace;
explicit ICToBool_Object(JitCode* stubCode)
: ICStub(ICStub::ToBool_Object, stubCode) {}
public:
// Compiler for this stub kind.
class Compiler : public ICStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
explicit Compiler(JSContext* cx)
: ICStubCompiler(cx, ICStub::ToBool_Object, Engine::Baseline) {}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICToBool_Object>(space, getStubCode());
}
};
};
// ToNumber
// JSOP_POS

Просмотреть файл

@ -31,11 +31,6 @@ namespace jit {
_(NewObject_WithTemplate) \
\
_(ToBool_Fallback) \
_(ToBool_Int32) \
_(ToBool_String) \
_(ToBool_NullUndefined) \
_(ToBool_Double) \
_(ToBool_Object) \
\
_(ToNumber_Fallback) \
\

Просмотреть файл

@ -4143,7 +4143,11 @@ TypeOfIRGenerator::tryAttachPrimitive(ValOperandId valId)
if (!val_.isPrimitive())
return false;
writer.guardType(valId, val_.isNumber() ? JSVAL_TYPE_DOUBLE : val_.extractNonDoubleType());
if (val_.isNumber())
writer.guardIsNumber(valId);
else
writer.guardType(valId, val_.extractNonDoubleType());
writer.loadStringResult(TypeName(js::TypeOfValue(val_), cx_->names()));
writer.returnFromIC();
@ -4682,3 +4686,144 @@ CompareIRGenerator::trackNotAttached()
}
#endif
}
ToBoolIRGenerator::ToBoolIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, ICState::Mode mode,
HandleValue val)
: IRGenerator(cx, script, pc, CacheKind::ToBool, mode),
val_(val)
{}
void
ToBoolIRGenerator::trackAttached(const char* name)
{
#ifdef JS_CACHEIR_SPEW
CacheIRSpewer& sp = CacheIRSpewer::singleton();
if (sp.enabled()) {
LockGuard<Mutex> guard(sp.lock());
sp.beginCache(guard, *this);
sp.valueProperty(guard, "val", val_);
sp.attached(guard, name);
sp.endCache(guard);
}
#endif
}
void
ToBoolIRGenerator::trackNotAttached()
{
#ifdef JS_CACHEIR_SPEW
CacheIRSpewer& sp = CacheIRSpewer::singleton();
if (sp.enabled()) {
LockGuard<Mutex> guard(sp.lock());
sp.beginCache(guard, *this);
sp.valueProperty(guard, "val", val_);
sp.endCache(guard);
}
#endif
}
bool
ToBoolIRGenerator::tryAttachStub()
{
AutoAssertNoPendingException aanpe(cx_);
if (tryAttachInt32())
return true;
if (tryAttachDouble())
return true;
if (tryAttachString())
return true;
if (tryAttachNullOrUndefined())
return true;
if (tryAttachObject())
return true;
if (tryAttachSymbol())
return true;
trackNotAttached();
return false;
}
bool
ToBoolIRGenerator::tryAttachInt32()
{
if (!val_.isInt32())
return false;
ValOperandId valId(writer.setInputOperandId(0));
writer.guardType(valId, JSVAL_TYPE_INT32);
writer.loadInt32TruthyResult(valId);
writer.returnFromIC();
trackAttached("ToBoolInt32");
return true;
}
bool
ToBoolIRGenerator::tryAttachDouble()
{
if (!val_.isDouble() || !cx_->runtime()->jitSupportsFloatingPoint)
return false;
ValOperandId valId(writer.setInputOperandId(0));
writer.guardType(valId, JSVAL_TYPE_DOUBLE);
writer.loadDoubleTruthyResult(valId);
writer.returnFromIC();
trackAttached("ToBoolDouble");
return true;
}
bool
ToBoolIRGenerator::tryAttachSymbol()
{
if (!val_.isSymbol())
return false;
ValOperandId valId(writer.setInputOperandId(0));
writer.guardType(valId, JSVAL_TYPE_SYMBOL);
writer.loadBooleanResult(true);
writer.returnFromIC();
trackAttached("ToBoolSymbol");
return true;
}
bool
ToBoolIRGenerator::tryAttachString()
{
if (!val_.isString())
return false;
ValOperandId valId(writer.setInputOperandId(0));
StringOperandId strId = writer.guardIsString(valId);
writer.loadStringTruthyResult(strId);
writer.returnFromIC();
trackAttached("ToBoolString");
return true;
}
bool
ToBoolIRGenerator::tryAttachNullOrUndefined()
{
if (!val_.isNullOrUndefined())
return false;
ValOperandId valId(writer.setInputOperandId(0));
writer.guardIsNullOrUndefined(valId);
writer.loadBooleanResult(false);
writer.returnFromIC();
trackAttached("ToBoolNullOrUndefined");
return true;
}
bool
ToBoolIRGenerator::tryAttachObject()
{
if (!val_.isObject())
return false;
ValOperandId valId(writer.setInputOperandId(0));
ObjOperandId objId = writer.guardIsObject(valId);
writer.loadObjectTruthyResult(objId);
writer.returnFromIC();
trackAttached("ToBoolObject");
return true;
}

Просмотреть файл

@ -151,6 +151,7 @@ class TypedOperandId : public OperandId
_(InstanceOf) \
_(GetIterator) \
_(Compare) \
_(ToBool) \
_(Call)
enum class CacheKind : uint8_t
@ -165,8 +166,10 @@ extern const char* CacheKindNames[];
#define CACHE_IR_OPS(_) \
_(GuardIsObject) \
_(GuardIsObjectOrNull) \
_(GuardIsNullOrUndefined) \
_(GuardIsString) \
_(GuardIsSymbol) \
_(GuardIsNumber) \
_(GuardIsInt32Index) \
_(GuardType) \
_(GuardShape) \
@ -268,6 +271,10 @@ extern const char* CacheKindNames[];
_(LoadStringResult) \
_(LoadInstanceOfObjectResult) \
_(LoadTypeOfObjectResult) \
_(LoadInt32TruthyResult) \
_(LoadDoubleTruthyResult) \
_(LoadStringTruthyResult) \
_(LoadObjectTruthyResult) \
\
_(CallStringSplitResult) \
\
@ -520,6 +527,9 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
writeOperandId(res);
return res;
}
void guardIsNumber(ValOperandId val) {
writeOpWithOperandId(CacheOp::GuardIsNumber, val);
}
void guardType(ValOperandId val, JSValueType type) {
writeOpWithOperandId(CacheOp::GuardType, val);
static_assert(sizeof(type) == sizeof(uint8_t), "JSValueType should fit in a byte");
@ -528,6 +538,9 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
void guardIsObjectOrNull(ValOperandId val) {
writeOpWithOperandId(CacheOp::GuardIsObjectOrNull, val);
}
void guardIsNullOrUndefined(ValOperandId val) {
writeOpWithOperandId(CacheOp::GuardIsNullOrUndefined, val);
}
void guardShape(ObjOperandId obj, Shape* shape) {
writeOpWithOperandId(CacheOp::GuardShape, obj);
addStubField(uintptr_t(shape), StubField::Type::Shape);
@ -1009,6 +1022,18 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
void loadTypeOfObjectResult(ObjOperandId obj) {
writeOpWithOperandId(CacheOp::LoadTypeOfObjectResult, obj);
}
void loadInt32TruthyResult(ValOperandId integer) {
writeOpWithOperandId(CacheOp::LoadInt32TruthyResult, integer);
}
void loadDoubleTruthyResult(ValOperandId dbl) {
writeOpWithOperandId(CacheOp::LoadDoubleTruthyResult, dbl);
}
void loadStringTruthyResult(StringOperandId str) {
writeOpWithOperandId(CacheOp::LoadStringTruthyResult, str);
}
void loadObjectTruthyResult(ObjOperandId obj) {
writeOpWithOperandId(CacheOp::LoadObjectTruthyResult, obj);
}
void callStringSplitResult(StringOperandId str, StringOperandId sep, ObjectGroup* group) {
writeOp(CacheOp::CallStringSplitResult);
writeOperandId(str);
@ -1596,6 +1621,27 @@ class MOZ_RAII CompareIRGenerator : public IRGenerator
bool tryAttachStub();
};
class MOZ_RAII ToBoolIRGenerator : public IRGenerator
{
HandleValue val_;
bool tryAttachInt32();
bool tryAttachDouble();
bool tryAttachString();
bool tryAttachSymbol();
bool tryAttachNullOrUndefined();
bool tryAttachObject();
void trackAttached(const char* name);
void trackNotAttached();
public:
ToBoolIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState::Mode mode,
HandleValue val);
bool tryAttachStub();
};
} // namespace jit
} // namespace js

Просмотреть файл

@ -9,6 +9,7 @@
#include "jit/IonIC.h"
#include "jit/SharedICHelpers.h"
#include "jsboolinlines.h"
#include "jscompartmentinlines.h"
#include "jit/MacroAssembler-inl.h"
@ -1205,6 +1206,25 @@ CacheIRCompiler::emitFailurePath(size_t index)
return true;
}
bool
CacheIRCompiler::emitGuardIsNumber()
{
ValOperandId inputId = reader.valOperandId();
JSValueType knownType = allocator.knownType(inputId);
// Doubles and ints are numbers!
if (knownType == JSVAL_TYPE_DOUBLE || knownType == JSVAL_TYPE_INT32)
return true;
ValueOperand input = allocator.useValueRegister(masm, inputId);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
masm.branchTestNumber(Assembler::NotEqual, input, failure->label());
return true;
}
bool
CacheIRCompiler::emitGuardIsObject()
{
@ -1220,6 +1240,27 @@ CacheIRCompiler::emitGuardIsObject()
return true;
}
bool
CacheIRCompiler::emitGuardIsNullOrUndefined()
{
ValOperandId inputId = reader.valOperandId();
JSValueType knownType = allocator.knownType(inputId);
if (knownType == JSVAL_TYPE_UNDEFINED || knownType == JSVAL_TYPE_NULL)
return true;
ValueOperand input = allocator.useValueRegister(masm, inputId);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
Label success;
masm.branchTestNull(Assembler::Equal, input, &success);
masm.branchTestUndefined(Assembler::NotEqual, input, failure->label());
masm.bind(&success);
return true;
}
bool
CacheIRCompiler::emitGuardIsObjectOrNull()
{
@ -1350,7 +1391,7 @@ CacheIRCompiler::emitGuardType()
masm.branchTestInt32(Assembler::NotEqual, input, failure->label());
break;
case JSVAL_TYPE_DOUBLE:
masm.branchTestNumber(Assembler::NotEqual, input, failure->label());
masm.branchTestDouble(Assembler::NotEqual, input, failure->label());
break;
case JSVAL_TYPE_BOOLEAN:
masm.branchTestBoolean(Assembler::NotEqual, input, failure->label());
@ -1842,7 +1883,7 @@ CacheIRCompiler::emitLoadStringCharResult()
// Bounds check, load string char.
masm.boundsCheck32ForLoad(index, Address(str, JSString::offsetOfLength()), scratch1,
failure->label());
masm.loadStringChar(str, index, scratch1, failure->label());
masm.loadStringChar(str, index, scratch1, scratch2, failure->label());
// Load StaticString for this char.
masm.boundsCheck32PowerOfTwo(scratch1, StaticStrings::UNIT_STATIC_LIMIT, failure->label());
@ -2273,6 +2314,98 @@ CacheIRCompiler::emitLoadTypeOfObjectResult()
return true;
}
bool
CacheIRCompiler::emitLoadInt32TruthyResult()
{
AutoOutputRegister output(*this);
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
Label ifFalse, done;
masm.branchTestInt32Truthy(false, val, &ifFalse);
masm.moveValue(BooleanValue(true), output.valueReg());
masm.jump(&done);
masm.bind(&ifFalse);
masm.moveValue(BooleanValue(false), output.valueReg());
masm.bind(&done);
return true;
}
bool
CacheIRCompiler::emitLoadStringTruthyResult()
{
AutoOutputRegister output(*this);
Register str = allocator.useRegister(masm, reader.stringOperandId());
Label ifFalse, done;
masm.branch32(Assembler::Equal, Address(str, JSString::offsetOfLength()), Imm32(0), &ifFalse);
masm.moveValue(BooleanValue(true), output.valueReg());
masm.jump(&done);
masm.bind(&ifFalse);
masm.moveValue(BooleanValue(false), output.valueReg());
masm.bind(&done);
return true;
}
bool
CacheIRCompiler::emitLoadDoubleTruthyResult()
{
AutoOutputRegister output(*this);
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
Label ifFalse, done, failurePopReg;
// If we're compiling a Baseline IC, FloatReg0 is always available.
if (mode_ != Mode::Baseline)
masm.push(FloatReg0);
masm.unboxDouble(val, FloatReg0);
masm.branchTestDoubleTruthy(false, FloatReg0, &ifFalse);
masm.moveValue(BooleanValue(true), output.valueReg());
masm.jump(&done);
masm.bind(&ifFalse);
masm.moveValue(BooleanValue(false), output.valueReg());
if (mode_ != Mode::Baseline)
masm.pop(FloatReg0);
masm.bind(&done);
return true;
}
bool
CacheIRCompiler::emitLoadObjectTruthyResult()
{
AutoOutputRegister output(*this);
Register obj = allocator.useRegister(masm, reader.objOperandId());
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
Label emulatesUndefined, slowPath, done;
masm.branchIfObjectEmulatesUndefined(obj, scratch, &slowPath, &emulatesUndefined);
masm.moveValue(BooleanValue(true), output.valueReg());
masm.jump(&done);
masm.bind(&emulatesUndefined);
masm.moveValue(BooleanValue(false), output.valueReg());
masm.jump(&done);
masm.bind(&slowPath);
masm.setupUnalignedABICall(scratch);
masm.passABIArg(obj);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, js::EmulatesUndefined));
masm.convertBoolToInt32(ReturnReg, ReturnReg);
masm.xor32(Imm32(1), ReturnReg);
masm.tagValue(JSVAL_TYPE_BOOLEAN, ReturnReg, output.valueReg());
masm.bind(&done);
return true;
}
bool
CacheIRCompiler::emitCompareStringResult()
{
@ -2684,4 +2817,4 @@ CacheIRCompiler::emitLoadInstanceOfObjectResult()
//fallthrough
masm.bind(&done);
return true;
}
}

Просмотреть файл

@ -16,9 +16,11 @@ namespace jit {
// BaselineCacheIRCompiler and IonCacheIRCompiler.
#define CACHE_IR_SHARED_OPS(_) \
_(GuardIsObject) \
_(GuardIsNullOrUndefined) \
_(GuardIsObjectOrNull) \
_(GuardIsString) \
_(GuardIsSymbol) \
_(GuardIsNumber) \
_(GuardIsInt32Index) \
_(GuardType) \
_(GuardClass) \
@ -56,6 +58,10 @@ namespace jit {
_(LoadTypedElementResult) \
_(LoadObjectResult) \
_(LoadTypeOfObjectResult) \
_(LoadInt32TruthyResult) \
_(LoadDoubleTruthyResult) \
_(LoadStringTruthyResult) \
_(LoadObjectTruthyResult) \
_(CompareStringResult) \
_(CompareObjectResult) \
_(CompareSymbolResult) \

Просмотреть файл

@ -358,6 +358,7 @@ CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool)
case CacheKind::Call:
case CacheKind::Compare:
case CacheKind::TypeOf:
case CacheKind::ToBool:
MOZ_CRASH("Unsupported IC");
}
MOZ_CRASH();
@ -7603,6 +7604,93 @@ CodeGenerator::visitIsNullOrLikeUndefinedAndBranchT(LIsNullOrLikeUndefinedAndBra
}
}
void
CodeGenerator::emitSameValue(FloatRegister left, FloatRegister right, FloatRegister temp,
Register output)
{
Label nonEqual, isSameValue, isNotSameValue;
masm.branchDouble(Assembler::DoubleNotEqualOrUnordered, left, right, &nonEqual);
{
// First, test for being equal to 0.0, which also includes -0.0.
masm.loadConstantDouble(0.0, temp);
masm.branchDouble(Assembler::DoubleNotEqual, left, temp, &isSameValue);
// The easiest way to distinguish -0.0 from 0.0 is that 1.0/-0.0
// is -Infinity instead of Infinity.
Label isNegInf;
masm.loadConstantDouble(1.0, temp);
masm.divDouble(left, temp);
masm.branchDouble(Assembler::DoubleLessThan, temp, left, &isNegInf);
{
masm.loadConstantDouble(1.0, temp);
masm.divDouble(right, temp);
masm.branchDouble(Assembler::DoubleGreaterThan, temp, right, &isSameValue);
masm.jump(&isNotSameValue);
}
masm.bind(&isNegInf);
{
masm.loadConstantDouble(1.0, temp);
masm.divDouble(right, temp);
masm.branchDouble(Assembler::DoubleLessThan, temp, right, &isSameValue);
masm.jump(&isNotSameValue);
}
}
masm.bind(&nonEqual);
{
// Test if both values are NaN.
masm.branchDouble(Assembler::DoubleOrdered, left, left, &isNotSameValue);
masm.branchDouble(Assembler::DoubleOrdered, right, right, &isNotSameValue);
}
Label done;
masm.bind(&isSameValue);
masm.move32(Imm32(1), output);
masm.jump(&done);
masm.bind(&isNotSameValue);
masm.move32(Imm32(0), output);
masm.bind(&done);
}
void
CodeGenerator::visitSameValueD(LSameValueD* lir)
{
FloatRegister left = ToFloatRegister(lir->left());
FloatRegister right = ToFloatRegister(lir->right());
FloatRegister temp = ToFloatRegister(lir->tempFloat());
Register output = ToRegister(lir->output());
emitSameValue(left, right, temp, output);
}
void
CodeGenerator::visitSameValueV(LSameValueV* lir)
{
ValueOperand left = ToValue(lir, LSameValueV::LhsInput);
FloatRegister right = ToFloatRegister(lir->right());
FloatRegister temp1 = ToFloatRegister(lir->tempFloat1());
FloatRegister temp2 = ToFloatRegister(lir->tempFloat2());
Register output = ToRegister(lir->output());
Label nonDouble;
masm.move32(Imm32(0), output);
masm.ensureDouble(left, temp1, &nonDouble);
emitSameValue(temp1, right, temp2, output);
masm.bind(&nonDouble);
}
typedef bool (*SameValueFn)(JSContext*, HandleValue, HandleValue, bool*);
static const VMFunction SameValueInfo = FunctionInfo<SameValueFn>(js::SameValue, "SameValue");
void
CodeGenerator::visitSameValueVM(LSameValueVM* lir)
{
pushArg(ToValue(lir, LSameValueVM::RhsInput));
pushArg(ToValue(lir, LSameValueVM::LhsInput));
callVM(SameValueInfo, lir);
}
typedef JSString* (*ConcatStringsFn)(JSContext*, HandleString, HandleString);
static const VMFunction ConcatStringsInfo =
FunctionInfo<ConcatStringsFn>(ConcatStrings<CanGC>, "ConcatStrings");
@ -8167,9 +8255,10 @@ CodeGenerator::visitCharCodeAt(LCharCodeAt* lir)
Register str = ToRegister(lir->str());
Register index = ToRegister(lir->index());
Register output = ToRegister(lir->output());
Register temp = ToRegister(lir->temp());
OutOfLineCode* ool = oolCallVM(CharCodeAtInfo, lir, ArgList(str, index), StoreRegisterTo(output));
masm.loadStringChar(str, index, output, ool->entry());
masm.loadStringChar(str, index, output, temp, ool->entry());
masm.bind(ool->rejoin());
}

Просмотреть файл

@ -284,6 +284,11 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitIsNullOrLikeUndefinedT(LIsNullOrLikeUndefinedT* lir) override;
void visitIsNullOrLikeUndefinedAndBranchV(LIsNullOrLikeUndefinedAndBranchV* lir) override;
void visitIsNullOrLikeUndefinedAndBranchT(LIsNullOrLikeUndefinedAndBranchT* lir) override;
void emitSameValue(FloatRegister left, FloatRegister right, FloatRegister temp,
Register output);
void visitSameValueD(LSameValueD* lir) override;
void visitSameValueV(LSameValueV* lir) override;
void visitSameValueVM(LSameValueVM* lir) override;
void emitConcat(LInstruction* lir, Register lhs, Register rhs, Register output);
void visitConcat(LConcat* lir) override;
void visitCharCodeAt(LCharCodeAt* lir) override;

Просмотреть файл

@ -94,6 +94,7 @@
\
_(Object) \
_(ObjectCreate) \
_(ObjectIs) \
_(ObjectToString) \
\
_(SimdInt32x4) \

Просмотреть файл

@ -5736,7 +5736,7 @@ IonBuilder::jsop_compare(JSOp op, MDefinition* left, MDefinition* right)
startTrackingOptimizations();
if (!forceInlineCaches()) {
MOZ_TRY(compareTrySpecialized(&emitted, op, left, right));
MOZ_TRY(compareTrySpecialized(&emitted, op, left, right, true));
if (emitted)
return Ok();
MOZ_TRY(compareTryBitwise(&emitted, op, left, right));
@ -5779,16 +5779,19 @@ ObjectOrSimplePrimitive(MDefinition* op)
}
AbortReasonOr<Ok>
IonBuilder::compareTrySpecialized(bool* emitted, JSOp op, MDefinition* left, MDefinition* right)
IonBuilder::compareTrySpecialized(bool* emitted, JSOp op, MDefinition* left, MDefinition* right,
bool canTrackOptimization)
{
MOZ_ASSERT(*emitted == false);
trackOptimizationAttempt(TrackedStrategy::Compare_SpecializedTypes);
if (canTrackOptimization)
trackOptimizationAttempt(TrackedStrategy::Compare_SpecializedTypes);
// Try to emit an compare based on the input types.
MCompare::CompareType type = MCompare::determineCompareType(op, left, right);
if (type == MCompare::Compare_Unknown) {
trackOptimizationOutcome(TrackedOutcome::SpeculationOnInputTypesFailed);
if (canTrackOptimization)
trackOptimizationOutcome(TrackedOutcome::SpeculationOnInputTypesFailed);
return Ok();
}
@ -5815,7 +5818,8 @@ IonBuilder::compareTrySpecialized(bool* emitted, JSOp op, MDefinition* left, MDe
current->push(ins);
MOZ_ASSERT(!ins->isEffectful());
trackOptimizationSuccess();
if (canTrackOptimization)
trackOptimizationSuccess();
*emitted = true;
return Ok();
}

Просмотреть файл

@ -328,7 +328,7 @@ class IonBuilder
// jsop_compare helpers.
AbortReasonOr<Ok> compareTrySpecialized(bool* emitted, JSOp op, MDefinition* left,
MDefinition* right);
MDefinition* right, bool canTrackOptimization);
AbortReasonOr<Ok> compareTryBitwise(bool* emitted, JSOp op, MDefinition* left,
MDefinition* right);
AbortReasonOr<Ok> compareTrySpecializedOnBaselineInspector(bool* emitted, JSOp op,
@ -697,6 +697,7 @@ class IonBuilder
// Object natives and intrinsics.
InliningResult inlineObject(CallInfo& callInfo);
InliningResult inlineObjectCreate(CallInfo& callInfo);
InliningResult inlineObjectIs(CallInfo& callInfo);
InliningResult inlineObjectToString(CallInfo& callInfo);
InliningResult inlineDefineDataProperty(CallInfo& callInfo);

Просмотреть файл

@ -546,6 +546,7 @@ IonCacheIRCompiler::init()
case CacheKind::Call:
case CacheKind::Compare:
case CacheKind::TypeOf:
case CacheKind::ToBool:
MOZ_CRASH("Unsupported IC");
}

Просмотреть файл

@ -63,6 +63,7 @@ IonIC::scratchRegisterForEntryJump()
case CacheKind::Call:
case CacheKind::Compare:
case CacheKind::TypeOf:
case CacheKind::ToBool:
MOZ_CRASH("Unsupported IC");
}

Просмотреть файл

@ -1167,6 +1167,33 @@ LIRGenerator::visitCompare(MCompare* comp)
MOZ_CRASH("Unrecognized compare type.");
}
void
LIRGenerator::visitSameValue(MSameValue* ins)
{
MDefinition* lhs = ins->lhs();
MDefinition* rhs = ins->rhs();
if (lhs->type() == MIRType::Double && rhs->type() == MIRType::Double) {
auto* lir = new(alloc()) LSameValueD(useRegister(lhs), useRegister(rhs), tempDouble());
define(lir, ins);
return;
}
if (lhs->type() == MIRType::Value && rhs->type() == MIRType::Double) {
auto* lir = new(alloc()) LSameValueV(useBox(lhs), useRegister(rhs), tempDouble(),
tempDouble());
define(lir, ins);
return;
}
MOZ_ASSERT(lhs->type() == MIRType::Value);
MOZ_ASSERT(rhs->type() == MIRType::Value);
auto* lir = new(alloc()) LSameValueVM(useBoxAtStart(lhs), useBoxAtStart(rhs));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
void
LIRGenerator::lowerBitOp(JSOp op, MInstruction* ins)
{
@ -1971,7 +1998,7 @@ LIRGenerator::visitCharCodeAt(MCharCodeAt* ins)
MOZ_ASSERT(str->type() == MIRType::String);
MOZ_ASSERT(idx->type() == MIRType::Int32);
LCharCodeAt* lir = new(alloc()) LCharCodeAt(useRegister(str), useRegister(idx));
LCharCodeAt* lir = new(alloc()) LCharCodeAt(useRegister(str), useRegister(idx), temp());
define(lir, ins);
assignSafepoint(lir, ins);
}

Просмотреть файл

@ -120,6 +120,7 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitFunctionDispatch(MFunctionDispatch* ins) override;
void visitObjectGroupDispatch(MObjectGroupDispatch* ins) override;
void visitCompare(MCompare* comp) override;
void visitSameValue(MSameValue* comp) override;
void visitTypeOf(MTypeOf* ins) override;
void visitToAsync(MToAsync* ins) override;
void visitToAsyncGen(MToAsyncGen* ins) override;

Просмотреть файл

@ -252,6 +252,8 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
return inlineObject(callInfo);
case InlinableNative::ObjectCreate:
return inlineObjectCreate(callInfo);
case InlinableNative::ObjectIs:
return inlineObjectIs(callInfo);
case InlinableNative::ObjectToString:
return inlineObjectToString(callInfo);
@ -2381,6 +2383,68 @@ IonBuilder::inlineObjectCreate(CallInfo& callInfo)
return InliningStatus_Inlined;
}
IonBuilder::InliningResult
IonBuilder::inlineObjectIs(CallInfo& callInfo)
{
if (callInfo.argc() < 2 || callInfo.constructing())
return InliningStatus_NotInlined;
if (getInlineReturnType() != MIRType::Boolean)
return InliningStatus_NotInlined;
MDefinition* left = callInfo.getArg(0);
MDefinition* right = callInfo.getArg(1);
MIRType leftType = left->type();
MIRType rightType = right->type();
bool strictEq;
bool incompatibleTypes = false;
if (leftType == rightType) {
// We can only compare the arguments with strict-equals semantics if
// they aren't floating-point types or values. Otherwise we need to
// use MSameValue.
strictEq = !(IsFloatingPointType(leftType) || leftType == MIRType::Value);
} else if (leftType == MIRType::Value) {
// Also use strict-equals when comparing a value with a non-number.
strictEq = !IsNumberType(rightType);
} else if (rightType == MIRType::Value) {
// Dual case to the previous one, only with reversed operands.
strictEq = !IsNumberType(leftType);
} else if (IsNumberType(leftType) && IsNumberType(rightType)) {
// Both arguments are numbers, but with different representations. We
// can't use strict-equals semantics to compare the operands, but
// instead need to use MSameValue.
strictEq = false;
} else {
incompatibleTypes = true;
}
if (incompatibleTypes) {
// The result is always |false| when comparing incompatible types.
pushConstant(BooleanValue(false));
} else {
bool emitted = false;
if (strictEq) {
// Specialize |Object.is(lhs, rhs)| as |lhs === rhs|.
MOZ_TRY(compareTrySpecialized(&emitted, JSOP_STRICTEQ, left, right, false));
}
if (!emitted) {
MSameValue* ins = MSameValue::New(alloc(), left, right);
// The more specific operand is expected to be in the rhs.
if (IsNumberType(leftType) && rightType == MIRType::Value)
ins->swapOperands();
current->add(ins);
current->push(ins);
}
}
callInfo.setImplicitlyUsedUnchecked();
return InliningStatus_Inlined;
}
IonBuilder::InliningResult
IonBuilder::inlineObjectToString(CallInfo& callInfo)
{

Просмотреть файл

@ -4811,6 +4811,31 @@ class MCompare
}
};
class MSameValue
: public MBinaryInstruction,
public SameValuePolicy::Data
{
MSameValue(MDefinition* left, MDefinition* right)
: MBinaryInstruction(classOpcode, left, right)
{
setResultType(MIRType::Boolean);
setMovable();
}
public:
INSTRUCTION_HEADER(SameValue)
TRIVIAL_NEW_WRAPPERS
bool congruentTo(const MDefinition* ins) const override {
return congruentIfOperandsEqual(ins);
}
AliasSet getAliasSet() const override {
return AliasSet::None();
}
ALLOW_CLONE(MSameValue)
};
// Takes a typed value and returns an untyped value.
class MBox
: public MUnaryInstruction,

Просмотреть файл

@ -44,6 +44,7 @@ namespace jit {
_(ObjectGroupDispatch) \
_(FunctionDispatch) \
_(Compare) \
_(SameValue) \
_(Phi) \
_(Beta) \
_(NaNToZero) \

Просмотреть файл

@ -1383,11 +1383,13 @@ MacroAssembler::loadStringChars(Register str, Register dest)
}
void
MacroAssembler::loadStringChar(Register str, Register index, Register output, Label* fail)
MacroAssembler::loadStringChar(Register str, Register index, Register output, Register scratch,
Label* fail)
{
MOZ_ASSERT(str != output);
MOZ_ASSERT(str != index);
MOZ_ASSERT(index != output);
MOZ_ASSERT(output != scratch);
movePtr(str, output);
@ -1400,17 +1402,7 @@ MacroAssembler::loadStringChar(Register str, Register index, Register output, La
// Check if the index is contained in the leftChild.
// Todo: Handle index in the rightChild.
Label failPopStr, inLeft;
push(str);
boundsCheck32ForLoad(index, Address(output, JSString::offsetOfLength()), str, &failPopStr);
pop(str);
jump(&inLeft);
bind(&failPopStr);
pop(str);
jump(fail);
bind(&inLeft);
boundsCheck32ForLoad(index, Address(output, JSString::offsetOfLength()), scratch, fail);
// If the left side is another rope, give up.
branchIfRope(output, fail);
@ -3468,7 +3460,6 @@ void
MacroAssembler::computeSpectreIndexMask(Register index, Register length, Register output)
{
MOZ_ASSERT(JitOptions.spectreIndexMasking);
MOZ_ASSERT(index != length);
MOZ_ASSERT(length != output);
MOZ_ASSERT(index != output);
@ -3513,7 +3504,6 @@ MacroAssembler::spectreMaskIndex(int32_t index, const Address& length, Register
void
MacroAssembler::spectreMaskIndex(Register index, Register length, Register output)
{
MOZ_ASSERT(index != length);
MOZ_ASSERT(length != output);
MOZ_ASSERT(index != output);

Просмотреть файл

@ -1834,7 +1834,8 @@ class MacroAssembler : public MacroAssemblerSpecific
}
void loadStringChars(Register str, Register dest);
void loadStringChar(Register str, Register index, Register output, Label* fail);
void loadStringChar(Register str, Register index, Register output, Register scratch,
Label* fail);
void loadStringIndexValue(Register str, Register dest, Label* fail);

Просмотреть файл

@ -99,7 +99,7 @@ ArithPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
}
bool
AllDoublePolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
AllDoublePolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
{
for (size_t i = 0, e = ins->numOperands(); i < e; i++) {
MDefinition* in = ins->getOperand(i);
@ -268,6 +268,37 @@ ComparePolicy::adjustInputs(TempAllocator& alloc, MInstruction* def)
return true;
}
bool
SameValuePolicy::adjustInputs(TempAllocator& alloc, MInstruction* def)
{
MOZ_ASSERT(def->isSameValue());
MSameValue* sameValue = def->toSameValue();
MIRType lhsType = sameValue->lhs()->type();
MIRType rhsType = sameValue->rhs()->type();
// If both operands are numbers, convert them to doubles.
if (IsNumberType(lhsType) && IsNumberType(rhsType))
return AllDoublePolicy::staticAdjustInputs(alloc, def);
// SameValue(Anything, Double) is specialized, so convert the rhs if it's
// not already a double.
if (lhsType == MIRType::Value && IsNumberType(rhsType)) {
if (rhsType != MIRType::Double) {
MInstruction* replace = MToDouble::New(alloc, sameValue->rhs());
def->block()->insertBefore(def, replace);
def->replaceOperand(1, replace);
if (!replace->typePolicy()->adjustInputs(alloc, replace))
return false;
}
return true;
}
// Otherwise box both operands.
return BoxInputsPolicy::staticAdjustInputs(alloc, def);
}
bool
TypeBarrierPolicy::adjustInputs(TempAllocator& alloc, MInstruction* def)
{
@ -1204,6 +1235,7 @@ FilterTypeSetPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
_(FilterTypeSetPolicy) \
_(InstanceOfPolicy) \
_(PowPolicy) \
_(SameValuePolicy) \
_(SimdAllPolicy) \
_(SimdSelectPolicy) \
_(SimdShufflePolicy) \

Просмотреть файл

@ -99,7 +99,10 @@ class AllDoublePolicy final : public TypePolicy
{
public:
EMPTY_DATA_;
MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
return staticAdjustInputs(alloc, def);
}
};
class BitwisePolicy final : public TypePolicy
@ -116,6 +119,13 @@ class ComparePolicy final : public TypePolicy
virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
};
class SameValuePolicy final : public TypePolicy
{
public:
EMPTY_DATA_;
virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
};
// Policy for MTest instructions.
class TestPolicy final : public TypePolicy
{

Просмотреть файл

@ -105,23 +105,6 @@ EmitBaselineLeaveStubFrame(MacroAssembler& masm, bool calledIntoIon = false)
masm.Pop(scratch);
}
inline void
EmitStowICValues(MacroAssembler& masm, int values)
{
MOZ_ASSERT(values >= 0 && values <= 2);
switch(values) {
case 1:
// Stow R0.
masm.Push(R0);
break;
case 2:
// Stow R0 and R1.
masm.Push(R0);
masm.Push(R1);
break;
}
}
template <typename AddrType>
inline void
EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)

Просмотреть файл

@ -103,24 +103,6 @@ EmitBaselineLeaveStubFrame(MacroAssembler& masm, bool calledIntoIon = false)
masm.checkStackAlignment();
}
inline void
EmitStowICValues(MacroAssembler& masm, int values)
{
switch (values) {
case 1:
// Stow R0.
masm.Push(R0);
break;
case 2:
// Stow R0 and R1.
masm.Push(R0.valueReg());
masm.Push(R1.valueReg());
break;
default:
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Expected 1 or 2 values");
}
}
template <typename AddrType>
inline void
EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)

Просмотреть файл

@ -117,22 +117,6 @@ EmitBaselineLeaveStubFrame(MacroAssembler& masm, bool calledIntoIon = false)
masm.addPtr(Imm32(STUB_FRAME_SIZE), StackPointer);
}
inline void
EmitStowICValues(MacroAssembler& masm, int values)
{
MOZ_ASSERT(values >= 0 && values <= 2);
switch(values) {
case 1:
// Stow R0
masm.Push(R0);
break;
case 2:
// Stow R0 and R1
masm.Push(R0);
masm.Push(R1);
}
}
template <typename AddrType>
inline void
EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)

Просмотреть файл

@ -19,7 +19,6 @@ inline void EmitEnterTypeMonitorIC(MacroAssembler&, size_t v = 0) { MOZ_CRASH();
inline void EmitReturnFromIC(MacroAssembler&) { MOZ_CRASH(); }
inline void EmitChangeICReturnAddress(MacroAssembler&, Register) { MOZ_CRASH(); }
inline void EmitBaselineLeaveStubFrame(MacroAssembler&, bool v = false) { MOZ_CRASH(); }
inline void EmitStowICValues(MacroAssembler&, int) { MOZ_CRASH(); }
inline void EmitStubGuardFailure(MacroAssembler&) { MOZ_CRASH(); }
template <typename T> inline void EmitPreBarrier(MacroAssembler&, T, MIRType) { MOZ_CRASH(); }

Просмотреть файл

@ -3132,6 +3132,68 @@ class LIsNullOrLikeUndefinedAndBranchT : public LControlInstructionHelper<2, 1,
}
};
class LSameValueD : public LInstructionHelper<1, 2, 1>
{
public:
LIR_HEADER(SameValueD)
LSameValueD(const LAllocation& left, const LAllocation& right, const LDefinition& temp) {
setOperand(0, left);
setOperand(1, right);
setTemp(0, temp);
}
const LAllocation* left() {
return getOperand(0);
}
const LAllocation* right() {
return getOperand(1);
}
const LDefinition* tempFloat() {
return getTemp(0);
}
};
class LSameValueV : public LInstructionHelper<1, BOX_PIECES + 1, 2>
{
public:
LIR_HEADER(SameValueV)
static const size_t LhsInput = 0;
LSameValueV(const LBoxAllocation& left, const LAllocation& right, const LDefinition& temp1,
const LDefinition& temp2)
{
setBoxOperand(LhsInput, left);
setOperand(BOX_PIECES, right);
setTemp(0, temp1);
setTemp(1, temp2);
}
const LAllocation* right() {
return getOperand(BOX_PIECES);
}
const LDefinition* tempFloat1() {
return getTemp(0);
}
const LDefinition* tempFloat2() {
return getTemp(1);
}
};
class LSameValueVM : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0>
{
public:
LIR_HEADER(SameValueVM)
static const size_t LhsInput = 0;
static const size_t RhsInput = BOX_PIECES;
LSameValueVM(const LBoxAllocation& left, const LBoxAllocation& right) {
setBoxOperand(LhsInput, left);
setBoxOperand(RhsInput, right);
}
};
// Not operation on an integer.
class LNotI : public LInstructionHelper<1, 1, 0>
{
@ -4084,14 +4146,15 @@ class LConcat : public LInstructionHelper<1, 2, 5>
};
// Get uint16 character code from a string.
class LCharCodeAt : public LInstructionHelper<1, 2, 0>
class LCharCodeAt : public LInstructionHelper<1, 2, 1>
{
public:
LIR_HEADER(CharCodeAt)
LCharCodeAt(const LAllocation& str, const LAllocation& index) {
LCharCodeAt(const LAllocation& str, const LAllocation& index, const LDefinition& temp) {
setOperand(0, str);
setOperand(1, index);
setTemp(0, temp);
}
const LAllocation* str() {
@ -4100,6 +4163,9 @@ class LCharCodeAt : public LInstructionHelper<1, 2, 0>
const LAllocation* index() {
return this->getOperand(1);
}
const LDefinition* temp() {
return getTemp(0);
}
};
// Convert uint16 character code to a string.

Просмотреть файл

@ -147,6 +147,9 @@
_(IsNullOrLikeUndefinedT) \
_(IsNullOrLikeUndefinedAndBranchV)\
_(IsNullOrLikeUndefinedAndBranchT)\
_(SameValueD) \
_(SameValueV) \
_(SameValueVM) \
_(MinMaxI) \
_(MinMaxD) \
_(MinMaxF) \

Просмотреть файл

@ -95,27 +95,6 @@ EmitBaselineLeaveStubFrame(MacroAssembler& masm, bool calledIntoIon = false)
masm.Pop(Operand(BaselineStackReg, 0));
}
inline void
EmitStowICValues(MacroAssembler& masm, int values)
{
MOZ_ASSERT(values >= 0 && values <= 2);
switch(values) {
case 1:
// Stow R0
masm.pop(ICTailCallReg);
masm.Push(R0);
masm.push(ICTailCallReg);
break;
case 2:
// Stow R0 and R1
masm.pop(ICTailCallReg);
masm.Push(R0);
masm.Push(R1);
masm.push(ICTailCallReg);
break;
}
}
template <typename AddrType>
inline void
EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)

Просмотреть файл

@ -96,27 +96,6 @@ EmitBaselineLeaveStubFrame(MacroAssembler& masm, bool calledIntoIon = false)
masm.Pop(Operand(BaselineStackReg, 0));
}
inline void
EmitStowICValues(MacroAssembler& masm, int values)
{
MOZ_ASSERT(values >= 0 && values <= 2);
switch(values) {
case 1:
// Stow R0
masm.pop(ICTailCallReg);
masm.Push(R0);
masm.push(ICTailCallReg);
break;
case 2:
// Stow R0 and R1
masm.pop(ICTailCallReg);
masm.Push(R0);
masm.Push(R1);
masm.push(ICTailCallReg);
break;
}
}
template <typename AddrType>
inline void
EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)

Просмотреть файл

@ -311,6 +311,12 @@ AtomIsPinnedInRuntime(JSRuntime* rt, JSAtom* atom)
#endif // DEBUG
template <typename CharT>
MOZ_ALWAYS_INLINE
static JSAtom*
AtomizeAndCopyCharsInner(JSContext* cx, const CharT* tbchars, size_t length, PinningBehavior pin,
const Maybe<uint32_t>& indexValue, const AtomHasher::Lookup& lookup);
/* |tbchars| must not point into an inline or short string. */
template <typename CharT>
MOZ_ALWAYS_INLINE
@ -361,6 +367,24 @@ AtomizeAndCopyChars(JSContext* cx, const CharT* tbchars, size_t length, PinningB
if (MOZ_UNLIKELY(!JSString::validateLength(cx, length)))
return nullptr;
JSAtom* atom = AtomizeAndCopyCharsInner(cx, tbchars, length, pin, indexValue, lookup);
if (!atom)
return nullptr;
cx->atomMarking().inlinedMarkAtom(cx, atom);
if (zonePtr)
mozilla::Unused << zone->atomCache().add(*zonePtr, AtomStateEntry(atom, false));
return atom;
}
template <typename CharT>
MOZ_ALWAYS_INLINE
static JSAtom*
AtomizeAndCopyCharsInner(JSContext* cx, const CharT* tbchars, size_t length, PinningBehavior pin,
const Maybe<uint32_t>& indexValue, const AtomHasher::Lookup& lookup)
{
AutoLockForExclusiveAccess lock(cx);
JSRuntime* rt = cx->runtime();
@ -390,9 +414,6 @@ AtomizeAndCopyChars(JSContext* cx, const CharT* tbchars, size_t length, PinningB
if (p) {
JSAtom* atom = p->asPtr(cx);
p->setPinned(bool(pin));
cx->atomMarking().inlinedMarkAtom(cx, atom);
if (zonePtr)
mozilla::Unused << zone->atomCache().add(*zonePtr, AtomStateEntry(atom, false));
return atom;
}
@ -425,9 +446,6 @@ AtomizeAndCopyChars(JSContext* cx, const CharT* tbchars, size_t length, PinningB
}
}
cx->atomMarking().inlinedMarkAtom(cx, atom);
if (zonePtr)
mozilla::Unused << zone->atomCache().add(*zonePtr, AtomStateEntry(atom, false));
return atom;
}

Просмотреть файл

@ -1495,18 +1495,6 @@ if test -n "$MOZ_DEBUG"; then
AC_DEFINE(JS_DEBUG)
fi
dnl ========================================================
dnl Enable breakpoint for artificial OOMs
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(oom-breakpoint,
[ --enable-oom-breakpoint
Enable a breakpoint function for artificial OOMs],
JS_OOM_BREAKPOINT=1,
JS_OOM_BREAKPOINT= )
if test -n "$JS_OOM_BREAKPOINT"; then
AC_DEFINE(JS_OOM_BREAKPOINT)
fi
dnl ========================================================
dnl = Enable using the clang plugin to build
dnl ========================================================

Просмотреть файл

@ -1162,4 +1162,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1525832557448000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1525893971751000);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -8,7 +8,7 @@
/*****************************************************************************/
#include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1528251745082000);
const PRTime gPreloadListExpirationTime = INT64_C(1528313159661000);
%%
0-1.party, 1
0.me.uk, 1
@ -734,7 +734,6 @@ academicexperts.us, 1
academie-de-police.ch, 1
academy4.net, 1
academytv.com.au, 1
acadianapatios.com, 1
acampar.com.br, 1
acaonegocios.com.br, 1
acara-yoga.de, 1
@ -1570,7 +1569,6 @@ alumni-kusa.jp, 1
alunonaescola.com.br, 1
alupferd.de, 1
aluroof.eu, 1
alvcs.com, 1
alviano.com, 1
alvicom.hu, 1
alvosec.com, 1
@ -2253,7 +2251,6 @@ arkaic.dyndns.org, 1
arkbyte.com, 1
arknodejs.com, 1
arksan.com.tr, 1
arlatools.com, 1
arlen.tv, 1
arlenarmageddon.com, 1
arlet.click, 1
@ -3535,7 +3532,6 @@ beoordelingen.be, 1
beranovi.com, 1
berasavocate.com, 1
beraten-entwickeln-steuern.de, 1
berdaguermontes.eu, 1
berduri.com, 1
bergenhave.nl, 1
bergevoet-fa.nl, 1
@ -3643,6 +3639,7 @@ betecnet.de, 1
betformular.com, 1
betgo9.cc, 1
betkoo.com, 1
betobaccofree.gov, 1
betonmoney.com, 1
betpamm.com, 1
bets.gg, 1
@ -4198,6 +4195,7 @@ blogom.at, 1
blogpentrusuflet.ro, 1
blogreen.org, 1
blogtroterzy.pl, 1
blok56.nl, 1
blokuhaka.fr, 1
bloodsports.org, 1
bloodyexcellent.com, 1
@ -6386,6 +6384,7 @@ closeli.com, 0
closelinksecurity.co.uk, 1
closelinksecurity.com, 1
closetemail.com, 1
closient.com, 0
closingholding.com, 1
cloturea.fr, 1
cloud-surfer.net, 1
@ -6887,6 +6886,7 @@ consumerfiles.com, 1
consumersentinel.gov, 1
consumidor.gov, 1
consuwijzer.nl, 1
contactsingapore.sg, 1
content-api-dev.azurewebsites.net, 0
contentcoms.co.uk, 1
contentdesign.de, 1
@ -7576,7 +7576,6 @@ d.nr, 1
d00d.de, 1
d0g.cc, 1
d0xq.net, 1
d2s.uk, 1
d3njjcbhbojbot.cloudfront.net, 1
d3x.pw, 1
d3xt3r01.tk, 1
@ -8801,6 +8800,7 @@ dogan.ch, 0
dogcontrol.ca, 1
dogcratereview.info, 1
dogear.ch, 1
dogfi.sh, 1
dogft.com, 1
doggroomingcourse.com, 1
dogmap.jp, 1
@ -9735,7 +9735,6 @@ electricgatemotorgermiston.co.za, 1
electronic-ignition-system.com, 1
electronicafacil.net, 1
electronicfasteners.com, 1
electrostatics.com, 1
eled.io, 1
elefantevoador.com, 1
eleicoes2014.com.br, 1
@ -10008,7 +10007,6 @@ engelundlicht.ch, 1
engg.ca, 1
engineowning.com, 1
enginepit.com, 1
enginx.cn, 1
enginx.net, 1
englerts.de, 1
englishbulgaria.net, 1
@ -10893,6 +10891,7 @@ fakturoid.cz, 1
falaowang.com, 1
falbros.com, 1
falcibiosystems.org, 1
falconfrag.com, 1
falconvintners.com, 1
falcoz.co, 1
faldoria.de, 0
@ -11025,7 +11024,6 @@ fathers4equalrights.org, 1
fatidique.com, 1
fatimamoldes.com.br, 1
fatowltees.com, 1
fatox.de, 1
faucetbox.com, 0
faui2k17.de, 1
faulty.equipment, 1
@ -11465,7 +11463,6 @@ flipneus.net, 1
fliptable.org, 1
flirt-norden.de, 1
flirtfaces.de, 1
flirtycourts.com, 1
flmortgagebank.com, 1
floaternet.com, 1
flocktofedora.org, 1
@ -11476,7 +11473,6 @@ flood.io, 1
flooringnightmares.com, 1
floort.net, 0
flopix.net, 0
flopy.club, 1
florence.uk.net, 1
florenceapp.co.uk, 1
florent-tatard.fr, 1
@ -12552,7 +12548,7 @@ gers-authentique.com, 1
gerum.dynv6.net, 1
gerwinvanderkamp.nl, 1
ges-bo.de, 1
geschenkly.de, 0
geschenkly.de, 1
geschmacksache.online, 1
geschmackspiloten.de, 1
geschwinder.net, 1
@ -12795,7 +12791,6 @@ glenhuntlyapartments.com.au, 1
glidingshop.cz, 1
glidingshop.de, 1
glidingshop.eu, 1
glittersjabloon.nl, 1
glloq.org, 1
glob-coin.com, 1
global-lights.ma, 1
@ -13657,6 +13652,7 @@ hash.works, 1
hashcat.net, 1
hashes.org, 1
hashi.dk, 1
hashiconf.com, 1
hashiconf.eu, 1
hashicorp.com, 1
hashimah.ca, 1
@ -14837,7 +14833,6 @@ idrinktoomuch.coffee, 1
idrissi.eu, 1
idrycleaningi.com, 1
idsafe.co.za, 1
idsoccer.com, 1
idtechnowizard.com, 1
idtheft.gov, 1
idubaj.cz, 1
@ -15083,7 +15078,7 @@ impulsionsa.com, 1
impyus.com, 1
imququ.com, 1
imreh.net, 1
imrejonk.nl, 0
imrejonk.nl, 1
imrunner.com, 1
imrunner.ru, 1
ims-sargans.ch, 1
@ -17100,7 +17095,6 @@ kibriscicek.net, 1
kick-in.nl, 1
kickasscanadians.ca, 1
kickedmycat.com, 1
kickerplaza.nl, 1
kidbacker.com, 1
kiddyboom.ua, 1
kids-at-home.ch, 1
@ -17224,7 +17218,6 @@ kirstin-peters.de, 1
kirwandigital.com, 1
kis-toitoidixi.de, 1
kisallatorvos.hu, 1
kisiselveri.com, 1
kissesb.com, 1
kissesb.net, 1
kissflow.com, 1
@ -17362,7 +17355,6 @@ knownsec.cf, 1
knthost.com, 1
knurps.de, 1
knutur.is, 1
knygos.lt, 1
ko-sys.com, 1
ko.si, 1
koalapress.fr, 1
@ -17480,7 +17472,6 @@ korobi.io, 1
korobkovsky.ru, 1
korono.de, 1
korosiprogram.hu, 1
korp.fr, 1
korrelzout.nl, 1
kortgebyr.dk, 1
koryfi.com, 1
@ -17879,7 +17870,7 @@ lancork.net, 1
lancyvbc.ch, 1
land.nrw, 0
landell.ml, 1
landflair-magazin.de, 1
landflair-magazin.de, 0
landhaus-christmann.de, 1
landinfo.no, 1
landofelves.net, 1
@ -18320,12 +18311,12 @@ letsgowhilewereyoung.com, 1
letspartyrugby.co.uk, 1
letstalkcounseling.com, 1
letterbox-online.de, 1
letterdance.de, 1
letteringinstitute.com, 1
lettersblogatory.com, 1
lettland-firma.com, 1
lettori.club, 1
leu.to, 0
leuenhagen.com, 1
leuthardtfamily.com, 1
levans.fr, 1
levanscatering.com, 1
@ -18447,6 +18438,7 @@ liduan.net, 1
liebel.org, 1
lieblingsholz.de, 1
lied8.eu, 1
liehuojun.com, 1
lieuu.com, 1
lifanov.com, 1
lifebetweenlives.com.au, 1
@ -19099,7 +19091,6 @@ lunidea.com, 1
lunight.ml, 1
lunis.net, 1
lunix.io, 1
lunorian.is, 0
luoe.me, 1
luoh.cc, 1
luoh.me, 1
@ -19936,7 +19927,6 @@ mdek.at, 1
mdewendt.de, 1
mdf-bis.com, 1
mdiv.pl, 1
mdkr.nl, 1
mdlayher.com, 1
mdma.net, 1
mdmed.clinic, 1
@ -21033,6 +21023,7 @@ mpc-hc.org, 1
mpcompliance.com, 1
mpe.org, 1
mpetroff.net, 1
mpg-universal.com, 1
mpg.ovh, 1
mpi-sa.fr, 1
mpintaamalabanna.it, 1
@ -24258,6 +24249,7 @@ pitfire.io, 1
pitot-rs.org, 1
pitsstop.nu, 1
pittaya.com, 1
pittmantraffic.co.uk, 1
pivotaltracker.com, 1
pivotanimation.org, 1
piwko.co, 1
@ -24835,7 +24827,6 @@ primordialsnooze.com, 1
primotilesandbathrooms.co.uk, 1
princeagency.com, 1
princeofwhales.com, 1
princesparktouch.com, 1
princessbackpack.de, 1
princessmargaretlotto.com, 1
principalstest.com, 1
@ -25605,6 +25596,7 @@ rattenkot.io, 1
raucris.ro, 1
raulrivero.es, 1
raumzeitlabor.de, 0
rauros.net, 1
rautermods.net, 1
ravchat.com, 1
raven.dog, 1
@ -27756,7 +27748,6 @@ shaken110.com, 1
shakepeers.org, 0
shakes4u.com, 1
shakespearesolutions.com.au, 0
shakespearevet.com, 1
shalott.org, 1
shamara.info, 1
shamariki.ru, 1
@ -28218,7 +28209,6 @@ sirburton.com, 1
sirena.co.jp, 1
sirenslove.com, 1
siriuspup.com, 1
siroop.ch, 1
sirtaptap.com, 1
sirtuins.com, 1
sistel.es, 1
@ -28710,7 +28700,6 @@ solsocog.de, 1
soluphant.de, 1
solus-project.com, 1
solutionhoisthire.com.au, 1
solve-it.se, 1
solved.tips, 1
solvemethod.com, 1
solvingproblems.com.au, 1
@ -30993,6 +30982,7 @@ tintencenter.com, 1
tintenfix.net, 1
tintenfux.de, 1
tintenland.de, 1
tintenprofi.de, 1
tiny.ee, 1
tinyhousefinance.com.au, 1
tinylan.com, 1
@ -31047,7 +31037,6 @@ tkn.tokyo, 1
tkts.cl, 1
tkusano.jp, 1
tkw01536.de, 1
tlach.cz, 1
tlca.org, 1
tlcnet.info, 1
tlehseasyads.com, 1
@ -32141,7 +32130,6 @@ unli.xyz, 1
unlockboot.com, 0
unlocken.nl, 1
unmanaged.space, 1
unmonito.red, 1
uno-pizza.ru, 1
uno.fi, 1
unobrindes.com.br, 1
@ -32224,6 +32212,7 @@ urbanmelbourne.info, 1
urbanmic.com, 1
urbannewsservice.com, 1
urbansparrow.in, 1
urbanstylestaging.com, 1
urbanwildlifealliance.org, 1
urbexdk.nl, 1
urcentral.com, 1
@ -32664,7 +32653,7 @@ vicyu.com, 1
vid-immobilien.de, 1
vida-it.com, 1
vida.es, 1
vidadu.com, 1
vidb.me, 1
vidbooster.com, 1
vide-dressing.org, 0
vide-greniers.org, 0
@ -33163,7 +33152,6 @@ wasema.com, 1
wasfestes.de, 1
washingtonregisteredagent.io, 1
washingtonviews.com, 1
wasi-net.de, 1
wasielewski.com.de, 1
wasil.org, 1
waslh.com, 1
@ -33188,7 +33176,6 @@ waterschaplimburg.nl, 1
watertrails.io, 1
waterworkscondos.com, 1
watsonwork.me, 1
wattechweb.com, 1
wave-ola.es, 1
wavesboardshop.com, 1
wavesoftime.com, 1
@ -33829,6 +33816,7 @@ withyoutube.com, 1
witneywaterpolo.org.uk, 1
witt-international.co.uk, 1
wittepapaver.nl, 1
witting.co, 1
witway.nl, 0
wivoc.nl, 1
wiz.at, 1
@ -34731,7 +34719,6 @@ yoitsu.moe, 1
yokohama-legaloffice.jp, 1
yolo.jetzt, 1
yolobert.de, 1
yolocelebs.com, 0
yolops.net, 1
yombo.net, 1
yomena.in, 1
@ -34911,6 +34898,7 @@ yzcloud.me, 1
yzimroni.net, 1
z-coder.com, 1
z-konzept-nutrition.ru, 1
z-latko.info, 1
z-vector.com, 1
z.ai, 1
z0rro.net, 1
@ -35029,7 +35017,7 @@ zenvideocloud.com, 1
zenycosta.com, 1
zepect.com, 1
zeplin.io, 1
zer0-day.pw, 0
zer0-day.pw, 1
zer0.de, 1
zero-sum.xyz, 1
zero-x-baadf00d.com, 1
@ -35066,6 +35054,7 @@ zh.search.yahoo.com, 0
zhang-hao.com, 1
zhang.nz, 1
zhangfangzhou.com, 1
zhangge.net, 1
zhanghao.me, 1
zhangsidan.com, 1
zhangsir.net, 1
@ -35129,7 +35118,6 @@ zlatakus.cz, 1
zlatosnadno.cz, 1
zlavomat.sk, 1
zlc1994.com, 1
zlima12.com, 1
zmk.fr, 1
znation.nl, 1
zning.net.cn, 1

Просмотреть файл

@ -27,3 +27,18 @@ only-for-build-platforms:
- macosx64-devedition-nightly/opt
- win32-devedition-nightly/opt
- win64-devedition-nightly/opt
job-template:
mozharness:
config:
by-build-platform:
linux-.*:
- repackage/linux32_signed.py
linux64-.*:
- repackage/linux64_signed.py
macosx64-.*:
- repackage/osx_signed.py
win32-.*:
- repackage/win32_signed.py
win64-.*:
- repackage/win64_signed.py

Просмотреть файл

@ -27,3 +27,18 @@ only-for-build-platforms:
- win32-devedition-nightly/opt
- win64-nightly/opt
- win64-devedition-nightly/opt
job-template:
mozharness:
config:
by-build-platform:
linux-.*:
- repackage/linux32_signed.py
linux64-.*:
- repackage/linux64_signed.py
macosx64-.*:
- repackage/osx_signed.py
win32-.*:
- repackage/win32_signed.py
win64-.*:
- repackage/win64_signed.py

Просмотреть файл

@ -14,6 +14,7 @@ echo "running as" $(id)
: MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT}
: MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG}
: MOZHARNESS_CONFIG_PATHS ${MOZHARNESS_CONFIG_PATHS}
: MOZHARNESS_ACTIONS ${MOZHARNESS_ACTIONS}
: MOZHARNESS_OPTIONS ${MOZHARNESS_OPTIONS}
@ -60,6 +61,11 @@ fi
# entirely effective.
export TOOLTOOL_CACHE
config_path_cmds=""
for path in ${MOZHARNESS_CONFIG_PATHS}; do
config_path_cmds="${config_path_cmds} --extra-config-path ${WORKSPACE}/build/src/${path}"
done
# support multiple, space delimited, config files
config_cmds=""
for cfg in $MOZHARNESS_CONFIG; do
@ -86,7 +92,9 @@ fi
cd /builds/worker
python2.7 $WORKSPACE/build/src/testing/${MOZHARNESS_SCRIPT} ${config_cmds} \
python2.7 $WORKSPACE/build/src/testing/${MOZHARNESS_SCRIPT} \
${config_path_cmds} \
${config_cmds} \
$actions \
$options \
--log-level=debug \

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше