mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
merge mozilla-inbound to mozilla-central. r=merge a=merge
MozReview-Commit-ID: 4EWdTlEncz7
This commit is contained in:
commit
f16a7f8371
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -29870,6 +29870,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
/* 900 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const networkRequest = __webpack_require__(901);
|
||||
const workerUtils = __webpack_require__(902);
|
||||
|
||||
@ -29882,6 +29886,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
/* 901 */
|
||||
/***/ function(module, exports) {
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function networkRequest(url, opts) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = new XMLHttpRequest();
|
||||
@ -29891,7 +29899,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
if (req.status === 200) {
|
||||
resolve({ content: req.responseText });
|
||||
} else {
|
||||
resolve(req.statusText);
|
||||
reject(req.statusText);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -29921,7 +29929,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
function WorkerDispatcher() {
|
||||
this.msgId = 1;
|
||||
this.worker = null;
|
||||
}
|
||||
} /* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
WorkerDispatcher.prototype = {
|
||||
start(url) {
|
||||
@ -29952,7 +29962,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
}
|
||||
|
||||
this.worker.removeEventListener("message", listener);
|
||||
|
||||
if (result.error) {
|
||||
reject(result.error);
|
||||
} else {
|
||||
@ -30070,6 +30079,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
getClosestExpression: _closest.getClosestExpression,
|
||||
getOutOfScopeLocations: _getOutOfScopeLocations2.default,
|
||||
getSymbols: _getSymbols2.default,
|
||||
clearSymbols: _getSymbols.clearSymbols,
|
||||
getVariablesInScope: _scopes.getVariablesInScope
|
||||
});
|
||||
|
||||
@ -30473,6 +30483,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
value: true
|
||||
});
|
||||
exports.default = getSymbols;
|
||||
exports.formatSymbols = formatSymbols;
|
||||
exports.clearSymbols = clearSymbols;
|
||||
|
||||
var _ast = __webpack_require__(1051);
|
||||
|
||||
@ -30519,26 +30531,32 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
}));
|
||||
}
|
||||
|
||||
function getSymbols(source) {
|
||||
if (symbolDeclarations.has(source.id)) {
|
||||
var _symbols = symbolDeclarations.get(source.id);
|
||||
if (_symbols) {
|
||||
return _symbols;
|
||||
}
|
||||
function getComments(ast) {
|
||||
if (!ast || !ast.comments) {
|
||||
return [];
|
||||
}
|
||||
return ast.comments.map(comment => ({
|
||||
name: comment.location,
|
||||
location: comment.loc
|
||||
}));
|
||||
}
|
||||
|
||||
var symbols = { functions: [], variables: [] };
|
||||
function extractSymbols(source) {
|
||||
var functions = [];
|
||||
var variables = [];
|
||||
var memberExpressions = [];
|
||||
var callExpressions = [];
|
||||
var objectProperties = [];
|
||||
var identifiers = [];
|
||||
|
||||
(0, _ast.traverseAst)(source, {
|
||||
var ast = (0, _ast.traverseAst)(source, {
|
||||
enter(path) {
|
||||
if ((0, _helpers.isVariable)(path)) {
|
||||
var _symbols$variables;
|
||||
|
||||
(_symbols$variables = symbols.variables).push.apply(_symbols$variables, _toConsumableArray(getVariableNames(path)));
|
||||
variables.push.apply(variables, _toConsumableArray(getVariableNames(path)));
|
||||
}
|
||||
|
||||
if ((0, _helpers.isFunction)(path)) {
|
||||
symbols.functions.push({
|
||||
functions.push({
|
||||
name: (0, _getFunctionName2.default)(path),
|
||||
location: path.node.loc,
|
||||
parameterNames: getFunctionParameterNames(path),
|
||||
@ -30547,18 +30565,291 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
}
|
||||
|
||||
if (t.isClassDeclaration(path)) {
|
||||
symbols.variables.push({
|
||||
variables.push({
|
||||
name: path.node.id.name,
|
||||
location: path.node.loc
|
||||
});
|
||||
}
|
||||
|
||||
if (t.isObjectProperty(path)) {
|
||||
var _path$node$key$loc = path.node.key.loc,
|
||||
start = _path$node$key$loc.start,
|
||||
end = _path$node$key$loc.end,
|
||||
identifierName = _path$node$key$loc.identifierName;
|
||||
|
||||
objectProperties.push({
|
||||
name: identifierName,
|
||||
location: { start, end },
|
||||
expression: getSnippet(path)
|
||||
});
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(path)) {
|
||||
var _path$node$property$l = path.node.property.loc,
|
||||
_start = _path$node$property$l.start,
|
||||
_end = _path$node$property$l.end;
|
||||
|
||||
memberExpressions.push({
|
||||
name: path.node.property.name,
|
||||
location: { start: _start, end: _end },
|
||||
expressionLocation: path.node.loc,
|
||||
expression: getSnippet(path)
|
||||
});
|
||||
}
|
||||
|
||||
if (t.isCallExpression(path)) {
|
||||
var callee = path.node.callee;
|
||||
if (!t.isMemberExpression(callee)) {
|
||||
var _callee$loc = callee.loc,
|
||||
_start2 = _callee$loc.start,
|
||||
_end2 = _callee$loc.end,
|
||||
_identifierName = _callee$loc.identifierName;
|
||||
|
||||
callExpressions.push({
|
||||
name: _identifierName,
|
||||
location: { start: _start2, end: _end2 }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isIdentifier(path)) {
|
||||
var _path$node$loc = path.node.loc,
|
||||
_start3 = _path$node$loc.start,
|
||||
_end3 = _path$node$loc.end;
|
||||
|
||||
|
||||
identifiers.push({
|
||||
name: path.node.name,
|
||||
expression: path.node.name,
|
||||
location: { start: _start3, end: _end3 }
|
||||
});
|
||||
}
|
||||
|
||||
if (t.isThisExpression(path.node)) {
|
||||
var _path$node$loc2 = path.node.loc,
|
||||
_start4 = _path$node$loc2.start,
|
||||
_end4 = _path$node$loc2.end;
|
||||
|
||||
identifiers.push({
|
||||
name: "this",
|
||||
location: { start: _start4, end: _end4 },
|
||||
expressionLocation: path.node.loc,
|
||||
expression: "this"
|
||||
});
|
||||
}
|
||||
|
||||
if (t.isVariableDeclarator(path)) {
|
||||
var node = path.node.id;
|
||||
var _path$node$loc3 = path.node.loc,
|
||||
_start5 = _path$node$loc3.start,
|
||||
_end5 = _path$node$loc3.end;
|
||||
|
||||
|
||||
identifiers.push({
|
||||
name: node.name,
|
||||
expression: node.name,
|
||||
location: { start: _start5, end: _end5 }
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// comments are extracted separately from the AST
|
||||
var comments = getComments(ast);
|
||||
|
||||
return {
|
||||
functions,
|
||||
variables,
|
||||
callExpressions,
|
||||
memberExpressions,
|
||||
objectProperties,
|
||||
comments,
|
||||
identifiers
|
||||
};
|
||||
}
|
||||
|
||||
function getSymbols(source) {
|
||||
if (symbolDeclarations.has(source.id)) {
|
||||
var _symbols = symbolDeclarations.get(source.id);
|
||||
if (_symbols) {
|
||||
return _symbols;
|
||||
}
|
||||
}
|
||||
|
||||
var symbols = extractSymbols(source);
|
||||
symbolDeclarations.set(source.id, symbols);
|
||||
return symbols;
|
||||
}
|
||||
|
||||
function extendSnippet(name, expression, path, prevPath) {
|
||||
var computed = path && path.node.computed;
|
||||
var prevComputed = prevPath && prevPath.node.computed;
|
||||
var prevArray = t.isArrayExpression(prevPath);
|
||||
var array = t.isArrayExpression(path);
|
||||
|
||||
if (expression === "") {
|
||||
if (computed) {
|
||||
return `[${name}]`;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
if (computed || array) {
|
||||
if (prevComputed || prevArray) {
|
||||
return `[${name}]${expression}`;
|
||||
}
|
||||
return `[${name}].${expression}`;
|
||||
}
|
||||
|
||||
if (prevComputed || prevArray) {
|
||||
return `${name}${expression}`;
|
||||
}
|
||||
|
||||
return `${name}.${expression}`;
|
||||
}
|
||||
|
||||
function getMemberSnippet(node) {
|
||||
var expression = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
|
||||
|
||||
if (t.isMemberExpression(node)) {
|
||||
var _name = node.property.name;
|
||||
|
||||
return getMemberSnippet(node.object, extendSnippet(_name, expression));
|
||||
}
|
||||
|
||||
if (t.isCallExpression(node)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (t.isThisExpression(node)) {
|
||||
return `this.${expression}`;
|
||||
}
|
||||
|
||||
if (t.isIdentifier(node)) {
|
||||
return `${node.name}.${expression}`;
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
function getObjectSnippet(path, prevPath) {
|
||||
var expression = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
|
||||
|
||||
if (!path) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
var name = path.node.key.name;
|
||||
|
||||
var extendedExpression = extendSnippet(name, expression, path, prevPath);
|
||||
|
||||
var nextPrevPath = path;
|
||||
var nextPath = path.parentPath && path.parentPath.parentPath;
|
||||
|
||||
return getSnippet(nextPath, nextPrevPath, extendedExpression);
|
||||
}
|
||||
|
||||
function getArraySnippet(path, prevPath, expression) {
|
||||
var index = prevPath.parentPath.key;
|
||||
var extendedExpression = extendSnippet(index, expression, path, prevPath);
|
||||
|
||||
var nextPrevPath = path;
|
||||
var nextPath = path.parentPath && path.parentPath.parentPath;
|
||||
|
||||
return getSnippet(nextPath, nextPrevPath, extendedExpression);
|
||||
}
|
||||
|
||||
function getSnippet(path, prevPath) {
|
||||
var expression = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
|
||||
|
||||
if (t.isVariableDeclaration(path)) {
|
||||
var node = path.node.declarations[0];
|
||||
var _name2 = node.id.name;
|
||||
return extendSnippet(_name2, expression, path, prevPath);
|
||||
}
|
||||
|
||||
if (t.isVariableDeclarator(path)) {
|
||||
var _node = path.node.id;
|
||||
if (t.isObjectPattern(_node)) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
var _name3 = _node.name;
|
||||
var prop = extendSnippet(_name3, expression, path, prevPath);
|
||||
return prop;
|
||||
}
|
||||
|
||||
if (t.isAssignmentExpression(path)) {
|
||||
var _node2 = path.node.left;
|
||||
var _name4 = t.isMemberExpression(_node2) ? getMemberSnippet(_node2) : _node2.name;
|
||||
|
||||
var _prop = extendSnippet(_name4, expression, path, prevPath);
|
||||
return _prop;
|
||||
}
|
||||
|
||||
if ((0, _helpers.isFunction)(path)) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
if (t.isIdentifier(path)) {
|
||||
var _node3 = path.node;
|
||||
return `${_node3.name}.${expression}`;
|
||||
}
|
||||
|
||||
if (t.isObjectProperty(path)) {
|
||||
return getObjectSnippet(path, prevPath, expression);
|
||||
}
|
||||
|
||||
if (t.isObjectExpression(path)) {
|
||||
var parentPath = prevPath && prevPath.parentPath;
|
||||
return getObjectSnippet(parentPath, prevPath, expression);
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(path)) {
|
||||
return getMemberSnippet(path.node, expression);
|
||||
}
|
||||
|
||||
if (t.isArrayExpression(path)) {
|
||||
return getArraySnippet(path, prevPath, expression);
|
||||
}
|
||||
}
|
||||
|
||||
function formatSymbols(source) {
|
||||
var _getSymbols = getSymbols(source),
|
||||
objectProperties = _getSymbols.objectProperties,
|
||||
memberExpressions = _getSymbols.memberExpressions,
|
||||
callExpressions = _getSymbols.callExpressions,
|
||||
identifiers = _getSymbols.identifiers,
|
||||
variables = _getSymbols.variables;
|
||||
|
||||
function formatLocation(loc) {
|
||||
if (!loc) {
|
||||
return "";
|
||||
}
|
||||
var start = loc.start,
|
||||
end = loc.end;
|
||||
|
||||
|
||||
var startLoc = `(${start.line}, ${start.column})`;
|
||||
var endLoc = `(${end.line}, ${end.column})`;
|
||||
return `[${startLoc}, ${endLoc}]`;
|
||||
}
|
||||
|
||||
function summarize(symbol) {
|
||||
var loc = formatLocation(symbol.location);
|
||||
var exprLoc = formatLocation(symbol.expressionLocation);
|
||||
var params = symbol.parameterNames ? symbol.parameterNames.join(", ") : "";
|
||||
var expression = symbol.expression || "";
|
||||
return `${loc} ${exprLoc} ${expression} ${symbol.name} ${params}`;
|
||||
}
|
||||
|
||||
return ["properties", objectProperties.map(summarize).join("\n"), "member expressions", memberExpressions.map(summarize).join("\n"), "call expressions", callExpressions.map(summarize).join("\n"), "identifiers", identifiers.map(summarize).join("\n"), "variables", variables.map(summarize).join("\n")].join("\n");
|
||||
}
|
||||
|
||||
function clearSymbols() {
|
||||
symbolDeclarations = new Map();
|
||||
}
|
||||
|
||||
/***/ },
|
||||
/* 1051 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
@ -30621,39 +30912,45 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
return ast;
|
||||
}
|
||||
|
||||
function getAst(sourceText) {
|
||||
if (ASTs.has(sourceText.id)) {
|
||||
return ASTs.get(sourceText.id);
|
||||
// Custom parser for parse-script-tags that adapts its input structure to
|
||||
// our parser's signature
|
||||
function htmlParser(_ref) {
|
||||
var source = _ref.source,
|
||||
line = _ref.line;
|
||||
|
||||
return parse(source, {
|
||||
startLine: line
|
||||
});
|
||||
}
|
||||
|
||||
function getAst(source) {
|
||||
if (!source || !source.text) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (ASTs.has(source.id)) {
|
||||
return ASTs.get(source.id);
|
||||
}
|
||||
|
||||
var ast = {};
|
||||
if (sourceText.contentType == "text/html") {
|
||||
// Custom parser for parse-script-tags that adapts its input structure to
|
||||
// our parser's signature
|
||||
var parser = (_ref) => {
|
||||
var source = _ref.source,
|
||||
line = _ref.line;
|
||||
|
||||
return parse(source, {
|
||||
startLine: line
|
||||
});
|
||||
};
|
||||
ast = (0, _parseScriptTags2.default)(sourceText.text, parser) || {};
|
||||
} else if (sourceText.contentType == "text/javascript") {
|
||||
ast = parse(sourceText.text);
|
||||
if (source.contentType == "text/html") {
|
||||
ast = (0, _parseScriptTags2.default)(source.text, htmlParser) || {};
|
||||
} else if (source.contentType == "text/javascript") {
|
||||
ast = parse(source.text);
|
||||
}
|
||||
|
||||
ASTs.set(sourceText.id, ast);
|
||||
ASTs.set(source.id, ast);
|
||||
return ast;
|
||||
}
|
||||
|
||||
function traverseAst(sourceText, visitor) {
|
||||
var ast = getAst(sourceText);
|
||||
function traverseAst(source, visitor) {
|
||||
var ast = getAst(source);
|
||||
if ((0, _isEmpty2.default)(ast)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
(0, _babelTraverse2.default)(ast, visitor);
|
||||
return ast;
|
||||
}
|
||||
|
||||
/***/ },
|
||||
@ -30980,15 +31277,18 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
|
||||
var _helpers = __webpack_require__(1052);
|
||||
|
||||
var _getSymbols = __webpack_require__(1050);
|
||||
var _getSymbols2 = __webpack_require__(1050);
|
||||
|
||||
var _getSymbols2 = _interopRequireDefault(_getSymbols);
|
||||
var _getSymbols3 = _interopRequireDefault(_getSymbols2);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function findFunctions(source) {
|
||||
var symbols = (0, _getSymbols2.default)(source);
|
||||
return symbols.functions;
|
||||
function findSymbols(source) {
|
||||
var _getSymbols = (0, _getSymbols3.default)(source),
|
||||
functions = _getSymbols.functions,
|
||||
comments = _getSymbols.comments;
|
||||
|
||||
return { functions, comments };
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31047,7 +31347,13 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
* location.
|
||||
*/
|
||||
function getOutOfScopeLocations(source, position) {
|
||||
return findFunctions(source).map(getLocation).filter(loc => !(0, _helpers.containsPosition)(loc, position)).reduce(removeOverlaps, []).sort(sortByStart);
|
||||
var _findSymbols = findSymbols(source),
|
||||
functions = _findSymbols.functions,
|
||||
comments = _findSymbols.comments;
|
||||
|
||||
var commentLocations = comments.map(c => c.location);
|
||||
|
||||
return functions.map(getLocation).concat(commentLocations).filter(loc => !(0, _helpers.containsPosition)(loc, position)).reduce(removeOverlaps, []).sort(sortByStart);
|
||||
}
|
||||
|
||||
exports.default = getOutOfScopeLocations;
|
||||
|
@ -5838,6 +5838,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
/***/ 900:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const networkRequest = __webpack_require__(901);
|
||||
const workerUtils = __webpack_require__(902);
|
||||
|
||||
@ -5851,6 +5855,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
/***/ 901:
|
||||
/***/ function(module, exports) {
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function networkRequest(url, opts) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = new XMLHttpRequest();
|
||||
@ -5860,7 +5868,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
if (req.status === 200) {
|
||||
resolve({ content: req.responseText });
|
||||
} else {
|
||||
resolve(req.statusText);
|
||||
reject(req.statusText);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -5891,7 +5899,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
function WorkerDispatcher() {
|
||||
this.msgId = 1;
|
||||
this.worker = null;
|
||||
}
|
||||
} /* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
WorkerDispatcher.prototype = {
|
||||
start(url) {
|
||||
@ -5922,7 +5932,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
}
|
||||
|
||||
this.worker.removeEventListener("message", listener);
|
||||
|
||||
if (result.error) {
|
||||
reject(result.error);
|
||||
} else {
|
||||
|
@ -472,6 +472,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
/***/ 900:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const networkRequest = __webpack_require__(901);
|
||||
const workerUtils = __webpack_require__(902);
|
||||
|
||||
@ -485,6 +489,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
/***/ 901:
|
||||
/***/ function(module, exports) {
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function networkRequest(url, opts) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = new XMLHttpRequest();
|
||||
@ -494,7 +502,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
if (req.status === 200) {
|
||||
resolve({ content: req.responseText });
|
||||
} else {
|
||||
resolve(req.statusText);
|
||||
reject(req.statusText);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -525,7 +533,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
function WorkerDispatcher() {
|
||||
this.msgId = 1;
|
||||
this.worker = null;
|
||||
}
|
||||
} /* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
WorkerDispatcher.prototype = {
|
||||
start(url) {
|
||||
@ -556,7 +566,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
}
|
||||
|
||||
this.worker.removeEventListener("message", listener);
|
||||
|
||||
if (result.error) {
|
||||
reject(result.error);
|
||||
} else {
|
||||
@ -589,7 +598,31 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
|
||||
/***/ },
|
||||
|
||||
/***/ 1116:
|
||||
/***/ 1123:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var _getMatches = __webpack_require__(1173);
|
||||
|
||||
var _getMatches2 = _interopRequireDefault(_getMatches);
|
||||
|
||||
var _projectSearch = __webpack_require__(1140);
|
||||
|
||||
var _projectSearch2 = _interopRequireDefault(_projectSearch);
|
||||
|
||||
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, searchSources: _projectSearch2.default });
|
||||
|
||||
/***/ },
|
||||
|
||||
/***/ 1138:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
@ -676,7 +709,65 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
|
||||
/***/ },
|
||||
|
||||
/***/ 1123:
|
||||
/***/ 1140:
|
||||
/***/ function(module, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.searchSource = searchSource;
|
||||
exports.default = searchSources;
|
||||
|
||||
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 searchSource(source, queryText) {
|
||||
var _ref;
|
||||
|
||||
var text = source.text,
|
||||
loading = source.loading;
|
||||
|
||||
if (loading || !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({
|
||||
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;
|
||||
}
|
||||
|
||||
function searchSources(query, sources) {
|
||||
var validSources = sources.valueSeq().filter(s => s.has("text")).toJS();
|
||||
return validSources.map(source => ({
|
||||
source,
|
||||
filepath: source.url,
|
||||
matches: searchSource(source, query)
|
||||
}));
|
||||
}
|
||||
|
||||
/***/ },
|
||||
|
||||
/***/ 1173:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
@ -684,27 +775,29 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.countMatches = countMatches;
|
||||
exports.default = getMatches;
|
||||
|
||||
var _buildQuery = __webpack_require__(1116);
|
||||
var _buildQuery = __webpack_require__(1138);
|
||||
|
||||
var _buildQuery2 = _interopRequireDefault(_buildQuery);
|
||||
|
||||
var _devtoolsUtils = __webpack_require__(900);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var workerHandler = _devtoolsUtils.workerUtils.workerHandler;
|
||||
function countMatches(query, text, modifiers) {
|
||||
function getMatches(query, text, modifiers) {
|
||||
var regexQuery = (0, _buildQuery2.default)(query, modifiers, {
|
||||
isGlobal: true
|
||||
});
|
||||
var match = text.match(regexQuery);
|
||||
return match ? match.length : 0;
|
||||
var matchedLocations = [];
|
||||
var lines = text.split("\n");
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var singleMatch = void 0;
|
||||
while ((singleMatch = regexQuery.exec(lines[i])) !== null) {
|
||||
matchedLocations.push({ line: i, ch: singleMatch.index });
|
||||
}
|
||||
}
|
||||
return matchedLocations;
|
||||
}
|
||||
|
||||
self.onmessage = workerHandler({ countMatches });
|
||||
|
||||
/***/ }
|
||||
|
||||
/******/ })
|
||||
|
@ -5,7 +5,11 @@
|
||||
// initializes and it properly highlights the right location in the
|
||||
// debugger.
|
||||
|
||||
add_task(function* () {
|
||||
async function waitOnToolbox(toolbox, event) {
|
||||
return new Promise(resolve => toolbox.on(event, resolve));
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
const url = EXAMPLE_URL + "doc-script-switching.html";
|
||||
const toolbox = yield openNewTabAndToolbox(url, "webconsole");
|
||||
|
||||
@ -14,9 +18,7 @@ add_task(function* () {
|
||||
jsterm.execute("debugger");
|
||||
|
||||
// Wait for the debugger to be selected and make sure it's paused
|
||||
yield new Promise((resolve) => {
|
||||
toolbox.on("jsdebugger-selected", resolve);
|
||||
});
|
||||
yield waitOnToolbox(toolbox, "jsdebugger-selected");
|
||||
is(toolbox.threadClient.state, "paused");
|
||||
|
||||
// Create a dbg context
|
||||
|
@ -46,6 +46,8 @@ add_task(function*() {
|
||||
clickElement(dbg, "gutter", 5);
|
||||
yield waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
yield setConditionalBreakpoint(dbg, 5, "1");
|
||||
yield waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION");
|
||||
|
||||
bp = findBreakpoint(dbg, "simple2", 5);
|
||||
is(bp.condition, "1", "breakpoint is created with the condition");
|
||||
});
|
||||
|
@ -34,6 +34,7 @@ add_task(function*() {
|
||||
|
||||
yield reload(dbg, "simple1");
|
||||
yield waitForSelectedSource(dbg);
|
||||
yield waitForDispatch(dbg, "SYNC_BREAKPOINT", 2);
|
||||
assertEditorBreakpoint(dbg, 4);
|
||||
assertEditorBreakpoint(dbg, 5);
|
||||
});
|
||||
|
@ -29,11 +29,18 @@ function enableBreakpoint(dbg, index) {
|
||||
});
|
||||
}
|
||||
|
||||
function toggleBreakpoints(dbg) {
|
||||
return Task.spawn(function*() {
|
||||
clickElement(dbg, "toggleBreakpoints");
|
||||
yield waitForDispatch(dbg, "TOGGLE_BREAKPOINTS");
|
||||
});
|
||||
function toggleBreakpoints(dbg, count) {
|
||||
clickElement(dbg, "toggleBreakpoints");
|
||||
}
|
||||
|
||||
function disableBreakpoints(dbg, count) {
|
||||
toggleBreakpoints(dbg);
|
||||
return waitForDispatch(dbg, "DISABLE_BREAKPOINT", count);
|
||||
}
|
||||
|
||||
function enableBreakpoints(dbg, count) {
|
||||
toggleBreakpoints(dbg);
|
||||
return waitForDispatch(dbg, "ENABLE_BREAKPOINT", count);
|
||||
}
|
||||
|
||||
function findBreakpoint(dbg, url, line) {
|
||||
@ -79,14 +86,14 @@ add_task(function*() {
|
||||
yield addBreakpoint(dbg, "simple2", 5);
|
||||
|
||||
// Disable all of the breakpoints
|
||||
yield toggleBreakpoints(dbg);
|
||||
yield disableBreakpoints(dbg, 2);
|
||||
let bp1 = findBreakpoint(dbg, "simple2", 3);
|
||||
let bp2 = findBreakpoint(dbg, "simple2", 5);
|
||||
is(bp1.disabled, true, "first breakpoint is disabled");
|
||||
is(bp2.disabled, true, "second breakpoint is disabled");
|
||||
|
||||
// Enable all of the breakpoints
|
||||
yield toggleBreakpoints(dbg);
|
||||
yield enableBreakpoints(dbg, 2);
|
||||
bp1 = findBreakpoint(dbg, "simple2", 3);
|
||||
bp2 = findBreakpoint(dbg, "simple2", 5);
|
||||
is(bp1.disabled, false, "first breakpoint is enabled");
|
||||
|
@ -11,7 +11,7 @@ function isElementVisible(dbg, elementName) {
|
||||
return bpLine && isVisibleWithin(cm, bpLine);
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
add_task(function*() {
|
||||
// This test runs too slowly on linux debug. I'd like to figure out
|
||||
// which is the slowest part of this and make it run faster, but to
|
||||
// fix a frequent failure allow a longer timeout.
|
||||
|
@ -4,6 +4,35 @@
|
||||
// Tests loading sourcemapped sources, setting breakpoints, and
|
||||
// stepping in them.
|
||||
|
||||
function assertBreakpointExists(dbg, source, line) {
|
||||
const { selectors: { getBreakpoint }, getState } = dbg;
|
||||
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: source.id, line }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
}
|
||||
|
||||
function assertEditorBreakpoint(dbg, line, shouldExist) {
|
||||
const exists = !!getLineEl(dbg, line).querySelector(".new-breakpoint");
|
||||
ok(
|
||||
exists === shouldExist,
|
||||
"Breakpoint " +
|
||||
(shouldExist ? "exists" : "does not exist") +
|
||||
" on line " +
|
||||
line
|
||||
);
|
||||
}
|
||||
|
||||
function getLineEl(dbg, line) {
|
||||
const lines = dbg.win.document.querySelectorAll(".CodeMirror-code > div");
|
||||
return lines[line - 1];
|
||||
}
|
||||
|
||||
function clickGutter(dbg, line) {
|
||||
clickElement(dbg, "gutter", line);
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
// NOTE: the CORS call makes the test run times inconsistent
|
||||
requestLongerTimeout(2);
|
||||
@ -13,6 +42,18 @@ add_task(function*() {
|
||||
|
||||
yield waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js");
|
||||
ok(true, "Original sources exist");
|
||||
const bundleSrc = findSource(dbg, "bundle.js");
|
||||
|
||||
yield selectSource(dbg, bundleSrc);
|
||||
|
||||
yield clickGutter(dbg, 13);
|
||||
yield waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
assertEditorBreakpoint(dbg, 13, true);
|
||||
|
||||
yield clickGutter(dbg, 13);
|
||||
yield waitForDispatch(dbg, "REMOVE_BREAKPOINT");
|
||||
is(getBreakpoints(getState()).size, 0, "No breakpoints exists");
|
||||
|
||||
const entrySrc = findSource(dbg, "entry.js");
|
||||
|
||||
yield selectSource(dbg, entrySrc);
|
||||
@ -25,18 +66,12 @@ add_task(function*() {
|
||||
// should not move anywhere.
|
||||
yield addBreakpoint(dbg, entrySrc, 13);
|
||||
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
assertBreakpointExists(dbg, entrySrc, 13);
|
||||
|
||||
// Test breaking on a breakpoint
|
||||
yield addBreakpoint(dbg, "entry.js", 15);
|
||||
is(getBreakpoints(getState()).size, 2, "Two breakpoints exist");
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: entrySrc.id, line: 15 }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
assertBreakpointExists(dbg, entrySrc, 15);
|
||||
|
||||
invokeInTab("keepMeAlive");
|
||||
yield waitForPaused(dbg);
|
||||
|
@ -24,7 +24,7 @@ add_task(function*() {
|
||||
yield addBreakpoint(dbg, mainSrc, 4);
|
||||
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4 }),
|
||||
getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4, column: 2 }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
|
||||
|
@ -136,6 +136,10 @@ sources.search.key2=CmdOrCtrl+P
|
||||
# search for searching all the source files the debugger has seen.
|
||||
sources.search.alt.key=CmdOrCtrl+O
|
||||
|
||||
# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the
|
||||
# full project text search for searching all the files the debugger has seen.
|
||||
projectTextSearch.key=CmdOrCtrl+Shift+F
|
||||
|
||||
# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger
|
||||
# does not have any sources.
|
||||
sources.noSourcesAvailable=This page has no sources
|
||||
|
@ -37,5 +37,5 @@ pref("devtools.debugger.pending-selected-location", "{}");
|
||||
pref("devtools.debugger.pending-breakpoints", "{}");
|
||||
pref("devtools.debugger.expressions", "[]");
|
||||
pref("devtools.debugger.file-search-case-sensitive", false);
|
||||
pref("devtools.debugger.file-search-whole-word", false );
|
||||
pref("devtools.debugger.file-search-whole-word", false);
|
||||
pref("devtools.debugger.file-search-regex-match", false);
|
||||
|
@ -247,8 +247,6 @@ CustomElementRegistry::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTy
|
||||
nsWeakPtr* elem = unresolved->AppendElement();
|
||||
*elem = do_GetWeakReference(aElement);
|
||||
aElement->AddStates(NS_EVENT_STATE_UNRESOLVED);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -773,7 +771,6 @@ CustomElementRegistry::Get(JSContext* aCx, const nsAString& aName,
|
||||
}
|
||||
|
||||
aRetVal.setObject(*data->mConstructor);
|
||||
return;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
|
@ -114,8 +114,6 @@ NSResultToNameAndMessage(nsresult aNSResult,
|
||||
}
|
||||
|
||||
NS_WARNING("Huh, someone is throwing non-DOM errors using the DOM module!");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -113,7 +113,6 @@ public:
|
||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent) override
|
||||
{
|
||||
NS_ASSERTION(false, "Trying to unbind a fragment from a tree");
|
||||
return;
|
||||
}
|
||||
|
||||
virtual Element* GetNameSpaceElement() override
|
||||
|
@ -1305,7 +1305,6 @@ Element::SetAttribute(const nsAString& aName,
|
||||
|
||||
aError = SetAttr(name->NamespaceID(), name->LocalName(), name->GetPrefix(),
|
||||
aValue, true);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2726,8 +2725,6 @@ Element::PreIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
|
||||
return;
|
||||
}
|
||||
RemoveFromIdTable();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2746,8 +2743,6 @@ Element::PostIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
|
||||
} else {
|
||||
ClearHasID();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EventListenerManager*
|
||||
|
@ -41,19 +41,11 @@ NodeInfo::~NodeInfo()
|
||||
NodeInfo::NodeInfo(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID,
|
||||
uint16_t aNodeType, nsIAtom* aExtraName,
|
||||
nsNodeInfoManager *aOwnerManager)
|
||||
: mDocument(aOwnerManager->GetDocument()),
|
||||
mInner(aName, aPrefix, aNamespaceID, aNodeType, aExtraName),
|
||||
mOwnerManager(aOwnerManager)
|
||||
{
|
||||
CheckValidNodeInfo(aNodeType, aName, aNamespaceID, aExtraName);
|
||||
MOZ_ASSERT(aOwnerManager, "Invalid aOwnerManager");
|
||||
|
||||
// Initialize mInner
|
||||
mInner.mName = aName;
|
||||
mInner.mPrefix = aPrefix;
|
||||
mInner.mNamespaceID = aNamespaceID;
|
||||
mInner.mNodeType = aNodeType;
|
||||
mOwnerManager = aOwnerManager;
|
||||
mInner.mExtraName = aExtraName;
|
||||
|
||||
mDocument = aOwnerManager->GetDocument();
|
||||
|
||||
// Now compute our cached members.
|
||||
|
||||
|
@ -246,28 +246,33 @@ protected:
|
||||
public:
|
||||
NodeInfoInner()
|
||||
: mName(nullptr), mPrefix(nullptr), mNamespaceID(kNameSpaceID_Unknown),
|
||||
mNodeType(0), mNameString(nullptr), mExtraName(nullptr)
|
||||
mNodeType(0), mNameString(nullptr), mExtraName(nullptr),
|
||||
mHash(0), mHashInitialized(false)
|
||||
{
|
||||
}
|
||||
NodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID,
|
||||
uint16_t aNodeType, nsIAtom* aExtraName)
|
||||
: mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
|
||||
mNodeType(aNodeType), mNameString(nullptr), mExtraName(aExtraName)
|
||||
mNodeType(aNodeType), mNameString(nullptr), mExtraName(aExtraName),
|
||||
mHash(aName->hash()), mHashInitialized(true)
|
||||
{
|
||||
}
|
||||
NodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix,
|
||||
int32_t aNamespaceID, uint16_t aNodeType)
|
||||
: mName(nullptr), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
|
||||
mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nullptr)
|
||||
mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nullptr),
|
||||
mHash(0), mHashInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> mName;
|
||||
const nsCOMPtr<nsIAtom> mName;
|
||||
nsCOMPtr<nsIAtom> mPrefix;
|
||||
int32_t mNamespaceID;
|
||||
uint16_t mNodeType; // As defined by nsIDOMNode.nodeType
|
||||
const nsAString* mNameString;
|
||||
const nsAString* const mNameString;
|
||||
nsCOMPtr<nsIAtom> mExtraName; // Only used by PIs and DocTypes
|
||||
PLHashNumber mHash;
|
||||
bool mHashInitialized;
|
||||
};
|
||||
|
||||
// nsNodeInfoManager needs to pass mInner to the hash table.
|
||||
|
@ -1303,7 +1303,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
|
||||
|
||||
AtomArray* array = GetAtomArrayValue();
|
||||
|
||||
if (!array->AppendElement(classAtom)) {
|
||||
if (!array->AppendElement(Move(classAtom))) {
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
@ -1318,7 +1318,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
|
||||
|
||||
classAtom = NS_AtomizeMainThread(Substring(start, iter));
|
||||
|
||||
if (!array->AppendElement(classAtom)) {
|
||||
if (!array->AppendElement(Move(classAtom))) {
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
@ -1330,7 +1330,6 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
|
||||
}
|
||||
|
||||
SetMiscAtomOrString(&aValue);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4895,7 +4895,6 @@ nsGlobalWindow::GetContentOuter(JSContext* aCx,
|
||||
}
|
||||
|
||||
aRetval.set(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -44,9 +44,14 @@ nsNodeInfoManager::GetNodeInfoInnerHashValue(const void *key)
|
||||
{
|
||||
MOZ_ASSERT(key, "Null key passed to NodeInfo::GetHashValue!");
|
||||
|
||||
auto *node = reinterpret_cast<const NodeInfo::NodeInfoInner*>(key);
|
||||
auto *node = const_cast<NodeInfo::NodeInfoInner*>
|
||||
(reinterpret_cast<const NodeInfo::NodeInfoInner*>(key));
|
||||
if (!node->mHashInitialized) {
|
||||
node->mHash = node->mName ? node->mName->hash() : HashString(*(node->mNameString));
|
||||
node->mHashInitialized = true;
|
||||
}
|
||||
|
||||
return node->mName ? node->mName->hash() : HashString(*(node->mNameString));
|
||||
return node->mHash;
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,7 +208,6 @@ WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
|
||||
}
|
||||
|
||||
ErrorInvalidEnum("%s: Bad pname.", funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -219,7 +219,6 @@ class WebGLImageConverter
|
||||
}
|
||||
|
||||
mSuccess = true;
|
||||
return;
|
||||
}
|
||||
|
||||
template<WebGLTexelFormat SrcFormat,
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "mozilla/TextComposition.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIAtom.h"
|
||||
@ -333,10 +334,9 @@ IMEContentObserver::InitWithEditor(nsPresContext* aPresContext,
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMRange> selDomRange;
|
||||
if (NS_SUCCEEDED(mSelection->GetRangeAt(0, getter_AddRefs(selDomRange)))) {
|
||||
nsRange* selRange = static_cast<nsRange*>(selDomRange.get());
|
||||
if (NS_WARN_IF(!selRange) || NS_WARN_IF(!selRange->GetStartContainer())) {
|
||||
auto selection = static_cast<mozilla::dom::Selection*>(mSelection.get());
|
||||
if (nsRange* selRange = selection->GetRangeAt(0)) {
|
||||
if (NS_WARN_IF(!selRange->GetStartContainer())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -345,8 +345,6 @@ HTMLFieldSetElement::UpdateValidity(bool aElementValidity)
|
||||
if (mFieldSet) {
|
||||
mFieldSet->UpdateValidity(aElementValidity);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EventStates
|
||||
|
@ -3418,7 +3418,6 @@ HTMLInputElement::Focus(ErrorResult& aError)
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(ANDROID) && !defined(XP_MACOSX)
|
||||
|
@ -494,8 +494,6 @@ HTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
|
||||
// If we get here we assume that we're loading a css file, so set the
|
||||
// type to 'text/css'
|
||||
aType.AssignLiteral("text/css");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CORSMode
|
||||
|
@ -296,10 +296,8 @@ nsHTMLDocument::TryHintCharset(nsIContentViewer* aCv,
|
||||
aCharsetSource = requestCharsetSource;
|
||||
aEncoding = WrapNotNull(requestCharset);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -836,7 +834,6 @@ nsHTMLDocument::StopDocumentLoad()
|
||||
|
||||
nsDocument::StopDocumentLoad();
|
||||
UnblockOnload(false);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -791,8 +791,6 @@ nsJSChannel::EvaluateScript()
|
||||
} else if (mIsAsync) {
|
||||
NotifyListener();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2541,7 +2541,6 @@ MediaFormatReader::SkipVideoDemuxToNextKeyFrame(TimeUnit aTimeThreshold)
|
||||
&MediaFormatReader::OnVideoSkipCompleted,
|
||||
&MediaFormatReader::OnVideoSkipFailed)
|
||||
->Track(mSkipRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1418,9 +1418,7 @@ MediaRecorder::NotifyError(nsresult aRv)
|
||||
rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Failed to dispatch the error event!!!");
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -123,7 +123,6 @@ TestOuputProtectionAPIs()
|
||||
{
|
||||
RunOutputProtectionAPITests();
|
||||
FakeDecryptor::Message("OP tests completed");
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace gmptest
|
||||
|
@ -840,7 +840,6 @@ TrackBuffersManager::CreateDemuxerforMIMEType()
|
||||
}
|
||||
#endif
|
||||
NS_WARNING("Not supported (yet)");
|
||||
return;
|
||||
}
|
||||
|
||||
// We reset the demuxer by creating a new one and initializing it.
|
||||
|
@ -103,14 +103,12 @@ public:
|
||||
if (aChannelCount != ChannelCount()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
void SetChannelCountModeValue(ChannelCountMode aMode, ErrorResult& aRv) override
|
||||
{
|
||||
if (aMode != ChannelCountMode::Explicit) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t BufferSize() const
|
||||
|
@ -58,14 +58,12 @@ void
|
||||
MediaEngineDefaultVideoSource::GetName(nsAString& aName) const
|
||||
{
|
||||
aName.AssignLiteral(u"Default Video Device");
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineDefaultVideoSource::GetUUID(nsACString& aUUID) const
|
||||
{
|
||||
aUUID.AssignLiteral("1041FCBD-3F12-4F7B-9E9B-1EC556DD5676");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -382,14 +380,12 @@ void
|
||||
MediaEngineDefaultAudioSource::GetName(nsAString& aName) const
|
||||
{
|
||||
aName.AssignLiteral(u"Default Audio Device");
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineDefaultAudioSource::GetUUID(nsACString& aUUID) const
|
||||
{
|
||||
aUUID.AssignLiteral("B7CBD7C1-53EF-42F9-8353-73F61C70C092");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -533,8 +529,6 @@ MediaEngineDefault::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
|
||||
RefPtr<MediaEngineVideoSource> newSource = new MediaEngineDefaultVideoSource();
|
||||
mVSources.AppendElement(newSource);
|
||||
aVSources->AppendElement(newSource);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -559,7 +553,6 @@ MediaEngineDefault::EnumerateAudioDevices(dom::MediaSourceEnum aMediaSource,
|
||||
mASources.AppendElement(newSource);
|
||||
aASources->AppendElement(newSource);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -61,8 +61,6 @@ MediaEngineRemoteVideoSource::Init()
|
||||
SetUUID(uniqueId);
|
||||
|
||||
mInitDone = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -99,7 +97,6 @@ MediaEngineRemoteVideoSource::Shutdown()
|
||||
|
||||
MOZ_ASSERT(mState == kReleased);
|
||||
mInitDone = false;
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -209,14 +209,12 @@ void
|
||||
MediaEngineWebRTCMicrophoneSource::GetName(nsAString& aName) const
|
||||
{
|
||||
aName.Assign(mDeviceName);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineWebRTCMicrophoneSource::GetUUID(nsACString& aUUID) const
|
||||
{
|
||||
aUUID.Assign(mDeviceUUID);
|
||||
return;
|
||||
}
|
||||
|
||||
// GetBestFitnessDistance returns the best distance the capture device can offer
|
||||
@ -942,7 +940,6 @@ MediaEngineWebRTCMicrophoneSource::Process(int channel,
|
||||
|
||||
uint32_t channels = isStereo ? 2 : 1;
|
||||
InsertInGraph<int16_t>(audio10ms, length, channels);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -53,14 +53,12 @@ void
|
||||
SpeechGrammar::GetSrc(nsString& aRetVal, ErrorResult& aRv) const
|
||||
{
|
||||
aRetVal = mSrc;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
SpeechGrammar::SetSrc(const nsAString& aArg, ErrorResult& aRv)
|
||||
{
|
||||
mSrc = aArg;
|
||||
return;
|
||||
}
|
||||
|
||||
float
|
||||
@ -74,7 +72,6 @@ void
|
||||
SpeechGrammar::SetWeight(float aArg, ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
@ -71,7 +71,6 @@ SpeechGrammarList::AddFromURI(const nsAString& aSrc,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -82,7 +81,6 @@ SpeechGrammarList::AddFromString(const nsAString& aString,
|
||||
SpeechGrammar* speechGrammar = new SpeechGrammar(mParent);
|
||||
speechGrammar->SetSrc(aString, aRv);
|
||||
mItems.AppendElement(speechGrammar);
|
||||
return;
|
||||
}
|
||||
|
||||
already_AddRefed<SpeechGrammar>
|
||||
|
@ -147,7 +147,6 @@ SpeechRecognition::SetState(FSMState state)
|
||||
{
|
||||
mCurrentState = state;
|
||||
SR_LOG("Transitioned to state %s", GetName(mCurrentState));
|
||||
return;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
@ -375,8 +374,6 @@ SpeechRecognition::Transition(SpeechEvent* aEvent)
|
||||
case STATE_COUNT:
|
||||
MOZ_CRASH("Invalid state STATE_COUNT");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -559,8 +556,6 @@ SpeechRecognition::NotifyError(SpeechEvent* aEvent)
|
||||
|
||||
bool defaultActionEnabled;
|
||||
this->DispatchEvent(aEvent->mError, &defaultActionEnabled);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************
|
||||
@ -641,8 +636,6 @@ SpeechRecognition::ProcessTestEventRequest(nsISupports* aSubject, const nsAStrin
|
||||
|
||||
// let the fake recognition service handle the request
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
already_AddRefed<SpeechGrammarList>
|
||||
@ -681,7 +674,6 @@ void
|
||||
SpeechRecognition::SetContinuous(bool aArg, ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -694,7 +686,6 @@ void
|
||||
SpeechRecognition::SetInterimResults(bool aArg)
|
||||
{
|
||||
mInterimResults = aArg;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -707,21 +698,18 @@ void
|
||||
SpeechRecognition::SetMaxAlternatives(uint32_t aArg)
|
||||
{
|
||||
mMaxAlternatives = aArg;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
SpeechRecognition::GetServiceURI(nsString& aRetVal, ErrorResult& aRv) const
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
SpeechRecognition::SetServiceURI(const nsAString& aArg, ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -997,8 +985,6 @@ SpeechRecognition::FeedAudioData(already_AddRefed<SharedBuffer> aSamples,
|
||||
event->mProvider = aProvider;
|
||||
event->mTrackRate = aTrackRate;
|
||||
NS_DispatchToMainThread(event);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const char*
|
||||
|
@ -182,8 +182,6 @@ SpeechSynthesis::AdvanceQueue()
|
||||
if (mCurrentTask) {
|
||||
mCurrentTask->SetSpeechSynthesis(this);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -658,7 +658,6 @@ nsPluginStreamListenerPeer::MakeByteRangeString(NPByteRange* aRangeList, nsACStr
|
||||
|
||||
rangeRequest = string;
|
||||
*numRequests = requestCnt;
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX: Converting the channel within nsPluginStreamListenerPeer
|
||||
|
@ -162,7 +162,6 @@ BrowserStreamParent::StreamAsFile(const char* fname)
|
||||
}
|
||||
|
||||
Unused << SendNPP_StreamAsFile(nsCString(fname));
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace plugins
|
||||
|
@ -2403,7 +2403,6 @@ PluginModuleChild::NPN_ReleaseObject(NPObject* aNPObj)
|
||||
if (doe)
|
||||
doe->mDeleted = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -213,7 +213,6 @@ GetUnitString(nsAString& unit, uint16_t unitType)
|
||||
return;
|
||||
}
|
||||
NS_NOTREACHED("Unknown unit type"); // Someone's using an SVGLength with an invalid unit?
|
||||
return;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
|
@ -295,8 +295,6 @@ SVGStyleElement::GetStyleSheetInfo(nsAString& aTitle,
|
||||
|
||||
*aIsScoped = HasAttr(kNameSpaceID_None, nsGkAtoms::scoped) &&
|
||||
OwnerDoc()->IsScopedStyleEnabled();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CORSMode
|
||||
|
@ -59,7 +59,6 @@ GetUnitString(nsAString& unit, uint16_t unitType)
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Unknown unit type");
|
||||
return;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
|
@ -63,7 +63,6 @@ GetUnitString(nsAString& unit, uint16_t unitType)
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Unknown unit type");
|
||||
return;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
|
@ -240,6 +240,19 @@ private:
|
||||
~ExternalRunnableWrapper()
|
||||
{ }
|
||||
|
||||
virtual bool
|
||||
PreDispatch(WorkerPrivate* aWorkerPrivate) override
|
||||
{
|
||||
// Silence bad assertions.
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void
|
||||
PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override
|
||||
{
|
||||
// Silence bad assertions.
|
||||
}
|
||||
|
||||
virtual bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||
{
|
||||
@ -884,7 +897,6 @@ private:
|
||||
override
|
||||
{
|
||||
aWorkerPrivate->ModifyBusyCountFromWorker(false);
|
||||
return;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
@ -1612,15 +1624,21 @@ public:
|
||||
nsresult
|
||||
Cancel() override
|
||||
{
|
||||
// First run the default cancelation code
|
||||
WorkerControlRunnable::Cancel();
|
||||
|
||||
// Attempt to cancel the inner runnable as well
|
||||
nsCOMPtr<nsICancelableRunnable> cr = do_QueryInterface(mInner);
|
||||
if (cr) {
|
||||
return cr->Cancel();
|
||||
|
||||
// If the inner runnable is not cancellable, then just do the normal
|
||||
// WorkerControlRunnable thing. This will end up calling Run().
|
||||
if (!cr) {
|
||||
WorkerControlRunnable::Cancel();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
// Otherwise call the inner runnable's Cancel() and treat this like
|
||||
// a WorkerRunnable cancel. We can't call WorkerControlRunnable::Cancel()
|
||||
// in this case since that would result in both Run() and the inner
|
||||
// Cancel() being called.
|
||||
Unused << cr->Cancel();
|
||||
return WorkerRunnable::Cancel();
|
||||
}
|
||||
};
|
||||
|
||||
@ -1628,17 +1646,36 @@ public:
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
class WorkerControlEventTarget final : public nsIEventTarget
|
||||
class WorkerEventTarget final : public nsISerialEventTarget
|
||||
{
|
||||
public:
|
||||
// The WorkerEventTarget supports different dispatch behaviors:
|
||||
//
|
||||
// * Hybrid targets will attempt to dispatch as a normal runnable,
|
||||
// but fallback to a control runnable if that fails. This is
|
||||
// often necessary for code that wants normal dispatch order, but
|
||||
// also needs to execute while the worker is shutting down (possibly
|
||||
// with a holder in place.)
|
||||
//
|
||||
// * ControlOnly targets will simply dispatch a control runnable.
|
||||
enum class Behavior : uint8_t {
|
||||
Hybrid,
|
||||
ControlOnly
|
||||
};
|
||||
|
||||
private:
|
||||
mozilla::Mutex mMutex;
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
const Behavior mBehavior;
|
||||
|
||||
~WorkerControlEventTarget() = default;
|
||||
~WorkerEventTarget() = default;
|
||||
|
||||
public:
|
||||
explicit WorkerControlEventTarget(WorkerPrivate* aWorkerPrivate)
|
||||
: mMutex("WorkerControlEventTarget")
|
||||
WorkerEventTarget(WorkerPrivate* aWorkerPrivate,
|
||||
Behavior aBehavior)
|
||||
: mMutex("WorkerEventTarget")
|
||||
, mWorkerPrivate(aWorkerPrivate)
|
||||
, mBehavior(aBehavior)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate);
|
||||
}
|
||||
@ -1647,7 +1684,7 @@ public:
|
||||
ForgetWorkerPrivate(WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate == aWorkerPrivate);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mWorkerPrivate || mWorkerPrivate == aWorkerPrivate);
|
||||
mWorkerPrivate = nullptr;
|
||||
}
|
||||
|
||||
@ -1667,8 +1704,20 @@ public:
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable(aRunnable);
|
||||
|
||||
if (mBehavior == Behavior::Hybrid) {
|
||||
RefPtr<WorkerRunnable> r =
|
||||
mWorkerPrivate->MaybeWrapAsWorkerRunnable(runnable.forget());
|
||||
if (r->Dispatch()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
runnable = r.forget();
|
||||
}
|
||||
|
||||
RefPtr<WorkerControlRunnable> r = new WrappedControlRunnable(mWorkerPrivate,
|
||||
Move(aRunnable));
|
||||
runnable.forget());
|
||||
if (!r->Dispatch()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -1704,7 +1753,8 @@ public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(WorkerControlEventTarget, nsIEventTarget)
|
||||
NS_IMPL_ISUPPORTS(WorkerEventTarget, nsIEventTarget,
|
||||
nsISerialEventTarget)
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
@ -2973,45 +3023,6 @@ WorkerPrivateParent<Derived>::MaybeWrapAsWorkerRunnable(already_AddRefed<nsIRunn
|
||||
return workerRunnable.forget();
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
already_AddRefed<nsISerialEventTarget>
|
||||
WorkerPrivateParent<Derived>::GetEventTarget()
|
||||
{
|
||||
WorkerPrivate* self = ParentAsWorkerPrivate();
|
||||
|
||||
nsCOMPtr<nsISerialEventTarget> target;
|
||||
|
||||
bool needAutoDisable = false;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (!mEventTarget) {
|
||||
mEventTarget = new EventTarget(self);
|
||||
|
||||
// If the worker is already shutting down then we want to
|
||||
// immediately disable the event target. This will cause
|
||||
// the Dispatch() method to fail, but the event target
|
||||
// will still exist.
|
||||
if (self->mStatus > Running) {
|
||||
needAutoDisable = true;
|
||||
}
|
||||
}
|
||||
|
||||
target = mEventTarget;
|
||||
}
|
||||
|
||||
// Make sure to call Disable() outside of the mutex since it
|
||||
// also internally locks a mutex.
|
||||
if (needAutoDisable) {
|
||||
mEventTarget->Disable();
|
||||
}
|
||||
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(target);
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
bool
|
||||
WorkerPrivateParent<Derived>::Start()
|
||||
@ -4425,7 +4436,10 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
|
||||
, mNumHoldersPreventingShutdownStart(0)
|
||||
, mDebuggerEventLoopLevel(0)
|
||||
, mMainThreadEventTarget(GetMainThreadEventTarget())
|
||||
, mWorkerControlEventTarget(new WorkerControlEventTarget(this))
|
||||
, mWorkerControlEventTarget(new WorkerEventTarget(this,
|
||||
WorkerEventTarget::Behavior::ControlOnly))
|
||||
, mWorkerHybridEventTarget(new WorkerEventTarget(this,
|
||||
WorkerEventTarget::Behavior::Hybrid))
|
||||
, mErrorHandlerRecursionCount(0)
|
||||
, mNextTimeoutId(1)
|
||||
, mStatus(Pending)
|
||||
@ -4488,6 +4502,12 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
|
||||
WorkerPrivate::~WorkerPrivate()
|
||||
{
|
||||
mWorkerControlEventTarget->ForgetWorkerPrivate(this);
|
||||
|
||||
// We force the hybrid event target to forget the thread when we
|
||||
// enter the Killing state, but we do it again here to be safe.
|
||||
// Its possible that we may be created and destroyed without progressing
|
||||
// to Killing via some obscure code path.
|
||||
mWorkerHybridEventTarget->ForgetWorkerPrivate(this);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -5050,7 +5070,7 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
|
||||
// After mStatus is set to Dead there can be no more
|
||||
// WorkerControlRunnables so no need to lock here.
|
||||
if (!mControlQueue.IsEmpty()) {
|
||||
WorkerControlRunnable* runnable;
|
||||
WorkerControlRunnable* runnable = nullptr;
|
||||
while (mControlQueue.Pop(runnable)) {
|
||||
runnable->Cancel();
|
||||
runnable->Release();
|
||||
@ -5071,7 +5091,7 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
|
||||
}
|
||||
|
||||
if (debuggerRunnablesPending) {
|
||||
WorkerRunnable* runnable;
|
||||
WorkerRunnable* runnable = nullptr;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
@ -5189,12 +5209,18 @@ WorkerPrivate::DispatchToMainThread(already_AddRefed<nsIRunnable> aRunnable,
|
||||
return mMainThreadEventTarget->Dispatch(runnable.forget(), aFlags);
|
||||
}
|
||||
|
||||
nsIEventTarget*
|
||||
nsISerialEventTarget*
|
||||
WorkerPrivate::ControlEventTarget()
|
||||
{
|
||||
return mWorkerControlEventTarget;
|
||||
}
|
||||
|
||||
nsISerialEventTarget*
|
||||
WorkerPrivate::HybridEventTarget()
|
||||
{
|
||||
return mWorkerHybridEventTarget;
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::InitializeGCTimers()
|
||||
{
|
||||
@ -5520,7 +5546,7 @@ void
|
||||
WorkerPrivate::ClearDebuggerEventQueue()
|
||||
{
|
||||
while (!mDebuggerQueue.IsEmpty()) {
|
||||
WorkerRunnable* runnable;
|
||||
WorkerRunnable* runnable = nullptr;
|
||||
mDebuggerQueue.Pop(runnable);
|
||||
// It should be ok to simply release the runnable, without running it.
|
||||
runnable->Release();
|
||||
@ -6070,7 +6096,7 @@ WorkerPrivate::EnterDebuggerEventLoop()
|
||||
// Start the periodic GC timer if it is not already running.
|
||||
SetGCTimerMode(PeriodicTimer);
|
||||
|
||||
WorkerRunnable* runnable;
|
||||
WorkerRunnable* runnable = nullptr;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
@ -6158,16 +6184,11 @@ WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus)
|
||||
Close();
|
||||
}
|
||||
|
||||
eventTarget = mEventTarget;
|
||||
}
|
||||
|
||||
// Disable the event target, if it exists.
|
||||
if (eventTarget) {
|
||||
// Since we'll no longer process events, make sure we no longer allow anyone
|
||||
// to post them. We have to do this without mMutex held, since our mutex
|
||||
// must be acquired *after* the WorkerEventTarget's mutex when they're both
|
||||
// held.
|
||||
eventTarget->Disable();
|
||||
// Make sure the hybrid event target stops dispatching runnables
|
||||
// once we reaching the killing state.
|
||||
if (aStatus == Killing) {
|
||||
mWorkerHybridEventTarget->ForgetWorkerPrivate(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (mCrossThreadDispatcher) {
|
||||
|
@ -87,7 +87,7 @@ BEGIN_WORKERS_NAMESPACE
|
||||
class AutoSyncLoopHolder;
|
||||
class SharedWorker;
|
||||
class ServiceWorkerClientInfo;
|
||||
class WorkerControlEventTarget;
|
||||
class WorkerEventTarget;
|
||||
class WorkerControlRunnable;
|
||||
class WorkerDebugger;
|
||||
class WorkerPrivate;
|
||||
@ -212,7 +212,6 @@ protected:
|
||||
mozilla::CondVar mCondVar;
|
||||
|
||||
// Protected by mMutex.
|
||||
RefPtr<EventTarget> mEventTarget;
|
||||
nsTArray<RefPtr<WorkerRunnable>> mPreStartRunnables;
|
||||
|
||||
private:
|
||||
@ -336,9 +335,6 @@ public:
|
||||
already_AddRefed<WorkerRunnable>
|
||||
MaybeWrapAsWorkerRunnable(already_AddRefed<nsIRunnable> aRunnable);
|
||||
|
||||
already_AddRefed<nsISerialEventTarget>
|
||||
GetEventTarget();
|
||||
|
||||
// May be called on any thread...
|
||||
bool
|
||||
Start();
|
||||
@ -1004,7 +1000,8 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
|
||||
uint32_t mDebuggerEventLoopLevel;
|
||||
RefPtr<ThrottledEventQueue> mMainThreadThrottledEventQueue;
|
||||
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
|
||||
RefPtr<WorkerControlEventTarget> mWorkerControlEventTarget;
|
||||
RefPtr<WorkerEventTarget> mWorkerControlEventTarget;
|
||||
RefPtr<WorkerEventTarget> mWorkerHybridEventTarget;
|
||||
|
||||
struct SyncLoopInfo
|
||||
{
|
||||
@ -1461,9 +1458,14 @@ public:
|
||||
// Get an event target that will dispatch runnables as control runnables on
|
||||
// the worker thread. Implement nsICancelableRunnable if you wish to take
|
||||
// action on cancelation.
|
||||
nsIEventTarget*
|
||||
nsISerialEventTarget*
|
||||
ControlEventTarget();
|
||||
|
||||
// Get an event target that will attempt to dispatch a normal WorkerRunnable,
|
||||
// but if that fails will then fall back to a control runnable.
|
||||
nsISerialEventTarget*
|
||||
HybridEventTarget();
|
||||
|
||||
private:
|
||||
WorkerPrivate(WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
|
@ -72,7 +72,7 @@ using mozilla::dom::cache::CacheStorage;
|
||||
using mozilla::ipc::PrincipalInfo;
|
||||
|
||||
WorkerGlobalScope::WorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
|
||||
: mSerialEventTarget(aWorkerPrivate->GetEventTarget())
|
||||
: mSerialEventTarget(aWorkerPrivate->HybridEventTarget())
|
||||
, mWindowInteractionsAllowed(0)
|
||||
, mWorkerPrivate(aWorkerPrivate)
|
||||
{
|
||||
@ -860,7 +860,7 @@ ServiceWorkerGlobalScope::OpenWindowEnabled(JSContext* aCx, JSObject* aObj)
|
||||
WorkerDebuggerGlobalScope::WorkerDebuggerGlobalScope(
|
||||
WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
, mSerialEventTarget(aWorkerPrivate->GetEventTarget())
|
||||
, mSerialEventTarget(aWorkerPrivate->HybridEventTarget())
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
|
@ -82,7 +82,6 @@ nsXBLContentSink::Init(nsIDocument* aDoc,
|
||||
void
|
||||
nsXBLContentSink::MaybeStartLayout(bool aIgnorePendingSheets)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -178,8 +178,6 @@ XMLStylesheetProcessingInstruction::GetStyleSheetInfo(nsAString& aTitle,
|
||||
// If we get here we assume that we're loading a css file, so set the
|
||||
// type to 'text/css'
|
||||
aType.AssignLiteral("text/css");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nsGenericDOMDataNode*
|
||||
|
@ -240,7 +240,6 @@ nsXMLFragmentContentSink::CloseElement(nsIContent* aContent)
|
||||
void
|
||||
nsXMLFragmentContentSink::MaybeStartLayout(bool aIgnorePendingSheets)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -434,7 +434,6 @@ RangeUpdater::SelAdjInsertText(Text& aTextNode,
|
||||
item->mEndOffset += len;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1258,7 +1258,7 @@ TextEditRules::WillOutputText(Selection* aSelection,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<Element> root = mTextEditor->GetRoot();
|
||||
Element* root = mTextEditor->GetRoot();
|
||||
if (!root) { // Don't warn it, this is possible, e.g., 997805.html
|
||||
aOutString->Truncate();
|
||||
*aHandled = true;
|
||||
|
@ -134,8 +134,6 @@ void JapaneseContextAnalysis::HandleData(const char* aBuf, uint32_t aLen)
|
||||
mLastCharOrder = order;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void JapaneseContextAnalysis::Reset()
|
||||
|
@ -236,5 +236,4 @@ void nsUniversalDetector::DataEnd()
|
||||
default:
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -75,7 +75,6 @@ EnsureSurfaceStoredRecording(DrawEventRecorderPrivate *aRecorder, SourceSurface
|
||||
userData->recorder = aRecorder;
|
||||
aSurface->AddUserData(reinterpret_cast<UserDataKey*>(aRecorder),
|
||||
userData, &RecordingSourceSurfaceUserDataFunc);
|
||||
return;
|
||||
}
|
||||
|
||||
class SourceSurfaceRecording : public SourceSurface
|
||||
|
@ -75,7 +75,6 @@ EnsureSurfaceStored(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface
|
||||
userData->recorder = aRecorder;
|
||||
aSurface->AddUserData(reinterpret_cast<UserDataKey*>(aRecorder),
|
||||
userData, &WrapAndRecordSourceSurfaceUserDataFunc);
|
||||
return;
|
||||
}
|
||||
|
||||
class SourceSurfaceWrapAndRecord : public SourceSurface
|
||||
|
@ -442,8 +442,6 @@ FindInflectionPoints(const BezierControlPoints &aControlPoints,
|
||||
*aCount = 2;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2503,7 +2503,6 @@ SplitByChar(const nsACString& str, const char delim, std::vector<nsCString>* con
|
||||
out->push_back(nsCString(substr));
|
||||
|
||||
start = end + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
nsDependentCSubstring substr(str, start);
|
||||
|
@ -942,7 +942,6 @@ GPUProcessManager::CreateContentVideoDecoderManager(base::ProcessId aOtherProces
|
||||
mGPUChild->SendNewContentVideoDecoderManager(Move(parentPipe));
|
||||
|
||||
*aOutEndpoint = Move(childPipe);
|
||||
return;
|
||||
}
|
||||
|
||||
already_AddRefed<IAPZCTreeManager>
|
||||
|
@ -572,8 +572,6 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aTransformedSubtreeRoo
|
||||
aPreviousTransformForRoot, newTransform, aFixedLayerMargins, aClipPartsCache);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1472,7 +1472,6 @@ LayerComposite::AddBlendModeEffect(EffectChain& aEffectChain)
|
||||
}
|
||||
|
||||
aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE] = new EffectBlendMode(blendMode);
|
||||
return;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -80,7 +80,6 @@ void
|
||||
WebRenderTextureHost::Unlock()
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -32,7 +32,6 @@ FindVisualAndDepth(Display* aDisplay, VisualID aVisualID,
|
||||
NS_ASSERTION(aVisualID == X11None, "VisualID not on Screen.");
|
||||
*aVisual = nullptr;
|
||||
*aDepth = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -177,6 +177,7 @@ MessageLoop::MessageLoop(Type type, nsIThread* aThread)
|
||||
exception_restoration_(false),
|
||||
state_(NULL),
|
||||
run_depth_base_(1),
|
||||
shutting_down_(false),
|
||||
#ifdef OS_WIN
|
||||
os_modal_loop_(false),
|
||||
#endif // OS_WIN
|
||||
@ -377,6 +378,9 @@ void MessageLoop::PostTask_Helper(already_AddRefed<nsIRunnable> task, int delay_
|
||||
return;
|
||||
}
|
||||
|
||||
// Tasks should only be queued before or during the Run loop, not after.
|
||||
MOZ_ASSERT(!shutting_down_);
|
||||
|
||||
#ifdef MOZ_TASK_TRACER
|
||||
nsCOMPtr<nsIRunnable> tracedTask = task;
|
||||
if (mozilla::tasktracer::IsStartLogging()) {
|
||||
@ -567,6 +571,9 @@ bool MessageLoop::DoIdleWork() {
|
||||
// MessageLoop::AutoRunState
|
||||
|
||||
MessageLoop::AutoRunState::AutoRunState(MessageLoop* loop) : loop_(loop) {
|
||||
// Top-level Run should only get called once.
|
||||
MOZ_ASSERT(!loop_->shutting_down_);
|
||||
|
||||
// Make the loop reference us.
|
||||
previous_state_ = loop_->state_;
|
||||
if (previous_state_) {
|
||||
@ -585,6 +592,9 @@ MessageLoop::AutoRunState::AutoRunState(MessageLoop* loop) : loop_(loop) {
|
||||
|
||||
MessageLoop::AutoRunState::~AutoRunState() {
|
||||
loop_->state_ = previous_state_;
|
||||
|
||||
// If exiting a top-level Run, then we're shutting down.
|
||||
loop_->shutting_down_ = !previous_state_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -112,9 +112,16 @@ public:
|
||||
// The MessageLoop takes ownership of the Task, and deletes it after it has
|
||||
// been Run().
|
||||
//
|
||||
// New tasks should not be posted after the invocation of a MessageLoop's
|
||||
// Run method. Otherwise, they may fail to actually run. Callers should check
|
||||
// if the MessageLoop is processing tasks if necessary by calling
|
||||
// IsAcceptingTasks().
|
||||
//
|
||||
// NOTE: These methods may be called on any thread. The Task will be invoked
|
||||
// on the thread that executes MessageLoop::Run().
|
||||
|
||||
bool IsAcceptingTasks() const { return !shutting_down_; }
|
||||
|
||||
void PostTask(already_AddRefed<nsIRunnable> task);
|
||||
|
||||
void PostDelayedTask(already_AddRefed<nsIRunnable> task, int delay_ms);
|
||||
@ -429,6 +436,7 @@ public:
|
||||
|
||||
RunState* state_;
|
||||
int run_depth_base_;
|
||||
bool shutting_down_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Should be set to true before calling Windows APIs like TrackPopupMenu, etc
|
||||
|
@ -127,7 +127,9 @@ void CALLBACK ObjectWatcher::DoneWaiting(void* param, BOOLEAN timed_out) {
|
||||
// We rely on the locking in PostTask() to ensure that a memory barrier is
|
||||
// provided, which in turn ensures our change to did_signal can be observed
|
||||
// on the target thread.
|
||||
watch->origin_loop->PostTask(addrefedWatch.forget());
|
||||
if (watch->origin_loop->IsAcceptingTasks()) {
|
||||
watch->origin_loop->PostTask(addrefedWatch.forget());
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectWatcher::WillDestroyCurrentMessageLoop() {
|
||||
|
@ -135,11 +135,9 @@ CrossProcessSemaphore::Wait(const Maybe<TimeDuration>& aWaitTime)
|
||||
ts.tv_nsec %= kNsPerSec;
|
||||
|
||||
while ((ret = sem_timedwait(mSemaphore, &ts)) == -1 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
while ((ret = sem_wait(mSemaphore)) == -1 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return ret == 0;
|
||||
|
@ -56,7 +56,7 @@ private:
|
||||
IGlobalInterfaceTable* ObtainGit();
|
||||
|
||||
private:
|
||||
REFIID mIid;
|
||||
IID mIid;
|
||||
RefPtr<IAgileReference> mAgileRef;
|
||||
DWORD mGitCookie;
|
||||
};
|
||||
|
@ -194,7 +194,6 @@ js::Nursery::enable()
|
||||
#endif
|
||||
|
||||
MOZ_ALWAYS_TRUE(runtime()->gc.storeBuffer().enable());
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -900,7 +900,6 @@ class BackReferenceNode : public SeqRegExpNode
|
||||
RegExpCompiler* compiler,
|
||||
int characters_filled_in,
|
||||
bool not_at_start) {
|
||||
return;
|
||||
}
|
||||
virtual bool FillInBMInfo(int offset,
|
||||
int budget,
|
||||
|
@ -292,6 +292,42 @@ BaselineCacheIRCompiler::emitGuardCompartment()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCacheIRCompiler::emitGuardAnyClass()
|
||||
{
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
AutoScratchRegister scratch(allocator, masm);
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
Address testAddr(stubAddress(reader.stubOffset()));
|
||||
|
||||
masm.loadObjGroup(obj, scratch);
|
||||
masm.loadPtr(Address(scratch, ObjectGroup::offsetOfClasp()), scratch);
|
||||
masm.branchPtr(Assembler::NotEqual, testAddr, scratch, failure->label());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCacheIRCompiler::emitGuardHasProxyHandler()
|
||||
{
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
AutoScratchRegister scratch(allocator, masm);
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
Address testAddr(stubAddress(reader.stubOffset()));
|
||||
masm.loadPtr(testAddr, scratch);
|
||||
|
||||
Address handlerAddr(obj, ProxyObject::offsetOfHandler());
|
||||
masm.branchPtr(Assembler::NotEqual, handlerAddr, scratch, failure->label());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCacheIRCompiler::emitGuardSpecificObject()
|
||||
{
|
||||
@ -367,6 +403,54 @@ BaselineCacheIRCompiler::emitGuardSpecificSymbol()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCacheIRCompiler::emitGuardXrayExpandoShapeAndDefaultProto()
|
||||
{
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
bool hasExpando = reader.readBool();
|
||||
Address shapeWrapperAddress(stubAddress(reader.stubOffset()));
|
||||
|
||||
AutoScratchRegister scratch(allocator, masm);
|
||||
Maybe<AutoScratchRegister> scratch2;
|
||||
if (hasExpando)
|
||||
scratch2.emplace(allocator, masm);
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), scratch);
|
||||
Address holderAddress(scratch, sizeof(Value) * GetXrayJitInfo()->xrayHolderSlot);
|
||||
Address expandoAddress(scratch, NativeObject::getFixedSlotOffset(GetXrayJitInfo()->holderExpandoSlot));
|
||||
|
||||
if (hasExpando) {
|
||||
masm.branchTestObject(Assembler::NotEqual, holderAddress, failure->label());
|
||||
masm.unboxObject(holderAddress, scratch);
|
||||
masm.branchTestObject(Assembler::NotEqual, expandoAddress, failure->label());
|
||||
masm.unboxObject(expandoAddress, scratch);
|
||||
|
||||
// Unwrap the expando before checking its shape.
|
||||
masm.loadPtr(Address(scratch, ProxyObject::offsetOfReservedSlots()), scratch);
|
||||
masm.unboxObject(Address(scratch, detail::ProxyReservedSlots::offsetOfPrivateSlot()), scratch);
|
||||
|
||||
masm.loadPtr(shapeWrapperAddress, scratch2.ref());
|
||||
LoadShapeWrapperContents(masm, scratch2.ref(), scratch2.ref(), failure->label());
|
||||
masm.branchTestObjShape(Assembler::NotEqual, scratch, scratch2.ref(), failure->label());
|
||||
|
||||
// The reserved slots on the expando should all be in fixed slots.
|
||||
Address protoAddress(scratch, NativeObject::getFixedSlotOffset(GetXrayJitInfo()->expandoProtoSlot));
|
||||
masm.branchTestUndefined(Assembler::NotEqual, protoAddress, failure->label());
|
||||
} else {
|
||||
Label done;
|
||||
masm.branchTestObject(Assembler::NotEqual, holderAddress, &done);
|
||||
masm.unboxObject(holderAddress, scratch);
|
||||
masm.branchTestObject(Assembler::Equal, expandoAddress, failure->label());
|
||||
masm.bind(&done);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCacheIRCompiler::emitLoadFixedSlotResult()
|
||||
{
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "vm/SelfHosting.h"
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
#include "vm/EnvironmentObject-inl.h"
|
||||
#include "vm/UnboxedObject-inl.h"
|
||||
|
||||
@ -177,6 +178,8 @@ GetPropIRGenerator::tryAttachStub()
|
||||
return true;
|
||||
if (tryAttachCrossCompartmentWrapper(obj, objId, id))
|
||||
return true;
|
||||
if (tryAttachXrayCrossCompartmentWrapper(obj, objId, id))
|
||||
return true;
|
||||
if (tryAttachFunction(obj, objId, id))
|
||||
return true;
|
||||
if (tryAttachProxy(obj, objId, id))
|
||||
@ -752,7 +755,7 @@ GetPropIRGenerator::tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperan
|
||||
|
||||
maybeEmitIdGuard(id);
|
||||
writer.guardIsProxy(objId);
|
||||
writer.guardIsCrossCompartmentWrapper(objId);
|
||||
writer.guardHasProxyHandler(objId, Wrapper::wrapperHandler(obj));
|
||||
|
||||
// Load the object wrapped by the CCW
|
||||
ObjOperandId wrapperTargetId = writer.loadWrapperTarget(objId);
|
||||
@ -776,6 +779,114 @@ GetPropIRGenerator::tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperan
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetXrayExpandoShapeWrapper(JSContext* cx, HandleObject xray, MutableHandleObject wrapper)
|
||||
{
|
||||
Value v = GetProxyReservedSlot(xray, GetXrayJitInfo()->xrayHolderSlot);
|
||||
if (v.isObject()) {
|
||||
NativeObject* holder = &v.toObject().as<NativeObject>();
|
||||
v = holder->getFixedSlot(GetXrayJitInfo()->holderExpandoSlot);
|
||||
if (v.isObject()) {
|
||||
RootedNativeObject expando(cx, &UncheckedUnwrap(&v.toObject())->as<NativeObject>());
|
||||
wrapper.set(NewWrapperWithObjectShape(cx, expando));
|
||||
return wrapper != nullptr;
|
||||
}
|
||||
}
|
||||
wrapper.set(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropIRGenerator::tryAttachXrayCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id)
|
||||
{
|
||||
if (!IsProxy(obj))
|
||||
return false;
|
||||
|
||||
XrayJitInfo* info = GetXrayJitInfo();
|
||||
if (!info || !info->isCrossCompartmentXray(GetProxyHandler(obj)))
|
||||
return false;
|
||||
|
||||
if (!info->globalHasExclusiveExpandos(cx_->global()))
|
||||
return false;
|
||||
|
||||
RootedObject target(cx_, UncheckedUnwrap(obj));
|
||||
|
||||
RootedObject expandoShapeWrapper(cx_);
|
||||
if (!GetXrayExpandoShapeWrapper(cx_, obj, &expandoShapeWrapper)) {
|
||||
cx_->recoverFromOutOfMemory();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Look for a getter we can call on the xray or its prototype chain.
|
||||
Rooted<PropertyDescriptor> desc(cx_);
|
||||
RootedObject holder(cx_, obj);
|
||||
AutoObjectVector prototypes(cx_);
|
||||
AutoObjectVector prototypeExpandoShapeWrappers(cx_);
|
||||
while (true) {
|
||||
if (!GetOwnPropertyDescriptor(cx_, holder, id, &desc)) {
|
||||
cx_->clearPendingException();
|
||||
return false;
|
||||
}
|
||||
if (desc.object())
|
||||
break;
|
||||
if (!GetPrototype(cx_, holder, &holder)) {
|
||||
cx_->clearPendingException();
|
||||
return false;
|
||||
}
|
||||
if (!holder || !IsProxy(holder) || !info->isCrossCompartmentXray(GetProxyHandler(holder)))
|
||||
return false;
|
||||
RootedObject prototypeExpandoShapeWrapper(cx_);
|
||||
if (!GetXrayExpandoShapeWrapper(cx_, holder, &prototypeExpandoShapeWrapper) ||
|
||||
!prototypes.append(holder) ||
|
||||
!prototypeExpandoShapeWrappers.append(prototypeExpandoShapeWrapper))
|
||||
{
|
||||
cx_->recoverFromOutOfMemory();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!desc.isAccessorDescriptor())
|
||||
return false;
|
||||
|
||||
RootedObject getter(cx_, desc.getterObject());
|
||||
if (!getter || !getter->is<JSFunction>() || !getter->as<JSFunction>().isNative())
|
||||
return false;
|
||||
|
||||
maybeEmitIdGuard(id);
|
||||
writer.guardIsProxy(objId);
|
||||
writer.guardHasProxyHandler(objId, GetProxyHandler(obj));
|
||||
|
||||
// Load the object wrapped by the CCW
|
||||
ObjOperandId wrapperTargetId = writer.loadWrapperTarget(objId);
|
||||
|
||||
// Test the wrapped object's class. The properties held by xrays or their
|
||||
// prototypes will be invariant for objects of a given class, except for
|
||||
// changes due to xray expandos or xray prototype mutations.
|
||||
writer.guardAnyClass(wrapperTargetId, target->getClass());
|
||||
|
||||
// Make sure the expandos on the xray and its prototype chain match up with
|
||||
// what we expect. The expando shape needs to be consistent, to ensure it
|
||||
// has not had any shadowing properties added, and the expando cannot have
|
||||
// any custom prototype (xray prototypes are stable otherwise).
|
||||
//
|
||||
// We can only do this for xrays with exclusive access to their expandos
|
||||
// (as we checked earlier), which store a pointer to their expando
|
||||
// directly. Xrays in other compartments may share their expandos with each
|
||||
// other and a VM call is needed just to find the expando.
|
||||
writer.guardXrayExpandoShapeAndDefaultProto(objId, expandoShapeWrapper);
|
||||
for (size_t i = 0; i < prototypes.length(); i++) {
|
||||
JSObject* proto = prototypes[i];
|
||||
ObjOperandId protoId = writer.loadObject(proto);
|
||||
writer.guardXrayExpandoShapeAndDefaultProto(protoId, prototypeExpandoShapeWrappers[i]);
|
||||
}
|
||||
|
||||
writer.callNativeGetterResult(objId, &getter->as<JSFunction>());
|
||||
writer.typeMonitorResult();
|
||||
|
||||
trackAttached("XrayGetter");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropIRGenerator::tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
bool handleDOMProxies)
|
||||
@ -3877,3 +3988,40 @@ CompareIRGenerator::trackNotAttached()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Class which holds a shape pointer for use when caches might reference data in other zones.
|
||||
static const Class shapeContainerClass = {
|
||||
"ShapeContainer",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1)
|
||||
};
|
||||
|
||||
static const size_t SHAPE_CONTAINER_SLOT = 0;
|
||||
|
||||
JSObject*
|
||||
jit::NewWrapperWithObjectShape(JSContext* cx, HandleNativeObject obj)
|
||||
{
|
||||
MOZ_ASSERT(cx->compartment() != obj->compartment());
|
||||
|
||||
RootedObject wrapper(cx);
|
||||
{
|
||||
AutoCompartment ac(cx, obj);
|
||||
wrapper = NewObjectWithClassProto(cx, &shapeContainerClass, nullptr);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
wrapper->as<NativeObject>().setSlot(SHAPE_CONTAINER_SLOT, PrivateGCThingValue(obj->lastProperty()));
|
||||
}
|
||||
if (!JS_WrapObject(cx, &wrapper))
|
||||
return nullptr;
|
||||
MOZ_ASSERT(IsWrapper(wrapper));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
void
|
||||
jit::LoadShapeWrapperContents(MacroAssembler& masm, Register obj, Register dst, Label* failure)
|
||||
{
|
||||
masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), dst);
|
||||
Address privateAddr(dst, detail::ProxyReservedSlots::offsetOfPrivateSlot());
|
||||
masm.branchTestObject(Assembler::NotEqual, privateAddr, failure);
|
||||
masm.unboxObject(privateAddr, dst);
|
||||
masm.unboxNonDouble(Address(dst, NativeObject::getFixedSlotOffset(SHAPE_CONTAINER_SLOT)), dst);
|
||||
}
|
||||
|
@ -168,11 +168,12 @@ extern const char* CacheKindNames[];
|
||||
_(GuardShape) \
|
||||
_(GuardGroup) \
|
||||
_(GuardProto) \
|
||||
_(GuardClass) \
|
||||
_(GuardClass) /* Guard an object class, per GuardClassKind */ \
|
||||
_(GuardAnyClass) /* Guard an arbitrary class for an object */ \
|
||||
_(GuardCompartment) \
|
||||
_(GuardIsNativeFunction) \
|
||||
_(GuardIsProxy) \
|
||||
_(GuardIsCrossCompartmentWrapper) \
|
||||
_(GuardHasProxyHandler) \
|
||||
_(GuardNotDOMProxy) \
|
||||
_(GuardSpecificObject) \
|
||||
_(GuardSpecificAtom) \
|
||||
@ -188,6 +189,8 @@ extern const char* CacheKindNames[];
|
||||
_(GuardAndGetIterator) \
|
||||
_(GuardHasGetterSetter) \
|
||||
_(GuardGroupHasUnanalyzedNewScript) \
|
||||
_(GuardIndexIsNonNegative) \
|
||||
_(GuardXrayExpandoShapeAndDefaultProto) \
|
||||
_(LoadStackValue) \
|
||||
_(LoadObject) \
|
||||
_(LoadProto) \
|
||||
@ -349,6 +352,14 @@ enum class GuardClassKind : uint8_t
|
||||
JSFunction,
|
||||
};
|
||||
|
||||
// Some ops refer to shapes that might be in other zones. Instead of putting
|
||||
// cross-zone pointers in the caches themselves (which would complicate tracing
|
||||
// enormously), these ops instead contain wrappers for objects in the target
|
||||
// zone, which refer to the actual shape via a reserved slot.
|
||||
JSObject* NewWrapperWithObjectShape(JSContext* cx, HandleNativeObject obj);
|
||||
|
||||
void LoadShapeWrapperContents(MacroAssembler& masm, Register obj, Register dst, Label* failure);
|
||||
|
||||
// Class to record CacheIR + some additional metadata for code generation.
|
||||
class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
|
||||
{
|
||||
@ -517,6 +528,10 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
|
||||
writeOpWithOperandId(CacheOp::GuardShape, obj);
|
||||
addStubField(uintptr_t(shape), StubField::Type::Shape);
|
||||
}
|
||||
void guardXrayExpandoShapeAndDefaultProto(ObjOperandId obj, JSObject* shapeWrapper) {
|
||||
writeOpWithOperandId(CacheOp::GuardXrayExpandoShapeAndDefaultProto, obj);
|
||||
buffer_.writeByte(uint32_t(!!shapeWrapper)); addStubField(uintptr_t(shapeWrapper), StubField::Type::JSObject);
|
||||
}
|
||||
void guardGroup(ObjOperandId obj, ObjectGroup* group) {
|
||||
writeOpWithOperandId(CacheOp::GuardGroup, obj);
|
||||
addStubField(uintptr_t(group), StubField::Type::ObjectGroup);
|
||||
@ -531,6 +546,10 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
|
||||
writeOpWithOperandId(CacheOp::GuardClass, obj);
|
||||
buffer_.writeByte(uint32_t(kind));
|
||||
}
|
||||
void guardAnyClass(ObjOperandId obj, const Class* clasp) {
|
||||
writeOpWithOperandId(CacheOp::GuardAnyClass, obj);
|
||||
addStubField(uintptr_t(clasp), StubField::Type::RawWord);
|
||||
}
|
||||
void guardIsNativeFunction(ObjOperandId obj, JSNative nativeFunc) {
|
||||
writeOpWithOperandId(CacheOp::GuardIsNativeFunction, obj);
|
||||
writePointer(JS_FUNC_TO_DATA_PTR(void*, nativeFunc));
|
||||
@ -538,8 +557,9 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
|
||||
void guardIsProxy(ObjOperandId obj) {
|
||||
writeOpWithOperandId(CacheOp::GuardIsProxy, obj);
|
||||
}
|
||||
void guardIsCrossCompartmentWrapper(ObjOperandId obj) {
|
||||
writeOpWithOperandId(CacheOp::GuardIsCrossCompartmentWrapper, obj);
|
||||
void guardHasProxyHandler(ObjOperandId obj, const void* handler) {
|
||||
writeOpWithOperandId(CacheOp::GuardHasProxyHandler, obj);
|
||||
addStubField(uintptr_t(handler), StubField::Type::RawWord);
|
||||
}
|
||||
void guardNotDOMProxy(ObjOperandId obj) {
|
||||
writeOpWithOperandId(CacheOp::GuardNotDOMProxy, obj);
|
||||
@ -605,6 +625,10 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
|
||||
addStubField(uintptr_t(group), StubField::Type::ObjectGroup);
|
||||
}
|
||||
|
||||
void guardIndexIsNonNegative(Int32OperandId index) {
|
||||
writeOpWithOperandId(CacheOp::GuardIndexIsNonNegative, index);
|
||||
}
|
||||
|
||||
void loadFrameCalleeResult() {
|
||||
writeOp(CacheOp::LoadFrameCalleeResult);
|
||||
}
|
||||
@ -1137,6 +1161,7 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator
|
||||
bool tryAttachModuleNamespace(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
bool tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
bool tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
bool tryAttachXrayCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
bool tryAttachFunction(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
|
||||
bool tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
|
@ -1435,22 +1435,6 @@ CacheIRCompiler::emitGuardIsProxy()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitGuardIsCrossCompartmentWrapper()
|
||||
{
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
AutoScratchRegister scratch(allocator, masm);
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
Address handlerAddr(obj, ProxyObject::offsetOfHandler());
|
||||
masm.branchPtr(Assembler::NotEqual, handlerAddr, ImmPtr(&CrossCompartmentWrapper::singleton),
|
||||
failure->label());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitGuardNotDOMProxy()
|
||||
{
|
||||
@ -1927,6 +1911,19 @@ CacheIRCompiler::emitLoadDenseElementResult()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitGuardIndexIsNonNegative()
|
||||
{
|
||||
Register index = allocator.useRegister(masm, reader.int32OperandId());
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
masm.branch32(Assembler::LessThan, index, Imm32(0), failure->label());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitLoadDenseElementHoleResult()
|
||||
{
|
||||
|
@ -24,7 +24,6 @@ namespace jit {
|
||||
_(GuardClass) \
|
||||
_(GuardIsNativeFunction) \
|
||||
_(GuardIsProxy) \
|
||||
_(GuardIsCrossCompartmentWrapper) \
|
||||
_(GuardNotDOMProxy) \
|
||||
_(GuardSpecificInt32Immediate) \
|
||||
_(GuardMagicValue) \
|
||||
@ -33,6 +32,7 @@ namespace jit {
|
||||
_(GuardNoDetachedTypedObjects) \
|
||||
_(GuardNoDenseElements) \
|
||||
_(GuardAndGetIndexFromString) \
|
||||
_(GuardIndexIsNonNegative) \
|
||||
_(LoadProto) \
|
||||
_(LoadEnclosingEnvironment) \
|
||||
_(LoadWrapperTarget) \
|
||||
|
@ -106,6 +106,12 @@ class MOZ_RAII IonCacheIRCompiler : public CacheIRCompiler
|
||||
JSCompartment* compartmentStubField(uint32_t offset) {
|
||||
return (JSCompartment*)readStubWord(offset, StubField::Type::RawWord);
|
||||
}
|
||||
const Class* classStubField(uintptr_t offset) {
|
||||
return (const Class*)readStubWord(offset, StubField::Type::RawWord);
|
||||
}
|
||||
const void* proxyHandlerStubField(uintptr_t offset) {
|
||||
return (const void*)readStubWord(offset, StubField::Type::RawWord);
|
||||
}
|
||||
jsid idStubField(uint32_t offset) {
|
||||
return mozilla::BitwiseCast<jsid>(readStubWord(offset, StubField::Type::Id));
|
||||
}
|
||||
@ -647,6 +653,37 @@ IonCacheIRCompiler::emitGuardCompartment()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonCacheIRCompiler::emitGuardAnyClass()
|
||||
{
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
AutoScratchRegister scratch(allocator, masm);
|
||||
|
||||
const Class* clasp = classStubField(reader.stubOffset());
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
masm.branchTestObjClass(Assembler::NotEqual, obj, scratch, clasp, failure->label());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonCacheIRCompiler::emitGuardHasProxyHandler()
|
||||
{
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
const void* handler = proxyHandlerStubField(reader.stubOffset());
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
Address handlerAddr(obj, ProxyObject::offsetOfHandler());
|
||||
masm.branchPtr(Assembler::NotEqual, handlerAddr, ImmPtr(handler), failure->label());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonCacheIRCompiler::emitGuardSpecificObject()
|
||||
{
|
||||
@ -720,6 +757,55 @@ IonCacheIRCompiler::emitGuardSpecificSymbol()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonCacheIRCompiler::emitGuardXrayExpandoShapeAndDefaultProto()
|
||||
{
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
bool hasExpando = reader.readBool();
|
||||
JSObject* shapeWrapper = objectStubField(reader.stubOffset());
|
||||
MOZ_ASSERT(hasExpando == !!shapeWrapper);
|
||||
|
||||
AutoScratchRegister scratch(allocator, masm);
|
||||
Maybe<AutoScratchRegister> scratch2;
|
||||
if (hasExpando)
|
||||
scratch2.emplace(allocator, masm);
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), scratch);
|
||||
Address holderAddress(scratch, sizeof(Value) * GetXrayJitInfo()->xrayHolderSlot);
|
||||
Address expandoAddress(scratch, NativeObject::getFixedSlotOffset(GetXrayJitInfo()->holderExpandoSlot));
|
||||
|
||||
if (hasExpando) {
|
||||
masm.branchTestObject(Assembler::NotEqual, holderAddress, failure->label());
|
||||
masm.unboxObject(holderAddress, scratch);
|
||||
masm.branchTestObject(Assembler::NotEqual, expandoAddress, failure->label());
|
||||
masm.unboxObject(expandoAddress, scratch);
|
||||
|
||||
// Unwrap the expando before checking its shape.
|
||||
masm.loadPtr(Address(scratch, ProxyObject::offsetOfReservedSlots()), scratch);
|
||||
masm.unboxObject(Address(scratch, detail::ProxyReservedSlots::offsetOfPrivateSlot()), scratch);
|
||||
|
||||
masm.movePtr(ImmGCPtr(shapeWrapper), scratch2.ref());
|
||||
LoadShapeWrapperContents(masm, scratch2.ref(), scratch2.ref(), failure->label());
|
||||
masm.branchTestObjShape(Assembler::NotEqual, scratch, scratch2.ref(), failure->label());
|
||||
|
||||
// The reserved slots on the expando should all be in fixed slots.
|
||||
Address protoAddress(scratch, NativeObject::getFixedSlotOffset(GetXrayJitInfo()->expandoProtoSlot));
|
||||
masm.branchTestUndefined(Assembler::NotEqual, protoAddress, failure->label());
|
||||
} else {
|
||||
Label done;
|
||||
masm.branchTestObject(Assembler::NotEqual, holderAddress, &done);
|
||||
masm.unboxObject(holderAddress, scratch);
|
||||
masm.branchTestObject(Assembler::Equal, expandoAddress, failure->label());
|
||||
masm.bind(&done);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonCacheIRCompiler::emitLoadFixedSlotResult()
|
||||
{
|
||||
|
@ -319,8 +319,6 @@ LIRGeneratorShared::defineSinCos(LInstructionHelper<2, Ops, Temps> *lir, MDefini
|
||||
lir->setMir(mir);
|
||||
mir->setVirtualRegister(vreg);
|
||||
add(lir);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// In LIR, we treat booleans and integers as the same low-level type (INTEGER).
|
||||
|
@ -362,7 +362,6 @@ js::jit::RegionLock::acquire(void* addr)
|
||||
uint32_t one = 1;
|
||||
while (!__atomic_compare_exchange(&spinlock, &zero, &one, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)) {
|
||||
zero = 0;
|
||||
continue;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
@ -363,7 +363,6 @@ CodeGeneratorX86Shared::visitWasmSelect(LWasmSelect* ins)
|
||||
}
|
||||
|
||||
masm.bind(&done);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1305,6 +1305,20 @@ js::GetDOMProxyShadowsCheck()
|
||||
return gDOMProxyShadowsCheck;
|
||||
}
|
||||
|
||||
static XrayJitInfo* gXrayJitInfo = nullptr;
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SetXrayJitInfo(XrayJitInfo* info)
|
||||
{
|
||||
gXrayJitInfo = info;
|
||||
}
|
||||
|
||||
XrayJitInfo*
|
||||
js::GetXrayJitInfo()
|
||||
{
|
||||
return gXrayJitInfo;
|
||||
}
|
||||
|
||||
bool
|
||||
js::detail::IdMatchesAtom(jsid id, JSAtom* atom)
|
||||
{
|
||||
|
@ -1319,6 +1319,34 @@ inline bool DOMProxyIsShadowing(DOMProxyShadowsResult result) {
|
||||
result == ShadowsViaIndirectExpando;
|
||||
}
|
||||
|
||||
// Callbacks and other information for use by the JITs when optimizing accesses
|
||||
// on xray wrappers.
|
||||
struct XrayJitInfo {
|
||||
// Test whether a proxy handler is a cross compartment xray with no
|
||||
// security checks.
|
||||
bool (*isCrossCompartmentXray)(const BaseProxyHandler* handler);
|
||||
|
||||
// Test whether xrays with a global object's compartment have expandos of
|
||||
// their own, instead of sharing them with Xrays from other compartments.
|
||||
bool (*globalHasExclusiveExpandos)(JSObject* obj);
|
||||
|
||||
// Proxy reserved slot used by xrays in sandboxes to store their holder
|
||||
// object.
|
||||
size_t xrayHolderSlot;
|
||||
|
||||
// Reserved slot used by xray holders to store the xray's expando object.
|
||||
size_t holderExpandoSlot;
|
||||
|
||||
// Reserved slot used by xray expandos to store a custom prototype.
|
||||
size_t expandoProtoSlot;
|
||||
};
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
SetXrayJitInfo(XrayJitInfo* info);
|
||||
|
||||
XrayJitInfo*
|
||||
GetXrayJitInfo();
|
||||
|
||||
/* Implemented in jsdate.cpp. */
|
||||
|
||||
/** Detect whether the internal date value is NaN. */
|
||||
|
@ -4684,8 +4684,6 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -197,9 +197,6 @@ ForOfIterator::closeThrow()
|
||||
|
||||
// Step 6.
|
||||
cx_->setPendingException(completionException);
|
||||
|
||||
// Steps 7-9 (skipped).
|
||||
return;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1488,15 +1488,9 @@ struct StackShape
|
||||
}
|
||||
|
||||
HashNumber hash() const {
|
||||
HashNumber hash = uintptr_t(base);
|
||||
|
||||
/* Accumulate from least to most random so the low bits are most random. */
|
||||
hash = mozilla::RotateLeft(hash, 4) ^ attrs;
|
||||
hash = mozilla::RotateLeft(hash, 4) ^ slot_;
|
||||
hash = mozilla::RotateLeft(hash, 4) ^ HashId(propid);
|
||||
hash = mozilla::RotateLeft(hash, 4) ^ uintptr_t(rawGetter);
|
||||
hash = mozilla::RotateLeft(hash, 4) ^ uintptr_t(rawSetter);
|
||||
return hash;
|
||||
HashNumber hash = HashId(propid);
|
||||
return mozilla::AddToHash(hash,
|
||||
mozilla::HashGeneric(base, attrs, slot_, rawGetter, rawSetter));
|
||||
}
|
||||
|
||||
// Traceable implementation.
|
||||
|
@ -3225,5 +3225,4 @@ js::unicode::AppendUpperCaseSpecialCasing(char16_t ch, char16_t* elements, size_
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("Bad character input.");
|
||||
return;
|
||||
}
|
||||
|
@ -188,8 +188,6 @@ SendCodeRangesToProfiler(const CodeSegment& cs, const Bytes& bytecode, const Met
|
||||
vtune::MarkWasm(vtune::GenerateUniqueMethodID(), name.begin(), (void*)start, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* static */ UniqueConstCodeSegment
|
||||
|
@ -111,8 +111,9 @@ this.XPCOMUtils = {
|
||||
if (interfaces) {
|
||||
for (let i = 0; i < interfaces.length; i++) {
|
||||
let iface = interfaces[i];
|
||||
if (Ci[iface]) {
|
||||
a.push(Ci[iface].name);
|
||||
let name = (iface && iface.name) || String(iface);
|
||||
if (name in Ci) {
|
||||
a.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2847,6 +2847,7 @@ XPCJSRuntime::Initialize(JSContext* cx)
|
||||
js::SetPreserveWrapperCallback(cx, PreserveWrapper);
|
||||
JS_SetAccumulateTelemetryCallback(cx, AccumulateTelemetryCallback);
|
||||
js::SetWindowProxyClass(cx, &OuterWindowProxyClass);
|
||||
js::SetXrayJitInfo(&gXrayJitInfo);
|
||||
JS::SetProcessLargeAllocationFailureCallback(OnLargeAllocationFailureCallback);
|
||||
|
||||
// The JS engine needs to keep the source code around in order to implement
|
||||
|
@ -32,6 +32,7 @@ support-files =
|
||||
!/js/xpconnect/tests/mochitest/file_expandosharing.html
|
||||
!/js/xpconnect/tests/mochitest/file_nodelists.html
|
||||
!/js/xpconnect/tests/mochitest/file_evalInSandbox.html
|
||||
!/js/xpconnect/tests/mochitest/file_xrayic.html
|
||||
|
||||
[test_APIExposer.xul]
|
||||
[test_bug361111.xul]
|
||||
@ -115,5 +116,6 @@ skip-if = os == 'win' || os == 'mac' || (os == 'linux' && !debug) # bug 1131110,
|
||||
[test_weakref.xul]
|
||||
[test_windowProxyDeadWrapper.html]
|
||||
[test_wrappers.xul]
|
||||
[test_xrayic.xul]
|
||||
[test_xrayToJS.xul]
|
||||
[test_asyncIteration.xul]
|
||||
|
76
js/xpconnect/tests/chrome/test_xrayic.xul
Normal file
76
js/xpconnect/tests/chrome/test_xrayic.xul
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1355109
|
||||
-->
|
||||
<window title="Mozilla Bug 1355109"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=758415"
|
||||
target="_blank">Mozilla Bug 758415</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
const Cu = Components.utils;
|
||||
|
||||
// Import our test JSM. We first strip the filename off
|
||||
// the chrome url, then append the jsm filename.
|
||||
var base = /.*\//.exec(window.location.href)[0];
|
||||
Cu.import(base + "file_expandosharing.jsm");
|
||||
|
||||
// Wait for all child frames to load.
|
||||
var gLoadCount = 0;
|
||||
function frameLoaded() {
|
||||
if (++gLoadCount == window.frames.length)
|
||||
go();
|
||||
}
|
||||
|
||||
function go() {
|
||||
testSandbox(1);
|
||||
testSandbox(100);
|
||||
testSandbox(1000);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function testSandbox(iterations) {
|
||||
var sandbox = new Cu.Sandbox(window);
|
||||
sandbox.iframes = document.getElementsByTagName('iframe');
|
||||
Cu.evalInSandbox(testClassName.toSource(), sandbox);
|
||||
Cu.evalInSandbox(testIC.toSource(), sandbox);
|
||||
is(Cu.evalInSandbox("testIC(" + iterations + ");", sandbox), true, "sandbox test");
|
||||
}
|
||||
|
||||
// This is in a separate function to provide a common source location for ICs.
|
||||
function testClassName(obj, expected) {
|
||||
var className = obj.className;
|
||||
if (className != expected)
|
||||
throw new Error("Got " + className + ", expected " + expected);
|
||||
}
|
||||
|
||||
function testIC(iterations) {
|
||||
for (var i = 0; i < this.iframes.length; i++) {
|
||||
var win = this.iframes[i].contentWindow;
|
||||
var spans = win.document.getElementsByTagName('span');
|
||||
for (var j = 0; j < spans.length; j++) {
|
||||
var span = spans[j];
|
||||
for (var k = 0; k < iterations; k++)
|
||||
testClassName(span, "iamaspan");
|
||||
Object.defineProperty(span, "className", { value: "what" });
|
||||
testClassName(span, "what");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
<iframe id="inlineFrame1" onload="frameLoaded();" type="content" src="http://test1.example.org/tests/js/xpconnect/tests/mochitest/file_xrayic.html" />
|
||||
<iframe id="inlineFrame2" onload="frameLoaded();" type="content" src="http://test1.example.org/tests/js/xpconnect/tests/mochitest/file_xrayic.html" />
|
||||
</window>
|
7
js/xpconnect/tests/mochitest/file_bug605167.html
Normal file
7
js/xpconnect/tests/mochitest/file_bug605167.html
Normal file
@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
parent.f = function() { return this; };
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
5
js/xpconnect/tests/mochitest/file_bug731471.html
Normal file
5
js/xpconnect/tests/mochitest/file_bug731471.html
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
1
|
||||
</body>
|
||||
</html>
|
15
js/xpconnect/tests/mochitest/file_xrayic.html
Normal file
15
js/xpconnect/tests/mochitest/file_xrayic.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript">
|
||||
function setup() {
|
||||
// Set up targets for sandbox expandos.
|
||||
window.targetDOM = [document.getElementById("hello"), document.getElementById("there")];
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="setup();">
|
||||
<span id="hello" class="iamaspan">Hello</span>
|
||||
<span id="there" class="iamaspan">There</span>
|
||||
</body>
|
||||
</html>
|
@ -9,10 +9,12 @@ support-files =
|
||||
file1_bug629227.html
|
||||
file2_bug629227.html
|
||||
file_bug505915.html
|
||||
file_bug605167.html
|
||||
file_bug650273.html
|
||||
file_bug658560.html
|
||||
file_bug706301.html
|
||||
file_bug720619.html
|
||||
file_bug731471.html
|
||||
file_bug738244.html
|
||||
file_bug760131.html
|
||||
file_bug781476.html
|
||||
@ -32,6 +34,7 @@ support-files =
|
||||
file_matches.html
|
||||
file_nodelists.html
|
||||
file_wrappers-2.html
|
||||
file_xrayic.html
|
||||
inner.html
|
||||
test1_bug629331.html
|
||||
test2_bug629331.html
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user