merge mozilla-inbound to mozilla-central. r=merge a=merge

MozReview-Commit-ID: 36L7JL73CzG
This commit is contained in:
Sebastian Hengst 2017-10-09 23:52:04 +02:00
Родитель c623cb074c 591c9f864b
Коммит c2d6023454
125 изменённых файлов: 6203 добавлений и 4454 удалений

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

@ -11,3 +11,4 @@ skip-if = (os == 'win' && bits == 32) # Bug 1352791
[browser_notification_remove_permission.js]
[browser_notification_replace.js]
[browser_notification_tab_switching.js]
skip-if = os == "win" || os == "linux" # Bug 1243263

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

@ -25,4 +25,7 @@ add_task(async function test_remove_history() {
await BrowserTestUtils.waitForCondition(
() => !gURLBar.popup.richlistbox.children.some(c => !c.collapsed && c.getAttribute("ac-value") == TEST_URL),
"Waiting for the result to disappear");
gURLBar.popup.hidePopup();
await promisePopupHidden(gURLBar.popup);
});

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

@ -131,6 +131,7 @@ skip-if = !e10s || debug || asan
[browser_ext_tabs_audio.js]
[browser_ext_tabs_captureVisibleTab.js]
[browser_ext_tabs_create.js]
skip-if = os == "linux" && debug && bits == 32 # Bug 1350189
[browser_ext_tabs_create_invalid_url.js]
[browser_ext_tabs_detectLanguage.js]
[browser_ext_tabs_discarded.js]

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

@ -1040,11 +1040,12 @@ Experiments.Experiments.prototype = {
let result = await loadJSONAsync(path, { compression: "lz4" });
this._populateFromCache(result);
} catch (e) {
this._experiments = new Map();
if (e instanceof OS.File.Error && e.becauseNoSuchFile) {
// No cached manifest yet.
this._experiments = new Map();
this._log.trace("_loadFromCache - no cached manifest yet");
} else {
throw e;
this._log.error("_loadFromCache - caught error", e);
}
}
},

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

@ -393,3 +393,19 @@ add_task(async function test_expiration() {
await promiseRestartManager();
await removeCacheFile();
});
add_task(async function test_invalid_cache() {
// Save uncompressed data to the cache file to trigger a loading error.
let encoder = new TextEncoder();
let data = encoder.encode("foo");
let path = OS.Path.join(OS.Constants.Path.profileDir, "experiments.json");
let options = { tmpPath: path + ".tmp" };
await OS.File.writeAtomic(path, data, options);
// Trigger loading from the cache. This should not throw and gracefully recover.
let experiments = new Experiments.Experiments(gPolicy);
let list = await experiments.getExperiments();
Assert.deepEqual(list, [], "The experiments cache should be empty.");
});

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

@ -0,0 +1,11 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Taken from upstream commit: 6a34276ba4e2e4f8dfb2123eb4e6795ae658486a
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.0
- babel-preset-react @6.24.1
- react @15.6.2
- react-dom @15.6.2
- webpack @3.6.0

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

@ -412,7 +412,7 @@ body {
.modal-wrapper {
position: fixed;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
top: 0;
@ -423,7 +423,7 @@ body {
.modal {
top: 0;
height: 230px;
margin: auto;
width: 500px;
background-color: var(--theme-toolbar-background);
transform: translateY(-250px);
@ -438,7 +438,7 @@ body {
.modal.entered,
.modal.exiting {
transform: translateY(30px);
transform: translateY(0px);
}
@media (max-width: 520px) {
@ -490,7 +490,6 @@ body {
}
.shortcuts-modal {
height: fit-content;
width: 45%;
}
@ -973,7 +972,7 @@ html .arrow.expanded svg {
width: 15px;
height: 15px;
margin-right: 5px;
vertical-align: bottom;
vertical-align: sub;
}
.theme-dark .webpack {
@ -1428,6 +1427,7 @@ html[dir="rtl"] .managed-tree .tree .node > div {
display: flex;
overflow-x: hidden;
overflow-y: auto;
padding-top: 11px;
}
.sources-list .managed-tree {
@ -1462,6 +1462,11 @@ html[dir="rtl"] .managed-tree .tree .node > div {
display: inline-block;
}
.sources-list .tree .node .no-arrow {
width: 10px;
display: inline-block;
}
.no-sources-message {
font-size: 12px;
color: var(--theme-comment-alt);
@ -1497,7 +1502,7 @@ html[dir="rtl"] .managed-tree .tree .node > div {
position: relative;
transition: all 0.25s ease;
overflow: hidden;
padding: 6.5px;
padding: 8px 8px 7px 8px;
margin-bottom: 0px;
margin-top: -1px;
cursor: default;
@ -2353,11 +2358,6 @@ html[dir="rtl"] .arrow svg,
--theme-conditional-breakpoint-color: var(--theme-body-color);
}
.paused .CodeMirror-line,
.paused .CodeMirror-linenumber {
opacity: 0.7;
}
/**
* There's a known codemirror flex issue with chrome that this addresses.
* BUG https://github.com/devtools-html/debugger.html/issues/63
@ -2629,6 +2629,7 @@ html .breakpoints-list .breakpoint.paused {
overflow-x: hidden;
text-overflow: ellipsis;
padding: 1px 0;
vertical-align: bottom;
}
.breakpoints-list .pause-indicator {
@ -3216,12 +3217,26 @@ html .command-bar > button:disabled {
offset-inline-start: auto;
}
.welcomebox .small-size-layout {
display: none;
}
.welcomebox .normal-layout {
display: inline-block;
}
.shortcutKeys {
text-align: right;
float: left;
font-family: Courier;
}
.shortcutKey {
display: inline-block;
margin-right: 10px;
font-family: Courier;
}
.shortcutFunction {
text-align: left;
float: left;
@ -3231,6 +3246,24 @@ html .command-bar > button:disabled {
html .welcomebox .toggle-button-end.collapsed {
bottom: 1px;
}
@media (max-width: 430px) {
.welcomebox .small-size-layout {
display: inline-block;
}
.welcomebox .normal-layout {
display: none;
}
.shortcutFunction {
margin-left: 0;
}
.shortcutKey {
display: block;
}
}
.source-header {
border-bottom: 1px solid var(--theme-splitter-color);
width: 100%;

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

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

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

@ -70,17 +70,74 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ __webpack_require__.p = "/assets/build";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 380);
/******/ return __webpack_require__(__webpack_require__.s = 1282);
/******/ })
/************************************************************************/
/******/ ({
/***/ 380:
/***/ 1282:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(964);
module.exports = __webpack_require__(1283);
/***/ }),
/***/ 1283:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _prettyFast = __webpack_require__(802);
var _prettyFast2 = _interopRequireDefault(_prettyFast);
var _devtoolsUtils = __webpack_require__(900);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var workerHandler = _devtoolsUtils.workerUtils.workerHandler;
function prettyPrint(_ref) {
var url = _ref.url,
indent = _ref.indent,
source = _ref.source;
var prettified = (0, _prettyFast2.default)(source, {
url: url,
indent: " ".repeat(indent)
});
return {
code: prettified.code,
mappings: invertMappings(prettified.map._mappings)
};
}
function invertMappings(mappings) {
return mappings._array.map(m => {
var mapping = {
generated: {
line: m.originalLine,
column: m.originalColumn
}
};
if (m.source) {
mapping.source = m.source;
mapping.original = {
line: m.generatedLine,
column: m.generatedColumn
};
mapping.name = m.name;
}
return mapping;
});
}
self.onmessage = workerHandler({ prettyPrint });
/***/ }),
/***/ 381:
@ -7532,63 +7589,6 @@ module.exports = {
streamingWorkerHandler
};
/***/ }),
/***/ 964:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _prettyFast = __webpack_require__(802);
var _prettyFast2 = _interopRequireDefault(_prettyFast);
var _devtoolsUtils = __webpack_require__(900);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var workerHandler = _devtoolsUtils.workerUtils.workerHandler;
function prettyPrint(_ref) {
var url = _ref.url,
indent = _ref.indent,
source = _ref.source;
var prettified = (0, _prettyFast2.default)(source, {
url: url,
indent: " ".repeat(indent)
});
return {
code: prettified.code,
mappings: invertMappings(prettified.map._mappings)
};
}
function invertMappings(mappings) {
return mappings._array.map(m => {
var mapping = {
generated: {
line: m.originalLine,
column: m.originalColumn
}
};
if (m.source) {
mapping.source = m.source;
mapping.original = {
line: m.generatedLine,
column: m.generatedColumn
};
mapping.name = m.name;
}
return mapping;
});
}
self.onmessage = workerHandler({ prettyPrint });
/***/ })
/******/ });

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

@ -70,7 +70,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ __webpack_require__.p = "/assets/build";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 382);
/******/ return __webpack_require__(__webpack_require__.s = 1284);
/******/ })
/************************************************************************/
/******/ ({
@ -262,168 +262,6 @@ function arrayMap(array, iteratee) {
module.exports = arrayMap;
/***/ }),
/***/ 1123:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _getMatches = __webpack_require__(1173);
var _getMatches2 = _interopRequireDefault(_getMatches);
var _projectSearch = __webpack_require__(1140);
var _devtoolsUtils = __webpack_require__(900);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var workerHandler = _devtoolsUtils.workerUtils.workerHandler;
self.onmessage = workerHandler({ getMatches: _getMatches2.default, findSourceMatches: _projectSearch.findSourceMatches });
/***/ }),
/***/ 1138:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = buildQuery;
var _escapeRegExp = __webpack_require__(259);
var _escapeRegExp2 = _interopRequireDefault(_escapeRegExp);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Ignore doing outline matches for less than 3 whitespaces
*
* @memberof utils/source-search
* @static
*/
function ignoreWhiteSpace(str) {
return (/^\s{0,2}$/.test(str) ? "(?!\\s*.*)" : str
);
}
function wholeMatch(query, wholeWord) {
if (query === "" || !wholeWord) {
return query;
}
return `\\b${query}\\b`;
}
function buildFlags(caseSensitive, isGlobal) {
if (caseSensitive && isGlobal) {
return "g";
}
if (!caseSensitive && isGlobal) {
return "gi";
}
if (!caseSensitive && !isGlobal) {
return "i";
}
return;
}
function buildQuery(originalQuery, modifiers, _ref) {
var _ref$isGlobal = _ref.isGlobal,
isGlobal = _ref$isGlobal === undefined ? false : _ref$isGlobal,
_ref$ignoreSpaces = _ref.ignoreSpaces,
ignoreSpaces = _ref$ignoreSpaces === undefined ? false : _ref$ignoreSpaces;
var caseSensitive = modifiers.caseSensitive,
regexMatch = modifiers.regexMatch,
wholeWord = modifiers.wholeWord;
if (originalQuery === "") {
return new RegExp(originalQuery);
}
var query = originalQuery;
if (ignoreSpaces) {
query = ignoreWhiteSpace(query);
}
if (!regexMatch) {
query = (0, _escapeRegExp2.default)(query);
}
query = wholeMatch(query, wholeWord);
var flags = buildFlags(caseSensitive, isGlobal);
if (flags) {
return new RegExp(query, flags);
}
return new RegExp(query);
}
/***/ }),
/***/ 1140:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.findSourceMatches = findSourceMatches;
var _source = __webpack_require__(233);
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } // Maybe reuse file search's functions?
function findSourceMatches(source, queryText) {
var _ref;
var text = source.text;
if (!(0, _source.isLoaded)(source) || !text || queryText == "") {
return [];
}
var lines = text.split("\n");
var result = undefined;
var query = new RegExp(queryText, "g");
var matches = lines.map((_text, line) => {
var indices = [];
while (result = query.exec(_text)) {
indices.push({
sourceId: source.id,
line: line + 1,
column: result.index,
match: result[0],
value: _text,
text: result.input
});
}
return indices;
}).filter(_matches => _matches.length > 0);
matches = (_ref = []).concat.apply(_ref, _toConsumableArray(matches));
return matches;
}
/***/ }),
/***/ 1165:
@ -681,44 +519,6 @@ module.exports = {
/***/ }),
/***/ 1173:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getMatches;
var _buildQuery = __webpack_require__(1138);
var _buildQuery2 = _interopRequireDefault(_buildQuery);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getMatches(query, text, modifiers) {
if (!query || !text || !modifiers) {
return [];
}
var regexQuery = (0, _buildQuery2.default)(query, modifiers, {
isGlobal: true
});
var matchedLocations = [];
var lines = text.split("\n");
for (var i = 0; i < lines.length; i++) {
var singleMatch = void 0;
var line = lines[i];
while ((singleMatch = regexQuery.exec(line)) !== null) {
matchedLocations.push({ line: i, ch: singleMatch.index });
}
}
return matchedLocations;
}
/***/ }),
/***/ 121:
/***/ (function(module, exports, __webpack_require__) {
@ -809,6 +609,94 @@ var isArray = Array.isArray || function (xs) {
};
/***/ }),
/***/ 1211:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = buildQuery;
var _escapeRegExp = __webpack_require__(259);
var _escapeRegExp2 = _interopRequireDefault(_escapeRegExp);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Ignore doing outline matches for less than 3 whitespaces
*
* @memberof utils/source-search
* @static
*/
function ignoreWhiteSpace(str) {
return (/^\s{0,2}$/.test(str) ? "(?!\\s*.*)" : str
);
}
function wholeMatch(query, wholeWord) {
if (query === "" || !wholeWord) {
return query;
}
return `\\b${query}\\b`;
}
function buildFlags(caseSensitive, isGlobal) {
if (caseSensitive && isGlobal) {
return "g";
}
if (!caseSensitive && isGlobal) {
return "gi";
}
if (!caseSensitive && !isGlobal) {
return "i";
}
return;
}
function buildQuery(originalQuery, modifiers, _ref) {
var _ref$isGlobal = _ref.isGlobal,
isGlobal = _ref$isGlobal === undefined ? false : _ref$isGlobal,
_ref$ignoreSpaces = _ref.ignoreSpaces,
ignoreSpaces = _ref$ignoreSpaces === undefined ? false : _ref$ignoreSpaces;
var caseSensitive = modifiers.caseSensitive,
regexMatch = modifiers.regexMatch,
wholeWord = modifiers.wholeWord;
if (originalQuery === "") {
return new RegExp(originalQuery);
}
var query = originalQuery;
if (ignoreSpaces) {
query = ignoreWhiteSpace(query);
}
if (!regexMatch) {
query = (0, _escapeRegExp2.default)(query);
}
query = wholeMatch(query, wholeWord);
var flags = buildFlags(caseSensitive, isGlobal);
if (flags) {
return new RegExp(query, flags);
}
return new RegExp(query);
}
/***/ }),
/***/ 122:
@ -902,6 +790,126 @@ var objectKeys = Object.keys || function (obj) {
};
/***/ }),
/***/ 1284:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(1285);
/***/ }),
/***/ 1285:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _getMatches = __webpack_require__(1286);
var _getMatches2 = _interopRequireDefault(_getMatches);
var _projectSearch = __webpack_require__(1287);
var _devtoolsUtils = __webpack_require__(900);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var workerHandler = _devtoolsUtils.workerUtils.workerHandler;
self.onmessage = workerHandler({ getMatches: _getMatches2.default, findSourceMatches: _projectSearch.findSourceMatches });
/***/ }),
/***/ 1286:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getMatches;
var _buildQuery = __webpack_require__(1211);
var _buildQuery2 = _interopRequireDefault(_buildQuery);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getMatches(query, text, modifiers) {
if (!query || !text || !modifiers) {
return [];
}
var regexQuery = (0, _buildQuery2.default)(query, modifiers, {
isGlobal: true
});
var matchedLocations = [];
var lines = text.split("\n");
for (var i = 0; i < lines.length; i++) {
var singleMatch = void 0;
var line = lines[i];
while ((singleMatch = regexQuery.exec(line)) !== null) {
matchedLocations.push({ line: i, ch: singleMatch.index });
}
}
return matchedLocations;
}
/***/ }),
/***/ 1287:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.findSourceMatches = findSourceMatches;
var _source = __webpack_require__(233);
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } // Maybe reuse file search's functions?
function findSourceMatches(source, queryText) {
var _ref;
var text = source.text;
if (!(0, _source.isLoaded)(source) || !text || queryText == "") {
return [];
}
var lines = text.split("\n");
var result = undefined;
var query = new RegExp(queryText, "g");
var matches = lines.map((_text, line) => {
var indices = [];
while (result = query.exec(_text)) {
indices.push({
sourceId: source.id,
line: line + 1,
column: result.index,
match: result[0],
value: _text,
text: result.input
});
}
return indices;
}).filter(_matches => _matches.length > 0);
matches = (_ref = []).concat.apply(_ref, _toConsumableArray(matches));
return matches;
}
/***/ }),
/***/ 14:
@ -949,7 +957,7 @@ module.exports = isObjectLike;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isThirdParty = exports.isPretty = exports.isJavaScript = undefined;
exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFileURL = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isThirdParty = exports.isPretty = exports.isJavaScript = undefined;
var _devtoolsSourceMap = __webpack_require__(898);
@ -1048,12 +1056,23 @@ function getRawSourceURL(url) {
return url.replace(/:formatted$/, "");
}
function getFilenameFromURL(url) {
function resolveFileURL(url) {
var transformUrl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : initialUrl => initialUrl;
url = getRawSourceURL(url || "");
var name = (0, _path.basename)(url) || "(index)";
var name = transformUrl(url);
return (0, _utils.endTruncateStr)(name, 50);
}
function getFilenameFromURL(url) {
return resolveFileURL(url, initialUrl => (0, _path.basename)(initialUrl) || "(index)");
}
function getFormattedSourceId(id) {
var sourceId = id.split("/")[1];
return `SOURCE${sourceId}`;
}
/**
* Show a source url's filename.
* If the source does not have a url, use the source id.
@ -1066,13 +1085,30 @@ function getFilename(source) {
id = source.id;
if (!url) {
var sourceId = id.split("/")[1];
return `SOURCE${sourceId}`;
return getFormattedSourceId(id);
}
return getFilenameFromURL(url);
}
/**
* Show a source url.
* If the source does not have a url, use the source id.
*
* @memberof utils/source
* @static
*/
function getFileURL(source) {
var url = source.url,
id = source.id;
if (!url) {
return getFormattedSourceId(id);
}
return resolveFileURL(url);
}
var contentTypeModeMap = {
"text/javascript": { name: "javascript" },
"text/typescript": { name: "javascript", typescript: true },
@ -1184,6 +1220,7 @@ exports.getPrettySourceURL = getPrettySourceURL;
exports.getRawSourceURL = getRawSourceURL;
exports.getFilename = getFilename;
exports.getFilenameFromURL = getFilenameFromURL;
exports.getFileURL = getFileURL;
exports.getSourcePath = getSourcePath;
exports.getSourceLineCount = getSourceLineCount;
exports.getMode = getMode;
@ -2463,14 +2500,6 @@ module.exports = {
};
/***/ }),
/***/ 382:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(1123);
/***/ }),
/***/ 6:

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

@ -19,6 +19,9 @@ support-files =
examples/sum/sum.js
examples/sum/sum.min.js
examples/sum/sum.min.js.map
examples/reload/code_reload_1.js
examples/reload/code_reload_2.js
examples/reload/doc_reload.html
examples/doc-async.html
examples/doc-asm.html
examples/doc-scripts.html
@ -53,6 +56,7 @@ 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]
@ -64,7 +68,6 @@ support-files =
skip-if = true # Bug 1383576
[browser_dbg-breakpoints-cond.js]
[browser_dbg-call-stack.js]
[browser_dbg-expressions.js]
[browser_dbg-scopes.js]
[browser_dbg-chrome-create.js]
[browser_dbg-chrome-debugging.js]
@ -74,6 +77,8 @@ skip-if = debug # bug 1374187
[browser_dbg-editor-gutter.js]
[browser_dbg-editor-select.js]
[browser_dbg-editor-highlight.js]
[browser_dbg-expressions.js]
[browser_dbg-expressions-error.js]
[browser_dbg-iframes.js]
[browser_dbg_keyboard_navigation.js]
[browser_dbg_keyboard-shortcuts.js]
@ -102,4 +107,4 @@ skip-if = true # Bug 1393121, 1393299
[browser_dbg-tabs.js]
[browser_dbg-toggling-tools.js]
[browser_dbg-wasm-sourcemaps.js]
skip-if = true
[browser_dbg-reload.js]

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

@ -0,0 +1,90 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* test pausing on an errored watch expression
* assert that you can:
* 1. resume
* 2. still evalutate expressions
* 3. expand properties
*/
const expressionSelectors = {
input: "input.input-expression"
};
function getLabel(dbg, index) {
return findElement(dbg, "expressionNode", index).innerText;
}
function getValue(dbg, index) {
return findElement(dbg, "expressionValue", index).innerText;
}
function assertEmptyValue(dbg, index) {
const value = findElement(dbg, "expressionValue", index);
if (value) {
is(value.innerText, "");
return;
}
is(value, null);
}
function toggleExpression(dbg, index) {
findElement(dbg, "expressionNode", index).click();
}
async function addExpression(dbg, input) {
info("Adding an expression");
findElementWithSelector(dbg, expressionSelectors.input).focus();
type(dbg, input);
pressKey(dbg, "Enter");
await waitForDispatch(dbg, "EVALUATE_EXPRESSION");
}
async function editExpression(dbg, input) {
info("updating the expression");
dblClickElement(dbg, "expressionNode", 1);
// Position cursor reliably at the end of the text.
pressKey(dbg, "End");
type(dbg, input);
pressKey(dbg, "Enter");
await waitForDispatch(dbg, "EVALUATE_EXPRESSION");
}
/*
* When we add a bad expression, we'll pause,
* resume, and wait for the expression to finish being evaluated.
*/
async function addBadExpression(dbg, input) {
const paused = waitForPaused(dbg);
const added = addExpression(dbg, input);
await paused;
ok(dbg.selectors.isEvaluatingExpression(dbg.getState()));
await resume(dbg);
await added;
}
add_task(async function() {
const dbg = await initDebugger("doc-script-switching.html");
await togglePauseOnExceptions(dbg, true, false);
// add a good expression, 2 bad expressions, and another good one
await addExpression(dbg, "location");
await addBadExpression(dbg, "foo.bar");
await addBadExpression(dbg, "foo.batt");
await addExpression(dbg, "2");
// check the value of
is(getValue(dbg, 2), "(unavailable)")
is(getValue(dbg, 3), "(unavailable)")
is(getValue(dbg, 4), 2);
toggleExpression(dbg, 1);
await waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES");
is(findAllElements(dbg, "expressionNodes").length, 20);
});

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

@ -0,0 +1,29 @@
/* 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
*/
add_task(async function() {
const dbg = await initDebugger("reload/doc_reload.html", "sjs_code_reload");
const sym = waitForDispatch(dbg, "SET_SYMBOLS");
await selectSource(dbg, "sjs_code_reload");
await sym;
await addBreakpoint(dbg, "sjs_code_reload", 2);
const sync = waitForDispatch(dbg, "SYNC_BREAKPOINT");
await reload(dbg, "sjs_code_reload");
await sync;
const breakpoints = dbg.selectors.getBreakpoints(dbg.getState());
const breakpointList = breakpoints.valueSeq().toJS();
const breakpoint = breakpointList[0];
is(breakpointList.length, 1);
is(breakpoint.location.line, 6);
});

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

@ -11,6 +11,7 @@ add_task(async function() {
await waitForPaused(dbg);
assertPausedLocation(dbg);
await waitForSource(dbg, "wasm-sourcemaps/average.c");
await addBreakpoint(dbg, "wasm-sourcemaps/average.c", 12);
clickElement(dbg, "resume");

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

@ -0,0 +1,3 @@
function foo(n) {
console.log("yo")
}

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

@ -0,0 +1,7 @@
/*
* comments
*/
function foo() {
console.log("YO")
}

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

@ -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"></script>
<head>
<meta charset="utf-8"/>
<title>Empty test page 1</title>
</head>
<body>
</body>
</html>

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

@ -0,0 +1,32 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* globals getState, setState */
/* exported handleRequest */
"use strict";
function _getUrl(request, counter) {
const { scheme, host, path } = request;
const newPath = path.substr(0, path.lastIndexOf("/") + 1);
const index = counter < 3 ? 1 : 2;
return `${scheme}://${host}${newPath}/code_reload_${index}.js`
}
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 = 1 + +getState("counter");
const newUrl = _getUrl(request, counter);
response.setStatusLine(request.httpVersion, 302, "Found");
response.setHeader("Location", newUrl);
setState("counter", "" + counter);
}

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

@ -504,7 +504,7 @@ function stepOut(dbg) {
function resume(dbg) {
info("Resuming");
dbg.actions.resume();
return waitForThreadEvents(dbg, "resumed");
return waitForState(dbg, (state) => !dbg.selectors.isPaused(state));
}
function deleteExpression(dbg, input) {

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

@ -790,3 +790,7 @@ shortcuts.projectSearch=Full Project Search
# LOCALIZATION NOTE (shortcuts.functionSearch): text describing
# keyboard shortcut action for function search
shortcuts.functionSearch=Function Search
# LOCALIZATION NOTE (shortcuts.buttonName): text describing
# keyboard shortcut button text
shortcuts.buttonName=Keyboard shortcuts

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

@ -31,7 +31,6 @@ pref("devtools.debugger.ui.variables-only-enum-visible", false);
pref("devtools.debugger.ui.variables-searchbox-visible", false);
pref("devtools.debugger.ui.framework-grouping-on", true);
pref("devtools.debugger.call-stack-visible", false);
pref("devtools.debugger.scopes-visible", false);
pref("devtools.debugger.start-panel-collapsed", false);
pref("devtools.debugger.end-panel-collapsed", false);
pref("devtools.debugger.tabs", "[]");

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

@ -814,10 +814,8 @@ NetworkMonitor.prototype = {
this.interceptedChannels.add(subject);
// On e10s, we never receive http-on-examine-cached-response, so fake one.
if (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT) {
this._httpResponseExaminer(channel, "http-on-examine-cached-response");
}
// Service workers never fire http-on-examine-cached-response, so fake one.
this._httpResponseExaminer(channel, "http-on-examine-cached-response");
},
/**

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

@ -97,11 +97,6 @@ let expectedConsoleCalls = [
filename: /helper_serviceworker/,
arguments: ['fetch event: ' + SCOPE_FRAME_URL2],
},
{
level: "log",
filename: /helper_serviceworker/,
arguments: ['message event: ' + MESSAGE],
},
];
let consoleCalls = [];
@ -169,10 +164,9 @@ let onAttach = Task.async(function*(state, response) {
// Now postMessage() the service worker to trigger its message event
// handler. This will generate 1 or 2 to console.log() statements
// depending on if the worker thread needs to spin up again. Although we
// don't have a controlled or registering document in both cases, we still
// could get console calls since we only flush reports when the channel is
// finally destroyed.
// depending on if the worker thread needs to spin up again. In either
// case, though, we should not get any console calls because we don't
// have a controlled or registering document.
info("Completed force refresh. Messaging service worker.");
yield messageServiceWorker(currentFrame.contentWindow, SCOPE, MESSAGE);

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

@ -15066,7 +15066,7 @@ nsDocShell::ChannelIntercepted(nsIInterceptedChannel* aChannel)
{
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (!swm) {
aChannel->Cancel(NS_ERROR_INTERCEPTION_FAILED);
aChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
return NS_OK;
}

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

@ -513,10 +513,10 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
// Note: GL_MAX_TEXTURE_UNITS is fixed at 4 for most desktop hardware,
// even though the hardware supports much more. The
// GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS value is the accurate value.
gl->GetUIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGLMaxTextureUnits);
mGLMaxCombinedTextureImageUnits = mGLMaxTextureUnits;
mGLMaxCombinedTextureImageUnits = gl->GetIntAs<GLuint>(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
mGLMaxTextureUnits = mGLMaxCombinedTextureImageUnits;
if (mGLMaxTextureUnits < 8) {
if (mGLMaxCombinedTextureImageUnits < 8) {
const nsPrintfCString reason("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %u is < 8!",
mGLMaxTextureUnits);
*out_failReason = { "FEATURE_FAILURE_WEBGL_T_UNIT", reason };

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

@ -1295,8 +1295,9 @@ EventStateManager::DispatchCrossProcessEvent(WidgetEvent* aEvent,
return;
}
case eDragEventClass: {
if (remote->Manager()->IsContentParent()) {
remote->Manager()->AsContentParent()->MaybeInvokeDragSession(remote);
RefPtr<TabParent> tabParent = remote;
if (tabParent->Manager()->IsContentParent()) {
tabParent->Manager()->AsContentParent()->MaybeInvokeDragSession(tabParent);
}
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
@ -1312,7 +1313,7 @@ EventStateManager::DispatchCrossProcessEvent(WidgetEvent* aEvent,
}
}
remote->SendRealDragEvent(*aEvent->AsDragEvent(), action, dropEffect);
tabParent->SendRealDragEvent(*aEvent->AsDragEvent(), action, dropEffect);
return;
}
case ePluginEventClass: {

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

@ -872,26 +872,32 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
}
// "HTTP-redirect fetch": step 14 "Append locationURL to request's URL list."
nsCOMPtr<nsIURI> uri;
MOZ_ALWAYS_SUCCEEDS(aNewChannel->GetURI(getter_AddRefs(uri)));
// However, ignore internal redirects here. We don't want to flip
// Response.redirected to true if an internal redirect occurs. These
// should be transparent to script.
if (!(aFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
nsCOMPtr<nsIURI> uri;
MOZ_ALWAYS_SUCCEEDS(aNewChannel->GetURI(getter_AddRefs(uri)));
nsCOMPtr<nsIURI> uriClone;
nsresult rv = uri->CloneIgnoringRef(getter_AddRefs(uriClone));
if(NS_WARN_IF(NS_FAILED(rv))){
return rv;
}
nsCString spec;
rv = uriClone->GetSpec(spec);
if(NS_WARN_IF(NS_FAILED(rv))){
return rv;
}
nsCString fragment;
rv = uri->GetRef(fragment);
if(NS_WARN_IF(NS_FAILED(rv))){
return rv;
nsCOMPtr<nsIURI> uriClone;
nsresult rv = uri->CloneIgnoringRef(getter_AddRefs(uriClone));
if(NS_WARN_IF(NS_FAILED(rv))){
return rv;
}
nsCString spec;
rv = uriClone->GetSpec(spec);
if(NS_WARN_IF(NS_FAILED(rv))){
return rv;
}
nsCString fragment;
rv = uri->GetRef(fragment);
if(NS_WARN_IF(NS_FAILED(rv))){
return rv;
}
mRequest->AddURL(spec, fragment);
}
mRequest->AddURL(spec, fragment);
NS_ConvertUTF8toUTF16 tRPHeaderValue(tRPHeaderCValue);
// updates requests associated referrer policy according to the
// Referrer-Policy header (if any).
@ -902,10 +908,10 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
mRequest->SetReferrerPolicy(net_referrerPolicy);
// Should update channel's referrer policy
if (httpChannel) {
rv = FetchUtil::SetRequestReferrer(mPrincipal,
mDocument,
httpChannel,
mRequest);
nsresult rv = FetchUtil::SetRequestReferrer(mPrincipal,
mDocument,
httpChannel,
mRequest);
NS_ENSURE_SUCCESS(rv, rv);
}
}

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

@ -201,6 +201,10 @@ public:
{
GetHTMLAttr(nsGkAtoms::name, aValue);
}
void GetName(nsAString& aValue)
{
GetHTMLAttr(nsGkAtoms::name, aValue);
}
void SetName(const nsAString& aValue, mozilla::ErrorResult& rv)
{
SetHTMLAttr(nsGkAtoms::name, aValue, rv);

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

@ -32,6 +32,8 @@ public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLBodyElement, body);
// Event listener stuff; we need to declare only the ones we need to
// forward to window that don't come from nsIDOMHTMLBodyElement.
#define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
@ -112,6 +114,10 @@ public:
{
GetHTMLAttr(nsGkAtoms::background, aBackground);
}
void GetBackground(nsAString& aBackground)
{
GetHTMLAttr(nsGkAtoms::background, aBackground);
}
void SetBackground(const nsAString& aBackground, ErrorResult& aError)
{
SetHTMLAttr(nsGkAtoms::background, aBackground, aError);

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

@ -1528,6 +1528,11 @@ CSPReportRedirectSink::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
uint32_t aRedirFlags,
nsIAsyncVerifyRedirectCallback* aCallback)
{
if (aRedirFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
aCallback->OnRedirectVerifyCallback(NS_OK);
return NS_OK;
}
// cancel the old channel so XHR failure callback happens
nsresult rv = aOldChannel->Cancel(NS_ERROR_ABORT);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -34,9 +34,9 @@ public:
: mKey(*aKey),
mForceCompositing(false)
{ }
nsSMILCompositor(const nsSMILCompositor& toCopy)
: mKey(toCopy.mKey),
mAnimationFunctions(toCopy.mAnimationFunctions),
nsSMILCompositor(nsSMILCompositor&& toMove)
: mKey(mozilla::Move(toMove.mKey)),
mAnimationFunctions(mozilla::Move(toMove.mAnimationFunctions)),
mForceCompositing(false)
{ }
~nsSMILCompositor() { }

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

@ -8,6 +8,13 @@
#include "nsSMILValue.h"
#include "nsDebug.h"
/*static*/ nsSMILNullType*
nsSMILNullType::Singleton()
{
static nsSMILNullType sSingleton;
return &sSingleton;
}
nsresult
nsSMILNullType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
{

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

@ -14,12 +14,7 @@ class nsSMILNullType : public nsISMILType
{
public:
// Singleton for nsSMILValue objects to hold onto.
static nsSMILNullType*
Singleton()
{
static nsSMILNullType sSingleton;
return &sSingleton;
}
static nsSMILNullType* Singleton();
protected:
// nsISMILType Methods

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

@ -9,11 +9,13 @@ interface XPathEvaluator {
// Based on nsIDOMXPathEvaluator
[NewObject, Throws]
XPathExpression createExpression(DOMString expression,
XPathNSResolver? resolver);
optional XPathNSResolver? resolver = null);
[Pure]
Node createNSResolver(Node nodeResolver);
[Throws]
XPathResult evaluate(DOMString expression, Node contextNode,
XPathNSResolver? resolver, unsigned short type,
object? result);
XPathResult evaluate(DOMString expression,
Node contextNode,
optional XPathNSResolver? resolver = null,
optional unsigned short type = 0 /* XPathResult.ANY_TYPE */,
optional object? result = null);
};

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

@ -9,7 +9,9 @@ interface XPathExpression {
// returned by this method. If this is specified as null or it's not an
// XPathResult object, a new result object will be constructed and returned.
[Throws]
XPathResult evaluate(Node contextNode, unsigned short type, object? result);
XPathResult evaluate(Node contextNode,
optional unsigned short type = 0 /* XPathResult.ANY_TYPE */,
optional object? result = null);
// The result specifies a specific result object which may be reused and
// returned by this method. If this is specified as null or it's not an
@ -18,5 +20,6 @@ interface XPathExpression {
XPathResult evaluateWithContext(Node contextNode,
unsigned long contextPosition,
unsigned long contextSize,
unsigned short type, object? result);
optional unsigned short type = 0 /* XPathResult.ANY_TYPE */,
optional object? result = null);
};

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

@ -115,7 +115,7 @@ CancelChannelRunnable::Run()
mChannel->SetHandleFetchEventEnd(TimeStamp::Now());
mChannel->SaveTimeStamps();
mChannel->Cancel(mStatus);
mChannel->CancelInterception(mStatus);
mRegistration->MaybeScheduleUpdate();
return NS_OK;
}
@ -199,7 +199,7 @@ public:
nsCOMPtr<nsILoadInfo> loadInfo = underlyingChannel->GetLoadInfo();
if (!loadInfo || !CSPPermitsResponse(loadInfo)) {
mChannel->Cancel(NS_ERROR_CONTENT_BLOCKED);
mChannel->CancelInterception(NS_ERROR_CONTENT_BLOCKED);
return NS_OK;
}
@ -213,14 +213,14 @@ public:
}
rv = mChannel->SetChannelInfo(&channelInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
mChannel->Cancel(NS_ERROR_INTERCEPTION_FAILED);
mChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
return NS_OK;
}
rv = mChannel->SynthesizeStatus(mInternalResponse->GetUnfilteredStatus(),
mInternalResponse->GetUnfilteredStatusText());
if (NS_WARN_IF(NS_FAILED(rv))) {
mChannel->Cancel(NS_ERROR_INTERCEPTION_FAILED);
mChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
return NS_OK;
}
@ -235,7 +235,7 @@ public:
rv = mChannel->FinishSynthesizedResponse(mResponseURLSpec);
if (NS_WARN_IF(NS_FAILED(rv))) {
mChannel->Cancel(NS_ERROR_INTERCEPTION_FAILED);
mChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
return NS_OK;
}

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

@ -0,0 +1,11 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<select>
<script>document.documentElement.offsetHeight</script>
<option>Hello there</option>
</select>
<script>
document.querySelector("body").style.display = "inline";
</script>
</body>
</html>

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

@ -10,3 +10,4 @@ load 453278.html
load 803586.xhtml
load 994740-1.xhtml
load 1038887.xhtml
load 1405878.xml

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

@ -1070,6 +1070,17 @@ nsXMLContentSink::HandleEndElement(const char16_t *aName,
isTemplateElement, "Wrong element being closed");
#endif
// Make sure to notify on our kids before we call out to any other code that
// might reenter us and call FlushTags, in a state in which we've already
// popped "content" from the stack but haven't notified on its kids yet.
int32_t stackLen = mContentStack.Length();
if (mNotifyLevel >= stackLen) {
if (numFlushed < content->GetChildCount()) {
NotifyAppend(content, numFlushed);
}
mNotifyLevel = stackLen - 1;
}
result = CloseElement(content);
if (mCurrentHead == content) {
@ -1085,13 +1096,6 @@ nsXMLContentSink::HandleEndElement(const char16_t *aName,
MaybeStartLayout(false);
}
int32_t stackLen = mContentStack.Length();
if (mNotifyLevel >= stackLen) {
if (numFlushed < content->GetChildCount()) {
NotifyAppend(content, numFlushed);
}
mNotifyLevel = stackLen - 1;
}
DidAddContent();
if (content->IsSVGElement(nsGkAtoms::svg)) {

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

@ -112,9 +112,9 @@ public:
: nsRefPtrHashKey<PermissionKey>(aPermissionKey)
{}
PermissionHashKey(const PermissionHashKey& toCopy)
: nsRefPtrHashKey<PermissionKey>(toCopy)
, mPermissions(toCopy.mPermissions)
PermissionHashKey(PermissionHashKey&& toCopy)
: nsRefPtrHashKey<PermissionKey>(mozilla::Move(toCopy))
, mPermissions(mozilla::Move(toCopy.mPermissions))
{}
bool KeyEquals(const PermissionKey* aKey) const

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

@ -166,12 +166,12 @@ static gfx::IntRect ContainerVisibleRect(ContainerT* aContainer)
/* all of the per-layer prepared data we need to maintain */
struct PreparedLayer
{
PreparedLayer(LayerComposite *aLayer,
PreparedLayer(Layer *aLayer,
RenderTargetIntRect aClipRect,
Maybe<gfx::Polygon>&& aGeometry)
: mLayer(aLayer), mClipRect(aClipRect), mGeometry(Move(aGeometry)) {}
LayerComposite* mLayer;
RefPtr<Layer> mLayer;
RenderTargetIntRect mClipRect;
Maybe<Polygon> mGeometry;
};
@ -235,7 +235,8 @@ ContainerPrepare(ContainerT* aContainer,
CULLING_LOG("Preparing sublayer %p\n", layerToRender->GetLayer());
layerToRender->Prepare(clipRect);
aContainer->mPrepared->mLayers.AppendElement(PreparedLayer(layerToRender, clipRect,
aContainer->mPrepared->mLayers.AppendElement(PreparedLayer(layerToRender->GetLayer(),
clipRect,
Move(layer.geometry)));
}
@ -413,7 +414,7 @@ RenderLayers(ContainerT* aContainer, LayerManagerComposite* aManager,
PreparedLayer& preparedData = aContainer->mPrepared->mLayers[i];
const gfx::IntRect clipRect = preparedData.mClipRect.ToUnknownRect();
LayerComposite* layerToRender = preparedData.mLayer;
LayerComposite* layerToRender = static_cast<LayerComposite*>(preparedData.mLayer->ImplData());
const Maybe<gfx::Polygon>& childGeometry = preparedData.mGeometry;
Layer* layer = layerToRender->GetLayer();

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

@ -20,15 +20,12 @@ StackingContextHelper::StackingContextHelper()
StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
wr::DisplayListBuilder& aBuilder,
nsDisplayListBuilder* aDisplayListBuilder,
nsDisplayItem* aItem,
nsDisplayList* aDisplayList,
const nsTArray<wr::WrFilterOp>& aFilters,
const gfx::Matrix4x4* aBoundTransform,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,
gfx::Matrix4x4* aPerspectivePtr,
const nsTArray<wr::WrFilterOp>& aFilters,
const gfx::CompositionOp& aMixBlendMode,
bool aBackfaceVisible)
: mBuilder(&aBuilder)

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

@ -30,15 +30,12 @@ class MOZ_RAII StackingContextHelper
public:
StackingContextHelper(const StackingContextHelper& aParentSC,
wr::DisplayListBuilder& aBuilder,
nsDisplayListBuilder* aDisplayListBuilder,
nsDisplayItem* aItem,
nsDisplayList* aDisplayList,
const gfx::Matrix4x4* aBoundTransform,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,
gfx::Matrix4x4* aPerspectivePtr = nullptr,
const nsTArray<wr::WrFilterOp>& aFilters = nsTArray<wr::WrFilterOp>(),
const gfx::Matrix4x4* aBoundTransform = nullptr,
uint64_t aAnimationsId = 0,
float* aOpacityPtr = nullptr,
gfx::Matrix4x4* aTransformPtr = nullptr,
gfx::Matrix4x4* aPerspectivePtr = nullptr,
const gfx::CompositionOp& aMixBlendMode = gfx::CompositionOp::OP_OVER,
bool aBackfaceVisible = true);
// This version of the constructor should only be used at the root level

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

@ -46,8 +46,11 @@ WebRenderCommandBuilder::BuildWebRenderCommands(wr::DisplayListBuilder& aBuilder
mLastCanvasDatas.Clear();
mLastAsr = nullptr;
CreateWebRenderCommandsFromDisplayList(aDisplayList, aDisplayListBuilder, sc,
aBuilder, aResourceUpdates);
{
StackingContextHelper pageRootSc(sc, aBuilder);
CreateWebRenderCommandsFromDisplayList(aDisplayList, aDisplayListBuilder,
pageRootSc, aBuilder, aResourceUpdates);
}
// Make a "root" layer data that has everything else as descendants
mLayerScrollData.emplace_back();

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

@ -237,7 +237,7 @@ AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell) {}
* Type T must be a public GC pointer type.
*/
template <typename T>
class Heap : public js::HeapBase<T, Heap<T>>
class MOZ_NON_MEMMOVABLE Heap : public js::HeapBase<T, Heap<T>>
{
// Please note: this can actually also be used by nsXBLMaybeCompiled<T>, for legacy reasons.
static_assert(js::IsHeapConstructibleType<T>::value,
@ -1173,6 +1173,14 @@ class JS_PUBLIC_API(ObjectPtr)
explicit ObjectPtr(JSObject* obj) : value(obj) {}
ObjectPtr(const ObjectPtr& other) : value(other.value) {}
ObjectPtr(ObjectPtr&& other)
: value(other.value)
{
other.value = nullptr;
}
/* Always call finalize before the destructor. */
~ObjectPtr() { MOZ_ASSERT(!value); }

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

@ -1428,14 +1428,25 @@ auto
DispatchTyped(F f, const JS::Value& val, Args&&... args)
-> decltype(f(static_cast<JSObject*>(nullptr), mozilla::Forward<Args>(args)...))
{
if (val.isString())
return f(val.toString(), mozilla::Forward<Args>(args)...);
if (val.isObject())
return f(&val.toObject(), mozilla::Forward<Args>(args)...);
if (val.isSymbol())
return f(val.toSymbol(), mozilla::Forward<Args>(args)...);
if (MOZ_UNLIKELY(val.isPrivateGCThing()))
if (val.isString()) {
JSString* str = val.toString();
MOZ_ASSERT(gc::IsCellPointerValid(str));
return f(str, mozilla::Forward<Args>(args)...);
}
if (val.isObject()) {
JSObject* obj = &val.toObject();
MOZ_ASSERT(gc::IsCellPointerValid(obj));
return f(obj, mozilla::Forward<Args>(args)...);
}
if (val.isSymbol()) {
JS::Symbol* sym = val.toSymbol();
MOZ_ASSERT(gc::IsCellPointerValid(sym));
return f(sym, mozilla::Forward<Args>(args)...);
}
if (MOZ_UNLIKELY(val.isPrivateGCThing())) {
MOZ_ASSERT(gc::IsCellPointerValid(val.toGCThing()));
return DispatchTyped(f, val.toGCCellPtr(), mozilla::Forward<Args>(args)...);
}
MOZ_ASSERT(!val.isGCThing());
return F::defaultValue(val);
}

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

@ -472,30 +472,30 @@ static bool ResolvePromiseFunction(JSContext* cx, unsigned argc, Value* vp);
static bool RejectPromiseFunction(JSContext* cx, unsigned argc, Value* vp);
// ES2016, 25.4.1.3.
static MOZ_MUST_USE bool
static MOZ_MUST_USE MOZ_ALWAYS_INLINE bool
CreateResolvingFunctions(JSContext* cx, HandleObject promise,
MutableHandleObject resolveFn,
MutableHandleObject rejectFn)
{
RootedAtom funName(cx, cx->names().empty);
RootedFunction resolve(cx, NewNativeFunction(cx, ResolvePromiseFunction, 1, funName,
gc::AllocKind::FUNCTION_EXTENDED, GenericObject));
if (!resolve)
HandlePropertyName funName = cx->names().empty;
resolveFn.set(NewNativeFunction(cx, ResolvePromiseFunction, 1, funName,
gc::AllocKind::FUNCTION_EXTENDED, GenericObject));
if (!resolveFn)
return false;
RootedFunction reject(cx, NewNativeFunction(cx, RejectPromiseFunction, 1, funName,
gc::AllocKind::FUNCTION_EXTENDED, GenericObject));
if (!reject)
rejectFn.set(NewNativeFunction(cx, RejectPromiseFunction, 1, funName,
gc::AllocKind::FUNCTION_EXTENDED, GenericObject));
if (!rejectFn)
return false;
resolve->setExtendedSlot(ResolveFunctionSlot_Promise, ObjectValue(*promise));
resolve->setExtendedSlot(ResolveFunctionSlot_RejectFunction, ObjectValue(*reject));
JSFunction* resolveFun = &resolveFn->as<JSFunction>();
JSFunction* rejectFun = &rejectFn->as<JSFunction>();
reject->setExtendedSlot(RejectFunctionSlot_Promise, ObjectValue(*promise));
reject->setExtendedSlot(RejectFunctionSlot_ResolveFunction, ObjectValue(*resolve));
resolveFun->initExtendedSlot(ResolveFunctionSlot_Promise, ObjectValue(*promise));
resolveFun->initExtendedSlot(ResolveFunctionSlot_RejectFunction, ObjectValue(*rejectFun));
resolveFn.set(resolve);
rejectFn.set(reject);
rejectFun->initExtendedSlot(RejectFunctionSlot_Promise, ObjectValue(*promise));
rejectFun->initExtendedSlot(RejectFunctionSlot_ResolveFunction, ObjectValue(*resolveFun));
return true;
}
@ -1465,12 +1465,11 @@ ClearResolutionFunctionSlots(JSFunction* resolutionFun)
}
// ES2016, 25.4.3.1. steps 3-7.
static MOZ_MUST_USE PromiseObject*
static MOZ_MUST_USE MOZ_ALWAYS_INLINE PromiseObject*
CreatePromiseObjectInternal(JSContext* cx, HandleObject proto /* = nullptr */,
bool protoIsWrapped /* = false */, bool informDebugger /* = true */)
{
// Step 3.
Rooted<PromiseObject*> promise(cx);
// Enter the unwrapped proto's compartment, if that's different from
// the current one.
// All state stored in a Promise's fixed slots must be created in the
@ -1480,12 +1479,12 @@ CreatePromiseObjectInternal(JSContext* cx, HandleObject proto /* = nullptr */,
if (protoIsWrapped)
ac.emplace(cx, proto);
promise = NewObjectWithClassProto<PromiseObject>(cx, proto);
PromiseObject* promise = NewObjectWithClassProto<PromiseObject>(cx, proto);
if (!promise)
return nullptr;
// Step 4.
promise->setFixedSlot(PromiseSlot_Flags, Int32Value(0));
promise->initFixedSlot(PromiseSlot_Flags, Int32Value(0));
// Steps 5-6.
// Omitted, we allocate our single list of reaction records lazily.
@ -1493,20 +1492,24 @@ CreatePromiseObjectInternal(JSContext* cx, HandleObject proto /* = nullptr */,
// Step 7.
// Implicit, the handled flag is unset by default.
if (MOZ_LIKELY(!ShouldCaptureDebugInfo(cx)))
return promise;
// Store an allocation stack so we can later figure out what the
// control flow was for some unexpected results. Frightfully expensive,
// but oh well.
if (ShouldCaptureDebugInfo(cx)) {
PromiseDebugInfo* debugInfo = PromiseDebugInfo::create(cx, promise);
if (!debugInfo)
return nullptr;
}
Rooted<PromiseObject*> promiseRoot(cx, promise);
PromiseDebugInfo* debugInfo = PromiseDebugInfo::create(cx, promiseRoot);
if (!debugInfo)
return nullptr;
// Let the Debugger know about this Promise.
if (informDebugger)
Debugger::onNewPromise(cx, promise);
Debugger::onNewPromise(cx, promiseRoot);
return promise;
return promiseRoot;
}
// ES2016, 25.4.3.1.
@ -1588,7 +1591,7 @@ PromiseConstructor(JSContext* cx, unsigned argc, Value* vp)
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
return false;
}
Rooted<PromiseObject*> promise(cx, PromiseObject::create(cx, executor, proto, needsWrapping));
PromiseObject* promise = PromiseObject::create(cx, executor, proto, needsWrapping);
if (!promise)
return false;
@ -1639,14 +1642,16 @@ PromiseObject::create(JSContext* cx, HandleObject executor, HandleObject proto /
return nullptr;
// Need to wrap the resolution functions before storing them on the Promise.
MOZ_ASSERT(promise->getFixedSlot(PromiseSlot_RejectFunction).isUndefined(),
"Slot must be undefined so initFixedSlot can be used");
if (needsWrapping) {
AutoCompartment ac(cx, promise);
RootedObject wrappedRejectFn(cx, rejectFn);
if (!cx->compartment()->wrap(cx, &wrappedRejectFn))
return nullptr;
promise->setFixedSlot(PromiseSlot_RejectFunction, ObjectValue(*wrappedRejectFn));
promise->initFixedSlot(PromiseSlot_RejectFunction, ObjectValue(*wrappedRejectFn));
} else {
promise->setFixedSlot(PromiseSlot_RejectFunction, ObjectValue(*rejectFn));
promise->initFixedSlot(PromiseSlot_RejectFunction, ObjectValue(*rejectFn));
}
// Step 9.
@ -2401,6 +2406,15 @@ NewReactionRecord(JSContext* cx, HandleObject resultPromise, HandleValue onFulfi
HandleValue onRejected, HandleObject resolve, HandleObject reject,
HandleObject incumbentGlobalObject)
{
// Either of the following conditions must be met:
// * resultPromise is a PromiseObject
// * resolve and reject are callable
// except for Async Generator, there resultPromise can be nullptr.
MOZ_ASSERT_IF(resultPromise && !resultPromise->is<PromiseObject>(), resolve);
MOZ_ASSERT_IF(resultPromise && !resultPromise->is<PromiseObject>(), IsCallable(resolve));
MOZ_ASSERT_IF(resultPromise && !resultPromise->is<PromiseObject>(), reject);
MOZ_ASSERT_IF(resultPromise && !resultPromise->is<PromiseObject>(), IsCallable(reject));
Rooted<PromiseReactionRecord*> reaction(cx, NewObjectWithClassProto<PromiseReactionRecord>(cx));
if (!reaction)
return nullptr;
@ -3108,7 +3122,7 @@ BlockOnPromise(JSContext* cx, HandleValue promiseVal, HandleObject blockedPromis
// rejected promises list.
bool addToDependent = true;
if (C == PromiseCtor) {
if (C == PromiseCtor && resultPromise->is<PromiseObject>()) {
addToDependent = false;
} else {
// 25.4.5.3., step 4.
@ -3167,12 +3181,14 @@ BlockOnPromise(JSContext* cx, HandleValue promiseVal, HandleObject blockedPromis
return false;
}
// If the object to depend on isn't a, maybe-wrapped, Promise instance,
// we ignore it. All this does is lose some small amount of debug
// information in scenarios that are highly unlikely to occur in useful
// code.
// If either the object to depend on or the object that gets blocked isn't
// a, maybe-wrapped, Promise instance, we ignore it. All this does is lose
// some small amount of debug information in scenarios that are highly
// unlikely to occur in useful code.
if (!unwrappedPromiseObj->is<PromiseObject>())
return true;
if (!blockedPromise_->is<PromiseObject>())
return true;
Rooted<PromiseObject*> promise(cx, &unwrappedPromiseObj->as<PromiseObject>());
return AddPromiseReaction(cx, promise, UndefinedHandleValue, UndefinedHandleValue,

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

@ -283,7 +283,7 @@ struct InternalBarrierMethods<Value>
DispatchTyped(PreBarrierFunctor<Value>(), v);
}
static void postBarrier(Value* vp, const Value& prev, const Value& next) {
static MOZ_ALWAYS_INLINE void postBarrier(Value* vp, const Value& prev, const Value& next) {
MOZ_ASSERT(!CurrentThreadIsIonCompiling());
MOZ_ASSERT(vp);
@ -318,8 +318,11 @@ struct InternalBarrierMethods<jsid>
};
// Base class of all barrier types.
//
// This is marked non-memmovable since post barriers added by derived classes
// can add pointers to class instances to the store buffer.
template <typename T>
class BarrieredBase
class MOZ_NON_MEMMOVABLE BarrieredBase
{
protected:
// BarrieredBase is not directly instantiable.
@ -369,7 +372,7 @@ class WriteBarrieredBase : public BarrieredBase<T>,
protected:
void pre() { InternalBarrierMethods<T>::preBarrier(this->value); }
void post(const T& prev, const T& next) {
MOZ_ALWAYS_INLINE void post(const T& prev, const T& next) {
InternalBarrierMethods<T>::postBarrier(&this->value, prev, next);
}
};

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

@ -2716,6 +2716,7 @@ void
js::gc::StoreBuffer::SlotsEdge::trace(TenuringTracer& mover) const
{
NativeObject* obj = object();
MOZ_ASSERT(IsCellPointerValid(obj));
// Beware JSObject::swap exchanging a native object for a non-native one.
if (!obj->isNative())
@ -2788,6 +2789,7 @@ js::gc::StoreBuffer::traceWholeCells(TenuringTracer& mover)
{
for (ArenaCellSet* cells = bufferWholeCell; cells; cells = cells->next) {
Arena* arena = cells->arena;
MOZ_ASSERT(IsCellPointerValid(arena));
MOZ_ASSERT(arena->bufferedCells() == cells);
arena->bufferedCells() = &ArenaCellSet::Empty;
@ -2817,6 +2819,7 @@ js::gc::StoreBuffer::CellPtrEdge::trace(TenuringTracer& mover) const
if (!*edge)
return;
MOZ_ASSERT(IsCellPointerValid(*edge));
MOZ_ASSERT((*edge)->getTraceKind() == JS::TraceKind::Object);
mover.traverse(reinterpret_cast<JSObject**>(edge));
}

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

@ -82,9 +82,12 @@ Zone::~Zone()
js_delete(jitZone_.ref());
#ifdef DEBUG
// Avoid assertion destroying the weak map list if the embedding leaked GC things.
if (!rt->gc.shutdownCollectedEverything())
// Avoid assertions failures warning that not everything has been destroyed
// if the embedding leaked GC things.
if (!rt->gc.shutdownCollectedEverything()) {
gcWeakMapList().clear();
regExps.clear();
}
#endif
}

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

@ -619,26 +619,71 @@ assertEq(e.call(), 1090);
let valueToConvert = 0;
function ffi(n) { if (n == 1337) { return valueToConvert }; return 42; }
// Baseline compile ffi.
for (let i = baselineTrigger + 1; i --> 0;)
ffi(i);
function sum(a, b, c) {
if (a === 1337)
return valueToConvert;
return (a|0) + (b|0) + (c|0) | 0;
}
let imports = { a: { ffi }};
// Baseline compile ffis.
for (let i = baselineTrigger + 1; i --> 0;) {
ffi(i);
sum((i%2)?i:undefined,
(i%3)?i:undefined,
(i%4)?i:undefined);
}
let imports = {
a: {
ffi,
sum
}
};
i = wasmEvalText(`(module
(import $ffi "a" "ffi" (param i32) (result i32))
(func $foo (export "foo") (param i32) (result i32)
(import $missingOneArg "a" "sum" (param i32) (param i32) (result i32))
(import $missingTwoArgs "a" "sum" (param i32) (result i32))
(import $missingThreeArgs "a" "sum" (result i32))
(func (export "foo") (param i32) (result i32)
get_local 0
call $ffi)
call $ffi
)
(func (export "missThree") (result i32)
call $missingThreeArgs
)
(func (export "missTwo") (param i32) (result i32)
get_local 0
call $missingTwoArgs
)
(func (export "missOne") (param i32) (param i32) (result i32)
get_local 0
get_local 1
call $missingOneArg
)
)`, imports).exports;
// Enable the jit exit.
// Enable the jit exit for each JS callee.
assertEq(i.foo(0), 42);
// Test the jit exit.
assertEq(i.missThree(), 0);
assertEq(i.missTwo(42), 42);
assertEq(i.missOne(13, 37), 50);
// Test the jit exit under normal conditions.
assertEq(i.foo(0), 42);
assertEq(i.foo(1337), 0);
// Test the arguments rectifier.
assertEq(i.missThree(), 0);
assertEq(i.missTwo(-1), -1);
assertEq(i.missOne(23, 10), 33);
// Test OOL coercion.
valueToConvert = 2**31;
assertEq(i.foo(1337), -(2**31));
@ -649,5 +694,7 @@ assertEq(e.call(), 1090);
valueToConvert = { toString() { throw new Error('a FFI to believe in'); } }
assertErrorMessage(() => i.foo(1337), Error, "a FFI to believe in");
})();
// Test the error path in the arguments rectifier.
assertErrorMessage(() => i.missTwo(1337), Error, "a FFI to believe in");
})();

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

@ -331,9 +331,17 @@ for (let type of ['f32', 'f64']) {
var m = new Module(wasmTextToBinary(`(module
(import $ffi "a" "ffi" (param i32) (result i32))
(func $foo (export "foo") (param i32) (result i32)
(import $missingOneArg "a" "sumTwo" (param i32) (result i32))
(func (export "foo") (param i32) (result i32)
get_local 0
call $ffi)
(func (export "id") (param i32) (result i32)
get_local 0
call $missingOneArg
)
)`));
var valueToConvert = 0;
@ -343,45 +351,71 @@ for (let type of ['f32', 'f64']) {
return 42;
}
// Baseline compile ffi.
for (var i = 20; i --> 0;)
ffi(i);
function sumTwo(a, b) {
return (a|0)+(b|0)|0;
}
var imports = { a: { ffi }};
// Baseline compile ffi.
for (var i = 20; i --> 0;) {
ffi(i);
sumTwo(i-1, i+1);
}
var imports = {
a: {
ffi,
sumTwo
}
};
var i = new Instance(m, imports).exports;
// Enable the jit exit.
assertEq(i.foo(0), 42);
assertEq(i.id(13), 13);
// Test normal conditions.
enableSingleStepProfiling();
assertEq(i.foo(0), 42);
assertEqStacks(disableSingleStepProfiling(), ["", ">", "1,>", "<,1,>",
assertEqStacks(disableSingleStepProfiling(), ["", ">", "2,>", "<,2,>",
// Losing stack information while the JIT func prologue sets profiler
// virtual FP.
"",
// Callee time.
"<,1,>",
"<,2,>",
// Losing stack information while we're exiting JIT func epilogue and
// recovering wasm FP.
"",
// Back into the jit exit (frame info has been recovered).
"<,1,>",
"<,2,>",
// Normal unwinding.
"1,>", ">", ""]);
"2,>", ">", ""]);
// Test rectifier frame.
enableSingleStepProfiling();
assertEq(i.id(100), 100);
assertEqStacks(disableSingleStepProfiling(), ["", ">", "3,>", "<,3,>",
// Rectifier frame time is spent here (lastProfilingFrame has not been
// set).
"",
"<,3,>",
// Rectifier frame unwinding time is spent here.
"",
"<,3,>",
"3,>", ">", ""]);
// Test OOL coercion path.
valueToConvert = 2**31;
enableSingleStepProfiling();
assertEq(i.foo(1337), -(2**31));
assertEqStacks(disableSingleStepProfiling(), ["", ">", "1,>", "<,1,>", "", "<,1,>", "",
assertEqStacks(disableSingleStepProfiling(), ["", ">", "2,>", "<,2,>", "", "<,2,>", "",
// Back into the jit exit (frame info has been recovered).
// Inline conversion fails, we skip to the OOL path, call from there
// and get back to the jit exit.
"<,1,>",
"<,2,>",
// Normal unwinding.
"1,>", ">", ""]);
"2,>", ">", ""]);
disableGeckoProfiling();
setJitCompilerOption("baseline.warmup.trigger", prevOptions["baseline.warmup.trigger"]);

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

@ -394,11 +394,13 @@ struct BaselineStackBuilder
BufferPointer<RectifierFrameLayout> priorFrame =
pointerAtStackOffset<RectifierFrameLayout>(priorOffset);
FrameType priorType = priorFrame->prevType();
MOZ_ASSERT(priorType == JitFrame_IonJS || priorType == JitFrame_BaselineStub);
MOZ_ASSERT(priorType == JitFrame_WasmToJSJit ||
priorType == JitFrame_IonJS ||
priorType == JitFrame_BaselineStub);
// If the frame preceding the rectifier is an IonJS frame, then once again
// the frame pointer does not matter.
if (priorType == JitFrame_IonJS)
// If the frame preceding the rectifier is an IonJS or WasmToJSJit
// entry frame, then once again the frame pointer does not matter.
if (priorType == JitFrame_IonJS || priorType == JitFrame_WasmToJSJit)
return nullptr;
// Otherwise, the frame preceding the rectifier is a BaselineStub frame.

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

@ -280,6 +280,15 @@ JitRuntime::initialize(JSContext* cx, AutoLockForExclusiveAccess& lock)
return false;
}
// The arguments rectifier has to use the same frame layout as the function
// frames it rectifies.
static_assert(mozilla::IsBaseOf<JitFrameLayout, RectifierFrameLayout>::value,
"a rectifier frame can be used with jit frame");
static_assert(mozilla::IsBaseOf<JitFrameLayout, WasmToJSJitFrameLayout>::value,
"wasm frames simply are jit frames");
static_assert(sizeof(JitFrameLayout) == sizeof(WasmToJSJitFrameLayout),
"thus a rectifier frame can be used with a wasm frame");
JitSpew(JitSpew_Codegen, "# Emitting sequential arguments rectifier");
argumentsRectifier_ = generateArgumentsRectifier(cx, &argumentsRectifierReturnAddr_.writeRef());
if (!argumentsRectifier_)

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

@ -643,6 +643,17 @@ JSJitProfilingFrameIterator::operator++()
moveToNextFrame(frame);
}
void
JSJitProfilingFrameIterator::moveToWasmFrame(CommonFrameLayout* frame)
{
// No previous js jit frame, this is a transition frame, used to
// pass a wasm iterator the correct value of FP.
returnAddressToFp_ = nullptr;
fp_ = GetPreviousRawFrame<uint8_t*>(frame);
type_ = JitFrame_WasmToJSJit;
MOZ_ASSERT(!done());
}
void
JSJitProfilingFrameIterator::moveToNextFrame(CommonFrameLayout* frame)
{
@ -666,6 +677,8 @@ JSJitProfilingFrameIterator::moveToNextFrame(CommonFrameLayout* frame)
* | ^--- Ion
* | |
* | ^--- Baseline Stub <---- Baseline
* | |
* | ^--- WasmToJSJit <--- (other wasm frames)
* |
* ^--- Entry Frame (From C++)
* Exit Frame (From previous JitActivation)
@ -726,6 +739,11 @@ JSJitProfilingFrameIterator::moveToNextFrame(CommonFrameLayout* frame)
return;
}
if (rectPrevType == JitFrame_WasmToJSJit) {
moveToWasmFrame(rectFrame);
return;
}
MOZ_CRASH("Bad frame type prior to rectifier frame.");
}
@ -742,11 +760,7 @@ JSJitProfilingFrameIterator::moveToNextFrame(CommonFrameLayout* frame)
}
if (prevType == JitFrame_WasmToJSJit) {
// No previous js jit frame, this is a transition frame, used to pass
// a wasm iterator the correct value of FP.
returnAddressToFp_ = nullptr;
fp_ = GetPreviousRawFrame<uint8_t*>(frame);
type_ = JitFrame_WasmToJSJit;
moveToWasmFrame(frame);
return;
}

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

@ -297,6 +297,7 @@ class JSJitProfilingFrameIterator
bool forLastCallSite);
void fixBaselineReturnAddress();
void moveToWasmFrame(CommonFrameLayout* frame);
void moveToNextFrame(CommonFrameLayout* frame);
public:

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

@ -445,11 +445,11 @@ class RectifierFrameLayout : public JitFrameLayout
}
};
class WasmFrameLayout : public JitFrameLayout
class WasmToJSJitFrameLayout : public JitFrameLayout
{
public:
static inline size_t Size() {
return sizeof(WasmFrameLayout);
return sizeof(WasmToJSJitFrameLayout);
}
};

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

@ -1654,6 +1654,22 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
}
}
void
MacroAssembler::assertRectifierFrameParentType(Register frameType)
{
#ifdef DEBUG
{
// Check the possible previous frame types here.
Label checkOk;
branch32(Assembler::Equal, frameType, Imm32(JitFrame_IonJS), &checkOk);
branch32(Assembler::Equal, frameType, Imm32(JitFrame_BaselineStub), &checkOk);
branch32(Assembler::Equal, frameType, Imm32(JitFrame_WasmToJSJit), &checkOk);
assumeUnreachable("Unrecognized frame type preceding RectifierFrame.");
bind(&checkOk);
}
#endif
}
void
MacroAssembler::loadBaselineOrIonRaw(Register script, Register dest, Label* failure)
{

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

@ -1837,6 +1837,8 @@ class MacroAssembler : public MacroAssemblerSpecific
// Generates code used to complete a bailout.
void generateBailoutTail(Register scratch, Register bailoutInfo);
void assertRectifierFrameParentType(Register frameType);
public:
#ifndef JS_CODEGEN_ARM64
// StackPointer manipulation functions.

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

@ -1287,10 +1287,10 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
//
// JitFrame_Rectifier
//
// The rectifier frame can be preceded by either an IonJS or a
// BaselineStub frame.
// The rectifier frame can be preceded by either an IonJS, a WasmToJSJit or
// a BaselineStub frame.
//
// Stack layout if caller of rectifier was Ion:
// Stack layout if caller of rectifier was Ion or WasmToJSJit:
//
// Ion-Descriptor
// Ion-ReturnAddr
@ -1335,10 +1335,11 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
// and |scratch2| points to Rectifier frame
// and |scratch3| contains Rect-Descriptor.Type
masm.assertRectifierFrameParentType(scratch3);
// Check for either Ion or BaselineStub frame.
Label handle_Rectifier_BaselineStub;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS),
&handle_Rectifier_BaselineStub);
Label notIonFrame;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS), &notIonFrame);
// Handle Rectifier <- IonJS
// scratch3 := RectFrame[ReturnAddr]
@ -1351,16 +1352,13 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
masm.storePtr(scratch3, lastProfilingFrame);
masm.ret();
masm.bind(&notIonFrame);
// Check for either BaselineStub or WasmToJSJit: since WasmToJSJit is
// just an entry, jump there if we see it.
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_BaselineStub), &handle_Entry);
// Handle Rectifier <- BaselineStub <- BaselineJS
masm.bind(&handle_Rectifier_BaselineStub);
#ifdef DEBUG
{
Label checkOk;
masm.branch32(Assembler::Equal, scratch3, Imm32(JitFrame_BaselineStub), &checkOk);
masm.assumeUnreachable("Unrecognized frame preceding baselineStub.");
masm.bind(&checkOk);
}
#endif
masm.ma_add(scratch2, scratch1, scratch3);
Address stubFrameReturnAddr(scratch3, RectifierFrameLayout::Size() +
BaselineStubFrameLayout::offsetOfReturnAddress());
@ -1424,7 +1422,7 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
}
//
// JitFrame_CppToJSJit / JitFrame_WasmJSToJit
// JitFrame_CppToJSJit / JitFrame_WasmToJSJit
//
// If at an entry frame, store null into both fields.
// A fast-path wasm->jit transition frame is an entry frame from the point

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

@ -1128,10 +1128,11 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
// and |scratch2| points to Rectifier frame
// and |scratch3| contains Rect-Descriptor.Type
masm.assertRectifierFrameParentType(scratch3);
// Check for either Ion or BaselineStub frame.
Label handle_Rectifier_BaselineStub;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS),
&handle_Rectifier_BaselineStub);
Label notIonFrame;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS), &notIonFrame);
// Handle Rectifier <- IonJS
// scratch3 := RectFrame[ReturnAddr]
@ -1144,16 +1145,13 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
masm.storePtr(scratch3, lastProfilingFrame);
masm.ret();
masm.bind(&notIonFrame);
// Check for either BaselineStub or WasmToJSJit: since WasmToJSJit is
// just an entry, jump there if we see it.
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_BaselineStub), &handle_Entry);
// Handle Rectifier <- BaselineStub <- BaselineJS
masm.bind(&handle_Rectifier_BaselineStub);
#ifdef DEBUG
{
Label checkOk;
masm.branch32(Assembler::Equal, scratch3, Imm32(JitFrame_BaselineStub), &checkOk);
masm.assumeUnreachable("Unrecognized frame preceding baselineStub.");
masm.bind(&checkOk);
}
#endif
masm.addPtr(scratch2, scratch1, scratch3);
Address stubFrameReturnAddr(scratch3, RectifierFrameLayout::Size() +
BaselineStubFrameLayout::offsetOfReturnAddress());
@ -1218,7 +1216,7 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
}
//
// JitFrame_CppToJSJit / JitFrame_WasmJSToJit
// JitFrame_CppToJSJit / JitFrame_WasmToJSJit
//
// If at an entry frame, store null into both fields.
// A fast-path wasm->jit transition frame is an entry frame from the point

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

@ -13,6 +13,7 @@
#define HWCAP_MIPS (1 << 28)
#define HWCAP_LOONGSON (1 << 27)
#define HWCAP_R2 (1 << 26)
#define HWCAP_FPU (1 << 0)
namespace js {
@ -25,6 +26,7 @@ get_mips_flags()
#if defined(JS_SIMULATOR_MIPS32) || defined(JS_SIMULATOR_MIPS64)
flags |= HWCAP_FPU;
flags |= HWCAP_R2;
#else
# ifdef __linux__
FILE* fp = fopen("/proc/cpuinfo", "r");
@ -39,6 +41,8 @@ get_mips_flags()
flags |= HWCAP_FPU;
if (strstr(buf, "Loongson"))
flags |= HWCAP_LOONGSON;
if (strstr(buf, "mips32r2") || strstr(buf, "mips64r2"))
flags |= HWCAP_R2;
# endif
#endif // JS_SIMULATOR_MIPS32 || JS_SIMULATOR_MIPS64
return flags;
@ -54,11 +58,17 @@ static bool check_loongson()
return mips_private::Flags & HWCAP_LOONGSON;
}
static bool check_r2()
{
return mips_private::Flags & HWCAP_R2;
}
namespace mips_private {
// Cache a local copy so we only have to read /proc/cpuinfo once.
uint32_t Flags = get_mips_flags();
bool hasFPU = check_fpu();;
bool isLoongson = check_loongson();
bool hasR2 = check_r2();
}
Registers::Code

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

@ -314,11 +314,13 @@ namespace mips_private {
extern uint32_t Flags;
extern bool hasFPU;
extern bool isLoongson;
extern bool hasR2;
}
inline uint32_t GetMIPSFlags() { return mips_private::Flags; }
inline bool hasFPU() { return mips_private::hasFPU; }
inline bool isLoongson() { return mips_private::isLoongson; }
inline bool hasR2() { return mips_private::hasR2; }
// MIPS doesn't have double registers that can NOT be treated as float32.
inline bool

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

@ -714,6 +714,7 @@ AssemblerMIPSShared::as_rotr(Register rd, Register rt, uint16_t sa)
{
MOZ_ASSERT(sa < 32);
spew("rotr %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special, rs_one, rt, rd, sa, ff_srl).encode());
}
@ -722,6 +723,7 @@ AssemblerMIPSShared::as_drotr(Register rd, Register rt, uint16_t sa)
{
MOZ_ASSERT(sa < 32);
spew("drotr %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special, rs_one, rt, rd, sa, ff_dsrl).encode());
}
@ -730,6 +732,7 @@ AssemblerMIPSShared::as_drotr32(Register rd, Register rt, uint16_t sa)
{
MOZ_ASSERT(31 < sa && sa < 64);
spew("drotr32%3s,%3s, 0x%x", rd.name(), rt.name(), sa - 32);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special, rs_one, rt, rd, sa - 32, ff_dsrl32).encode());
}
@ -737,6 +740,7 @@ BufferOffset
AssemblerMIPSShared::as_rotrv(Register rd, Register rt, Register rs)
{
spew("rotrv %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special, rs, rt, rd, 1, ff_srlv).encode());
}
@ -744,6 +748,7 @@ BufferOffset
AssemblerMIPSShared::as_drotrv(Register rd, Register rt, Register rs)
{
spew("drotrv %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special, rs, rt, rd, 1, ff_dsrlv).encode());
}
@ -1076,6 +1081,7 @@ AssemblerMIPSShared::as_ins(Register rt, Register rs, uint16_t pos, uint16_t siz
Register rd;
rd = Register::FromCode(pos + size - 1);
spew("ins %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_ins).encode());
}
@ -1086,6 +1092,7 @@ AssemblerMIPSShared::as_dins(Register rt, Register rs, uint16_t pos, uint16_t si
Register rd;
rd = Register::FromCode(pos + size - 1);
spew("dins %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_dins).encode());
}
@ -1096,6 +1103,7 @@ AssemblerMIPSShared::as_dinsm(Register rt, Register rs, uint16_t pos, uint16_t s
Register rd;
rd = Register::FromCode(pos + size - 1 - 32);
spew("dinsm %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_dinsm).encode());
}
@ -1106,6 +1114,7 @@ AssemblerMIPSShared::as_dinsu(Register rt, Register rs, uint16_t pos, uint16_t s
Register rd;
rd = Register::FromCode(pos + size - 1 - 32);
spew("dinsu %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, rs, rt, rd, pos - 32, ff_dinsu).encode());
}
@ -1116,6 +1125,7 @@ AssemblerMIPSShared::as_ext(Register rt, Register rs, uint16_t pos, uint16_t siz
Register rd;
rd = Register::FromCode(size - 1);
spew("ext %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_ext).encode());
}
@ -1124,6 +1134,7 @@ BufferOffset
AssemblerMIPSShared::as_seb(Register rd, Register rt)
{
spew("seb %3s,%3s", rd.name(), rt.name());
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, zero, rt, rd, 16, ff_bshfl).encode());
}
@ -1131,6 +1142,7 @@ BufferOffset
AssemblerMIPSShared::as_seh(Register rd, Register rt)
{
spew("seh %3s,%3s", rd.name(), rt.name());
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, zero, rt, rd, 24, ff_bshfl).encode());
}
@ -1141,6 +1153,7 @@ AssemblerMIPSShared::as_dext(Register rt, Register rs, uint16_t pos, uint16_t si
Register rd;
rd = Register::FromCode(size - 1);
spew("dext %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_dext).encode());
}
@ -1151,7 +1164,8 @@ AssemblerMIPSShared::as_dextm(Register rt, Register rs, uint16_t pos, uint16_t s
Register rd;
rd = Register::FromCode(size - 1 - 32);
spew("dextm %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_dextm).encode());
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_dextm).encode());
}
BufferOffset
@ -1161,6 +1175,7 @@ AssemblerMIPSShared::as_dextu(Register rt, Register rs, uint16_t pos, uint16_t s
Register rd;
rd = Register::FromCode(size - 1);
spew("dextu %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_special3, rs, rt, rd, pos - 32, ff_dextu).encode());
}
@ -1412,6 +1427,7 @@ BufferOffset
AssemblerMIPSShared::as_truncls(FloatRegister fd, FloatRegister fs)
{
spew("trunc.l.s%3s,%3s", fd.name(), fs.name());
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_trunc_l_fmt).encode());
}
@ -1447,6 +1463,7 @@ BufferOffset
AssemblerMIPSShared::as_truncld(FloatRegister fd, FloatRegister fs)
{
spew("trunc.l.d%3s,%3s", fd.name(), fs.name());
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_trunc_l_fmt).encode());
}
@ -1454,6 +1471,7 @@ BufferOffset
AssemblerMIPSShared::as_cvtdl(FloatRegister fd, FloatRegister fs)
{
spew("cvt.d.l%3s,%3s", fd.name(), fs.name());
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_cop1, rs_l, zero, fs, fd, ff_cvt_d_fmt).encode());
}
@ -1482,6 +1500,7 @@ BufferOffset
AssemblerMIPSShared::as_cvtsl(FloatRegister fd, FloatRegister fs)
{
spew("cvt.s.l%3s,%3s", fd.name(), fs.name());
MOZ_ASSERT(hasR2());
return writeInst(InstReg(op_cop1, rs_l, zero, fs, fd, ff_cvt_s_fmt).encode());
}

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

@ -1580,7 +1580,7 @@ CodeGeneratorMIPSShared::visitCopySignF(LCopySignF* ins)
masm.moveFromFloat32(rhs, rhsi);
// Combine.
masm.as_ins(rhsi, lhsi, 0, 31);
masm.ma_ins(rhsi, lhsi, 0, 31);
masm.moveToFloat32(rhsi, output);
}
@ -1600,7 +1600,7 @@ CodeGeneratorMIPSShared::visitCopySignD(LCopySignD* ins)
masm.moveFromDoubleHi(rhs, rhsi);
// Combine.
masm.as_ins(rhsi, lhsi, 0, 31);
masm.ma_ins(rhsi, lhsi, 0, 31);
masm.moveToDoubleHi(rhsi, output);
}

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

@ -29,13 +29,13 @@ MacroAssembler::moveGPRToFloat32(Register src, FloatRegister dest)
void
MacroAssembler::move8SignExtend(Register src, Register dest)
{
as_seb(dest, src);
ma_seb(dest, src);
}
void
MacroAssembler::move16SignExtend(Register src, Register dest)
{
as_seh(dest, src);
ma_seh(dest, src);
}
// ===============================================================

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

@ -71,13 +71,27 @@ MacroAssemblerMIPSShared::ma_sra(Register rd, Register rt, Imm32 shift)
void
MacroAssemblerMIPSShared::ma_ror(Register rd, Register rt, Imm32 shift)
{
as_rotr(rd, rt, shift.value % 32);
if (hasR2()) {
as_rotr(rd, rt, shift.value % 32);
} else {
ScratchRegisterScope scratch(asMasm());
as_srl(scratch, rt, shift.value % 32);
as_sll(rd, rt, (32 - (shift.value % 32)) % 32);
as_or(rd, rd, scratch);
}
}
void
MacroAssemblerMIPSShared::ma_rol(Register rd, Register rt, Imm32 shift)
{
as_rotr(rd, rt, 32 - (shift.value % 32));
if (hasR2()) {
as_rotr(rd, rt, (32 - (shift.value % 32)) % 32);
} else {
ScratchRegisterScope scratch(asMasm());
as_srl(scratch, rt, (32 - (shift.value % 32)) % 32);
as_sll(rd, rt, shift.value % 32);
as_or(rd, rd, scratch);
}
}
void
@ -101,14 +115,29 @@ MacroAssemblerMIPSShared::ma_sra(Register rd, Register rt, Register shift)
void
MacroAssemblerMIPSShared::ma_ror(Register rd, Register rt, Register shift)
{
as_rotrv(rd, rt, shift);
if (hasR2()) {
as_rotrv(rd, rt, shift);
} else {
ScratchRegisterScope scratch(asMasm());
ma_negu(scratch, shift);
as_sllv(scratch, rt, scratch);
as_srlv(rd, rt, shift);
as_or(rd, rd, scratch);
}
}
void
MacroAssemblerMIPSShared::ma_rol(Register rd, Register rt, Register shift)
{
ma_negu(ScratchRegister, shift);
as_rotrv(rd, rt, ScratchRegister);
ScratchRegisterScope scratch(asMasm());
ma_negu(scratch, shift);
if (hasR2()) {
as_rotrv(rd, rt, scratch);
} else {
as_srlv(rd, rt, scratch);
as_sllv(scratch, rt, shift);
as_or(rd, rd, scratch);
}
}
void
@ -123,6 +152,69 @@ MacroAssemblerMIPSShared::ma_not(Register rd, Register rs)
as_nor(rd, rs, zero);
}
// Bit extract/insert
void
MacroAssemblerMIPSShared::ma_ext(Register rt, Register rs, uint16_t pos, uint16_t size) {
MOZ_ASSERT(pos < 32);
MOZ_ASSERT(pos + size < 33);
if (hasR2()) {
as_ext(rt, rs, pos, size);
} else {
int shift_left = 32 - (pos + size);
as_sll(rt, rs, shift_left);
int shift_right = 32 - size;
if (shift_right > 0) {
as_srl(rt, rt, shift_right);
}
}
}
void
MacroAssemblerMIPSShared::ma_ins(Register rt, Register rs, uint16_t pos, uint16_t size) {
MOZ_ASSERT(pos < 32);
MOZ_ASSERT(pos + size <= 32);
MOZ_ASSERT(size != 0);
if (hasR2()) {
as_ins(rt, rs, pos, size);
} else {
ScratchRegisterScope scratch(asMasm());
SecondScratchRegisterScope scratch2(asMasm());
ma_subu(scratch, zero, Imm32(1));
as_srl(scratch, scratch, 32 - size);
as_and(scratch2, rs, scratch);
as_sll(scratch2, scratch2, pos);
as_sll(scratch, scratch, pos);
as_nor(scratch, scratch, zero);
as_and(scratch, rt, scratch);
as_or(rt, scratch2, scratch);
}
}
// Sign extend
void
MacroAssemblerMIPSShared::ma_seb(Register rd, Register rt)
{
if (hasR2()) {
as_seb(rd, rt);
} else {
as_sll(rd, rt, 24);
as_sra(rd, rd, 24);
}
}
void
MacroAssemblerMIPSShared::ma_seh(Register rd, Register rt)
{
if (hasR2()) {
as_seh(rd, rt);
} else {
as_sll(rd, rt, 16);
as_sra(rd, rd, 16);
}
}
// And.
void
MacroAssemblerMIPSShared::ma_and(Register rd, Register rs)
@ -484,7 +576,7 @@ MacroAssemblerMIPSShared::ma_load_unaligned(Register dest, const BaseIndex& src,
as_lbu(temp, base, hiOffset);
else
as_lb(temp, base, hiOffset);
as_ins(dest, temp, 8, 24);
ma_ins(dest, temp, 8, 24);
break;
case SizeWord:
as_lwl(dest, base, hiOffset);
@ -627,7 +719,7 @@ MacroAssemblerMIPSShared::ma_store_unaligned(Register data, const BaseIndex& des
switch (size) {
case SizeHalfWord:
as_sb(data, base, lowOffset);
as_ext(temp, data, 8, 8);
ma_ext(temp, data, 8, 8);
as_sb(temp, base, hiOffset);
break;
case SizeWord:
@ -1243,10 +1335,10 @@ MacroAssemblerMIPSShared::atomicFetchOpMIPSr2(int nbytes, bool signExtend, Atomi
if (signExtend) {
switch (nbytes) {
case 1:
as_seb(output, output);
ma_seb(output, output);
break;
case 2:
as_seh(output, output);
ma_seh(output, output);
break;
case 4:
break;
@ -1418,10 +1510,10 @@ MacroAssemblerMIPSShared::compareExchangeMIPSr2(int nbytes, bool signExtend, con
if (signExtend) {
switch (nbytes) {
case 1:
as_seb(output, output);
ma_seb(output, output);
break;
case 2:
as_seh(output, output);
ma_seh(output, output);
break;
case 4:
break;
@ -1769,7 +1861,7 @@ MacroAssembler::wasmTruncateDoubleToInt32(FloatRegister input, Register output,
as_truncwd(ScratchFloat32Reg, input);
as_cfc1(ScratchRegister, Assembler::FCSR);
moveFromFloat32(ScratchFloat32Reg, output);
as_ext(ScratchRegister, ScratchRegister, 6, 1);
ma_ext(ScratchRegister, ScratchRegister, 6, 1);
ma_b(ScratchRegister, Imm32(0), oolEntry, Assembler::NotEqual);
}
@ -1780,7 +1872,7 @@ MacroAssembler::wasmTruncateFloat32ToInt32(FloatRegister input, Register output,
as_truncws(ScratchFloat32Reg, input);
as_cfc1(ScratchRegister, Assembler::FCSR);
moveFromFloat32(ScratchFloat32Reg, output);
as_ext(ScratchRegister, ScratchRegister, 6, 1);
ma_ext(ScratchRegister, ScratchRegister, 6, 1);
ma_b(ScratchRegister, Imm32(0), oolEntry, Assembler::NotEqual);
}

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

@ -85,6 +85,14 @@ class MacroAssemblerMIPSShared : public Assembler
void ma_not(Register rd, Register rs);
// Bit extract/insert
void ma_ext(Register rt, Register rs, uint16_t pos, uint16_t size);
void ma_ins(Register rt, Register rs, uint16_t pos, uint16_t size);
// Sign extend
void ma_seb(Register rd, Register rt);
void ma_seh(Register rd, Register rt);
// and
void ma_and(Register rd, Register rs);
void ma_and(Register rd, Imm32 imm);

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

@ -427,21 +427,21 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut)
MacroAssembler masm(cx);
masm.pushReturnAddress();
// ArgumentsRectifierReg contains the |nargs| pushed onto the current
// frame. Including |this|, there are (|nargs| + 1) arguments to copy.
MOZ_ASSERT(ArgumentsRectifierReg == s3);
Register numActArgsReg = t6;
Register calleeTokenReg = t7;
Register numArgsReg = t5;
// Copy number of actual arguments into numActArgsReg
// Load the number of actual arguments into numActArgsReg
masm.loadPtr(Address(StackPointer, RectifierFrameLayout::offsetOfNumActualArgs()),
numActArgsReg);
// Load the number of |undefined|s to push into t1.
masm.loadPtr(Address(StackPointer, RectifierFrameLayout::offsetOfCalleeToken()),
calleeTokenReg);
// Copy the number of actual arguments into s3.
masm.mov(numActArgsReg, s3);
masm.mov(calleeTokenReg, numArgsReg);
masm.andPtr(Imm32(CalleeTokenMask), numArgsReg);
masm.load16ZeroExtend(Address(numArgsReg, JSFunction::offsetOfNargs()), numArgsReg);
@ -1266,10 +1266,10 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
//
// JitFrame_Rectifier
//
// The rectifier frame can be preceded by either an IonJS or a
// BaselineStub frame.
// The rectifier frame can be preceded by either an IonJS, a WasmToJSJit or
// a BaselineStub frame.
//
// Stack layout if caller of rectifier was Ion:
// Stack layout if caller of rectifier was Ion or WasmToJSJit:
//
// Ion-Descriptor
// Ion-ReturnAddr
@ -1314,10 +1314,11 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
// and |scratch2| points to Rectifier frame
// and |scratch3| contains Rect-Descriptor.Type
masm.assertRectifierFrameParentType(scratch3);
// Check for either Ion or BaselineStub frame.
Label handle_Rectifier_BaselineStub;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS),
&handle_Rectifier_BaselineStub);
Label notIonFrame;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS), &notIonFrame);
// Handle Rectifier <- IonJS
// scratch3 := RectFrame[ReturnAddr]
@ -1330,16 +1331,13 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
masm.storePtr(scratch3, lastProfilingFrame);
masm.ret();
masm.bind(&notIonFrame);
// Check for either BaselineStub or WasmToJSJit: since WasmToJSJit is
// just an entry, jump there if we see it.
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_BaselineStub), &handle_Entry);
// Handle Rectifier <- BaselineStub <- BaselineJS
masm.bind(&handle_Rectifier_BaselineStub);
#ifdef DEBUG
{
Label checkOk;
masm.branch32(Assembler::Equal, scratch3, Imm32(JitFrame_BaselineStub), &checkOk);
masm.assumeUnreachable("Unrecognized frame preceding baselineStub.");
masm.bind(&checkOk);
}
#endif
masm.as_addu(scratch3, scratch2, scratch1);
Address stubFrameReturnAddr(scratch3, RectifierFrameLayout::Size() +
BaselineStubFrameLayout::offsetOfReturnAddress());
@ -1403,7 +1401,7 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
}
//
// JitFrame_CppToJSJit / JitFrame_WasmJSToJit
// JitFrame_CppToJSJit / JitFrame_WasmToJSJit
//
// If at an entry frame, store null into both fields.
// A fast-path wasm->jit transition frame is an entry frame from the point

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

@ -683,7 +683,7 @@ CodeGeneratorMIPS64::visitWasmTruncateToInt64(LWasmTruncateToInt64* lir)
masm.moveFromDouble(ScratchDoubleReg, output);
masm.as_cfc1(ScratchRegister, Assembler::FCSR);
// extract invalid operation flag (bit 6) from FCSR
masm.as_ext(ScratchRegister, ScratchRegister, 6, 1);
masm.ma_ext(ScratchRegister, ScratchRegister, 6, 1);
masm.ma_dsrl(SecondScratchReg, output, Imm32(63));
masm.ma_or(SecondScratchReg, ScratchRegister);
masm.ma_b(SecondScratchReg, Imm32(0), ool->entry(), Assembler::NotEqual);
@ -703,7 +703,7 @@ CodeGeneratorMIPS64::visitWasmTruncateToInt64(LWasmTruncateToInt64* lir)
// Check that the result is in the uint64_t range.
masm.moveFromDouble(ScratchDoubleReg, output);
masm.as_cfc1(ScratchRegister, Assembler::FCSR);
masm.as_ext(ScratchRegister, ScratchRegister, 6, 1);
masm.ma_ext(ScratchRegister, ScratchRegister, 6, 1);
masm.ma_dsrl(SecondScratchReg, output, Imm32(63));
masm.ma_or(SecondScratchReg, ScratchRegister);
masm.ma_b(SecondScratchReg, Imm32(0), ool->entry(), Assembler::NotEqual);
@ -724,7 +724,7 @@ CodeGeneratorMIPS64::visitWasmTruncateToInt64(LWasmTruncateToInt64* lir)
// Check that the result is in the int64_t range.
masm.as_cfc1(output, Assembler::FCSR);
masm.as_ext(output, output, 6, 1);
masm.ma_ext(output, output, 6, 1);
masm.ma_b(output, Imm32(0), ool->entry(), Assembler::NotEqual);
masm.bind(ool->rejoin());

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

@ -2578,7 +2578,7 @@ MacroAssembler::wasmTruncateDoubleToUInt32(FloatRegister input, Register output,
as_truncld(ScratchDoubleReg, input);
moveFromDoubleHi(ScratchDoubleReg, output);
as_cfc1(ScratchRegister, Assembler::FCSR);
as_ext(ScratchRegister, ScratchRegister, 6, 1);
ma_ext(ScratchRegister, ScratchRegister, 6, 1);
ma_or(ScratchRegister, output);
moveFromFloat32(ScratchDoubleReg, output);
ma_b(ScratchRegister, Imm32(0), oolEntry, Assembler::NotEqual);
@ -2592,7 +2592,7 @@ MacroAssembler::wasmTruncateFloat32ToUInt32(FloatRegister input, Register output
as_truncls(ScratchDoubleReg, input);
moveFromDoubleHi(ScratchDoubleReg, output);
as_cfc1(ScratchRegister, Assembler::FCSR);
as_ext(ScratchRegister, ScratchRegister, 6, 1);
ma_ext(ScratchRegister, ScratchRegister, 6, 1);
ma_or(ScratchRegister, output);
moveFromFloat32(ScratchDoubleReg, output);
ma_b(ScratchRegister, Imm32(0), oolEntry, Assembler::NotEqual);

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

@ -428,14 +428,10 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut)
masm.pushReturnAddress();
// Caller:
// [arg2] [arg1] [this] [[argc] [callee] [descr] [raddr]] <- sp
// '--- s3 ---'
// ArgumentsRectifierReg contains the |nargs| pushed onto the current
// frame. Including |this|, there are (|nargs| + 1) arguments to copy.
MOZ_ASSERT(ArgumentsRectifierReg == s3);
// Add |this|, in the counter of known arguments.
masm.addPtr(Imm32(1), ArgumentsRectifierReg);
masm.loadPtr(Address(StackPointer, RectifierFrameLayout::offsetOfNumActualArgs()), s3);
masm.addPtr(Imm32(1), s3);
Register numActArgsReg = a6;
Register calleeTokenReg = a7;
@ -1211,10 +1207,10 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
//
// JitFrame_Rectifier
//
// The rectifier frame can be preceded by either an IonJS or a
// BaselineStub frame.
// The rectifier frame can be preceded by either an IonJS, a WasmToJSJit or
// a BaselineStub frame.
//
// Stack layout if caller of rectifier was Ion:
// Stack layout if caller of rectifier was Ion or WasmToJSJit:
//
// Ion-Descriptor
// Ion-ReturnAddr
@ -1259,10 +1255,11 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
// and |scratch2| points to Rectifier frame
// and |scratch3| contains Rect-Descriptor.Type
masm.assertRectifierFrameParentType(scratch3);
// Check for either Ion or BaselineStub frame.
Label handle_Rectifier_BaselineStub;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS),
&handle_Rectifier_BaselineStub);
Label notIonFrame;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS), &notIonFrame);
// Handle Rectifier <- IonJS
// scratch3 := RectFrame[ReturnAddr]
@ -1275,16 +1272,13 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
masm.storePtr(scratch3, lastProfilingFrame);
masm.ret();
masm.bind(&notIonFrame);
// Check for either BaselineStub or WasmToJSJit: since WasmToJSJit is
// just an entry, jump there if we see it.
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_BaselineStub), &handle_Entry);
// Handle Rectifier <- BaselineStub <- BaselineJS
masm.bind(&handle_Rectifier_BaselineStub);
#ifdef DEBUG
{
Label checkOk;
masm.branch32(Assembler::Equal, scratch3, Imm32(JitFrame_BaselineStub), &checkOk);
masm.assumeUnreachable("Unrecognized frame preceding baselineStub.");
masm.bind(&checkOk);
}
#endif
masm.as_daddu(scratch3, scratch2, scratch1);
Address stubFrameReturnAddr(scratch3, RectifierFrameLayout::Size() +
BaselineStubFrameLayout::offsetOfReturnAddress());
@ -1348,7 +1342,7 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
}
//
// JitFrame_CppToJSJit / JitFrame_WasmJSToJit
// JitFrame_CppToJSJit / JitFrame_WasmToJSJit
//
// If at an entry frame, store null into both fields.
// A fast-path wasm->jit transition frame is an entry frame from the point

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

@ -1180,10 +1180,10 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
//
// JitFrame_Rectifier
//
// The rectifier frame can be preceded by either an IonJS or a
// BaselineStub frame.
// The rectifier frame can be preceded by either an IonJS, a WasmToJSJit or
// a BaselineStub frame.
//
// Stack layout if caller of rectifier was Ion:
// Stack layout if caller of rectifier was Ion or WasmToJSJit:
//
// Ion-Descriptor
// Ion-ReturnAddr
@ -1228,10 +1228,11 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
// and |scratch2| points to Rectifier frame
// and |scratch3| contains Rect-Descriptor.Type
// Check for either Ion or BaselineStub frame.
Label handle_Rectifier_BaselineStub;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS),
&handle_Rectifier_BaselineStub);
masm.assertRectifierFrameParentType(scratch3);
// Check for either Ion or something else frame.
Label notIonFrame;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS), &notIonFrame);
// Handle Rectifier <- IonJS
// scratch3 := RectFrame[ReturnAddr]
@ -1243,16 +1244,13 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
masm.storePtr(scratch3, lastProfilingFrame);
masm.ret();
masm.bind(&notIonFrame);
// Check for either BaselineStub or WasmToJSJit: since WasmToJSJit is
// just an entry, jump there if we see it.
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_BaselineStub), &handle_Entry);
// Handle Rectifier <- BaselineStub <- BaselineJS
masm.bind(&handle_Rectifier_BaselineStub);
#ifdef DEBUG
{
Label checkOk;
masm.branch32(Assembler::Equal, scratch3, Imm32(JitFrame_BaselineStub), &checkOk);
masm.assumeUnreachable("Unrecognized frame preceding baselineStub.");
masm.bind(&checkOk);
}
#endif
BaseIndex stubFrameReturnAddr(scratch2, scratch1, TimesOne,
RectifierFrameLayout::Size() +
BaselineStubFrameLayout::offsetOfReturnAddress());
@ -1314,7 +1312,7 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
}
//
// JitFrame_CppToJSJit / JitFrame_WasmJSToJit
// JitFrame_CppToJSJit / JitFrame_WasmToJSJit
//
// If at an entry frame, store null into both fields.
// A fast-path wasm->jit transition frame is an entry frame from the point

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

@ -1214,10 +1214,10 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
//
// JitFrame_Rectifier
//
// The rectifier frame can be preceded by either an IonJS or a
// BaselineStub frame.
// The rectifier frame can be preceded by either an IonJS, a WasmToJSJit or
// a BaselineStub frame.
//
// Stack layout if caller of rectifier was Ion:
// Stack layout if caller of rectifier was Ion or WasmToJSJit:
//
// Ion-Descriptor
// Ion-ReturnAddr
@ -1262,10 +1262,11 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
// and |scratch2| points to Rectifier frame
// and |scratch3| contains Rect-Descriptor.Type
masm.assertRectifierFrameParentType(scratch3);
// Check for either Ion or BaselineStub frame.
Label handle_Rectifier_BaselineStub;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS),
&handle_Rectifier_BaselineStub);
Label notIonFrame;
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_IonJS), &notIonFrame);
// Handle Rectifier <- IonJS
// scratch3 := RectFrame[ReturnAddr]
@ -1277,16 +1278,13 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
masm.storePtr(scratch3, lastProfilingFrame);
masm.ret();
masm.bind(&notIonFrame);
// Check for either BaselineStub or WasmToJSJit: since WasmToJSJit is
// just an entry, jump there if we see it.
masm.branch32(Assembler::NotEqual, scratch3, Imm32(JitFrame_BaselineStub), &handle_Entry);
// Handle Rectifier <- BaselineStub <- BaselineJS
masm.bind(&handle_Rectifier_BaselineStub);
#ifdef DEBUG
{
Label checkOk;
masm.branch32(Assembler::Equal, scratch3, Imm32(JitFrame_BaselineStub), &checkOk);
masm.assumeUnreachable("Unrecognized frame preceding baselineStub.");
masm.bind(&checkOk);
}
#endif
BaseIndex stubFrameReturnAddr(scratch2, scratch1, TimesOne,
RectifierFrameLayout::Size() +
BaselineStubFrameLayout::offsetOfReturnAddress());
@ -1348,7 +1346,7 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
}
//
// JitFrame_CppToJSJit / JitFrame_WasmJSToJit
// JitFrame_CppToJSJit / JitFrame_WasmToJSJit
//
// If at an entry frame, store null into both fields.
// A fast-path wasm->jit transition frame is an entry frame from the point

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

@ -7525,19 +7525,6 @@ UnhideScriptedCaller(JSContext* cx)
} /* namespace JS */
AutoGCRooter::AutoGCRooter(JSContext* cx, ptrdiff_t tag)
: AutoGCRooter(JS::RootingContext::get(cx), tag)
{}
AutoGCRooter::AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag)
: down(cx->autoGCRooters_),
tag_(tag),
stackTop(&cx->autoGCRooters_)
{
MOZ_ASSERT(this != *stackTop);
*stackTop = this;
}
#ifdef JS_DEBUG
JS_PUBLIC_API(void)
JS::detail::AssertArgumentsAreSane(JSContext* cx, HandleValue value)

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

@ -2036,28 +2036,6 @@ JSFunction::needsNamedLambdaEnvironment() const
return scope->hasEnvironment();
}
JSFunction*
js::NewNativeFunction(JSContext* cx, Native native, unsigned nargs, HandleAtom atom,
gc::AllocKind allocKind /* = AllocKind::FUNCTION */,
NewObjectKind newKind /* = SingletonObject */)
{
MOZ_ASSERT(native);
return NewFunctionWithProto(cx, native, nargs, JSFunction::NATIVE_FUN,
nullptr, atom, nullptr, allocKind, newKind);
}
JSFunction*
js::NewNativeConstructor(JSContext* cx, Native native, unsigned nargs, HandleAtom atom,
gc::AllocKind allocKind /* = AllocKind::FUNCTION */,
NewObjectKind newKind /* = SingletonObject */,
JSFunction::Flags flags /* = JSFunction::NATIVE_CTOR */)
{
MOZ_ASSERT(native);
MOZ_ASSERT(flags & JSFunction::NATIVE_CTOR);
return NewFunctionWithProto(cx, native, nargs, flags, nullptr, atom,
nullptr, allocKind, newKind);
}
JSFunction*
js::NewScriptedFunction(JSContext* cx, unsigned nargs,
JSFunction::Flags flags, HandleAtom atom,
@ -2092,26 +2070,16 @@ js::NewFunctionWithProto(JSContext* cx, Native native,
unsigned nargs, JSFunction::Flags flags, HandleObject enclosingEnv,
HandleAtom atom, HandleObject proto,
gc::AllocKind allocKind /* = AllocKind::FUNCTION */,
NewObjectKind newKind /* = GenericObject */,
NewFunctionProtoHandling protoHandling /* = NewFunctionClassProto */)
NewObjectKind newKind /* = GenericObject */)
{
MOZ_ASSERT(allocKind == AllocKind::FUNCTION || allocKind == AllocKind::FUNCTION_EXTENDED);
MOZ_ASSERT_IF(native, !enclosingEnv);
MOZ_ASSERT(NewFunctionEnvironmentIsWellFormed(cx, enclosingEnv));
RootedObject funobj(cx);
if (protoHandling == NewFunctionClassProto) {
funobj = NewObjectWithClassProto(cx, &JSFunction::class_, proto, allocKind,
newKind);
} else {
funobj = NewObjectWithGivenTaggedProto(cx, &JSFunction::class_, AsTaggedProto(proto),
allocKind, newKind);
}
if (!funobj)
JSFunction* fun = NewObjectWithClassProto<JSFunction>(cx, proto, allocKind, newKind);
if (!fun)
return nullptr;
RootedFunction fun(cx, &funobj->as<JSFunction>());
if (allocKind == AllocKind::FUNCTION_EXTENDED)
flags = JSFunction::Flags(flags | JSFunction::EXTENDED);

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

@ -687,20 +687,41 @@ AsyncFunctionConstructor(JSContext* cx, unsigned argc, Value* vp);
extern bool
AsyncGeneratorConstructor(JSContext* cx, unsigned argc, Value* vp);
// If enclosingEnv is null, the function will have a null environment()
// (yes, null, not the global). In all cases, the global will be used as the
// parent.
extern JSFunction*
NewFunctionWithProto(JSContext* cx, JSNative native, unsigned nargs,
JSFunction::Flags flags, HandleObject enclosingEnv, HandleAtom atom,
HandleObject proto, gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
NewObjectKind newKind = GenericObject);
// Allocate a new function backed by a JSNative. Note that by default this
// creates a singleton object.
extern JSFunction*
inline JSFunction*
NewNativeFunction(JSContext* cx, JSNative native, unsigned nargs, HandleAtom atom,
gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
NewObjectKind newKind = SingletonObject);
NewObjectKind newKind = SingletonObject)
{
MOZ_ASSERT(native);
return NewFunctionWithProto(cx, native, nargs, JSFunction::NATIVE_FUN,
nullptr, atom, nullptr, allocKind, newKind);
}
// Allocate a new constructor backed by a JSNative. Note that by default this
// creates a singleton object.
extern JSFunction*
inline JSFunction*
NewNativeConstructor(JSContext* cx, JSNative native, unsigned nargs, HandleAtom atom,
gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
NewObjectKind newKind = SingletonObject,
JSFunction::Flags flags = JSFunction::NATIVE_CTOR);
JSFunction::Flags flags = JSFunction::NATIVE_CTOR)
{
MOZ_ASSERT(native);
MOZ_ASSERT(flags & JSFunction::NATIVE_CTOR);
return NewFunctionWithProto(cx, native, nargs, flags, nullptr, atom,
nullptr, allocKind, newKind);
}
// Allocate a new scripted function. If enclosingEnv is null, the
// global will be used. In all cases the parent of the resulting object will be
@ -711,25 +732,6 @@ NewScriptedFunction(JSContext* cx, unsigned nargs, JSFunction::Flags flags,
gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
NewObjectKind newKind = GenericObject,
HandleObject enclosingEnv = nullptr);
// By default, if proto is nullptr, Function.prototype is used instead.i
// If protoHandling is NewFunctionExactProto, and proto is nullptr, the created
// function will use nullptr as its [[Prototype]] instead. If
// enclosingEnv is null, the function will have a null environment()
// (yes, null, not the global). In all cases, the global will be used as the
// parent.
enum NewFunctionProtoHandling {
NewFunctionClassProto,
NewFunctionGivenProto
};
extern JSFunction*
NewFunctionWithProto(JSContext* cx, JSNative native, unsigned nargs,
JSFunction::Flags flags, HandleObject enclosingEnv, HandleAtom atom,
HandleObject proto, gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
NewObjectKind newKind = GenericObject,
NewFunctionProtoHandling protoHandling = NewFunctionClassProto);
extern JSAtom*
IdToFunctionName(JSContext* cx, HandleId id,
FunctionPrefixKind prefixKind = FunctionPrefixKind::None);

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

@ -210,11 +210,90 @@ class MOZ_STACK_CLASS JS_PUBLIC_API(AutoEnterCycleCollection)
class RootingContext;
// Our instantiations of Rooted<void*> and PersistentRooted<void*> require an
// instantiation of MapTypeToRootKind.
template <>
struct MapTypeToRootKind<void*> {
static const RootKind kind = RootKind::Traceable;
};
using RootedListHeads = mozilla::EnumeratedArray<RootKind, RootKind::Limit,
Rooted<void*>*>;
/*
* This list enumerates the different types of conceptual stacks we have in
* SpiderMonkey. In reality, they all share the C stack, but we allow different
* stack limits depending on the type of code running.
*/
enum StackKind
{
StackForSystemCode, // C++, such as the GC, running on behalf of the VM.
StackForTrustedScript, // Script running with trusted principals.
StackForUntrustedScript, // Script running with untrusted principals.
StackKindCount
};
class JS_PUBLIC_API(AutoGCRooter);
// Superclass of JSContext which can be used for rooting data in use by the
// current thread but that does not provide all the functions of a JSContext.
class RootingContext
{
// Stack GC roots for Rooted GC heap pointers.
RootedListHeads stackRoots_;
template <typename T> friend class JS::Rooted;
// Stack GC roots for AutoFooRooter classes.
JS::AutoGCRooter* autoGCRooters_;
friend class JS::AutoGCRooter;
public:
RootingContext();
void traceStackRoots(JSTracer* trc);
void checkNoGCRooters();
protected:
// The remaining members in this class should only be accessed through
// JSContext pointers. They are unrelated to rooting and are in place so
// that inlined API functions can directly access the data.
/* The current compartment. */
JSCompartment* compartment_;
/* The current zone. */
JS::Zone* zone_;
public:
/* Limit pointer for checking native stack consumption. */
uintptr_t nativeStackLimit[StackKindCount];
static const RootingContext* get(const JSContext* cx) {
return reinterpret_cast<const RootingContext*>(cx);
}
static RootingContext* get(JSContext* cx) {
return reinterpret_cast<RootingContext*>(cx);
}
friend JSCompartment* js::GetContextCompartment(const JSContext* cx);
friend JS::Zone* js::GetContextZone(const JSContext* cx);
};
class JS_PUBLIC_API(AutoGCRooter)
{
public:
AutoGCRooter(JSContext* cx, ptrdiff_t tag);
AutoGCRooter(RootingContext* cx, ptrdiff_t tag);
AutoGCRooter(JSContext* cx, ptrdiff_t tag)
: AutoGCRooter(JS::RootingContext::get(cx), tag)
{}
AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag)
: down(cx->autoGCRooters_),
tag_(tag),
stackTop(&cx->autoGCRooters_)
{
MOZ_ASSERT(this != *stackTop);
*stackTop = this;
}
~AutoGCRooter() {
MOZ_ASSERT(this == *stackTop);
@ -262,74 +341,6 @@ class JS_PUBLIC_API(AutoGCRooter)
void operator=(AutoGCRooter& ida) = delete;
};
// Our instantiations of Rooted<void*> and PersistentRooted<void*> require an
// instantiation of MapTypeToRootKind.
template <>
struct MapTypeToRootKind<void*> {
static const RootKind kind = RootKind::Traceable;
};
using RootedListHeads = mozilla::EnumeratedArray<RootKind, RootKind::Limit,
Rooted<void*>*>;
/*
* This list enumerates the different types of conceptual stacks we have in
* SpiderMonkey. In reality, they all share the C stack, but we allow different
* stack limits depending on the type of code running.
*/
enum StackKind
{
StackForSystemCode, // C++, such as the GC, running on behalf of the VM.
StackForTrustedScript, // Script running with trusted principals.
StackForUntrustedScript, // Script running with untrusted principals.
StackKindCount
};
// Superclass of JSContext which can be used for rooting data in use by the
// current thread but that does not provide all the functions of a JSContext.
class RootingContext
{
// Stack GC roots for Rooted GC heap pointers.
RootedListHeads stackRoots_;
template <typename T> friend class JS::Rooted;
// Stack GC roots for AutoFooRooter classes.
JS::AutoGCRooter* autoGCRooters_;
friend class JS::AutoGCRooter;
public:
RootingContext();
void traceStackRoots(JSTracer* trc);
void checkNoGCRooters();
protected:
// The remaining members in this class should only be accessed through
// JSContext pointers. They are unrelated to rooting and are in place so
// that inlined API functions can directly access the data.
/* The current compartment. */
JSCompartment* compartment_;
/* The current zone. */
JS::Zone* zone_;
public:
/* Limit pointer for checking native stack consumption. */
uintptr_t nativeStackLimit[StackKindCount];
static const RootingContext* get(const JSContext* cx) {
return reinterpret_cast<const RootingContext*>(cx);
}
static RootingContext* get(JSContext* cx) {
return reinterpret_cast<RootingContext*>(cx);
}
friend JSCompartment* js::GetContextCompartment(const JSContext* cx);
friend JS::Zone* js::GetContextZone(const JSContext* cx);
};
} /* namespace JS */
namespace js {

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

@ -279,6 +279,10 @@ class RegExpZone
/* Like 'get', but compile 'maybeOpt' (if non-null). */
RegExpShared* get(JSContext* cx, HandleAtom source, JSString* maybeOpt);
#ifdef DEBUG
void clear() { set_.clear(); }
#endif
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
};

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

@ -538,6 +538,7 @@ JitFrameIter::skipNonScriptedJSFrames()
jit::JSJitFrameIter& frames = asJSJit();
while (!frames.isScripted() && !frames.done())
++frames;
settle();
}
}

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

@ -215,10 +215,6 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
if (script->baselineScript()->hasPendingIonBuilder())
return true;
// Currently we can't rectify arguments. Therefore disable if argc is too low.
if (importFun->nargs() > fi.sig().args().length())
return true;
// Ensure the argument types are included in the argument TypeSets stored in
// the TypeScript. This is necessary for Ion, because the import will use
// the skip-arg-checks entry point.
@ -229,9 +225,13 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
// patched back.
if (!TypeScript::ThisTypes(script)->hasType(TypeSet::UndefinedType()))
return true;
for (uint32_t i = 0; i < importFun->nargs(); i++) {
const ValTypeVector& importArgs = fi.sig().args();
size_t numKnownArgs = Min(importArgs.length(), importFun->nargs());
for (uint32_t i = 0; i < numKnownArgs; i++) {
TypeSet::Type type = TypeSet::UnknownType();
switch (fi.sig().args()[i]) {
switch (importArgs[i]) {
case ValType::I32: type = TypeSet::Int32Type(); break;
case ValType::I64: MOZ_CRASH("can't happen because of above guard");
case ValType::F32: type = TypeSet::DoubleType(); break;
@ -248,6 +248,14 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
return true;
}
// These arguments will be filled with undefined at runtime by the
// arguments rectifier: check that the imported function can handle
// undefined there.
for (uint32_t i = importArgs.length(); i < importFun->nargs(); i++) {
if (!TypeScript::ArgTypes(script, i)->hasType(TypeSet::UndefinedType()))
return true;
}
// Let's optimize it!
if (!script->baselineScript()->addDependentWasmImport(cx, *this, funcImportIndex))
return false;
@ -451,6 +459,13 @@ Instance::init(JSContext* cx)
}
}
if (!metadata(code_->bestTier()).funcImports.empty()) {
JitRuntime* jitRuntime = cx->runtime()->getJitRuntime(cx);
if (!jitRuntime)
return false;
jsJitArgsRectifier_ = jitRuntime->getArgumentsRectifier();
}
return true;
}
@ -508,6 +523,8 @@ Instance::tracePrivate(JSTracer* trc)
MOZ_ASSERT(!gc::IsAboutToBeFinalized(&object_));
TraceEdge(trc, &object_, "wasm instance object");
TraceNullableEdge(trc, &jsJitArgsRectifier_, "wasm jit args rectifier");
// OK to just do one tier here; though the tiers have different funcImports
// tables, they share the tls object.
for (const FuncImport& fi : metadata(code().stableTier()).funcImports)

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

@ -71,6 +71,7 @@ class Instance
{
JSCompartment* const compartment_;
ReadBarrieredWasmInstanceObject object_;
GCPtrJitCode jsJitArgsRectifier_;
const SharedCode code_;
const UniqueDebugState debug_;
const UniqueGlobalSegment globals_;
@ -122,6 +123,8 @@ class Instance
bool memoryAccessInGuardRegion(uint8_t* addr, unsigned numBytes) const;
TlsData* tlsData() const { return globals_->tlsData(); }
static size_t offsetOfJSJitArgsRectifier() { return offsetof(Instance, jsJitArgsRectifier_); }
// This method returns a pointer to the GC object that owns this Instance.
// Instances may be reached via weak edges (e.g., Compartment::instances_)
// so this perform a read-barrier on the returned object unless the barrier

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

@ -23,6 +23,7 @@
#include "wasm/WasmCode.h"
#include "wasm/WasmGenerator.h"
#include "wasm/WasmInstance.h"
#include "jit/MacroAssembler-inl.h"
@ -710,7 +711,7 @@ GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* throwLa
// the return address.
static_assert(WasmStackAlignment >= JitStackAlignment, "subsumes");
unsigned sizeOfRetAddr = sizeof(void*);
unsigned sizeOfPreFrame = WasmFrameLayout::Size() - sizeOfRetAddr;
unsigned sizeOfPreFrame = WasmToJSJitFrameLayout::Size() - sizeOfRetAddr;
unsigned sizeOfThisAndArgs = (1 + fi.sig().args().length()) * sizeof(Value);
unsigned totalJitFrameBytes = sizeOfRetAddr + sizeOfPreFrame + sizeOfThisAndArgs;
unsigned jitFramePushed = StackDecrementForCall(masm, JitStackAlignment, totalJitFrameBytes) -
@ -722,7 +723,7 @@ GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* throwLa
// 1. Descriptor
size_t argOffset = 0;
uint32_t descriptor = MakeFrameDescriptor(sizeOfThisAndArgsAndPadding, JitFrame_WasmToJSJit,
WasmFrameLayout::Size());
WasmToJSJitFrameLayout::Size());
masm.storePtr(ImmWord(uintptr_t(descriptor)), Address(masm.getStackPointer(), argOffset));
argOffset += sizeof(size_t);
@ -730,17 +731,13 @@ GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* throwLa
Register callee = ABINonArgReturnReg0; // live until call
Register scratch = ABINonArgReturnReg1; // repeatedly clobbered
// 2.1. Get callee
// 2.1. Get JSFunction callee
masm.loadWasmGlobalPtr(fi.tlsDataOffset() + offsetof(FuncImportTls, obj), callee);
// 2.2. Save callee
masm.storePtr(callee, Address(masm.getStackPointer(), argOffset));
argOffset += sizeof(size_t);
// 2.3. Load callee executable entry point
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
masm.loadBaselineOrIonNoArgCheck(callee, callee, nullptr);
// 3. Argc
unsigned argc = fi.sig().args().length();
masm.storePtr(ImmWord(uintptr_t(argc)), Address(masm.getStackPointer(), argOffset));
@ -757,6 +754,19 @@ GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* throwLa
argOffset += fi.sig().args().length() * sizeof(Value);
MOZ_ASSERT(argOffset == sizeOfThisAndArgs + sizeOfPreFrame);
// 6. Check if we need to rectify arguments
masm.load16ZeroExtend(Address(callee, JSFunction::offsetOfNargs()), scratch);
Label rectify;
masm.branch32(Assembler::Above, scratch, Imm32(fi.sig().args().length()), &rectify);
// 7. If we haven't rectified arguments, load callee executable entry point
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
masm.loadBaselineOrIonNoArgCheck(callee, callee, nullptr);
Label rejoinBeforeCall;
masm.bind(&rejoinBeforeCall);
AssertStackAlignment(masm, JitStackAlignment, sizeOfRetAddr);
masm.callJitNoProfiler(callee);
@ -818,6 +828,15 @@ GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* throwLa
GenerateJitExitEpilogue(masm, masm.framePushed(), offsets);
{
// Call the arguments rectifier.
masm.bind(&rectify);
masm.loadPtr(Address(WasmTlsReg, offsetof(TlsData, instance)), callee);
masm.loadPtr(Address(callee, Instance::offsetOfJSJitArgsRectifier()), callee);
masm.loadPtr(Address(callee, JitCode::offsetOfCode()), callee);
masm.jump(&rejoinBeforeCall);
}
if (oolConvert.used()) {
masm.bind(&oolConvert);
masm.setFramePushed(nativeFramePushed);

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

@ -6279,17 +6279,8 @@ nsDisplayOpacity::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuil
}
nsTArray<mozilla::wr::WrFilterOp> filters;
StackingContextHelper sc(aSc,
aBuilder,
aDisplayListBuilder,
this,
&mList,
nullptr,
animationsId,
opacityForSC,
nullptr,
nullptr,
filters);
StackingContextHelper sc(aSc, aBuilder, filters, nullptr, animationsId,
opacityForSC);
aManager->CommandBuilder().CreateWebRenderCommandsFromDisplayList(&mList,
aDisplayListBuilder,
@ -6341,9 +6332,8 @@ nsDisplayBlendMode::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBu
nsDisplayListBuilder* aDisplayListBuilder)
{
nsTArray<mozilla::wr::WrFilterOp> filters;
StackingContextHelper sc(aSc, aBuilder, aDisplayListBuilder, this,
&mList, nullptr, 0, nullptr, nullptr, nullptr,
filters, nsCSSRendering::GetGFXBlendMode(mBlendMode));
StackingContextHelper sc(aSc, aBuilder, filters, nullptr, 0, nullptr, nullptr,
nullptr, nsCSSRendering::GetGFXBlendMode(mBlendMode));
return nsDisplayWrapList::CreateWebRenderCommands(aBuilder,aResources, sc,
aManager, aDisplayListBuilder);
@ -6471,8 +6461,7 @@ nsDisplayBlendContainer::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
StackingContextHelper sc(aSc, aBuilder, aDisplayListBuilder, this,
&mList, nullptr, 0, nullptr, nullptr);
StackingContextHelper sc(aSc, aBuilder);
return nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, sc,
aManager, aDisplayListBuilder);
@ -6578,8 +6567,8 @@ nsDisplayOwnLayer::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBui
animationInfo.EnsureAnimationsId();
mWrAnimationId = animationInfo.GetCompositorAnimationsId();
StackingContextHelper sc(aSc, aBuilder, aDisplayListBuilder, this,
&mList, nullptr, mWrAnimationId, nullptr, nullptr);
StackingContextHelper sc(aSc, aBuilder, nsTArray<wr::WrFilterOp>(), nullptr,
mWrAnimationId);
nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, sc,
aManager, aDisplayListBuilder);
@ -7131,8 +7120,7 @@ nsDisplayStickyPosition::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder
// adjusted origin and use that for the nested items. This way all the
// ToRelativeLayoutRect calls on this StackingContextHelper object will
// include the necessary adjustment.
StackingContextHelper sc(aSc, aBuilder, aDisplayListBuilder, this,
&mList, nullptr, 0, nullptr, nullptr);
StackingContextHelper sc(aSc, aBuilder);
sc.AdjustOrigin(scTranslation);
// TODO: if, inside this nested command builder, we try to turn a gecko clip
@ -8056,15 +8044,12 @@ nsDisplayTransform::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBu
nsTArray<mozilla::wr::WrFilterOp> filters;
StackingContextHelper sc(aSc,
aBuilder,
aDisplayListBuilder,
this,
mStoredList.GetChildren(),
filters,
&newTransformMatrix,
animationsId,
nullptr,
transformForSC,
nullptr,
filters,
gfx::CompositionOp::OP_OVER,
!BackfaceIsHidden());
@ -8670,15 +8655,12 @@ nsDisplayPerspective::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& a
nsTArray<mozilla::wr::WrFilterOp> filters;
StackingContextHelper sc(aSc,
aBuilder,
aDisplayListBuilder,
this,
mList.GetChildren(),
filters,
nullptr,
0,
nullptr,
&transformForSC,
&perspectiveMatrix,
filters,
gfx::CompositionOp::OP_OVER,
!BackfaceIsHidden());
@ -9409,17 +9391,7 @@ nsDisplayFilter::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuild
wrFilters.AppendElement(wr::ToWrFilterOp(ToCSSFilter(filter)));
}
StackingContextHelper sc(aSc,
aBuilder,
aDisplayListBuilder,
this,
&mList,
nullptr,
0,
nullptr,
nullptr,
nullptr,
wrFilters);
StackingContextHelper sc(aSc, aBuilder, wrFilters);
nsDisplaySVGEffects::CreateWebRenderCommands(aBuilder, aResources, sc, aManager, aDisplayListBuilder);
return true;

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

@ -0,0 +1,7 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<select>
<script>document.documentElement.offsetHeight</script>
<option>Hello there</option>
<script>document.documentElement.offsetHeight</script>
</select>
</html>

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

@ -0,0 +1,6 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<select>
<script>document.documentElement.offsetHeight</script>
<option>Hello there</option>
</select>
</html>

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

@ -2042,5 +2042,6 @@ needs-focus != 1377447-1.html 1377447-2.html
== 1398500-1.html 1398500-1-ref.html
== 1401317.html 1401317-ref.html
== 1401992.html 1401992-ref.html
== 1405878-1.xml 1405878-1-ref.xml
== 1404057.html 1404057-ref.html
!= 1404057.html 1404057-noref.html

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

@ -2,9 +2,9 @@ pref(layout.css.mix-blend-mode.enabled,true) == blend-canvas.html blend-canvas-r
pref(layout.css.mix-blend-mode.enabled,true) == blend-constant-background-color.html blend-constant-background-color-ref.html
pref(layout.css.mix-blend-mode.enabled,true) fuzzy-if(webrender,1-1,7875-7875) == blend-gradient-background-color.html blend-gradient-background-color-ref.html
pref(layout.css.mix-blend-mode.enabled,true) == blend-image.html blend-image-ref.html
pref(layout.css.mix-blend-mode.enabled,true) fails-if(webrender) == blend-difference-stacking.html blend-difference-stacking-ref.html
pref(layout.css.mix-blend-mode.enabled,true) == blend-difference-stacking.html blend-difference-stacking-ref.html
fuzzy-if(skiaContent,1,30000) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-alpha.html background-blending-alpha-ref.html
fuzzy-if(skiaContent,1,30000) pref(layout.css.background-blend-mode.enabled,true) == background-blending-alpha.html background-blending-alpha-ref.html
pref(layout.css.background-blend-mode.enabled,true) fuzzy-if(webrender,1-1,7875-7875) == background-blending-gradient-color.html background-blending-gradient-color-ref.html
fuzzy-if(azureSkiaGL,3,7597) fuzzy-if(cocoaWidget,3,7597) fuzzy-if(d2d,1,3800) fuzzy-if(d3d11,1,4200) fuzzy-if(skiaContent,2,9450) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-gradient-gradient.html background-blending-gradient-gradient-ref.html
fuzzy-if(azureSkiaGL,2,7174) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-gradient-image.html background-blending-gradient-color-ref.html
@ -12,21 +12,21 @@ fuzzy-if(azureSkia||d2d||gtkWidget,1,10000) pref(layout.css.background-blend-mod
pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-png.html background-blending-image-color-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-svg.html background-blending-image-color-ref.html
fuzzy-if(azureSkiaGL,2,7174) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-image-gradient.html background-blending-gradient-color-ref.html
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-image-image.html background-blending-image-color-ref.html
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-isolation.html background-blending-isolation-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-image.html background-blending-image-color-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-isolation.html background-blending-isolation-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-list-repeat.html background-blending-list-repeat-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-multiple-images.html background-blending-multiple-images-ref.html
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-color-burn.html background-blending-color-burn-ref.svg
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-color-dodge.html background-blending-color-dodge-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-color-burn.html background-blending-color-burn-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-color-dodge.html background-blending-color-dodge-ref.svg
# need to investigate why these tests are fuzzy - first suspect is a possible color space conversion on some platforms; same for mix-blend-mode tests
fuzzy-if(azureSkia||gtkWidget,2,9600) fuzzy-if(d2d,1,8000) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-color.html background-blending-color-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-darken.html background-blending-darken-ref.svg
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-difference.html background-blending-difference-ref.svg
fuzzy-if(skiaContent,1,1600) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-exclusion.html background-blending-exclusion-ref.svg
fuzzy-if(cocoaWidget||d2d,1,1600) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-hard-light.html background-blending-hard-light-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-difference.html background-blending-difference-ref.svg
fuzzy-if(skiaContent,1,1600) pref(layout.css.background-blend-mode.enabled,true) == background-blending-exclusion.html background-blending-exclusion-ref.svg
fuzzy-if(cocoaWidget||d2d,1,1600) pref(layout.css.background-blend-mode.enabled,true) == background-blending-hard-light.html background-blending-hard-light-ref.svg
fuzzy-if(d2d,1,9600) fuzzy-if(azureSkia||gtkWidget,2,9600) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-hue.html background-blending-hue-ref.svg
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-lighten.html background-blending-lighten-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-lighten.html background-blending-lighten-ref.svg
fuzzy-if(d2d,1,8000) fuzzy-if(azureSkia||gtkWidget,2,9600) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-luminosity.html background-blending-luminosity-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-multiply.html background-blending-multiply-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-normal.html background-blending-normal-ref.svg
@ -60,7 +60,7 @@ pref(layout.css.background-blend-mode.enabled,true) == background-blending-image
# Test plan 5.3.2 Background layers do not blend with content outside the background (or behind the element) - tests 2 and 3
pref(layout.css.background-blend-mode.enabled,true) == background-blending-isolation-parent-child-color.html background-blending-isolation-parent-child-ref.html
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-isolation-parent-child-image.html background-blending-isolation-parent-child-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-isolation-parent-child-image.html background-blending-isolation-parent-child-ref.html
# Test plan 5.3.6 background-blend-mode for an element with background-position
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-position-percentage.html background-blending-background-position-percentage-ref.html
@ -85,16 +85,16 @@ pref(layout.css.background-blend-mode.enabled,true) == background-blending-backg
# Test plan 5.3.11 background-blend-mode for an element with background-attachement
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-attachement-fixed.html background-blending-background-attachement-fixed-ref.html
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-background-attachement-fixed-scroll.html background-blending-background-attachement-fixed-scroll-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-attachement-fixed-scroll.html background-blending-background-attachement-fixed-scroll-ref.html
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blend-mode-body-image.html background-blend-mode-body-image-ref.html
fuzzy-if(Android,4,768) fuzzy-if(gtkWidget,1,132) fuzzy-if(skiaContent,1,800) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blend-mode-body-transparent-image.html background-blend-mode-body-transparent-image-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blend-mode-body-image.html background-blend-mode-body-image-ref.html
fuzzy-if(Android,4,768) fuzzy-if(gtkWidget,1,132) fuzzy-if(skiaContent,1,800) pref(layout.css.background-blend-mode.enabled,true) == background-blend-mode-body-transparent-image.html background-blend-mode-body-transparent-image-ref.html
pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-moz-element.html background-blending-moz-element-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-moz-element.html background-blending-moz-element-ref.html
fuzzy(1,40000) pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == mix-blend-mode-soft-light.html mix-blend-mode-soft-light-ref.html
# Test plan 4.4.2 element with isolation:isolate creates an isolated group for blended children
pref(layout.css.isolation.enabled,true) fails-if(webrender) == blend-isolation.html blend-isolation-ref.html
pref(layout.css.isolation.enabled,true) == blend-isolation.html blend-isolation-ref.html
pref(layout.css.background-blend-mode.enabled,true) == bug1281593.html bug1281593-ref.html

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

@ -178,7 +178,7 @@ HTTP(..) == reflow-sanity-1.html reflow-sanity-1-data.html
HTTP(..) == reflow-sanity-delay-1a.html reflow-sanity-1-ref.html
HTTP(..) == reflow-sanity-delay-1b.html reflow-sanity-1-ref.html
HTTP(..) == reflow-sanity-delay-1c.html reflow-sanity-1-ref.html
HTTP(..) == reflow-sanity-delay-1-metrics.html reflow-sanity-1-ref.html
skip-if(winWidget&&!isDebugBuild) HTTP(..) == reflow-sanity-delay-1-metrics.html reflow-sanity-1-ref.html
# font-display
skip-if(/^Linux\x20i686/.test(http.oscpu)) HTTP(..) == font-display-1.html font-display-1-ref.html # normal font load (~500ms)

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

@ -194,14 +194,25 @@ public:
mozilla::LogicalSide aOwner,
bool aBevel);
bool IsIStartStart() const;
inline bool IsIStartStart() const
{
return (bool)mIStartStart;
}
void SetIStartStart(bool aValue);
inline void SetIStartStart(bool aValue)
{
mIStartStart = aValue;
}
bool IsBStartStart() const;
void SetBStartStart(bool aValue);
inline bool IsBStartStart() const
{
return (bool)mBStartStart;
}
inline void SetBStartStart(bool aValue)
{
mBStartStart = aValue;
}
protected:
BCPixelSize mIStartSize; // size in pixels of iStart border
@ -371,7 +382,8 @@ inline void CellData::SetOverlap(bool aOverlap)
inline BCData::BCData()
{
mIStartOwner = mBStartOwner = eCellOwner;
mIStartStart = mBStartStart = 1;
SetBStartStart(true);
SetIStartStart(true);
mIStartSize = mCornerSubSize = mBStartSize = 0;
mCornerSide = mozilla::eLogicalSideBStart;
mCornerBevel = false;
@ -385,7 +397,7 @@ inline nscoord BCData::GetIStartEdge(BCBorderOwner& aOwner,
bool& aStart) const
{
aOwner = (BCBorderOwner)mIStartOwner;
aStart = (bool)mIStartStart;
aStart = IsIStartStart();
return (nscoord)mIStartSize;
}
@ -396,14 +408,14 @@ inline void BCData::SetIStartEdge(BCBorderOwner aOwner,
{
mIStartOwner = aOwner;
mIStartSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
mIStartStart = aStart;
SetIStartStart(aStart);
}
inline nscoord BCData::GetBStartEdge(BCBorderOwner& aOwner,
bool& aStart) const
{
aOwner = (BCBorderOwner)mBStartOwner;
aStart = (bool)mBStartStart;
aStart = IsBStartStart();
return (nscoord)mBStartSize;
}
@ -414,7 +426,7 @@ inline void BCData::SetBStartEdge(BCBorderOwner aOwner,
{
mBStartOwner = aOwner;
mBStartSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
mBStartStart = aStart;
SetBStartStart(aStart);
}
inline BCPixelSize BCData::GetCorner(mozilla::LogicalSide& aOwnerSide,
@ -434,24 +446,4 @@ inline void BCData::SetCorner(BCPixelSize aSubSize,
mCornerBevel = aBevel;
}
inline bool BCData::IsIStartStart() const
{
return (bool)mIStartStart;
}
inline void BCData::SetIStartStart(bool aValue)
{
mIStartStart = aValue;
}
inline bool BCData::IsBStartStart() const
{
return (bool)mBStartStart;
}
inline void BCData::SetBStartStart(bool aValue)
{
mBStartStart = aValue;
}
#endif

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

@ -1312,8 +1312,8 @@ pref("dom.timeout.foreground_budget_regeneration_rate", 1);
pref("dom.timeout.foreground_throttling_max_budget", -1);
// The maximum amount a timeout can be delayed by budget throttling
pref("dom.timeout.budget_throttling_max_delay", 15000);
// Turn off budget throttling by default
pref("dom.timeout.enable_budget_timer_throttling", false);
// Turn on budget throttling by default
pref("dom.timeout.enable_budget_timer_throttling", true);
// Don't use new input types
pref("dom.experimental_forms", false);

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

@ -106,6 +106,28 @@ nsBaseChannel::Redirect(nsIChannel *newChannel, uint32_t redirectFlags,
new nsRedirectHistoryEntry(uriPrincipal, nullptr, EmptyCString());
newLoadInfo->AppendRedirectHistoryEntry(entry, isInternalRedirect);
// Ensure the channel's loadInfo's result principal URI so that it's
// either non-null or updated to the redirect target URI.
// We must do this because in case the loadInfo's result principal URI
// is null, it would be taken from OriginalURI of the channel. But we
// overwrite it with the whole redirect chain first URI before opening
// the target channel, hence the information would be lost.
// If the protocol handler that created the channel wants to use
// the originalURI of the channel as the principal URI, it has left
// the result principal URI on the load info null.
nsCOMPtr<nsIURI> resultPrincipalURI;
nsCOMPtr<nsILoadInfo> existingLoadInfo = newChannel->GetLoadInfo();
if (existingLoadInfo) {
existingLoadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
}
if (!resultPrincipalURI) {
newChannel->GetOriginalURI(getter_AddRefs(resultPrincipalURI));
}
newLoadInfo->SetResultPrincipalURI(resultPrincipalURI);
newChannel->SetLoadInfo(newLoadInfo);
}
else {

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

@ -68,7 +68,7 @@ interface nsIInterceptedChannel : nsISupports
* @return NS_ERROR_FAILURE if the response has already been synthesized or
* the original request has been instructed to continue.
*/
void cancel(in nsresult status);
void cancelInterception(in nsresult status);
/**
* The synthesized response body to be produced.

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

@ -780,7 +780,6 @@ bool nsIDNService::isLabelSafe(const nsAString &label)
if (illegalScriptCombo(script, savedScript)) {
return false;
}
lastScript = script;
}
// Check for mixed numbering systems
@ -833,6 +832,10 @@ bool nsIDNService::isLabelSafe(const nsAString &label)
}
}
if (script != Script::COMMON && script != Script::INHERITED) {
lastScript = script;
}
// Simplified/Traditional Chinese check temporarily disabled -- bug 857481
#if 0

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

@ -371,6 +371,36 @@ public: /* Necko internal use only... */
return mChannelId;
}
void InternalSetUploadStream(nsIInputStream *uploadStream)
{
mUploadStream = uploadStream;
}
void SetUploadStreamHasHeaders(bool hasHeaders)
{
mUploadStreamHasHeaders = hasHeaders;
}
MOZ_MUST_USE nsresult
SetReferrerWithPolicyInternal(nsIURI *referrer, uint32_t referrerPolicy)
{
nsAutoCString spec;
nsresult rv = referrer->GetAsciiSpec(spec);
if (NS_FAILED(rv)) {
return rv;
}
mReferrer = referrer;
mReferrerPolicy = referrerPolicy;
rv = mRequestHead.SetHeader(nsHttp::Referer, spec);
return rv;
}
MOZ_MUST_USE nsresult SetTopWindowURI(nsIURI* aTopWindowURI)
{
mTopWindowURI = aTopWindowURI;
return NS_OK;
}
protected:
// Handle notifying listener, removing from loadgroup if request failed.
void DoNotifyListener();

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

@ -3570,12 +3570,6 @@ HttpChannelChild::ForceIntercepted(bool aPostRedirectChannelShouldIntercept,
return NS_OK;
}
NS_IMETHODIMP
HttpChannelChild::ForceIntercepted(uint64_t aInterceptionID)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
void
HttpChannelChild::ForceIntercepted(nsIInputStream* aSynthesizedInput)
{

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

@ -98,7 +98,6 @@ public:
NS_IMETHOD GetProtocolVersion(nsACString& aProtocolVersion) override;
// nsIHttpChannelInternal
NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey) override;
NS_IMETHOD ForceIntercepted(uint64_t aInterceptionID) override;
// nsISupportsPriority
NS_IMETHOD SetPriority(int32_t value) override;
// nsIClassOfService

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

@ -113,7 +113,7 @@ HttpChannelParent::ActorDestroy(ActorDestroyReason why)
// If this is an intercepted channel, we need to make sure that any resources are
// cleaned up to avoid leaks.
if (mParentListener) {
mParentListener->ClearInterceptedChannel();
mParentListener->ClearInterceptedChannel(this);
}
CleanupBackgroundChannel();
@ -235,8 +235,9 @@ HttpChannelParent::CleanupBackgroundChannel()
// The nsHttpChannel may have a reference to this parent, release it
// to avoid circular references.
if (mChannel) {
mChannel->SetWarningReporter(nullptr);
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel);
if (httpChannelImpl) {
httpChannelImpl->SetWarningReporter(nullptr);
}
if (!mPromise.IsEmpty()) {
@ -521,7 +522,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
return SendFailedAsyncOpen(rv);
}
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(channel, &rv);
RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(channel, &rv);
if (NS_FAILED(rv)) {
return SendFailedAsyncOpen(rv);
}
@ -531,7 +532,10 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
httpChannel->SetTopLevelContentWindowId(aContentWindowId);
httpChannel->SetTopLevelOuterContentWindowId(aTopLevelOuterContentWindowId);
httpChannel->SetWarningReporter(this);
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(httpChannel);
if (httpChannelImpl) {
httpChannelImpl->SetWarningReporter(this);
}
httpChannel->SetTimingEnabled(true);
if (mPBOverride != kPBOverride_Unset) {
httpChannel->SetPrivate(mPBOverride == kPBOverride_Private ? true : false);
@ -566,8 +570,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
httpChannel->SetEmptyRequestHeader(requestHeaders[i].mHeader);
} else {
httpChannel->SetRequestHeader(requestHeaders[i].mHeader,
requestHeaders[i].mValue,
requestHeaders[i].mMerge);
requestHeaders[i].mValue,
requestHeaders[i].mMerge);
}
}
@ -645,7 +649,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
if (aSynthesizedResponseHead.type() == OptionalHttpResponseHead::TnsHttpResponseHead) {
parentListener->SetupInterception(aSynthesizedResponseHead.get_nsHttpResponseHead());
mWillSynthesizeResponse = true;
httpChannel->SetCouldBeSynthesized();
httpChannelImpl->SetCouldBeSynthesized();
if (!aSecurityInfoSerialization.IsEmpty()) {
nsCOMPtr<nsISupports> secInfo;
@ -671,10 +675,14 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
return SendFailedAsyncOpen(rv);
}
httpChannel->SetCacheKey(cacheKey);
httpChannel->PreferAlternativeDataType(aPreferredAlternativeType);
nsCOMPtr<nsICacheInfoChannel> cacheChannel =
do_QueryInterface(static_cast<nsIChannel*>(httpChannel.get()));
if (cacheChannel) {
cacheChannel->SetCacheKey(cacheKey);
cacheChannel->PreferAlternativeDataType(aPreferredAlternativeType);
httpChannel->SetAllowStaleCacheContent(aAllowStaleCacheContent);
cacheChannel->SetAllowStaleCacheContent(aAllowStaleCacheContent);
}
httpChannel->SetContentType(aContentTypeHint);
@ -814,14 +822,17 @@ HttpChannelParent::ConnectChannel(const uint32_t& registrarId, const bool& shoul
LOG((" found channel %p, rv=%08" PRIx32, channel.get(), static_cast<uint32_t>(rv)));
mChannel = do_QueryObject(channel);
if (!mChannel) {
LOG((" but it's not nsHttpChannel"));
LOG((" but it's not HttpBaseChannel"));
Delete();
return true;
}
LOG((" and it is nsHttpChannel %p", mChannel.get()));
LOG((" and it is HttpBaseChannel %p", mChannel.get()));
mChannel->SetWarningReporter(this);
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel);
if (httpChannelImpl) {
httpChannelImpl->SetWarningReporter(this);
}
nsCOMPtr<nsINetworkInterceptController> controller;
NS_QueryNotificationCallbacks(channel, controller);
@ -1409,15 +1420,15 @@ HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
MOZ_RELEASE_ASSERT(!mDivertingFromChild,
"Cannot call OnStartRequest if diverting is set!");
RefPtr<nsHttpChannel> chan = do_QueryObject(aRequest);
RefPtr<HttpBaseChannel> chan = do_QueryObject(aRequest);
if (!chan) {
LOG((" aRequest is not nsHttpChannel"));
NS_ERROR("Expecting only nsHttpChannel as aRequest in HttpChannelParent::OnStartRequest");
LOG((" aRequest is not HttpBaseChannel"));
NS_ERROR("Expecting only HttpBaseChannel as aRequest in HttpChannelParent::OnStartRequest");
return NS_ERROR_UNEXPECTED;
}
MOZ_ASSERT(mChannel == chan,
"HttpChannelParent getting OnStartRequest from a different nsHttpChannel instance");
"HttpChannelParent getting OnStartRequest from a different HttpBaseChannel instance");
// Send down any permissions which are relevant to this URL if we are
// performing a document load. We can't do that is mIPCClosed is set.
@ -1432,28 +1443,36 @@ HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
nsHttpResponseHead *responseHead = chan->GetResponseHead();
nsHttpRequestHead *requestHead = chan->GetRequestHead();
bool isFromCache = false;
chan->IsFromCache(&isFromCache);
int32_t fetchCount = 0;
chan->GetCacheTokenFetchCount(&fetchCount);
uint32_t expirationTime = nsICacheEntry::NO_EXPIRATION_TIME;
chan->GetCacheTokenExpirationTime(&expirationTime);
nsCString cachedCharset;
chan->GetCacheTokenCachedCharset(cachedCharset);
bool loadedFromApplicationCache;
chan->GetLoadedFromApplicationCache(&loadedFromApplicationCache);
if (loadedFromApplicationCache) {
mOfflineForeignMarker = chan->GetOfflineCacheEntryAsForeignMarker();
nsCOMPtr<nsIApplicationCache> appCache;
chan->GetApplicationCache(getter_AddRefs(appCache));
nsCString appCacheGroupId;
nsCString appCacheClientId;
appCache->GetGroupID(appCacheGroupId);
appCache->GetClientID(appCacheClientId);
if (mIPCClosed ||
!SendAssociateApplicationCache(appCacheGroupId, appCacheClientId))
{
return NS_ERROR_UNEXPECTED;
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(chan);
if (httpChannelImpl) {
httpChannelImpl->IsFromCache(&isFromCache);
httpChannelImpl->GetCacheTokenFetchCount(&fetchCount);
httpChannelImpl->GetCacheTokenExpirationTime(&expirationTime);
httpChannelImpl->GetCacheTokenCachedCharset(cachedCharset);
}
bool loadedFromApplicationCache = false;
if (httpChannelImpl) {
httpChannelImpl->GetLoadedFromApplicationCache(&loadedFromApplicationCache);
if (loadedFromApplicationCache) {
mOfflineForeignMarker = httpChannelImpl->GetOfflineCacheEntryAsForeignMarker();
nsCOMPtr<nsIApplicationCache> appCache;
httpChannelImpl->GetApplicationCache(getter_AddRefs(appCache));
nsCString appCacheGroupId;
nsCString appCacheClientId;
appCache->GetGroupID(appCacheGroupId);
appCache->GetClientID(appCacheClientId);
if (mIPCClosed ||
!SendAssociateApplicationCache(appCacheGroupId, appCacheClientId))
{
return NS_ERROR_UNEXPECTED;
}
}
}
@ -1464,11 +1483,32 @@ HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
// Keep the cache entry for future use in RecvSetCacheTokenCachedCharset().
// It could be already released by nsHttpChannel at that time.
nsCOMPtr<nsISupports> cacheEntry;
chan->GetCacheToken(getter_AddRefs(cacheEntry));
mCacheEntry = do_QueryInterface(cacheEntry);
nsresult channelStatus = NS_OK;
chan->GetStatus(&channelStatus);
uint32_t cacheKeyValue = 0;
nsAutoCString altDataType;
if (httpChannelImpl) {
httpChannelImpl->GetCacheToken(getter_AddRefs(cacheEntry));
mCacheEntry = do_QueryInterface(cacheEntry);
httpChannelImpl->GetStatus(&channelStatus);
nsCOMPtr<nsISupports> cacheKey;
httpChannelImpl->GetCacheKey(getter_AddRefs(cacheKey));
if (cacheKey) {
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(cacheKey);
if (!container) {
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult rv = container->GetData(&cacheKeyValue);
if (NS_FAILED(rv)) {
return rv;
}
}
httpChannelImpl->GetAlternativeDataType(altDataType);
}
nsCString secInfoSerialization;
UpdateAndSerializeSecurityInfo(secInfoSerialization);
@ -1476,23 +1516,6 @@ HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
uint8_t redirectCount = 0;
chan->GetRedirectCount(&redirectCount);
nsCOMPtr<nsISupports> cacheKey;
chan->GetCacheKey(getter_AddRefs(cacheKey));
uint32_t cacheKeyValue = 0;
if (cacheKey) {
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(cacheKey);
if (!container) {
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult rv = container->GetData(&cacheKeyValue);
if (NS_FAILED(rv)) {
return rv;
}
}
nsAutoCString altDataType;
chan->GetAlternativeDataType(altDataType);
int64_t altDataLen = chan->GetAltDataLength();
// !!! We need to lock headers and please don't forget to unlock them !!!
@ -1562,7 +1585,10 @@ HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
mChannel->GetCacheReadStart(&timing.cacheReadStart);
mChannel->GetCacheReadEnd(&timing.cacheReadEnd);
mChannel->SetWarningReporter(nullptr);
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel);
if (httpChannelImpl) {
httpChannelImpl->SetWarningReporter(nullptr);
}
// Either IPC channel is closed or background channel
// is ready to send OnStopRequest.
@ -1597,9 +1623,11 @@ HttpChannelParent::OnDataAvailable(nsIRequest *aRequest,
nsresult channelStatus = NS_OK;
mChannel->GetStatus(&channelStatus);
nsresult transportStatus =
(mChannel->IsReadingFromCache()) ? NS_NET_STATUS_READING
: NS_NET_STATUS_RECEIVING_FROM;
nsresult transportStatus = NS_NET_STATUS_RECEIVING_FROM;
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel);
if (httpChannelImpl && httpChannelImpl->IsReadingFromCache()) {
transportStatus = NS_NET_STATUS_READING;
}
static uint32_t const kCopyChunkSize = 128 * 1024;
uint32_t toRead = std::min<uint32_t>(aCount, kCopyChunkSize);
@ -1778,8 +1806,40 @@ HttpChannelParent::StartRedirect(uint32_t registrarId,
"newChannel=%p callback=%p]\n", this, registrarId, newChannel,
callback));
if (mIPCClosed)
if (mIPCClosed) {
return NS_BINDING_ABORTED;
}
// If this is an internal redirect for service worker interception, then
// hide it from the child process. The original e10s interception code
// was not designed with this in mind and its not necessary to replace
// the HttpChannelChild/Parent objects in this case.
if (redirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
nsCOMPtr<nsIInterceptedChannel> newIntercepted = do_QueryInterface(newChannel);
if (newIntercepted) {
#ifdef DEBUG
// Note, InterceptedHttpChannel can also do an internal redirect
// for opaque response interception. This should not actually
// happen here in e10s mode.
nsCOMPtr<nsIInterceptedChannel> oldIntercepted =
do_QueryInterface(static_cast<nsIChannel*>(mChannel.get()));
MOZ_ASSERT(!oldIntercepted);
#endif
// Re-link the HttpChannelParent to the new InterceptedHttpChannel.
nsCOMPtr<nsIChannel> linkedChannel;
rv = NS_LinkRedirectChannels(registrarId, this, getter_AddRefs(linkedChannel));
NS_ENSURE_SUCCESS(rv, rv);
MOZ_ASSERT(linkedChannel == newChannel);
// We immediately store the InterceptedHttpChannel as our nested
// mChannel. None of the redirect IPC messaging takes place.
mChannel = do_QueryObject(newChannel);
callback->OnRedirectVerifyCallback(NS_OK);
return NS_OK;
}
}
// Sending down the original URI, because that is the URI we have
// to construct the channel from - this is the URI we've been actually
@ -1798,7 +1858,7 @@ HttpChannelParent::StartRedirect(uint32_t registrarId,
// If the channel is a HTTP channel, we also want to inform the child
// about the parent's channelId attribute, so that both parent and child
// share the same ID. Useful for monitoring channel activity in devtools.
uint64_t channelId;
uint64_t channelId = 0;
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
if (httpChannel) {
rv = httpChannel->GetChannelId(&channelId);
@ -1839,6 +1899,13 @@ HttpChannelParent::CompleteRedirect(bool succeeded)
LOG(("HttpChannelParent::CompleteRedirect [this=%p succeeded=%d]\n",
this, succeeded));
// If this was an internal redirect for a service worker interception then
// we will not have a redirecting channel here. Hide this redirect from
// the child.
if (!mRedirectChannel) {
return NS_OK;
}
if (succeeded && !mIPCClosed) {
// TODO: check return value: assume child dead if failed
Unused << SendRedirect3Complete();
@ -1873,7 +1940,9 @@ HttpChannelParent::SuspendForDiversion()
// MessageDiversionStarted call will suspend mEventQ as many times as the
// channel has been suspended, so that channel and this queue are in sync.
mChannel->MessageDiversionStarted(this);
nsCOMPtr<nsIChannelWithDivertableParentListener> divertChannel =
do_QueryInterface(static_cast<nsIChannel*>(mChannel.get()));
divertChannel->MessageDiversionStarted(this);
nsresult rv = NS_OK;
@ -1889,7 +1958,7 @@ HttpChannelParent::SuspendForDiversion()
// OnDataAvailable until diversion is over. At the same time we should
// send the diverted OnDataAvailable-s to the listeners and not queue them
// in mEventQ.
rv = mChannel->SuspendInternal();
rv = divertChannel->SuspendInternal();
MOZ_ASSERT(NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_AVAILABLE);
mSuspendedForDiversion = NS_SUCCEEDED(rv);
} else {
@ -1944,11 +2013,13 @@ HttpChannelParent::ResumeForDiversion()
return NS_ERROR_UNEXPECTED;
}
mChannel->MessageDiversionStop();
nsCOMPtr<nsIChannelWithDivertableParentListener> divertChannel =
do_QueryInterface(static_cast<nsIChannel*>(mChannel.get()));
divertChannel->MessageDiversionStop();
if (mSuspendedForDiversion) {
// The nsHttpChannel will deliver remaining OnData/OnStop for the transfer.
nsresult rv = mChannel->ResumeInternal();
nsresult rv = divertChannel->ResumeInternal();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -2104,7 +2175,9 @@ HttpChannelParent::NotifyDiversionFailed(nsresult aErrorCode)
// Resume only if we suspended earlier.
if (mSuspendedForDiversion) {
mChannel->ResumeInternal();
nsCOMPtr<nsIChannelWithDivertableParentListener> divertChannel =
do_QueryInterface(static_cast<nsIChannel*>(mChannel.get()));
divertChannel->ResumeInternal();
}
// Channel has already sent OnStartRequest to the child, so ensure that we
// call it here if it hasn't already been called.

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

@ -260,7 +260,7 @@ private:
friend class DivertStopRequestEvent;
friend class DivertCompleteEvent;
RefPtr<nsHttpChannel> mChannel;
RefPtr<HttpBaseChannel> mChannel;
nsCOMPtr<nsICacheEntry> mCacheEntry;
nsCOMPtr<nsIAssociatedContentSecurity> mAssociatedContentSecurity;
bool mIPCClosed; // PHttpChannel actor has been Closed()

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