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

This commit is contained in:
Cosmin Sabou 2018-08-24 00:40:14 +03:00
commit 3211507dfb
1613 changed files with 134341 additions and 36735 deletions

View file

@ -48,12 +48,18 @@ tasks:
tags: tags:
$if: 'tasks_for == "hg-push"' $if: 'tasks_for == "hg-push"'
then: {createdForUser: "${ownerEmail}"} then:
createdForUser: "${ownerEmail}"
kind: decision-task
else: else:
$if: 'tasks_for == "action"' $if: 'tasks_for == "action"'
then: then:
createdForUser: '${ownerEmail}' createdForUser: '${ownerEmail}'
kind: 'action-callback' kind: 'action-callback'
else:
$if: 'tasks_for == "cron"'
then:
kind: cron-task
routes: routes:
$flatten: $flatten:

550
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -416,7 +416,7 @@ skip-if = verify
[browser_tab_drag_drop_perwindow.js] [browser_tab_drag_drop_perwindow.js]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD. # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_tab_dragdrop.js] [browser_tab_dragdrop.js]
skip-if = debug || (os == 'linux') || (os == 'mac') # Bug 1312436, Bug 1388973 skip-if = debug || (os == 'linux') || (os == 'mac') || (os == 'win' && asan) # Bug 1312436, Bug 1388973
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD. # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_tab_dragdrop2.js] [browser_tab_dragdrop2.js]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD. # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.

View file

@ -589,11 +589,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// invoked regardless, thus this should be enough. // invoked regardless, thus this should be enough.
if (this._formattingInstance != instance) if (this._formattingInstance != instance)
return; return;
let isDomainRTL = window.windowUtils.getDirectionFromText(domain); let directionality = window.windowUtils.getDirectionFromText(domain);
// In the future, for example in bug 525831, we may add a forceRTL // In the future, for example in bug 525831, we may add a forceRTL
// char just after the domain, and in such a case we should not // char just after the domain, and in such a case we should not
// scroll to the left. // scroll to the left.
if (isDomainRTL && value[preDomain.length + domain.length] != "\u200E") { if (directionality == window.windowUtils.DIRECTION_RTL &&
value[preDomain.length + domain.length] != "\u200E") {
this.inputField.scrollLeft = this.inputField.scrollLeftMax; this.inputField.scrollLeft = this.inputField.scrollLeftMax;
} }
}); });

View file

@ -239,7 +239,6 @@
} }
50% { 50% {
transform: translateX(-1232px); transform: translateX(-1232px);
fill: var(--tracking-protection-shield-color);
} }
65% { 65% {
fill: var(--tracking-protection-shield-color); fill: var(--tracking-protection-shield-color);
@ -266,7 +265,6 @@
} }
50% { 50% {
transform: scaleX(-1) translateX(-1232px); transform: scaleX(-1) translateX(-1232px);
fill: var(--tracking-protection-shield-color);
} }
65% { 65% {
fill: var(--tracking-protection-shield-color); fill: var(--tracking-protection-shield-color);

View file

@ -1,9 +1,9 @@
This is the debugger.html project output. This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html See https://github.com/devtools-html/debugger.html
Version 84 Version 85
Comparison: https://github.com/devtools-html/debugger.html/compare/release-83...release-84 Comparison: https://github.com/devtools-html/debugger.html/compare/release-84...release-85
Packages: Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.2 - babel-plugin-transform-es2015-modules-commonjs @6.26.2

File diff suppressed because one or more lines are too long

View file

@ -8,7 +8,6 @@ exports.selectSourceURL = selectSourceURL;
exports.selectSource = selectSource; exports.selectSource = selectSource;
exports.selectLocation = selectLocation; exports.selectLocation = selectLocation;
exports.selectSpecificLocation = selectSpecificLocation; exports.selectSpecificLocation = selectSpecificLocation;
exports.selectSpecificSource = selectSpecificSource;
exports.jumpToMappedLocation = jumpToMappedLocation; exports.jumpToMappedLocation = jumpToMappedLocation;
exports.jumpToMappedSelectedLocation = jumpToMappedSelectedLocation; exports.jumpToMappedSelectedLocation = jumpToMappedSelectedLocation;
@ -106,7 +105,7 @@ function selectSource(sourceId) {
const location = (0, _location.createLocation)({ const location = (0, _location.createLocation)({
sourceId sourceId
}); });
return await dispatch(selectLocation(location)); return await dispatch(selectSpecificLocation(location));
}; };
} }
/** /**
@ -196,22 +195,6 @@ function selectSpecificLocation(location) {
*/ */
function selectSpecificSource(sourceId) {
return async ({
dispatch
}) => {
const location = (0, _location.createLocation)({
sourceId
});
return await dispatch(selectSpecificLocation(location));
};
}
/**
* @memberof actions/sources
* @static
*/
function jumpToMappedLocation(location) { function jumpToMappedLocation(location) {
return async function ({ return async function ({
dispatch, dispatch,

View file

@ -366,7 +366,7 @@ async function checkServerSupportsListWorkers() {
return false; return false;
} }
const deviceFront = await (0, _frontsDevice.getDeviceFront)(debuggerClient, root); const deviceFront = await debuggerClient.mainRoot.getFront("device");
const description = await deviceFront.getDescription(); const description = await deviceFront.getDescription();
const isFennec = description.apptype === "mobile/android"; const isFennec = description.apptype === "mobile/android";

View file

@ -132,7 +132,7 @@ class Tab extends _react.PureComponent {
render() { render() {
const { const {
selectedSource, selectedSource,
selectSpecificSource, selectSource,
closeTab, closeTab,
source, source,
tabSources tabSources
@ -149,7 +149,7 @@ class Tab extends _react.PureComponent {
function handleTabClick(e) { function handleTabClick(e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
return selectSpecificSource(sourceId); return selectSource(sourceId);
} }
const className = (0, _classnames2.default)("source-tab", { const className = (0, _classnames2.default)("source-tab", {
@ -190,7 +190,7 @@ const mapStateToProps = (state, {
}; };
exports.default = (0, _reactRedux.connect)(mapStateToProps, { exports.default = (0, _reactRedux.connect)(mapStateToProps, {
selectSpecificSource: _actions2.default.selectSpecificSource, selectSource: _actions2.default.selectSource,
closeTab: _actions2.default.closeTab, closeTab: _actions2.default.closeTab,
closeTabs: _actions2.default.closeTabs, closeTabs: _actions2.default.closeTabs,
togglePrettyPrint: _actions2.default.togglePrettyPrint, togglePrettyPrint: _actions2.default.togglePrettyPrint,

View file

@ -67,11 +67,11 @@ class Tabs extends _react.PureComponent {
this.renderDropdownSource = source => { this.renderDropdownSource = source => {
const { const {
selectSpecificSource selectSource
} = this.props; } = this.props;
const filename = (0, _source.getFilename)(source); const filename = (0, _source.getFilename)(source);
const onClick = () => selectSpecificSource(source.id); const onClick = () => selectSource(source.id);
return _react2.default.createElement("li", { return _react2.default.createElement("li", {
key: source.id, key: source.id,
@ -206,7 +206,7 @@ const mapStateToProps = state => ({
}); });
exports.default = (0, _reactRedux.connect)(mapStateToProps, { exports.default = (0, _reactRedux.connect)(mapStateToProps, {
selectSpecificSource: _actions2.default.selectSpecificSource, selectSource: _actions2.default.selectSource,
moveTab: _actions2.default.moveTab, moveTab: _actions2.default.moveTab,
closeTab: _actions2.default.closeTab, closeTab: _actions2.default.closeTab,
togglePaneCollapse: _actions2.default.togglePaneCollapse, togglePaneCollapse: _actions2.default.togglePaneCollapse,

View file

@ -247,17 +247,14 @@ var _initialiseProps = function () {
this.getPath = item => { this.getPath = item => {
const path = `${item.path}/${item.name}`; const path = `${item.path}/${item.name}`;
const source = this.getSource(item);
if ((0, _sourcesTree.isDirectory)(item)) { if (!source || (0, _sourcesTree.isDirectory)(item)) {
return path; return path;
} }
const source = this.getSource(item); const blackBoxedPart = source.isBlackBoxed ? ":blackboxed" : "";
const blackBoxedPart = source && source.isBlackBoxed ? ":blackboxed" : ""; // Original and generated sources can point to the same path return `${path}/${source.id}/${blackBoxedPart}`;
// therefore necessary to distinguish as path is used as keys.
const generatedPart = source && source.sourceMapURL ? ":generated" : "";
return `${path}${blackBoxedPart}${generatedPart}`;
}; };
this.onExpand = (item, expandedState) => { this.onExpand = (item, expandedState) => {

View file

@ -21,14 +21,13 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/>. */ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
function findSource(dbg, url) { function findSource(dbg, url) {
const sources = dbg.selectors.getSources(); const sources = dbg.selectors.getSourceList();
const source = sources.find(s => (s.url || "").includes(url)); return sources.find(s => (s.url || "").includes(url));
}
if (!source) { function findSources(dbg, url) {
return; const sources = dbg.selectors.getSourceList();
} return sources.filter(s => (s.url || "").includes(url));
return source;
} }
function sendPacket(dbg, packet, callback) { function sendPacket(dbg, packet, callback) {
@ -76,6 +75,7 @@ function setupHelper(obj) {
getCM, getCM,
helpers: { helpers: {
findSource: url => findSource(dbg, url), findSource: url => findSource(dbg, url),
findSources: url => findSources(dbg, url),
evaluate: (expression, cbk) => evaluate(dbg, expression, cbk), evaluate: (expression, cbk) => evaluate(dbg, expression, cbk),
sendPacketToThread: (packet, cbk) => sendPacketToThread(dbg, packet, cbk), sendPacketToThread: (packet, cbk) => sendPacketToThread(dbg, packet, cbk),
sendPacket: (packet, cbk) => sendPacket(dbg, packet, cbk) sendPacket: (packet, cbk) => sendPacket(dbg, packet, cbk)

View file

@ -31,8 +31,13 @@ async function buildMappedScopes(source, frame, scopes, sourceMaps, client) {
return null; return null;
} }
const generatedAstBindings = (0, _buildGeneratedBindingList.buildGeneratedBindingList)(scopes, generatedAstScopes, frame.this);
const originalRanges = await (0, _rangeMetadata.loadRangeMetadata)(source, frame, originalAstScopes, sourceMaps); const originalRanges = await (0, _rangeMetadata.loadRangeMetadata)(source, frame, originalAstScopes, sourceMaps);
if (hasLineMappings(originalRanges)) {
return null;
}
const generatedAstBindings = (0, _buildGeneratedBindingList.buildGeneratedBindingList)(scopes, generatedAstScopes, frame.this);
const { const {
mappedOriginalScopes, mappedOriginalScopes,
expressionLookup expressionLookup
@ -104,6 +109,10 @@ function isReliableScope(scope) {
return totalBindings === 0 || unknownBindings / totalBindings < 0.25; return totalBindings === 0 || unknownBindings / totalBindings < 0.25;
} }
function hasLineMappings(ranges) {
return ranges.every(range => range.columnStart === 0 && range.columnEnd === Infinity);
}
function batchScopeMappings(originalAstScopes, source, sourceMaps) { function batchScopeMappings(originalAstScopes, source, sourceMaps) {
const precalculatedRanges = new Map(); const precalculatedRanges = new Map();
const precalculatedLocations = new Map(); // Explicitly dispatch all of the sourcemap requests synchronously up front so const precalculatedLocations = new Map(); // Explicitly dispatch all of the sourcemap requests synchronously up front so

View file

@ -20,7 +20,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/>. */ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
const prefsSchemaVersion = "1.0.3"; const prefsSchemaVersion = "1.0.4";
const pref = _devtoolsServices2.default.pref; const pref = _devtoolsServices2.default.pref;
if ((0, _devtoolsEnvironment.isDevelopment)()) { if ((0, _devtoolsEnvironment.isDevelopment)()) {
@ -128,5 +128,6 @@ const asyncStore = exports.asyncStore = (0, _asyncStoreHelper.asyncStoreHelper)(
if (prefs.debuggerPrefsSchemaVersion !== prefsSchemaVersion) { if (prefs.debuggerPrefsSchemaVersion !== prefsSchemaVersion) {
// clear pending Breakpoints // clear pending Breakpoints
prefs.pendingBreakpoints = {}; prefs.pendingBreakpoints = {};
prefs.tabs = [];
prefs.debuggerPrefsSchemaVersion = prefsSchemaVersion; prefs.debuggerPrefsSchemaVersion = prefsSchemaVersion;
} }

View file

@ -60,7 +60,7 @@ add_task(async function() {
]); ]);
info(`Test that you can not preview in another original file`); info(`Test that you can not preview in another original file`);
await selectSpecificSource(dbg, "output"); await selectSource(dbg, "output");
await hoverAtPos(dbg, { line: 2, ch: 16 }); await hoverAtPos(dbg, { line: 2, ch: 16 });
await assertNoTooltip(dbg); await assertNoTooltip(dbg);
}); });

View file

@ -49,7 +49,7 @@ add_task(async function() {
ok(true, "Original sources exist"); ok(true, "Original sources exist");
const bundleSrc = findSource(dbg, "bundle.js"); const bundleSrc = findSource(dbg, "bundle.js");
await selectSpecificSource(dbg, bundleSrc); await selectSource(dbg, bundleSrc);
await clickGutter(dbg, 13); await clickGutter(dbg, 13);
await waitForDispatch(dbg, "ADD_BREAKPOINT"); await waitForDispatch(dbg, "ADD_BREAKPOINT");
@ -61,7 +61,7 @@ add_task(async function() {
const entrySrc = findSource(dbg, "entry.js"); const entrySrc = findSource(dbg, "entry.js");
await selectSpecificSource(dbg, entrySrc); await selectSource(dbg, entrySrc);
ok( ok(
getCM(dbg) getCM(dbg)
.getValue() .getValue()

View file

@ -24,7 +24,7 @@ add_task(async function() {
ok(true, "Original sources exist"); ok(true, "Original sources exist");
const mainSrc = findSource(dbg, "fib.c"); const mainSrc = findSource(dbg, "fib.c");
await selectSpecificSource(dbg, mainSrc); await selectSource(dbg, mainSrc);
await addBreakpoint(dbg, "fib.c", 10); await addBreakpoint(dbg, "fib.c", 10);
resume(dbg); resume(dbg);

View file

@ -598,12 +598,6 @@ function waitForLoadedSources(dbg) {
* @static * @static
*/ */
async function selectSource(dbg, url, line) { async function selectSource(dbg, url, line) {
const source = findSource(dbg, url);
await dbg.actions.selectLocation({ sourceId: source.id, line });
return waitForSelectedSource(dbg, url);
}
async function selectSpecificSource(dbg, url, line) {
const source = findSource(dbg, url); const source = findSource(dbg, url);
await dbg.actions.selectLocation({ sourceId: source.id, line }, {keepContext: false}); await dbg.actions.selectLocation({ sourceId: source.id, line }, {keepContext: false});
return waitForSelectedSource(dbg, url); return waitForSelectedSource(dbg, url);

View file

@ -53,17 +53,18 @@ function SourceMapURLService(toolbox, sourceMapService) {
*/ */
SourceMapURLService.prototype._getLoadingPromise = function() { SourceMapURLService.prototype._getLoadingPromise = function() {
if (!this._loadingPromise) { if (!this._loadingPromise) {
let styleSheetsLoadingPromise = null; this._loadingPromise = (async () => {
this._stylesheetsFront = this._toolbox.initStyleSheetsFront(); if (this._target.isWorkerTarget) {
if (this._stylesheetsFront) { return;
}
this._stylesheetsFront = await this._target.getFront("stylesheets");
this._stylesheetsFront.on("stylesheet-added", this._onNewStyleSheet); this._stylesheetsFront.on("stylesheet-added", this._onNewStyleSheet);
styleSheetsLoadingPromise = const styleSheetsLoadingPromise =
this._stylesheetsFront.getStyleSheets().then(sheets => { this._stylesheetsFront.getStyleSheets().then(sheets => {
sheets.forEach(this._onNewStyleSheet); sheets.forEach(this._onNewStyleSheet);
}, () => { }, () => {
// Ignore any protocol-based errors. // Ignore any protocol-based errors.
}); });
}
// Start fetching the sources now. // Start fetching the sources now.
const loadingPromise = this._toolbox.threadClient.getSources().then(({sources}) => { const loadingPromise = this._toolbox.threadClient.getSources().then(({sources}) => {
@ -76,7 +77,9 @@ SourceMapURLService.prototype._getLoadingPromise = function() {
// Also ignore any protocol-based errors. // Also ignore any protocol-based errors.
}); });
this._loadingPromise = Promise.all([styleSheetsLoadingPromise, loadingPromise]); await styleSheetsLoadingPromise;
await loadingPromise;
})();
} }
return this._loadingPromise; return this._loadingPromise;
}; };

View file

@ -13,6 +13,7 @@ loader.lazyRequireGetter(this, "DebuggerClient",
"devtools/shared/client/debugger-client", true); "devtools/shared/client/debugger-client", true);
loader.lazyRequireGetter(this, "gDevTools", loader.lazyRequireGetter(this, "gDevTools",
"devtools/client/framework/devtools", true); "devtools/client/framework/devtools", true);
loader.lazyRequireGetter(this, "getFront", "devtools/shared/protocol", true);
const targets = new WeakMap(); const targets = new WeakMap();
const promiseTargets = new WeakMap(); const promiseTargets = new WeakMap();
@ -138,6 +139,9 @@ function TabTarget(tab) {
} else { } else {
this._isBrowsingContext = true; this._isBrowsingContext = true;
} }
// Cache of already created targed-scoped fronts
// [typeName:string => Front instance]
this.fronts = new Map();
} }
exports.TabTarget = TabTarget; exports.TabTarget = TabTarget;
@ -271,26 +275,21 @@ TabTarget.prototype = {
return this._form; return this._form;
}, },
// Get a promise of the root form returned by a getRoot request. This promise // Get a promise of the RootActor's form
// is cached.
get root() { get root() {
if (!this._root) { return this.client.mainRoot.rootForm;
this._root = this._getRoot();
}
return this._root;
}, },
_getRoot: function() { // Get a Front for a target-scoped actor.
return new Promise((resolve, reject) => { // i.e. an actor served by RootActor.listTabs or RootActorActor.getTab requests
this.client.mainRoot.getRoot(response => { getFront(typeName) {
if (response.error) { let front = this.fronts.get(typeName);
reject(new Error(response.error + ": " + response.message)); if (front) {
return; return front;
} }
front = getFront(this.client, typeName, this.form);
resolve(response); this.fronts.set(typeName, front);
}); return front;
});
}, },
get client() { get client() {
@ -506,7 +505,6 @@ TabTarget.prototype = {
*/ */
_setupListeners: function() { _setupListeners: function() {
this.tab.addEventListener("TabClose", this); this.tab.addEventListener("TabClose", this);
this.tab.parentNode.addEventListener("TabSelect", this);
this.tab.ownerDocument.defaultView.addEventListener("unload", this); this.tab.ownerDocument.defaultView.addEventListener("unload", this);
this.tab.addEventListener("TabRemotenessChange", this); this.tab.addEventListener("TabRemotenessChange", this);
}, },
@ -517,7 +515,6 @@ TabTarget.prototype = {
_teardownListeners: function() { _teardownListeners: function() {
this._tab.ownerDocument.defaultView.removeEventListener("unload", this); this._tab.ownerDocument.defaultView.removeEventListener("unload", this);
this._tab.removeEventListener("TabClose", this); this._tab.removeEventListener("TabClose", this);
this._tab.parentNode.removeEventListener("TabSelect", this);
this._tab.removeEventListener("TabRemotenessChange", this); this._tab.removeEventListener("TabRemotenessChange", this);
}, },
@ -599,13 +596,6 @@ TabTarget.prototype = {
case "unload": case "unload":
this.destroy(); this.destroy();
break; break;
case "TabSelect":
if (this.tab.selected) {
this.emit("visible", event);
} else {
this.emit("hidden", event);
}
break;
case "TabRemotenessChange": case "TabRemotenessChange":
this.onRemotenessChange(); this.onRemotenessChange();
break; break;
@ -650,10 +640,14 @@ TabTarget.prototype = {
return this._destroyer; return this._destroyer;
} }
this._destroyer = new Promise(resolve => { this._destroyer = new Promise(async (resolve) => {
// Before taking any action, notify listeners that destruction is imminent. // Before taking any action, notify listeners that destruction is imminent.
this.emit("close"); this.emit("close");
for (const [, front] of this.fronts) {
await front.destroy();
}
if (this._tab) { if (this._tab) {
this._teardownListeners(); this._teardownListeners();
} }

View file

@ -9,16 +9,6 @@ add_task(async function() {
await target.makeRemote(); await target.makeRemote();
is(target.tab, gBrowser.selectedTab, "Target linked to the right tab."); is(target.tab, gBrowser.selectedTab, "Target linked to the right tab.");
const hidden = once(target, "hidden");
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
await hidden;
ok(true, "Hidden event received");
const visible = once(target, "visible");
gBrowser.removeCurrentTab();
await visible;
ok(true, "Visible event received");
const willNavigate = once(target, "will-navigate"); const willNavigate = once(target, "will-navigate");
const navigate = once(target, "navigate"); const navigate = once(target, "navigate");
ContentTask.spawn(gBrowser.selectedBrowser, null, () => { ContentTask.spawn(gBrowser.selectedBrowser, null, () => {

View file

@ -92,12 +92,21 @@ function test() {
const target = await getTarget(client); const target = await getTarget(client);
await runTools(target); await runTools(target);
const rootFronts = [...client.mainRoot.fronts.values()];
// Actor fronts should be destroyed now that the toolbox has closed, but // Actor fronts should be destroyed now that the toolbox has closed, but
// look for any that remain. // look for any that remain.
for (const pool of client.__pools) { for (const pool of client.__pools) {
if (!pool.__poolMap) { if (!pool.__poolMap) {
continue; continue;
} }
// Ignore the root fronts, which are top-level pools and aren't released
// on toolbox destroy, but on client close.
if (rootFronts.includes(pool)) {
continue;
}
for (const actor of pool.__poolMap.keys()) { for (const actor of pool.__poolMap.keys()) {
// Bug 1056342: Profiler fails today because of framerate actor, but // Bug 1056342: Profiler fails today because of framerate actor, but
// this appears more complex to rework, so leave it for that bug to // this appears more complex to rework, so leave it for that bug to

View file

@ -45,10 +45,6 @@ loader.lazyRequireGetter(this, "InspectorFront",
"devtools/shared/fronts/inspector", true); "devtools/shared/fronts/inspector", true);
loader.lazyRequireGetter(this, "flags", loader.lazyRequireGetter(this, "flags",
"devtools/shared/flags"); "devtools/shared/flags");
loader.lazyRequireGetter(this, "createPerformanceFront",
"devtools/shared/fronts/performance", true);
loader.lazyRequireGetter(this, "getPreferenceFront",
"devtools/shared/fronts/preference", true);
loader.lazyRequireGetter(this, "KeyShortcuts", loader.lazyRequireGetter(this, "KeyShortcuts",
"devtools/client/shared/key-shortcuts"); "devtools/client/shared/key-shortcuts");
loader.lazyRequireGetter(this, "ZoomKeys", loader.lazyRequireGetter(this, "ZoomKeys",
@ -63,12 +59,8 @@ loader.lazyRequireGetter(this, "HUDService",
"devtools/client/webconsole/hudservice", true); "devtools/client/webconsole/hudservice", true);
loader.lazyRequireGetter(this, "viewSource", loader.lazyRequireGetter(this, "viewSource",
"devtools/client/shared/view-source"); "devtools/client/shared/view-source");
loader.lazyRequireGetter(this, "StyleSheetsFront",
"devtools/shared/fronts/stylesheets", true);
loader.lazyRequireGetter(this, "buildHarLog", loader.lazyRequireGetter(this, "buildHarLog",
"devtools/client/netmonitor/src/har/har-builder-utils", true); "devtools/client/netmonitor/src/har/har-builder-utils", true);
loader.lazyRequireGetter(this, "getKnownDeviceFront",
"devtools/shared/fronts/device", true);
loader.lazyRequireGetter(this, "NetMonitorAPI", loader.lazyRequireGetter(this, "NetMonitorAPI",
"devtools/client/netmonitor/src/api", true); "devtools/client/netmonitor/src/api", true);
loader.lazyRequireGetter(this, "sortPanelDefinitions", loader.lazyRequireGetter(this, "sortPanelDefinitions",
@ -125,7 +117,6 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId,
this._initInspector = null; this._initInspector = null;
this._inspector = null; this._inspector = null;
this._styleSheets = null;
this._netMonitorAPI = null; this._netMonitorAPI = null;
// Map of frames (id => frame-info) and currently selected frame id. // Map of frames (id => frame-info) and currently selected frame id.
@ -2220,16 +2211,7 @@ Toolbox.prototype = {
* client. See the definition of the preference actor for more information. * client. See the definition of the preference actor for more information.
*/ */
get preferenceFront() { get preferenceFront() {
if (this._preferenceFront) { return this.target.client.mainRoot.getFront("preference");
return Promise.resolve(this._preferenceFront);
}
return this.isOpen.then(() => {
return this.target.root.then(rootForm => {
const front = getPreferenceFront(this.target.client, rootForm);
this._preferenceFront = front;
return front;
});
});
}, },
// Is the disable auto-hide of pop-ups feature available in this context? // Is the disable auto-hide of pop-ups feature available in this context?
@ -2935,22 +2917,8 @@ Toolbox.prototype = {
// Destroy the profiler connection // Destroy the profiler connection
outstanding.push(this.destroyPerformance()); outstanding.push(this.destroyPerformance());
// Destroy the preference front // Reset preferences set by the toolbox
outstanding.push(this.destroyPreference()); outstanding.push(this.resetPreference());
// Destroy the style sheet front.
if (this._styleSheets) {
this._styleSheets.destroy();
this._styleSheets = null;
}
// Destroy the device front for the current client if any.
// A given DeviceFront instance can cached and shared between different panels, so
// destroying it is the responsibility of the toolbox.
const deviceFront = getKnownDeviceFront(this.target.client);
if (deviceFront) {
deviceFront.destroy();
}
// Detach the thread // Detach the thread
detachThread(this._threadClient); detachThread(this._threadClient);
@ -3104,7 +3072,7 @@ Toolbox.prototype = {
resolvePerformance = resolve; resolvePerformance = resolve;
}); });
this._performance = createPerformanceFront(this._target); this._performance = this.target.getFront("performance");
await this.performance.connect(); await this.performance.connect();
// Emit an event when connected, but don't wait on startup for this. // Emit an event when connected, but don't wait on startup for this.
@ -3135,20 +3103,9 @@ Toolbox.prototype = {
}, },
/** /**
* Return the style sheets front, creating it if necessary. If the * Reset preferences set by the toolbox.
* style sheets front is not supported by the target, returns null.
*/ */
initStyleSheetsFront: function() { async resetPreference() {
if (!this._styleSheets && this.target.hasActor("styleSheets")) {
this._styleSheets = StyleSheetsFront(this.target.client, this.target.form);
}
return this._styleSheets;
},
/**
* Destroy the preferences actor when the toolbox is unloaded.
*/
async destroyPreference() {
if (!this._preferenceFront) { if (!this._preferenceFront) {
return; return;
} }
@ -3159,7 +3116,6 @@ Toolbox.prototype = {
await this._preferenceFront.clearUserPref(DISABLE_AUTOHIDE_PREF); await this._preferenceFront.clearUserPref(DISABLE_AUTOHIDE_PREF);
} }
this._preferenceFront.destroy();
this._preferenceFront = null; this._preferenceFront = null;
}, },

View file

@ -4,7 +4,6 @@
"use strict"; "use strict";
const { PerfFront } = require("devtools/shared/fronts/perf"); const { PerfFront } = require("devtools/shared/fronts/perf");
const { getPreferenceFront } = require("devtools/shared/fronts/preference");
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter"); loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
class PerformancePanel { class PerformancePanel {
@ -32,7 +31,7 @@ class PerformancePanel {
const rootForm = await this.target.root; const rootForm = await this.target.root;
const perfFront = new PerfFront(this.target.client, rootForm); const perfFront = new PerfFront(this.target.client, rootForm);
const preferenceFront = getPreferenceFront(this.target.client, rootForm); const preferenceFront = this.target.client.mainRoot.getFront("preference");
this.isReady = true; this.isReady = true;
this.emit("ready"); this.emit("ready");

View file

@ -335,8 +335,8 @@ pref("devtools.aboutdebugging.network-locations", "[]");
#endif #endif
// Map top-level await expressions in the console // Map top-level await expressions in the console
#if defined(RELEASE_OR_BETA) #if defined(NIGHTLY_BUILD) || defined(MOZ_DEV_EDITION)
pref("devtools.debugger.features.map-await-expression", false);
#else
pref("devtools.debugger.features.map-await-expression", true); pref("devtools.debugger.features.map-await-expression", true);
#else
pref("devtools.debugger.features.map-await-expression", false);
#endif #endif

View file

@ -47,7 +47,7 @@ StyleEditorPanel.prototype = {
this.target.on("close", this.destroy); this.target.on("close", this.destroy);
this._debuggee = this._toolbox.initStyleSheetsFront(); this._debuggee = await this._target.getFront("stylesheets");
// Initialize the CSS properties database. // Initialize the CSS properties database.
const {cssProperties} = await initCssProperties(this._toolbox); const {cssProperties} = await initCssProperties(this._toolbox);

View file

@ -11,8 +11,6 @@ const {AppProjects} = require("devtools/client/webide/modules/app-projects");
const TabStore = require("devtools/client/webide/modules/tab-store"); const TabStore = require("devtools/client/webide/modules/tab-store");
const {AppValidator} = require("devtools/client/webide/modules/app-validator"); const {AppValidator} = require("devtools/client/webide/modules/app-validator");
const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager"); const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager");
const {getDeviceFront} = require("devtools/shared/fronts/device");
const {getPreferenceFront} = require("devtools/shared/fronts/preference");
const {RuntimeScanners} = require("devtools/client/webide/modules/runtimes"); const {RuntimeScanners} = require("devtools/client/webide/modules/runtimes");
const {RuntimeTypes} = require("devtools/client/webide/modules/runtime-types"); const {RuntimeTypes} = require("devtools/client/webide/modules/runtime-types");
const {NetUtil} = require("resource://gre/modules/NetUtil.jsm"); const {NetUtil} = require("resource://gre/modules/NetUtil.jsm");
@ -141,7 +139,7 @@ var AppManager = exports.AppManager = {
} }
}, },
onConnectionChanged: function() { onConnectionChanged: async function() {
console.log("Connection status changed: " + this.connection.status); console.log("Connection status changed: " + this.connection.status);
if (this.connection.status == Connection.Status.DISCONNECTED) { if (this.connection.status == Connection.Status.DISCONNECTED) {
@ -150,12 +148,21 @@ var AppManager = exports.AppManager = {
if (!this.connected) { if (!this.connected) {
this._listTabsResponse = null; this._listTabsResponse = null;
this.deviceFront = null;
this.preferenceFront = null;
} else { } else {
this.connection.client.listTabs().then((response) => { const response = await this.connection.client.listTabs();
// RootClient.getRoot request was introduced in FF59, but RootClient.getFront
// expects it to work. Override its root form with the listTabs results (which is
// an equivalent) in orfer to fix RootClient.getFront.
Object.defineProperty(this.connection.client.mainRoot, "rootForm", {
value: response
});
this._listTabsResponse = response; this._listTabsResponse = response;
this.deviceFront = await this.connection.client.mainRoot.getFront("device");
this.preferenceFront = await this.connection.client.mainRoot.getFront("preference");
this._recordRuntimeInfo(); this._recordRuntimeInfo();
this.update("runtime-global-actors"); this.update("runtime-global-actors");
});
} }
this.update("connection"); this.update("connection");
@ -509,20 +516,6 @@ var AppManager = exports.AppManager = {
return this._listTabsResponse; return this._listTabsResponse;
}, },
get deviceFront() {
if (!this._listTabsResponse) {
return null;
}
return getDeviceFront(this.connection.client, this._listTabsResponse);
},
get preferenceFront() {
if (!this._listTabsResponse) {
return null;
}
return getPreferenceFront(this.connection.client, this._listTabsResponse);
},
disconnectRuntime: function() { disconnectRuntime: function() {
if (!this.connected) { if (!this.connected) {
return Promise.resolve(); return Promise.resolve();

View file

@ -33,10 +33,13 @@
const docRuntime = getRuntimeDocument(win); const docRuntime = getRuntimeDocument(win);
win.AppManager.update("runtime-list"); win.AppManager.update("runtime-list");
const onGlobalActors = waitForUpdate(win, "runtime-global-actors");
const onRuntimeTargets = waitForUpdate(win, "runtime-targets");
connectToLocal(win, docRuntime); connectToLocal(win, docRuntime);
await onGlobalActors;
await onRuntimeTargets;
// Select main process // Select main process
await waitForUpdate(win, "runtime-targets");
SimpleTest.executeSoon(() => { SimpleTest.executeSoon(() => {
docProject.querySelectorAll("#project-panel-runtimeapps .panel-item")[0].click(); docProject.querySelectorAll("#project-panel-runtimeapps .panel-item")[0].click();
}); });

View file

@ -136,11 +136,13 @@
ok(!isStopActive(), "stop button is disabled"); ok(!isStopActive(), "stop button is disabled");
connectionsChanged = waitForConnectionChange("opened", 2); connectionsChanged = waitForConnectionChange("opened", 2);
const onGlobalActors = waitForUpdate(win, "runtime-global-actors");
const onRuntimeTargets = waitForUpdate(win, "runtime-targets");
docRuntime.querySelectorAll(".runtime-panel-item-other")[1].click(); docRuntime.querySelectorAll(".runtime-panel-item-other")[1].click();
await waitForUpdate(win, "runtime-targets");
await connectionsChanged; await connectionsChanged;
await onGlobalActors;
await onRuntimeTargets;
is(Object.keys(DebuggerServer._connections).length, 2, "Locally connected"); is(Object.keys(DebuggerServer._connections).length, 2, "Locally connected");
ok(win.AppManager.isMainProcessDebuggable(), "Main process available"); ok(win.AppManager.isMainProcessDebuggable(), "Main process available");

View file

@ -22,16 +22,14 @@ window.onload = function() {
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
const {getDeviceFront} = require("devtools/shared/fronts/device");
DebuggerServer.init(); DebuggerServer.init();
DebuggerServer.registerAllActors(); DebuggerServer.registerAllActors();
const client = new DebuggerClient(DebuggerServer.connectPipe()); const client = new DebuggerClient(DebuggerServer.connectPipe());
client.connect().then(function onConnect() { client.connect().then(function onConnect() {
client.listTabs().then(function onListTabs(response) { client.listTabs().then(function onListTabs(response) {
const d = getDeviceFront(client, response); return client.mainRoot.getFront("device");
}).then(function(d) {
let desc; let desc;
const appInfo = Services.appinfo; const appInfo = Services.appinfo;
const utils = window.windowUtils; const utils = window.windowUtils;

View file

@ -22,16 +22,14 @@ function runTests() {
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
const {getPreferenceFront} = require("devtools/shared/fronts/preference");
DebuggerServer.init(); DebuggerServer.init();
DebuggerServer.registerAllActors(); DebuggerServer.registerAllActors();
const client = new DebuggerClient(DebuggerServer.connectPipe()); const client = new DebuggerClient(DebuggerServer.connectPipe());
client.connect().then(function onConnect() { client.connect().then(function onConnect() {
client.listTabs().then(function onListTabs(response) { client.listTabs().then(function onListTabs(response) {
const p = getPreferenceFront(client, response); return client.mainRoot.getFront("preference");
}).then(function(p) {
const prefs = {}; const prefs = {};
const localPref = { const localPref = {

View file

@ -7,8 +7,6 @@
// Test the xpcshell-test debug support. Ideally we should have this test // Test the xpcshell-test debug support. Ideally we should have this test
// next to the xpcshell support code, but that's tricky... // next to the xpcshell support code, but that's tricky...
const {getDeviceFront} = require("devtools/shared/fronts/device");
add_task(async function() { add_task(async function() {
const testFile = do_get_file("xpcshell_debugging_script.js"); const testFile = do_get_file("xpcshell_debugging_script.js");
@ -23,8 +21,7 @@ add_task(async function() {
await client.connect(); await client.connect();
// Ensure that global actors are available. Just test the device actor. // Ensure that global actors are available. Just test the device actor.
const rootForm = await client.mainRoot.getRoot(); const deviceFront = await client.mainRoot.getFront("device");
const deviceFront = await getDeviceFront(client, rootForm);
const desc = await deviceFront.getDescription(); const desc = await deviceFront.getDescription();
equal(desc.geckobuildid, Services.appinfo.platformBuildID, "device actor works"); equal(desc.geckobuildid, Services.appinfo.platformBuildID, "device actor works");

View file

@ -19,7 +19,6 @@ const {
loader.lazyRequireGetter(this, "Authentication", "devtools/shared/security/auth"); loader.lazyRequireGetter(this, "Authentication", "devtools/shared/security/auth");
loader.lazyRequireGetter(this, "DebuggerSocket", "devtools/shared/security/socket", true); loader.lazyRequireGetter(this, "DebuggerSocket", "devtools/shared/security/socket", true);
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter"); loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
loader.lazyRequireGetter(this, "getDeviceFront", "devtools/shared/fronts/device", true);
loader.lazyRequireGetter(this, "WebConsoleClient", "devtools/shared/webconsole/client", true); loader.lazyRequireGetter(this, "WebConsoleClient", "devtools/shared/webconsole/client", true);
loader.lazyRequireGetter(this, "AddonClient", "devtools/shared/client/addon-client"); loader.lazyRequireGetter(this, "AddonClient", "devtools/shared/client/addon-client");
@ -204,9 +203,7 @@ DebuggerClient.prototype = {
async checkRuntimeVersion(listTabsForm) { async checkRuntimeVersion(listTabsForm) {
let incompatible = null; let incompatible = null;
// Instead of requiring to pass `listTabsForm` here, const deviceFront = await this.mainRoot.getFront("device");
// we can call getRoot() instead, but only once Firefox ESR59 is released
const deviceFront = await getDeviceFront(this, listTabsForm);
const desc = await deviceFront.getDescription(); const desc = await deviceFront.getDescription();
// 1) Check for Firefox too recent on device. // 1) Check for Firefox too recent on device.

View file

@ -6,6 +6,7 @@
const { Ci } = require("chrome"); const { Ci } = require("chrome");
const { arg, DebuggerClient } = require("devtools/shared/client/debugger-client"); const { arg, DebuggerClient } = require("devtools/shared/client/debugger-client");
loader.lazyRequireGetter(this, "getFront", "devtools/shared/protocol", true);
/** /**
* A RootClient object represents a root actor on the server. Each * A RootClient object represents a root actor on the server. Each
@ -32,6 +33,23 @@ function RootClient(client, greeting) {
this.actor = greeting.from; this.actor = greeting.from;
this.applicationType = greeting.applicationType; this.applicationType = greeting.applicationType;
this.traits = greeting.traits; this.traits = greeting.traits;
// Cache root form as this will always be the same value.
//
// Note that rootForm is overloaded by DebuggerClient.checkRuntimeVersion
// in order to support <FF59 that doesn't support getRoot request.
Object.defineProperty(this, "rootForm", {
get() {
delete this.rootForm;
this.rootForm = this._getRoot();
return this.rootForm;
},
configurable: true
});
// Cache of already created global scoped fronts
// [typeName:string => Front instance]
this.fronts = new Map();
} }
exports.RootClient = RootClient; exports.RootClient = RootClient;
@ -43,7 +61,7 @@ RootClient.prototype = {
* browser. This can replace usages of `listTabs` that only wanted the global actors * browser. This can replace usages of `listTabs` that only wanted the global actors
* and didn't actually care about tabs. * and didn't actually care about tabs.
*/ */
getRoot: DebuggerClient.requester({ type: "getRoot" }), _getRoot: DebuggerClient.requester({ type: "getRoot" }),
/** /**
* List the open tabs. * List the open tabs.
@ -259,6 +277,24 @@ RootClient.prototype = {
return this.request(packet); return this.request(packet);
}, },
/*
* This function returns a protocol.js Front for any root actor.
* i.e. the one directly served from RootActor.listTabs or getRoot.
*
* @param String typeName
* The type name used in protocol.js's spec for this actor.
*/
async getFront(typeName) {
let front = this.fronts.get(typeName);
if (front) {
return front;
}
const rootForm = await this.rootForm;
front = getFront(this._client, typeName, rootForm);
this.fronts.set(typeName, front);
return front;
},
/** /**
* Description of protocol's actors and methods. * Description of protocol's actors and methods.
* *

View file

@ -36,29 +36,4 @@ const DeviceFront = protocol.FrontClassWithSpec(deviceSpec, {
}, },
}); });
const _knownDeviceFronts = new WeakMap(); exports.DeviceFront = DeviceFront;
/**
* Retrieve the device front already created for the provided client, if available.
*/
exports.getKnownDeviceFront = function(client) {
return _knownDeviceFronts.get(client);
};
/**
* Only one DeviceFront is created for a given client, afterwards the instance is cached
* and returned immediately.
*/
exports.getDeviceFront = function(client, form) {
if (!form.deviceActor) {
return null;
}
if (_knownDeviceFronts.has(client)) {
return _knownDeviceFronts.get(client);
}
const front = new DeviceFront(client, form);
_knownDeviceFronts.set(client, front);
return front;
};

View file

@ -131,7 +131,3 @@ const PerformanceFront = FrontClassWithSpec(performanceSpec, {
}); });
exports.PerformanceFront = PerformanceFront; exports.PerformanceFront = PerformanceFront;
exports.createPerformanceFront = function createPerformanceFront(target) {
return new PerformanceFront(target.client, target.form);
};

View file

@ -14,18 +14,4 @@ const PreferenceFront = protocol.FrontClassWithSpec(preferenceSpec, {
}, },
}); });
const _knownPreferenceFronts = new WeakMap(); exports.PreferenceFront = PreferenceFront;
exports.getPreferenceFront = function(client, form) {
if (!form.preferenceActor) {
return null;
}
if (_knownPreferenceFronts.has(client)) {
return _knownPreferenceFronts.get(client);
}
const front = new PreferenceFront(client, form);
_knownPreferenceFronts.set(client, front);
return front;
};

View file

@ -1642,3 +1642,15 @@ exports.dumpProtocolSpec = function() {
return ret; return ret;
}; };
function getFront(client, typeName, form) {
const type = types.getType(typeName);
if (!type) {
throw new Error(`No spec for front type '${typeName}'.`);
}
if (!type.frontClass) {
lazyLoadFront(typeName);
}
return type.frontClass(client, form);
}
exports.getFront = getFront;

View file

@ -906,12 +906,10 @@ CopyingStructuredCloneReadCallback(JSContext* aCx,
if (aTag == SCTAG_DOM_BLOB) { if (aTag == SCTAG_DOM_BLOB) {
MOZ_ASSERT(file.mType == StructuredCloneFile::eBlob); MOZ_ASSERT(file.mType == StructuredCloneFile::eBlob);
MOZ_ASSERT(!file.mBlob->IsFile());
RefPtr<Blob> blob = file.mBlob;
MOZ_ASSERT(!blob->IsFile());
JS::Rooted<JS::Value> wrappedBlob(aCx); JS::Rooted<JS::Value> wrappedBlob(aCx);
if (NS_WARN_IF(!ToJSValue(aCx, blob, &wrappedBlob))) { if (NS_WARN_IF(!ToJSValue(aCx, file.mBlob, &wrappedBlob))) {
return nullptr; return nullptr;
} }
@ -923,6 +921,9 @@ CopyingStructuredCloneReadCallback(JSContext* aCx,
if (aTag == SCTAG_DOM_FILE) { if (aTag == SCTAG_DOM_FILE) {
MOZ_ASSERT(file.mType == StructuredCloneFile::eBlob); MOZ_ASSERT(file.mType == StructuredCloneFile::eBlob);
{
// Create a scope so ~RefPtr fires before returning an unwrapped
// JS::Value.
RefPtr<Blob> blob = file.mBlob; RefPtr<Blob> blob = file.mBlob;
MOZ_ASSERT(blob->IsFile()); MOZ_ASSERT(blob->IsFile());
@ -935,6 +936,7 @@ CopyingStructuredCloneReadCallback(JSContext* aCx,
} }
result.set(&wrappedFile.toObject()); result.set(&wrappedFile.toObject());
}
return result; return result;
} }

View file

@ -109,6 +109,8 @@
#include "CubebUtils.h" #include "CubebUtils.h"
#elif defined(XP_MACOSX) #elif defined(XP_MACOSX)
#include "mozilla/Sandbox.h" #include "mozilla/Sandbox.h"
#elif defined(__OpenBSD__)
#include <unistd.h>
#endif #endif
#endif #endif
@ -1783,6 +1785,8 @@ ContentChild::RecvSetProcessSandbox(const MaybeFileDesc& aBroker)
mozilla::SandboxTarget::Instance()->StartSandbox(); mozilla::SandboxTarget::Instance()->StartSandbox();
#elif defined(XP_MACOSX) #elif defined(XP_MACOSX)
sandboxEnabled = StartMacOSContentSandbox(); sandboxEnabled = StartMacOSContentSandbox();
#elif defined(__OpenBSD__)
sandboxEnabled = StartOpenBSDSandbox(GeckoProcessType_Content);
#endif #endif
CrashReporter::AnnotateCrashReport( CrashReporter::AnnotateCrashReport(
@ -3921,6 +3925,55 @@ ContentChild::OnMessageReceived(const Message& aMsg, Message*& aReply)
} // namespace dom } // namespace dom
#if defined(__OpenBSD__) && defined(MOZ_CONTENT_SANDBOX)
#include <unistd.h>
static LazyLogModule sPledgeLog("SandboxPledge");
bool
StartOpenBSDSandbox(GeckoProcessType type)
{
nsAutoCString promisesString;
nsAutoCString processTypeString;
switch (type) {
case GeckoProcessType_Default:
processTypeString = "main";
Preferences::GetCString("security.sandbox.pledge.main",
promisesString);
break;
case GeckoProcessType_Content:
processTypeString = "content";
Preferences::GetCString("security.sandbox.pledge.content",
promisesString);
break;
default:
MOZ_ASSERT(false, "unknown process type");
return false;
};
if (pledge(promisesString.get(), NULL) == -1) {
if (errno == EINVAL) {
MOZ_LOG(sPledgeLog, LogLevel::Error,
("pledge promises for %s process is a malformed string: '%s'\n",
processTypeString.get(), promisesString.get()));
} else if (errno == EPERM) {
MOZ_LOG(sPledgeLog, LogLevel::Error,
("pledge promises for %s process can't elevate privileges: '%s'\n",
processTypeString.get(), promisesString.get()));
}
return false;
} else {
MOZ_LOG(sPledgeLog, LogLevel::Debug,
("pledged %s process with promises: '%s'\n",
processTypeString.get(), promisesString.get()));
}
return true;
}
#endif
#if !defined(XP_WIN) #if !defined(XP_WIN)
bool IsDevelopmentBuild() bool IsDevelopmentBuild()
{ {

View file

@ -1,41 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stddef.h>
#include "mozilla/Module.h"
#include "mozilla/ModuleUtils.h"
#include "mozilla/TransactionManager.h"
#include "nsID.h"
#include "nsITransactionManager.h"
using mozilla::TransactionManager;
////////////////////////////////////////////////////////////////////////
// Define the contructor function for the objects
//
// NOTE: This creates an instance of objects by using the default constructor
//
NS_GENERIC_FACTORY_CONSTRUCTOR(TransactionManager)
NS_DEFINE_NAMED_CID(NS_TRANSACTIONMANAGER_CID);
static const mozilla::Module::CIDEntry kTxMgrCIDs[] = {
{ &kNS_TRANSACTIONMANAGER_CID, false, nullptr,
TransactionManagerConstructor },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kTxMgrContracts[] = {
{ NS_TRANSACTIONMANAGER_CONTRACTID, &kNS_TRANSACTIONMANAGER_CID },
{ nullptr }
};
static const mozilla::Module kTxMgrModule = {
mozilla::Module::kVersion,
kTxMgrCIDs,
kTxMgrContracts
};
NSMODULE_DEFN(nsTransactionManagerModule) = &kTxMgrModule;

View file

@ -26,7 +26,6 @@ EXPORTS.mozilla += [
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'TransactionItem.cpp', 'TransactionItem.cpp',
'TransactionManager.cpp', 'TransactionManager.cpp',
'TransactionManagerFactory.cpp',
'TransactionStack.cpp', 'TransactionStack.cpp',
] ]

View file

@ -160,14 +160,3 @@ interface nsITransactionManager : nsISupports
inline mozilla::TransactionManager* AsTransactionManager(); inline mozilla::TransactionManager* AsTransactionManager();
%} %}
}; };
%{ C++
#define NS_TRANSACTIONMANAGER_CONTRACTID "@mozilla.org/transactionmanager;1"
// 9C8F9601-801A-11d2-98BA-00805F297D89
#define NS_TRANSACTIONMANAGER_CID \
{ 0x9c8f9601, 0x801a, 0x11d2, \
{ 0x98, 0xba, 0x0, 0x80, 0x5f, 0x29, 0x7d, 0x89 } }
%} C++

View file

@ -8,6 +8,9 @@
#include "nsITransactionManager.h" #include "nsITransactionManager.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "mozilla/Likely.h" #include "mozilla/Likely.h"
#include "mozilla/TransactionManager.h"
using mozilla::TransactionManager;
static int32_t sConstructorCount = 0; static int32_t sConstructorCount = 0;
static int32_t sDoCount = 0; static int32_t sDoCount = 0;
@ -533,10 +536,7 @@ quick_test(TestTransactionFactory *factory)
* *
*******************************************************************/ *******************************************************************/
nsresult rv; nsCOMPtr<nsITransactionManager> mgr = new TransactionManager();
nsCOMPtr<nsITransactionManager> mgr =
do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &rv);
ASSERT_TRUE(NS_SUCCEEDED(rv));
/******************************************************************* /*******************************************************************
* *
@ -544,7 +544,7 @@ quick_test(TestTransactionFactory *factory)
* *
*******************************************************************/ *******************************************************************/
rv = mgr->DoTransaction(0); nsresult rv = mgr->DoTransaction(0);
EXPECT_EQ(rv, NS_ERROR_NULL_POINTER); EXPECT_EQ(rv, NS_ERROR_NULL_POINTER);
/******************************************************************* /*******************************************************************
@ -1285,11 +1285,7 @@ quick_batch_test(TestTransactionFactory *factory)
* *
*******************************************************************/ *******************************************************************/
nsresult rv; nsCOMPtr<nsITransactionManager> mgr = new TransactionManager();
nsCOMPtr<nsITransactionManager> mgr =
do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &rv);
ASSERT_TRUE(mgr);
ASSERT_TRUE(NS_SUCCEEDED(rv));
int32_t numitems; int32_t numitems;
@ -1300,7 +1296,7 @@ quick_batch_test(TestTransactionFactory *factory)
* *
*******************************************************************/ *******************************************************************/
rv = mgr->GetNumberOfUndoItems(&numitems); nsresult rv = mgr->GetNumberOfUndoItems(&numitems);
EXPECT_TRUE(NS_SUCCEEDED(rv)); EXPECT_TRUE(NS_SUCCEEDED(rv));
EXPECT_EQ(numitems, 0); EXPECT_EQ(numitems, 0);
@ -1920,12 +1916,9 @@ stress_test(TestTransactionFactory *factory, int32_t iterations)
* *
*******************************************************************/ *******************************************************************/
nsresult rv; nsCOMPtr<nsITransactionManager> mgr = new TransactionManager();
nsCOMPtr<nsITransactionManager> mgr =
do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &rv);
ASSERT_TRUE(NS_SUCCEEDED(rv));
ASSERT_TRUE(mgr);
nsresult rv;
int32_t i, j; int32_t i, j;
for (i = 1; i <= iterations; i++) { for (i = 1; i <= iterations; i++) {

View file

@ -1543,7 +1543,7 @@ gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet,
continue; continue;
} }
#ifdef MOZ_CONTENT_SANDBOX #if defined(MOZ_CONTENT_SANDBOX) && defined (XP_LINUX)
// Skip any fonts that will be blocked by the content-process sandbox // Skip any fonts that will be blocked by the content-process sandbox
// policy. // policy.
if (aPolicy && !(aPolicy->Lookup(reinterpret_cast<const char*>(path)) & if (aPolicy && !(aPolicy->Lookup(reinterpret_cast<const char*>(path)) &
@ -1705,7 +1705,7 @@ gfxFcPlatformFontList::InitFontListForPlatform()
UniquePtr<SandboxPolicy> policy; UniquePtr<SandboxPolicy> policy;
#ifdef MOZ_CONTENT_SANDBOX #if defined(MOZ_CONTENT_SANDBOX) && defined (XP_LINUX)
// If read sandboxing is enabled, create a temporary SandboxPolicy to // If read sandboxing is enabled, create a temporary SandboxPolicy to
// check font paths; use a fake PID to avoid picking up any PID-specific // check font paths; use a fake PID to avoid picking up any PID-specific
// rules by accident. // rules by accident.

View file

@ -340,7 +340,7 @@ public:
protected: protected:
virtual ~gfxFcPlatformFontList(); virtual ~gfxFcPlatformFontList();
#ifdef MOZ_CONTENT_SANDBOX #if defined(MOZ_CONTENT_SANDBOX) && defined(XP_LINUX)
typedef mozilla::SandboxBroker::Policy SandboxPolicy; typedef mozilla::SandboxBroker::Policy SandboxPolicy;
#else #else
// Dummy type just so we can still have a SandboxPolicy* parameter. // Dummy type just so we can still have a SandboxPolicy* parameter.

View file

@ -117,7 +117,7 @@
#elif defined(__alpha__) #elif defined(__alpha__)
#define ARCH_CPU_ALPHA 1 #define ARCH_CPU_ALPHA 1
#define ARCH_CPU_64_BITS 1 #define ARCH_CPU_64_BITS 1
#elif defined(__aarch64__) #elif defined(__aarch64__) || defined(_M_ARM64)
#define ARCH_CPU_ARM_FAMILY 1 #define ARCH_CPU_ARM_FAMILY 1
#define ARCH_CPU_ARM64 1 #define ARCH_CPU_ARM64 1
#define ARCH_CPU_64_BITS 1 #define ARCH_CPU_64_BITS 1

View file

@ -128,40 +128,6 @@ class TempAllocPolicy : public AllocPolicyBase
} }
}; };
/*
* Allocation policy that uses Zone::pod_malloc and friends, so that memory
* pressure is accounted for on the zone. This is suitable for memory associated
* with GC things allocated in the zone.
*
* Since it doesn't hold a JSContext (those may not live long enough), it can't
* report out-of-memory conditions itself; the caller must check for OOM and
* take the appropriate action.
*
* FIXME bug 647103 - replace these *AllocPolicy names.
*/
class ZoneAllocPolicy
{
JS::Zone* const zone;
public:
MOZ_IMPLICIT ZoneAllocPolicy(JS::Zone* z) : zone(z) {}
// These methods are defined in gc/Zone.h.
template <typename T> inline T* maybe_pod_malloc(size_t numElems);
template <typename T> inline T* maybe_pod_calloc(size_t numElems);
template <typename T> inline T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize);
template <typename T> inline T* pod_malloc(size_t numElems);
template <typename T> inline T* pod_calloc(size_t numElems);
template <typename T> inline T* pod_realloc(T* p, size_t oldSize, size_t newSize);
template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); }
void reportAllocOverflow() const {}
MOZ_MUST_USE bool checkSimulatedOOM() const {
return !js::oom::ShouldFailWithOOM();
}
};
} /* namespace js */ } /* namespace js */
#endif /* js_AllocPolicy_h */ #endif /* js_AllocPolicy_h */

View file

@ -26,6 +26,12 @@
// is not itself a GC pointer. // is not itself a GC pointer.
# define JS_HAZ_GC_INVALIDATED __attribute__((tag("Invalidated by GC"))) # define JS_HAZ_GC_INVALIDATED __attribute__((tag("Invalidated by GC")))
// Mark a class as a base class of rooted types, eg CustomAutoRooter. All
// descendants of this class will be considered rooted, though classes that
// merely contain these as a field member will not be. "Inherited" by
// templatized types with MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS
# define JS_HAZ_ROOTED_BASE __attribute__((tag("Rooted Base")))
// Mark a type that would otherwise be considered a GC Pointer (eg because it // Mark a type that would otherwise be considered a GC Pointer (eg because it
// contains a JS::Value field) as a non-GC pointer. It is handled almost the // contains a JS::Value field) as a non-GC pointer. It is handled almost the
// same in the analysis as a rooted pointer, except it will not be reported as // same in the analysis as a rooted pointer, except it will not be reported as
@ -52,6 +58,7 @@
# define JS_HAZ_GC_POINTER # define JS_HAZ_GC_POINTER
# define JS_HAZ_ROOTED # define JS_HAZ_ROOTED
# define JS_HAZ_GC_INVALIDATED # define JS_HAZ_GC_INVALIDATED
# define JS_HAZ_ROOTED_BASE
# define JS_HAZ_NON_GC_POINTER # define JS_HAZ_NON_GC_POINTER
# define JS_HAZ_GC_CALL # define JS_HAZ_GC_CALL
# define JS_HAZ_GC_SUPPRESSED # define JS_HAZ_GC_SUPPRESSED

View file

@ -945,7 +945,7 @@ class JS_PUBLIC_API(AutoGCRooter)
/* No copy or assignment semantics. */ /* No copy or assignment semantics. */
AutoGCRooter(AutoGCRooter& ida) = delete; AutoGCRooter(AutoGCRooter& ida) = delete;
void operator=(AutoGCRooter& ida) = delete; void operator=(AutoGCRooter& ida) = delete;
}; } JS_HAZ_ROOTED_BASE;
namespace detail { namespace detail {

View file

@ -689,10 +689,10 @@ js::atomics_wait(JSContext* cx, unsigned argc, Value* vp)
} }
int64_t int64_t
js::atomics_wake_impl(SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t count) js::atomics_notify_impl(SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t count)
{ {
// Validation should ensure this does not happen. // Validation should ensure this does not happen.
MOZ_ASSERT(sarb, "wake is only applicable to shared memory"); MOZ_ASSERT(sarb, "notify is only applicable to shared memory");
AutoLockFutexAPI lock; AutoLockFutexAPI lock;
@ -706,7 +706,7 @@ js::atomics_wake_impl(SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t c
iter = iter->lower_pri; iter = iter->lower_pri;
if (c->offset != byteOffset || !c->cx->fx.isWaiting()) if (c->offset != byteOffset || !c->cx->fx.isWaiting())
continue; continue;
c->cx->fx.wake(FutexThread::WakeExplicit); c->cx->fx.notify(FutexThread::NotifyExplicit);
// Overflow will be a problem only in two cases: // Overflow will be a problem only in two cases:
// (1) 128-bit systems with substantially more than 2^64 bytes of // (1) 128-bit systems with substantially more than 2^64 bytes of
// memory per process, and a very lightweight // memory per process, and a very lightweight
@ -723,7 +723,7 @@ js::atomics_wake_impl(SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t c
} }
bool bool
js::atomics_wake(JSContext* cx, unsigned argc, Value* vp) js::atomics_notify(JSContext* cx, unsigned argc, Value* vp)
{ {
CallArgs args = CallArgsFromVp(argc, vp); CallArgs args = CallArgsFromVp(argc, vp);
HandleValue objv = args.get(0); HandleValue objv = args.get(0);
@ -758,7 +758,7 @@ js::atomics_wake(JSContext* cx, unsigned argc, Value* vp)
(view->viewDataShared().cast<uint8_t*>().unwrap(/* arithmetic */) - (view->viewDataShared().cast<uint8_t*>().unwrap(/* arithmetic */) -
sab->dataPointerShared().unwrap(/* arithmetic */)); sab->dataPointerShared().unwrap(/* arithmetic */));
r.setNumber(double(atomics_wake_impl(sab->rawBufferObject(), byteOffset, count))); r.setNumber(double(atomics_notify_impl(sab->rawBufferObject(), byteOffset, count)));
return true; return true;
} }
@ -830,7 +830,7 @@ js::FutexThread::isWaiting()
// When a worker is awoken for an interrupt it goes into state // When a worker is awoken for an interrupt it goes into state
// WaitingNotifiedForInterrupt for a short time before it actually // WaitingNotifiedForInterrupt for a short time before it actually
// wakes up and goes into WaitingInterrupted. In those states the // wakes up and goes into WaitingInterrupted. In those states the
// worker is still waiting, and if an explicit wake arrives the // worker is still waiting, and if an explicit notify arrives the
// worker transitions to Woken. See further comments in // worker transitions to Woken. See further comments in
// FutexThread::wait(). // FutexThread::wait().
return state_ == Waiting || state_ == WaitingInterrupted || state_ == WaitingNotifiedForInterrupt; return state_ == Waiting || state_ == WaitingInterrupted || state_ == WaitingNotifiedForInterrupt;
@ -909,14 +909,14 @@ js::FutexThread::wait(JSContext* cx, js::UniqueLock<js::Mutex>& locked,
// should be woken when the interrupt handler returns. // should be woken when the interrupt handler returns.
// To that end, we flag the thread as interrupted around // To that end, we flag the thread as interrupted around
// the interrupt and check state_ when the interrupt // the interrupt and check state_ when the interrupt
// handler returns. A wake() call that reaches the // handler returns. A notify() call that reaches the
// runtime during the interrupt sets state_ to Woken. // runtime during the interrupt sets state_ to Woken.
// //
// - It is in principle possible for wait() to be // - It is in principle possible for wait() to be
// reentered on the same thread/runtime and waiting on the // reentered on the same thread/runtime and waiting on the
// same location and to yet again be interrupted and enter // same location and to yet again be interrupted and enter
// the interrupt handler. In this case, it is important // the interrupt handler. In this case, it is important
// that when another agent wakes waiters, all waiters using // that when another agent notifies waiters, all waiters using
// the same runtime on the same location are woken in LIFO // the same runtime on the same location are woken in LIFO
// order; FIFO may be the required order, but FIFO would // order; FIFO may be the required order, but FIFO would
// fail to wake up the innermost call. Interrupts are // fail to wake up the innermost call. Interrupts are
@ -947,25 +947,25 @@ js::FutexThread::wait(JSContext* cx, js::UniqueLock<js::Mutex>& locked,
} }
void void
js::FutexThread::wake(WakeReason reason) js::FutexThread::notify(NotifyReason reason)
{ {
MOZ_ASSERT(isWaiting()); MOZ_ASSERT(isWaiting());
if ((state_ == WaitingInterrupted || state_ == WaitingNotifiedForInterrupt) && reason == WakeExplicit) { if ((state_ == WaitingInterrupted || state_ == WaitingNotifiedForInterrupt) && reason == NotifyExplicit) {
state_ = Woken; state_ = Woken;
return; return;
} }
switch (reason) { switch (reason) {
case WakeExplicit: case NotifyExplicit:
state_ = Woken; state_ = Woken;
break; break;
case WakeForJSInterrupt: case NotifyForJSInterrupt:
if (state_ == WaitingNotifiedForInterrupt) if (state_ == WaitingNotifiedForInterrupt)
return; return;
state_ = WaitingNotifiedForInterrupt; state_ = WaitingNotifiedForInterrupt;
break; break;
default: default:
MOZ_CRASH("bad WakeReason in FutexThread::wake()"); MOZ_CRASH("bad NotifyReason in FutexThread::notify()");
} }
cond_->notify_all(); cond_->notify_all();
} }
@ -982,7 +982,8 @@ const JSFunctionSpec AtomicsMethods[] = {
JS_INLINABLE_FN("xor", atomics_xor, 3,0, AtomicsXor), JS_INLINABLE_FN("xor", atomics_xor, 3,0, AtomicsXor),
JS_INLINABLE_FN("isLockFree", atomics_isLockFree, 1,0, AtomicsIsLockFree), JS_INLINABLE_FN("isLockFree", atomics_isLockFree, 1,0, AtomicsIsLockFree),
JS_FN("wait", atomics_wait, 4,0), JS_FN("wait", atomics_wait, 4,0),
JS_FN("wake", atomics_wake, 3,0), JS_FN("notify", atomics_notify, 3,0),
JS_FN("wake", atomics_notify, 3,0), // Legacy name
JS_FS_END JS_FS_END
}; };

View file

@ -39,7 +39,7 @@ MOZ_MUST_USE bool atomics_or(JSContext* cx, unsigned argc, Value* vp);
MOZ_MUST_USE bool atomics_xor(JSContext* cx, unsigned argc, Value* vp); MOZ_MUST_USE bool atomics_xor(JSContext* cx, unsigned argc, Value* vp);
MOZ_MUST_USE bool atomics_isLockFree(JSContext* cx, unsigned argc, Value* vp); MOZ_MUST_USE bool atomics_isLockFree(JSContext* cx, unsigned argc, Value* vp);
MOZ_MUST_USE bool atomics_wait(JSContext* cx, unsigned argc, Value* vp); MOZ_MUST_USE bool atomics_wait(JSContext* cx, unsigned argc, Value* vp);
MOZ_MUST_USE bool atomics_wake(JSContext* cx, unsigned argc, Value* vp); MOZ_MUST_USE bool atomics_notify(JSContext* cx, unsigned argc, Value* vp);
class FutexThread class FutexThread
{ {
@ -56,10 +56,10 @@ public:
MOZ_MUST_USE bool initInstance(); MOZ_MUST_USE bool initInstance();
void destroyInstance(); void destroyInstance();
// Parameters to wake(). // Parameters to notify().
enum WakeReason { enum NotifyReason {
WakeExplicit, // Being asked to wake up by another thread NotifyExplicit, // Being asked to wake up by another thread
WakeForJSInterrupt // Interrupt requested NotifyForJSInterrupt // Interrupt requested
}; };
// Result codes from wait() and atomics_wait_impl(). // Result codes from wait() and atomics_wait_impl().
@ -78,29 +78,27 @@ public:
// times allowed; specify mozilla::Nothing() for an indefinite // times allowed; specify mozilla::Nothing() for an indefinite
// wait. // wait.
// //
// wait() will not wake up spuriously. It will return true and // wait() will not wake up spuriously.
// set *result to a return code appropriate for
// Atomics.wait() on success, and return false on error.
MOZ_MUST_USE WaitResult wait(JSContext* cx, js::UniqueLock<js::Mutex>& locked, MOZ_MUST_USE WaitResult wait(JSContext* cx, js::UniqueLock<js::Mutex>& locked,
const mozilla::Maybe<mozilla::TimeDuration>& timeout); const mozilla::Maybe<mozilla::TimeDuration>& timeout);
// Wake the thread this is associated with. // Notify the thread this is associated with.
// //
// The futex lock must be held around this call. (The sleeping // The futex lock must be held around this call. (The sleeping
// thread will not wake up until the caller of Atomics.wake() // thread will not wake up until the caller of Atomics.notify()
// releases the lock.) // releases the lock.)
// //
// If the thread is not waiting then this method does nothing. // If the thread is not waiting then this method does nothing.
// //
// If the thread is waiting in a call to wait() and the // If the thread is waiting in a call to wait() and the
// reason is WakeExplicit then the wait() call will return // reason is NotifyExplicit then the wait() call will return
// with Woken. // with Woken.
// //
// If the thread is waiting in a call to wait() and the // If the thread is waiting in a call to wait() and the
// reason is WakeForJSInterrupt then the wait() will return // reason is NotifyForJSInterrupt then the wait() will return
// with WaitingNotifiedForInterrupt; in the latter case the caller // with WaitingNotifiedForInterrupt; in the latter case the caller
// of wait() must handle the interrupt. // of wait() must handle the interrupt.
void wake(WakeReason reason); void notify(NotifyReason reason);
bool isWaiting(); bool isWaiting();
@ -123,7 +121,7 @@ public:
// interrupt handler // interrupt handler
WaitingInterrupted, // We are waiting, but have been interrupted WaitingInterrupted, // We are waiting, but have been interrupted
// and are running the interrupt handler // and are running the interrupt handler
Woken // Woken by a script call to Atomics.wake Woken // Woken by a script call to Atomics.notify
}; };
// Condition variable that this runtime will wait on. // Condition variable that this runtime will wait on.
@ -157,12 +155,12 @@ MOZ_MUST_USE FutexThread::WaitResult
atomics_wait_impl(JSContext* cx, SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t value, atomics_wait_impl(JSContext* cx, SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t value,
const mozilla::Maybe<mozilla::TimeDuration>& timeout); const mozilla::Maybe<mozilla::TimeDuration>& timeout);
// Wake some waiters on the given address. If `count` is negative then wake // Notify some waiters on the given address. If `count` is negative then notify
// all. The return value is nonnegative and is the number of waiters woken. If // all. The return value is nonnegative and is the number of waiters woken. If
// the number of waiters woken exceeds INT64_MAX then this never returns. If // the number of waiters woken exceeds INT64_MAX then this never returns. If
// `count` is nonnegative then the return value is never greater than `count`. // `count` is nonnegative then the return value is never greater than `count`.
MOZ_MUST_USE int64_t MOZ_MUST_USE int64_t
atomics_wake_impl(SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t count); atomics_notify_impl(SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t count);
} /* namespace js */ } /* namespace js */

View file

@ -171,7 +171,7 @@ bool
DataViewObject::constructSameCompartment(JSContext* cx, HandleObject bufobj, const CallArgs& args) DataViewObject::constructSameCompartment(JSContext* cx, HandleObject bufobj, const CallArgs& args)
{ {
MOZ_ASSERT(args.isConstructing()); MOZ_ASSERT(args.isConstructing());
assertSameCompartment(cx, bufobj); cx->check(bufobj);
uint32_t byteOffset, byteLength; uint32_t byteOffset, byteLength;
if (!getAndCheckConstructorArgs(cx, bufobj, args, &byteOffset, &byteLength)) if (!getAndCheckConstructorArgs(cx, bufobj, args, &byteOffset, &byteLength))

View file

@ -440,7 +440,7 @@ static bool
ExecuteInExtensibleLexicalEnvironment(JSContext* cx, HandleScript scriptArg, HandleObject env) ExecuteInExtensibleLexicalEnvironment(JSContext* cx, HandleScript scriptArg, HandleObject env)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, env); cx->check(env);
MOZ_ASSERT(IsExtensibleLexicalEnvironment(env)); MOZ_ASSERT(IsExtensibleLexicalEnvironment(env));
MOZ_RELEASE_ASSERT(scriptArg->hasNonSyntacticScope()); MOZ_RELEASE_ASSERT(scriptArg->hasNonSyntacticScope());
@ -518,7 +518,7 @@ JS_FRIEND_API(bool)
js::ExecuteInJSMEnvironment(JSContext* cx, HandleScript scriptArg, HandleObject varEnv, js::ExecuteInJSMEnvironment(JSContext* cx, HandleScript scriptArg, HandleObject varEnv,
AutoObjectVector& targetObj) AutoObjectVector& targetObj)
{ {
assertSameCompartment(cx, varEnv); cx->check(varEnv);
MOZ_ASSERT(ObjectRealm::get(varEnv).getNonSyntacticLexicalEnvironment(varEnv)); MOZ_ASSERT(ObjectRealm::get(varEnv).getNonSyntacticLexicalEnvironment(varEnv));
MOZ_DIAGNOSTIC_ASSERT(scriptArg->noScriptRval()); MOZ_DIAGNOSTIC_ASSERT(scriptArg->noScriptRval());

View file

@ -1711,7 +1711,7 @@ RetT
CallObjFunc(RetT(*ObjFunc)(JSContext*, HandleObject), JSContext* cx, HandleObject obj) CallObjFunc(RetT(*ObjFunc)(JSContext*, HandleObject), JSContext* cx, HandleObject obj)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj); cx->check(obj);
// Always unwrap, in case this is an xray or cross-compartment wrapper. // Always unwrap, in case this is an xray or cross-compartment wrapper.
RootedObject unwrappedObj(cx); RootedObject unwrappedObj(cx);
@ -1729,7 +1729,7 @@ CallObjFunc(bool(*ObjFunc)(JSContext *cx, HandleObject obj, HandleValue key, boo
JSContext *cx, HandleObject obj, HandleValue key, bool *rval) JSContext *cx, HandleObject obj, HandleValue key, bool *rval)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, key); cx->check(obj, key);
// Always unwrap, in case this is an xray or cross-compartment wrapper. // Always unwrap, in case this is an xray or cross-compartment wrapper.
RootedObject unwrappedObj(cx); RootedObject unwrappedObj(cx);
@ -1754,7 +1754,7 @@ CallObjFunc(bool(*ObjFunc)(JSContext* cx, Iter kind,
JSContext *cx, Iter iterType, HandleObject obj, MutableHandleValue rval) JSContext *cx, Iter iterType, HandleObject obj, MutableHandleValue rval)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj); cx->check(obj);
// Always unwrap, in case this is an xray or cross-compartment wrapper. // Always unwrap, in case this is an xray or cross-compartment wrapper.
RootedObject unwrappedObj(cx); RootedObject unwrappedObj(cx);
@ -1794,7 +1794,7 @@ JS_PUBLIC_API(bool)
JS::MapGet(JSContext* cx, HandleObject obj, HandleValue key, MutableHandleValue rval) JS::MapGet(JSContext* cx, HandleObject obj, HandleValue key, MutableHandleValue rval)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, key, rval); cx->check(obj, key, rval);
// Unwrap the object, and enter its realm. If object isn't wrapped, // Unwrap the object, and enter its realm. If object isn't wrapped,
// this is essentially a noop. // this is essentially a noop.
@ -1825,7 +1825,7 @@ JS_PUBLIC_API(bool)
JS::MapSet(JSContext *cx, HandleObject obj, HandleValue key, HandleValue val) JS::MapSet(JSContext *cx, HandleObject obj, HandleValue key, HandleValue val)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, key, val); cx->check(obj, key, val);
// Unwrap the object, and enter its compartment. If object isn't wrapped, // Unwrap the object, and enter its compartment. If object isn't wrapped,
// this is essentially a noop. // this is essentially a noop.
@ -1906,7 +1906,7 @@ JS_PUBLIC_API(bool)
JS::SetAdd(JSContext *cx, HandleObject obj, HandleValue key) JS::SetAdd(JSContext *cx, HandleObject obj, HandleValue key)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, key); cx->check(obj, key);
// Unwrap the object, and enter its compartment. If object isn't wrapped, // Unwrap the object, and enter its compartment. If object isn't wrapped,
// this is essentially a noop. // this is essentially a noop.

View file

@ -1192,8 +1192,6 @@ GlobalObject::initModuleProto(JSContext* cx, Handle<GlobalObject*> global)
static const JSFunctionSpec protoFunctions[] = { static const JSFunctionSpec protoFunctions[] = {
JS_SELF_HOSTED_FN("getExportedNames", "ModuleGetExportedNames", 1, 0), JS_SELF_HOSTED_FN("getExportedNames", "ModuleGetExportedNames", 1, 0),
JS_SELF_HOSTED_FN("resolveExport", "ModuleResolveExport", 2, 0), JS_SELF_HOSTED_FN("resolveExport", "ModuleResolveExport", 2, 0),
JS_SELF_HOSTED_FN("declarationInstantiation", "ModuleInstantiate", 0, 0),
JS_SELF_HOSTED_FN("evaluation", "ModuleEvaluate", 0, 0),
JS_FS_END JS_FS_END
}; };

View file

@ -12,6 +12,7 @@
#include "jsapi.h" #include "jsapi.h"
#include "builtin/SelfHostingDefines.h" #include "builtin/SelfHostingDefines.h"
#include "gc/Zone.h"
#include "js/GCVector.h" #include "js/GCVector.h"
#include "js/Id.h" #include "js/Id.h"
#include "js/UniquePtr.h" #include "js/UniquePtr.h"

View file

@ -400,7 +400,7 @@ static const JSFunctionSpec profiling_functions[] = {
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
JS_DefineProfilingFunctions(JSContext* cx, HandleObject obj) JS_DefineProfilingFunctions(JSContext* cx, HandleObject obj)
{ {
assertSameCompartment(cx, obj); cx->check(obj);
#ifdef MOZ_PROFILING #ifdef MOZ_PROFILING
return JS_DefineFunctions(cx, obj, profiling_functions); return JS_DefineFunctions(cx, obj, profiling_functions);
#else #else

View file

@ -232,9 +232,9 @@ NewPromiseAllDataHolder(JSContext* cx, HandleObject resultPromise, HandleValue v
if (!dataHolder) if (!dataHolder)
return nullptr; return nullptr;
assertSameCompartment(cx, resultPromise); cx->check(resultPromise);
assertSameCompartment(cx, valuesArray); cx->check(valuesArray);
assertSameCompartment(cx, resolve); cx->check(resolve);
dataHolder->setFixedSlot(PromiseAllDataHolderSlot_Promise, ObjectValue(*resultPromise)); dataHolder->setFixedSlot(PromiseAllDataHolderSlot_Promise, ObjectValue(*resultPromise));
dataHolder->setFixedSlot(PromiseAllDataHolderSlot_RemainingElements, Int32Value(1)); dataHolder->setFixedSlot(PromiseAllDataHolderSlot_RemainingElements, Int32Value(1));
@ -772,7 +772,7 @@ static bool Promise_then_impl(JSContext* cx, HandleValue promiseVal, HandleValue
static MOZ_MUST_USE bool static MOZ_MUST_USE bool
ResolvePromiseInternal(JSContext* cx, HandleObject promise, HandleValue resolutionVal) ResolvePromiseInternal(JSContext* cx, HandleObject promise, HandleValue resolutionVal)
{ {
assertSameCompartment(cx, promise, resolutionVal); cx->check(promise, resolutionVal);
MOZ_ASSERT(!IsSettledMaybeWrappedPromise(promise)); MOZ_ASSERT(!IsSettledMaybeWrappedPromise(promise));
// Step 7 (reordered). // Step 7 (reordered).
@ -935,7 +935,7 @@ EnqueuePromiseReactionJob(JSContext* cx, HandleObject reactionObj,
// Must not enqueue a reaction job more than once. // Must not enqueue a reaction job more than once.
MOZ_ASSERT(reaction->targetState() == JS::PromiseState::Pending); MOZ_ASSERT(reaction->targetState() == JS::PromiseState::Pending);
assertSameCompartment(cx, handlerArg); cx->check(handlerArg);
reaction->setTargetStateAndHandlerArg(targetState, handlerArg); reaction->setTargetStateAndHandlerArg(targetState, handlerArg);
RootedValue reactionVal(cx, ObjectValue(*reaction)); RootedValue reactionVal(cx, ObjectValue(*reaction));
@ -1637,7 +1637,7 @@ PromiseResolveBuiltinThenableJob(JSContext* cx, unsigned argc, Value* vp)
RootedObject promise(cx, &job->getExtendedSlot(BuiltinThenableJobSlot_Promise).toObject()); RootedObject promise(cx, &job->getExtendedSlot(BuiltinThenableJobSlot_Promise).toObject());
RootedObject thenable(cx, &job->getExtendedSlot(BuiltinThenableJobSlot_Thenable).toObject()); RootedObject thenable(cx, &job->getExtendedSlot(BuiltinThenableJobSlot_Thenable).toObject());
assertSameCompartment(cx, promise, thenable); cx->check(promise, thenable);
MOZ_ASSERT(promise->is<PromiseObject>()); MOZ_ASSERT(promise->is<PromiseObject>());
MOZ_ASSERT(thenable->is<PromiseObject>()); MOZ_ASSERT(thenable->is<PromiseObject>());
@ -1740,7 +1740,7 @@ static MOZ_MUST_USE bool
EnqueuePromiseResolveThenableBuiltinJob(JSContext* cx, HandleObject promiseToResolve, EnqueuePromiseResolveThenableBuiltinJob(JSContext* cx, HandleObject promiseToResolve,
HandleObject thenable) HandleObject thenable)
{ {
assertSameCompartment(cx, promiseToResolve, thenable); cx->check(promiseToResolve, thenable);
MOZ_ASSERT(promiseToResolve->is<PromiseObject>()); MOZ_ASSERT(promiseToResolve->is<PromiseObject>());
MOZ_ASSERT(thenable->is<PromiseObject>()); MOZ_ASSERT(thenable->is<PromiseObject>());
@ -2156,7 +2156,7 @@ js::GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises)
#ifdef DEBUG #ifdef DEBUG
for (size_t i = 0, len = promises.length(); i < len; i++) { for (size_t i = 0, len = promises.length(); i < len; i++) {
JSObject* obj = promises[i]; JSObject* obj = promises[i];
assertSameCompartment(cx, obj); cx->check(obj);
MOZ_ASSERT(UncheckedUnwrap(obj)->is<PromiseObject>()); MOZ_ASSERT(UncheckedUnwrap(obj)->is<PromiseObject>());
} }
#endif #endif
@ -2285,9 +2285,9 @@ RunResolutionFunction(JSContext *cx, HandleObject resolutionFun, HandleValue res
// subclass constructor passes null/undefined to `super()`.) // subclass constructor passes null/undefined to `super()`.)
// There are also reactions where the Promise itself is missing. For // There are also reactions where the Promise itself is missing. For
// those, there's nothing left to do here. // those, there's nothing left to do here.
assertSameCompartment(cx, resolutionFun); cx->check(resolutionFun);
assertSameCompartment(cx, result); cx->check(result);
assertSameCompartment(cx, promiseObj); cx->check(promiseObj);
if (resolutionFun) { if (resolutionFun) {
RootedValue calleeOrRval(cx, ObjectValue(*resolutionFun)); RootedValue calleeOrRval(cx, ObjectValue(*resolutionFun));
return Call(cx, calleeOrRval, UndefinedHandleValue, result, &calleeOrRval); return Call(cx, calleeOrRval, UndefinedHandleValue, result, &calleeOrRval);
@ -3080,12 +3080,12 @@ NewReactionRecord(JSContext* cx, Handle<PromiseCapability> resultCapability,
if (!reaction) if (!reaction)
return nullptr; return nullptr;
assertSameCompartment(cx, resultCapability.promise()); cx->check(resultCapability.promise());
assertSameCompartment(cx, onFulfilled); cx->check(onFulfilled);
assertSameCompartment(cx, onRejected); cx->check(onRejected);
assertSameCompartment(cx, resultCapability.resolve()); cx->check(resultCapability.resolve());
assertSameCompartment(cx, resultCapability.reject()); cx->check(resultCapability.reject());
assertSameCompartment(cx, incumbentGlobalObject); cx->check(incumbentGlobalObject);
reaction->setFixedSlot(ReactionRecordSlot_Promise, reaction->setFixedSlot(ReactionRecordSlot_Promise,
ObjectOrNullValue(resultCapability.promise())); ObjectOrNullValue(resultCapability.promise()));
@ -3160,7 +3160,7 @@ static MOZ_MUST_USE bool
OriginalPromiseThenWithoutSettleHandlers(JSContext* cx, Handle<PromiseObject*> promise, OriginalPromiseThenWithoutSettleHandlers(JSContext* cx, Handle<PromiseObject*> promise,
Handle<PromiseObject*> promiseToResolve) Handle<PromiseObject*> promiseToResolve)
{ {
assertSameCompartment(cx, promise); cx->check(promise);
// Steps 3-4. // Steps 3-4.
Rooted<PromiseCapability> resultCapability(cx); Rooted<PromiseCapability> resultCapability(cx);
@ -3187,7 +3187,7 @@ static bool
OriginalPromiseThenBuiltin(JSContext* cx, HandleValue promiseVal, HandleValue onFulfilled, OriginalPromiseThenBuiltin(JSContext* cx, HandleValue promiseVal, HandleValue onFulfilled,
HandleValue onRejected, MutableHandleValue rval, bool rvalUsed) HandleValue onRejected, MutableHandleValue rval, bool rvalUsed)
{ {
assertSameCompartment(cx, promiseVal, onFulfilled, onRejected); cx->check(promiseVal, onFulfilled, onRejected);
MOZ_ASSERT(CanCallOriginalPromiseThenBuiltin(cx, promiseVal)); MOZ_ASSERT(CanCallOriginalPromiseThenBuiltin(cx, promiseVal));
Rooted<PromiseObject*> promise(cx, &promiseVal.toObject().as<PromiseObject>()); Rooted<PromiseObject*> promise(cx, &promiseVal.toObject().as<PromiseObject>());

View file

@ -186,7 +186,7 @@ CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlag flags)
// If we already have a RegExpShared for this pattern/flags, we can // If we already have a RegExpShared for this pattern/flags, we can
// avoid the much slower CheckPatternSyntaxSlow call. // avoid the much slower CheckPatternSyntaxSlow call.
if (RegExpShared* shared = cx->zone()->regExps.maybeGet(pattern, flags)) { if (RegExpShared* shared = cx->zone()->regExps().maybeGet(pattern, flags)) {
#ifdef DEBUG #ifdef DEBUG
// Assert the pattern is valid. // Assert the pattern is valid.
if (!CheckPatternSyntaxSlow(cx, pattern, flags)) { if (!CheckPatternSyntaxSlow(cx, pattern, flags)) {
@ -202,7 +202,7 @@ CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlag flags)
// Allocate and return a new RegExpShared so we will hit the fast path // Allocate and return a new RegExpShared so we will hit the fast path
// next time. // next time.
return cx->zone()->regExps.get(cx, pattern, flags); return cx->zone()->regExps().get(cx, pattern, flags);
} }
/* /*

View file

@ -205,6 +205,22 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp)
if (!JS_SetProperty(cx, info, "arm64-simulator", value)) if (!JS_SetProperty(cx, info, "arm64-simulator", value))
return false; return false;
#ifdef JS_SIMULATOR_MIPS32
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "mips32-simulator", value))
return false;
#ifdef JS_SIMULATOR_MIPS64
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "mips64-simulator", value))
return false;
#ifdef MOZ_ASAN #ifdef MOZ_ASAN
value = BooleanValue(true); value = BooleanValue(true);
#else #else
@ -4397,96 +4413,6 @@ SetRNGState(JSContext* cx, unsigned argc, Value* vp)
} }
#endif #endif
static ModuleEnvironmentObject*
GetModuleEnvironment(JSContext* cx, HandleModuleObject module)
{
// Use the initial environment so that tests can check bindings exists
// before they have been instantiated.
RootedModuleEnvironmentObject env(cx, &module->initialEnvironment());
MOZ_ASSERT(env);
return env;
}
static bool
GetModuleEnvironmentNames(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 1) {
JS_ReportErrorASCII(cx, "Wrong number of arguments");
return false;
}
if (!args[0].isObject() || !args[0].toObject().is<ModuleObject>()) {
JS_ReportErrorASCII(cx, "First argument should be a ModuleObject");
return false;
}
RootedModuleObject module(cx, &args[0].toObject().as<ModuleObject>());
if (module->hadEvaluationError()) {
JS_ReportErrorASCII(cx, "Module environment unavailable");
return false;
}
RootedModuleEnvironmentObject env(cx, GetModuleEnvironment(cx, module));
Rooted<IdVector> ids(cx, IdVector(cx));
if (!JS_Enumerate(cx, env, &ids))
return false;
uint32_t length = ids.length();
RootedArrayObject array(cx, NewDenseFullyAllocatedArray(cx, length));
if (!array)
return false;
array->setDenseInitializedLength(length);
for (uint32_t i = 0; i < length; i++)
array->initDenseElement(i, StringValue(JSID_TO_STRING(ids[i])));
args.rval().setObject(*array);
return true;
}
static bool
GetModuleEnvironmentValue(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 2) {
JS_ReportErrorASCII(cx, "Wrong number of arguments");
return false;
}
if (!args[0].isObject() || !args[0].toObject().is<ModuleObject>()) {
JS_ReportErrorASCII(cx, "First argument should be a ModuleObject");
return false;
}
if (!args[1].isString()) {
JS_ReportErrorASCII(cx, "Second argument should be a string");
return false;
}
RootedModuleObject module(cx, &args[0].toObject().as<ModuleObject>());
if (module->hadEvaluationError()) {
JS_ReportErrorASCII(cx, "Module environment unavailable");
return false;
}
RootedModuleEnvironmentObject env(cx, GetModuleEnvironment(cx, module));
RootedString name(cx, args[1].toString());
RootedId id(cx);
if (!JS_StringToId(cx, name, &id))
return false;
if (!GetProperty(cx, env, env, id, args.rval()))
return false;
if (args.rval().isMagic(JS_UNINITIALIZED_LEXICAL)) {
ReportRuntimeLexicalError(cx, JSMSG_UNINITIALIZED_LEXICAL, id);
return false;
}
return true;
}
#ifdef DEBUG #ifdef DEBUG
static const char* static const char*
AssertionTypeToString(irregexp::RegExpAssertion::AssertionType type) AssertionTypeToString(irregexp::RegExpAssertion::AssertionType type)
@ -6002,14 +5928,6 @@ gc::ZealModeHelpText),
" Set this compartment's RNG state.\n"), " Set this compartment's RNG state.\n"),
#endif #endif
JS_FN_HELP("getModuleEnvironmentNames", GetModuleEnvironmentNames, 1, 0,
"getModuleEnvironmentNames(module)",
" Get the list of a module environment's bound names for a specified module.\n"),
JS_FN_HELP("getModuleEnvironmentValue", GetModuleEnvironmentValue, 2, 0,
"getModuleEnvironmentValue(module, name)",
" Get the value of a bound name in a module environment.\n"),
#if defined(FUZZING) && defined(__AFL_COMPILER) #if defined(FUZZING) && defined(__AFL_COMPILER)
JS_FN_HELP("aflloop", AflLoop, 1, 0, JS_FN_HELP("aflloop", AflLoop, 1, 0,
"aflloop(max_cnt)", "aflloop(max_cnt)",

View file

@ -204,7 +204,7 @@ JS::GetWeakMapEntry(JSContext* cx, HandleObject mapObj, HandleObject key,
MutableHandleValue rval) MutableHandleValue rval)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, key); cx->check(key);
rval.setUndefined(); rval.setUndefined();
ObjectValueMap* map = mapObj->as<WeakMapObject>().getMap(); ObjectValueMap* map = mapObj->as<WeakMapObject>().getMap();
if (!map) if (!map)
@ -223,7 +223,7 @@ JS::SetWeakMapEntry(JSContext* cx, HandleObject mapObj, HandleObject key,
HandleValue val) HandleValue val)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, key, val); cx->check(key, val);
Handle<WeakMapObject*> rootedMap = mapObj.as<WeakMapObject>(); Handle<WeakMapObject*> rootedMap = mapObj.as<WeakMapObject>();
return WeakCollectionPutEntryInternal(cx, rootedMap, key, val); return WeakCollectionPutEntryInternal(cx, rootedMap, key, val);
} }

View file

@ -222,6 +222,9 @@ function edgeUsesVariable(edge, variable, body)
case "Loop": case "Loop":
return 0; return 0;
case "Assembly":
return 0;
default: default:
assert(false); assert(false);
} }

View file

@ -176,20 +176,9 @@ function process(functionName, functionBodies)
if (markerPos > 0) { if (markerPos > 0) {
var inChargeXTor = functionName.replace(internalMarker, ""); var inChargeXTor = functionName.replace(internalMarker, "");
print("D " + memo(inChargeXTor) + " " + memo(functionName)); print("D " + memo(inChargeXTor) + " " + memo(functionName));
// Bug 1056410: Oh joy. GCC does something even funkier internally,
// where it generates calls to ~Foo() but a body for ~Foo(int32) even
// though it uses the same mangled name for both. So we need to add a
// synthetic edge from ~Foo() -> ~Foo(int32).
//
// inChargeXTor will have the (int32).
if (functionName.indexOf("::~") > 0) {
var calledDestructor = inChargeXTor.replace("(int32)", "()");
print("D " + memo(calledDestructor) + " " + memo(inChargeXTor));
}
} }
// Further note: from http://mentorembedded.github.io/cxx-abi/abi.html the // Further note: from https://itanium-cxx-abi.github.io/cxx-abi/abi.html the
// different kinds of constructors/destructors are: // different kinds of constructors/destructors are:
// C1 # complete object constructor // C1 # complete object constructor
// C2 # base object constructor // C2 # base object constructor
@ -210,18 +199,35 @@ function process(functionName, functionBodies)
// inject an edge to it from C1, C2, and C3 (or D1, D2, and D3). (Note that // inject an edge to it from C1, C2, and C3 (or D1, D2, and D3). (Note that
// C3 isn't even used in current GCC, but add the edge anyway just in // C3 isn't even used in current GCC, but add the edge anyway just in
// case.) // case.)
if (functionName.indexOf("C4E") != -1 || functionName.indexOf("D4Ev") != -1) { //
// from gcc/cp/mangle.c:
//
// <special-name> ::= D0 # deleting (in-charge) destructor
// ::= D1 # complete object (in-charge) destructor
// ::= D2 # base object (not-in-charge) destructor
// <special-name> ::= C1 # complete object constructor
// ::= C2 # base object constructor
// ::= C3 # complete object allocating constructor
//
// Currently, allocating constructors are never used.
//
if (functionName.indexOf("C4") != -1) {
var [ mangled, unmangled ] = splitFunction(functionName); var [ mangled, unmangled ] = splitFunction(functionName);
// E terminates the method name (and precedes the method parameters). // E terminates the method name (and precedes the method parameters).
// If eg "C4E" shows up in the mangled name for another reason, this // If eg "C4E" shows up in the mangled name for another reason, this
// will create bogus edges in the callgraph. But will affect little and // will create bogus edges in the callgraph. But it will affect little
// is somewhat difficult to avoid, so we will live with it. // and is somewhat difficult to avoid, so we will live with it.
for (let [synthetic, variant] of [['C4E', 'C1E'], //
// Another possibility! A templatized constructor will contain C4I...E
// for template arguments.
//
for (let [synthetic, variant] of [
['C4E', 'C1E'],
['C4E', 'C2E'], ['C4E', 'C2E'],
['C4E', 'C3E'], ['C4E', 'C3E'],
['D4Ev', 'D1Ev'], ['C4I', 'C1I'],
['D4Ev', 'D2Ev'], ['C4I', 'C2I'],
['D4Ev', 'D3Ev']]) ['C4I', 'C3I']])
{ {
if (mangled.indexOf(synthetic) == -1) if (mangled.indexOf(synthetic) == -1)
continue; continue;
@ -231,6 +237,30 @@ function process(functionName, functionBodies)
print("D " + memo(variant_full) + " " + memo(functionName)); print("D " + memo(variant_full) + " " + memo(functionName));
} }
} }
// For destructors:
//
// I've never seen D4Ev() + D4Ev(int32), only one or the other. So
// for a D4Ev of any sort, create:
//
// D0() -> D1() # deleting destructor calls complete destructor, then deletes
// D1() -> D2() # complete destructor calls base destructor, then destroys virtual bases
// D2() -> D4(?) # base destructor might be aliased to unified destructor
// # use whichever one is defined, in-charge or not.
// # ('?') means either () or (int32).
//
// Note that this doesn't actually make sense -- D0 and D1 should be
// in-charge, but gcc doesn't seem to give them the in-charge parameter?!
//
if (functionName.indexOf("D4Ev") != -1 && functionName.indexOf("::~") != -1) {
const not_in_charge_dtor = functionName.replace("(int32)", "()");
const D0 = not_in_charge_dtor.replace("D4Ev", "D0Ev");
const D1 = not_in_charge_dtor.replace("D4Ev", "D1Ev");
const D2 = not_in_charge_dtor.replace("D4Ev", "D2Ev");
print("D " + memo(D0) + " " + memo(D1));
print("D " + memo(D1) + " " + memo(D2));
print("D " + memo(D2) + " " + memo(functionName));
}
} }
for (var nameIndex = minStream; nameIndex <= maxStream; nameIndex++) { for (var nameIndex = minStream; nameIndex <= maxStream; nameIndex++) {

View file

@ -15,6 +15,7 @@ var typeInfo = {
'NonGCPointers': {}, 'NonGCPointers': {},
'RootedGCThings': {}, 'RootedGCThings': {},
'RootedPointers': {}, 'RootedPointers': {},
'RootedBases': {'JS::AutoGCRooter': true},
// RAII types within which we should assume GC is suppressed, eg // RAII types within which we should assume GC is suppressed, eg
// AutoSuppressGC. // AutoSuppressGC.
@ -36,6 +37,26 @@ var rootedPointers = {};
function processCSU(csu, body) function processCSU(csu, body)
{ {
for (let { 'Name': [ annType, tag ] } of (body.Annotation || [])) {
if (annType != 'Tag')
continue;
if (tag == 'GC Pointer')
typeInfo.GCPointers.push(csu);
else if (tag == 'Invalidated by GC')
typeInfo.GCPointers.push(csu);
else if (tag == 'GC Thing')
typeInfo.GCThings.push(csu);
else if (tag == 'Suppressed GC Pointer')
typeInfo.NonGCPointers[csu] = true;
else if (tag == 'Rooted Pointer')
typeInfo.RootedPointers[csu] = true;
else if (tag == 'Rooted Base')
typeInfo.RootedBases[csu] = true;
else if (tag == 'Suppress GC')
typeInfo.GCSuppressors[csu] = true;
}
for (let { 'Base': base } of (body.CSUBaseClass || [])) for (let { 'Base': base } of (body.CSUBaseClass || []))
addBaseClass(csu, base); addBaseClass(csu, base);
@ -52,32 +73,9 @@ function processCSU(csu, body)
if (target.Kind == "CSU") if (target.Kind == "CSU")
addNestedStructure(csu, target.Name, fieldName); addNestedStructure(csu, target.Name, fieldName);
} }
if (type.Kind == "CSU") { if (type.Kind == "CSU")
// Ignore nesting in classes which are AutoGCRooters. We only consider
// types with fields that may not be properly rooted.
if (type.Name == "JS::AutoGCRooter" || type.Name == "JS::CustomAutoRooter")
return;
addNestedStructure(csu, type.Name, fieldName); addNestedStructure(csu, type.Name, fieldName);
} }
}
for (let { 'Name': [ annType, tag ] } of (body.Annotation || [])) {
if (annType != 'Tag')
continue;
if (tag == 'GC Pointer')
typeInfo.GCPointers.push(csu);
else if (tag == 'Invalidated by GC')
typeInfo.GCPointers.push(csu);
else if (tag == 'GC Thing')
typeInfo.GCThings.push(csu);
else if (tag == 'Suppressed GC Pointer')
typeInfo.NonGCPointers[csu] = true;
else if (tag == 'Rooted Pointer')
typeInfo.RootedPointers[csu] = true;
else if (tag == 'Suppress GC')
typeInfo.GCSuppressors[csu] = true;
}
} }
// csu.field is of type inner // csu.field is of type inner
@ -86,6 +84,8 @@ function addNestedStructure(csu, inner, field)
if (!(inner in structureParents)) if (!(inner in structureParents))
structureParents[inner] = []; structureParents[inner] = [];
// Skip fields that are really base classes, to avoid duplicating the base
// fields; addBaseClass already added a "base-N" name.
if (field.match(/^field:\d+$/) && (csu in baseClasses) && (baseClasses[csu].indexOf(inner) != -1)) if (field.match(/^field:\d+$/) && (csu in baseClasses) && (baseClasses[csu].indexOf(inner) != -1))
return; return;
@ -140,6 +140,16 @@ for (const csu of typeInfo.GCThings)
for (const csu of typeInfo.GCPointers) for (const csu of typeInfo.GCPointers)
addGCPointer(csu); addGCPointer(csu);
// Everything that inherits from a "Rooted Base" is considered to be rooted.
// This is for things like CustomAutoRooter and its subclasses.
var basework = Object.keys(typeInfo.RootedBases);
while (basework.length) {
const base = basework.pop();
typeInfo.RootedPointers[base] = true;
if (base in subClasses)
basework.push(...subClasses[base]);
}
// "typeName is a (pointer to a)^'typePtrLevel' GC type because it contains a field // "typeName is a (pointer to a)^'typePtrLevel' GC type because it contains a field
// named 'child' of type 'why' (or pointer to 'why' if fieldPtrLevel == 1), which is // named 'child' of type 'why' (or pointer to 'why' if fieldPtrLevel == 1), which is
// itself a GCThing or GCPointer." // itself a GCThing or GCPointer."
@ -230,7 +240,7 @@ function addGCPointer(typeName)
// Call a function for a type and every type that contains the type in a field // Call a function for a type and every type that contains the type in a field
// or as a base class (which internally is pretty much the same thing -- // or as a base class (which internally is pretty much the same thing --
// sublcasses are structs beginning with the base class and adding on their // subclasses are structs beginning with the base class and adding on their
// local fields.) // local fields.)
function foreachContainingStruct(typeName, func, seen = new Set()) function foreachContainingStruct(typeName, func, seen = new Set())
{ {

View file

@ -41,15 +41,6 @@ BumpChunk::newWithCapacity(size_t size, bool protect)
return result; return result;
} }
bool
BumpChunk::canAlloc(size_t n)
{
uint8_t* aligned = AlignPtr(bump_);
uint8_t* newBump = aligned + n;
// bump_ <= newBump, is necessary to catch overflow.
return bump_ <= newBump && newBump <= capacity_;
}
#ifdef LIFO_CHUNK_PROTECT #ifdef LIFO_CHUNK_PROTECT
static const uint8_t* static const uint8_t*
@ -186,12 +177,11 @@ LifoAlloc::newChunkWithCapacity(size_t n)
MOZ_ASSERT(fallibleScope_, "[OOM] Cannot allocate a new chunk in an infallible scope."); MOZ_ASSERT(fallibleScope_, "[OOM] Cannot allocate a new chunk in an infallible scope.");
// Compute the size which should be requested in order to be able to fit |n| // Compute the size which should be requested in order to be able to fit |n|
// bytes in the newly allocated chunk, or default the |defaultChunkSize_|. // bytes in a newly allocated chunk, or default to |defaultChunkSize_|.
size_t defaultChunkFreeSpace = defaultChunkSize_ - detail::BumpChunkReservedSpace; uint8_t* u8begin = nullptr;
size_t chunkSize; uint8_t* u8end = u8begin + detail::BumpChunkReservedSpace;
if (n > defaultChunkFreeSpace) { u8end = detail::BumpChunk::nextAllocEnd(detail::BumpChunk::nextAllocBase(u8end), n);
MOZ_ASSERT(defaultChunkFreeSpace < defaultChunkSize_); size_t allocSizeWithCanaries = u8end - u8begin;
size_t allocSizeWithCanaries = n + (defaultChunkSize_ - defaultChunkFreeSpace);
// Guard for overflow. // Guard for overflow.
if (allocSizeWithCanaries < n || if (allocSizeWithCanaries < n ||
@ -200,10 +190,11 @@ LifoAlloc::newChunkWithCapacity(size_t n)
return nullptr; return nullptr;
} }
size_t chunkSize;
if (allocSizeWithCanaries > defaultChunkSize_)
chunkSize = RoundUpPow2(allocSizeWithCanaries); chunkSize = RoundUpPow2(allocSizeWithCanaries);
} else { else
chunkSize = defaultChunkSize_; chunkSize = defaultChunkSize_;
}
bool protect = false; bool protect = false;
#ifdef LIFO_CHUNK_PROTECT #ifdef LIFO_CHUNK_PROTECT

View file

@ -224,7 +224,7 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
static constexpr uintptr_t magicNumber = uintptr_t(0x4c6966); static constexpr uintptr_t magicNumber = uintptr_t(0x4c6966);
#endif #endif
#if defined(DEBUG) || defined(MOZ_ASAN) #if defined(DEBUG)
# define LIFO_CHUNK_PROTECT 1 # define LIFO_CHUNK_PROTECT 1
#endif #endif
@ -250,6 +250,7 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
do { \ do { \
uint8_t* base = (addr); \ uint8_t* base = (addr); \
size_t sz = (size); \ size_t sz = (size); \
MOZ_MAKE_MEM_UNDEFINED(base, sz); \
memset(base, undefinedChunkMemory, sz); \ memset(base, undefinedChunkMemory, sz); \
MOZ_MAKE_MEM_NOACCESS(base, sz); \ MOZ_MAKE_MEM_NOACCESS(base, sz); \
} while (0) } while (0)
@ -269,6 +270,13 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
# define LIFO_MAKE_MEM_UNDEFINED(addr, size) MOZ_MAKE_MEM_UNDEFINED((addr), (size)) # define LIFO_MAKE_MEM_UNDEFINED(addr, size) MOZ_MAKE_MEM_UNDEFINED((addr), (size))
#endif #endif
#ifdef LIFO_HAVE_MEM_CHECKS
// Red zone reserved after each allocation.
static constexpr size_t RedZoneSize = 16;
#else
static constexpr size_t RedZoneSize = 0;
#endif
void assertInvariants() { void assertInvariants() {
MOZ_DIAGNOSTIC_ASSERT(magic_ == magicNumber); MOZ_DIAGNOSTIC_ASSERT(magic_ == magicNumber);
MOZ_ASSERT(begin() <= end()); MOZ_ASSERT(begin() <= end());
@ -319,10 +327,15 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
MOZ_ASSERT(newBump <= capacity_); MOZ_ASSERT(newBump <= capacity_);
#if defined(LIFO_HAVE_MEM_CHECKS) #if defined(LIFO_HAVE_MEM_CHECKS)
// Poison/Unpoison memory that we just free'd/allocated. // Poison/Unpoison memory that we just free'd/allocated.
if (bump_ > newBump) if (bump_ > newBump) {
LIFO_MAKE_MEM_NOACCESS(newBump, bump_ - newBump); LIFO_MAKE_MEM_NOACCESS(newBump, bump_ - newBump);
else if (newBump > bump_) } else if (newBump > bump_) {
LIFO_MAKE_MEM_UNDEFINED(bump_, newBump - bump_); MOZ_ASSERT(newBump - RedZoneSize >= bump_);
LIFO_MAKE_MEM_UNDEFINED(bump_, newBump - RedZoneSize - bump_);
// The area [newBump - RedZoneSize .. newBump[ is already flagged as
// no-access either with the previous if-branch or with the
// BumpChunk constructor. No need to mark it twice.
}
#endif #endif
bump_ = newBump; bump_ = newBump;
} }
@ -417,13 +430,27 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
setBump(m.bump_); setBump(m.bump_);
} }
// Given a bump chunk pointer, find the next base/end pointers. This is
// useful for having consistent allocations, and iterating over known size
// allocations.
static uint8_t* nextAllocBase(uint8_t* e) {
return detail::AlignPtr(e);
}
static uint8_t* nextAllocEnd(uint8_t* b, size_t n) {
return b + n + RedZoneSize;
}
// Returns true, if the unused space is large enough for an allocation of // Returns true, if the unused space is large enough for an allocation of
// |n| bytes. // |n| bytes.
bool canAlloc(size_t n); bool canAlloc(size_t n) const {
uint8_t* newBump = nextAllocEnd(nextAllocBase(end()), n);
// bump_ <= newBump, is necessary to catch overflow.
return bump_ <= newBump && newBump <= capacity_;
}
// Space remaining in the current chunk. // Space remaining in the current chunk.
size_t unused() const { size_t unused() const {
uint8_t* aligned = AlignPtr(end()); uint8_t* aligned = nextAllocBase(end());
if (aligned < capacity_) if (aligned < capacity_)
return capacity_ - aligned; return capacity_ - aligned;
return 0; return 0;
@ -432,8 +459,8 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
// Try to perform an allocation of size |n|, returns nullptr if not possible. // Try to perform an allocation of size |n|, returns nullptr if not possible.
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
void* tryAlloc(size_t n) { void* tryAlloc(size_t n) {
uint8_t* aligned = AlignPtr(end()); uint8_t* aligned = nextAllocBase(end());
uint8_t* newBump = aligned + n; uint8_t* newBump = nextAllocEnd(aligned, n);
if (newBump > capacity_) if (newBump > capacity_)
return nullptr; return nullptr;
@ -903,15 +930,15 @@ class LifoAlloc
uint8_t* seekBaseAndAdvanceBy(size_t size) { uint8_t* seekBaseAndAdvanceBy(size_t size) {
MOZ_ASSERT(!empty()); MOZ_ASSERT(!empty());
uint8_t* aligned = detail::AlignPtr(head_); uint8_t* aligned = detail::BumpChunk::nextAllocBase(head_);
if (aligned + size > chunkIt_->end()) { if (detail::BumpChunk::nextAllocEnd(aligned, size) > chunkIt_->end()) {
++chunkIt_; ++chunkIt_;
aligned = chunkIt_->begin(); aligned = chunkIt_->begin();
// The current code assumes that if we have a chunk, then we // The current code assumes that if we have a chunk, then we
// have allocated something it in. // have allocated something it in.
MOZ_ASSERT(!chunkIt_->empty()); MOZ_ASSERT(!chunkIt_->empty());
} }
head_ = aligned + size; head_ = detail::BumpChunk::nextAllocEnd(aligned, size);
MOZ_ASSERT(head_ <= chunkIt_->end()); MOZ_ASSERT(head_ <= chunkIt_->end());
return aligned; return aligned;
} }

View file

@ -26,7 +26,6 @@
#endif #endif
#include "vm/Debugger.h" #include "vm/Debugger.h"
#include "vm/EnvironmentObject.h" #include "vm/EnvironmentObject.h"
#include "vm/RegExpObject.h"
#include "vm/RegExpShared.h" #include "vm/RegExpShared.h"
#include "vm/Scope.h" #include "vm/Scope.h"
#include "vm/Shape.h" #include "vm/Shape.h"

View file

@ -116,6 +116,10 @@ JS_FOR_EACH_TRACEKIND(TRACE_ROOTS)
#undef TRACE_ROOTS #undef TRACE_ROOTS
TracePersistentRootedList<jsid>(trc, heapRoots.ref()[JS::RootKind::Id], "persistent-id"); TracePersistentRootedList<jsid>(trc, heapRoots.ref()[JS::RootKind::Id], "persistent-id");
TracePersistentRootedList<Value>(trc, heapRoots.ref()[JS::RootKind::Value], "persistent-value"); TracePersistentRootedList<Value>(trc, heapRoots.ref()[JS::RootKind::Value], "persistent-value");
// ConcreteTraceable calls through a function pointer.
JS::AutoSuppressGCAnalysis nogc;
TracePersistentRootedList<ConcreteTraceable>( TracePersistentRootedList<ConcreteTraceable>(
trc, heapRoots.ref()[JS::RootKind::Traceable], "persistent-traceable"); trc, heapRoots.ref()[JS::RootKind::Traceable], "persistent-traceable");
} }
@ -391,6 +395,9 @@ js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrM
if (!JS::RuntimeHeapIsMinorCollecting()) { if (!JS::RuntimeHeapIsMinorCollecting()) {
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_EMBEDDING); gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_EMBEDDING);
// The analysis doesn't like the function pointers below.
JS::AutoSuppressGCAnalysis nogc;
/* /*
* The embedding can register additional roots here. * The embedding can register additional roots here.
* *

View file

@ -11,6 +11,7 @@
#include "gc/Barrier.h" #include "gc/Barrier.h"
#include "gc/DeletePolicy.h" #include "gc/DeletePolicy.h"
#include "gc/Zone.h"
#include "js/HashTable.h" #include "js/HashTable.h"
namespace JS { namespace JS {

View file

@ -43,7 +43,6 @@ JS::Zone::Zone(JSRuntime* rt)
weakCaches_(this), weakCaches_(this),
gcWeakKeys_(this, SystemAllocPolicy(), rt->randomHashCodeScrambler()), gcWeakKeys_(this, SystemAllocPolicy(), rt->randomHashCodeScrambler()),
typeDescrObjects_(this, this), typeDescrObjects_(this, this),
regExps(this),
markedAtoms_(this), markedAtoms_(this),
atomCache_(this), atomCache_(this),
externalStringCache_(this), externalStringCache_(this),
@ -97,7 +96,7 @@ Zone::~Zone()
// if the embedding leaked GC things. // if the embedding leaked GC things.
if (!rt->gc.shutdownCollectedEverything()) { if (!rt->gc.shutdownCollectedEverything()) {
gcWeakMapList().clear(); gcWeakMapList().clear();
regExps.clear(); regExps().clear();
} }
#endif #endif
} }
@ -106,7 +105,8 @@ bool
Zone::init(bool isSystemArg) Zone::init(bool isSystemArg)
{ {
isSystem = isSystemArg; isSystem = isSystemArg;
return gcWeakKeys().init(); regExps_.ref() = make_unique<RegExpZone>(this);
return regExps_.ref() && gcWeakKeys().init();
} }
void void
@ -357,7 +357,7 @@ Zone::nextZone() const
void void
Zone::clearTables() Zone::clearTables()
{ {
MOZ_ASSERT(regExps.empty()); MOZ_ASSERT(regExps().empty());
baseShapes().clear(); baseShapes().clear();
initialShapes().clear(); initialShapes().clear();

View file

@ -14,12 +14,12 @@
#include "gc/GCRuntime.h" #include "gc/GCRuntime.h"
#include "js/GCHashTable.h" #include "js/GCHashTable.h"
#include "vm/MallocProvider.h" #include "vm/MallocProvider.h"
#include "vm/RegExpShared.h"
#include "vm/Runtime.h" #include "vm/Runtime.h"
namespace js { namespace js {
class Debugger; class Debugger;
class RegExpZone;
namespace jit { namespace jit {
class JitZone; class JitZone;
@ -459,8 +459,10 @@ class Zone : public JS::shadow::Zone,
counter.recordTrigger(trigger); counter.recordTrigger(trigger);
} }
js::MainThreadData<js::UniquePtr<js::RegExpZone>> regExps_;
public: public:
js::RegExpZone regExps; js::RegExpZone& regExps() { return *regExps_.ref(); }
JS::WeakCache<TypeDescrObjectSet>& typeDescrObjects() { return typeDescrObjects_.ref(); } JS::WeakCache<TypeDescrObjectSet>& typeDescrObjects() { return typeDescrObjects_.ref(); }
@ -755,47 +757,50 @@ class Zone : public JS::shadow::Zone,
namespace js { namespace js {
template <typename T> /*
inline T* * Allocation policy that uses Zone::pod_malloc and friends, so that memory
ZoneAllocPolicy::maybe_pod_malloc(size_t numElems) * pressure is accounted for on the zone. This is suitable for memory associated
* with GC things allocated in the zone.
*
* Since it doesn't hold a JSContext (those may not live long enough), it can't
* report out-of-memory conditions itself; the caller must check for OOM and
* take the appropriate action.
*
* FIXME bug 647103 - replace these *AllocPolicy names.
*/
class ZoneAllocPolicy
{ {
JS::Zone* const zone;
public:
MOZ_IMPLICIT ZoneAllocPolicy(JS::Zone* z) : zone(z) {}
template <typename T> T* maybe_pod_malloc(size_t numElems) {
return zone->maybe_pod_malloc<T>(numElems); return zone->maybe_pod_malloc<T>(numElems);
} }
template <typename T> T* maybe_pod_calloc(size_t numElems) {
template <typename T>
inline T*
ZoneAllocPolicy::maybe_pod_calloc(size_t numElems)
{
return zone->maybe_pod_calloc<T>(numElems); return zone->maybe_pod_calloc<T>(numElems);
} }
template <typename T> T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) {
template <typename T>
inline T*
ZoneAllocPolicy::maybe_pod_realloc(T* p, size_t oldSize, size_t newSize)
{
return zone->maybe_pod_realloc<T>(p, oldSize, newSize); return zone->maybe_pod_realloc<T>(p, oldSize, newSize);
} }
template <typename T> T* pod_malloc(size_t numElems) {
template <typename T>
inline T*
ZoneAllocPolicy::pod_malloc(size_t numElems)
{
return zone->pod_malloc<T>(numElems); return zone->pod_malloc<T>(numElems);
} }
template <typename T> T* pod_calloc(size_t numElems) {
template <typename T>
inline T*
ZoneAllocPolicy::pod_calloc(size_t numElems)
{
return zone->pod_calloc<T>(numElems); return zone->pod_calloc<T>(numElems);
} }
template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
template <typename T>
inline T*
ZoneAllocPolicy::pod_realloc(T* p, size_t oldSize, size_t newSize)
{
return zone->pod_realloc<T>(p, oldSize, newSize); return zone->pod_realloc<T>(p, oldSize, newSize);
} }
template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); }
void reportAllocOverflow() const {}
MOZ_MUST_USE bool checkSimulatedOOM() const {
return !js::oom::ShouldFailWithOOM();
}
};
} // namespace js } // namespace js

View file

@ -7,6 +7,6 @@ while(i++ < 500) {
assertFloat32(0x23456789 | 0, false); assertFloat32(0x23456789 | 0, false);
`); `);
let m = parseModule(""); let m = parseModule("");
m.declarationInstantiation(); instantiateModule(m);
} }

View file

@ -1,4 +1,4 @@
// |jit-test| --no-threads; --ion-eager; --ion-shared-stubs=off // |jit-test| --no-threads; --ion-eager;
setJitCompilerOption('ion.forceinlineCaches', 1); setJitCompilerOption('ion.forceinlineCaches', 1);
function foo(t) { function foo(t) {
"use strict"; "use strict";

View file

@ -32,8 +32,8 @@ loadFile(lfLogBuffer);
function loadFile(lfVarx) { function loadFile(lfVarx) {
try { try {
let m = parseModule(lfVarx); let m = parseModule(lfVarx);
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);
} catch (lfVare) {} } catch (lfVare) {}
} }

View file

@ -17,5 +17,5 @@ let m = parseModule(`
f(i); f(i);
actual; actual;
`); `);
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);

View file

@ -0,0 +1,14 @@
// |jit-test| error: SyntaxError;
g = newGlobal();
dbg = new Debugger;
setInterruptCallback(function () {
dbg.addDebuggee(g);
dbg.getNewestFrame();
return true;
});
g.eval("" + function f() {
for (var i = 0; i < 1; evaluate("class h { constructor() {} }")) {
interruptIf(1);
}
});
g.f();

View file

@ -5,5 +5,5 @@ for (var i=0; i < 10000; ++i) {
for (var x of iterator) {} for (var x of iterator) {}
} }
`); `);
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);

View file

@ -11,7 +11,7 @@ loadFile(lfLogBuffer);
function loadFile(lfVarx) { function loadFile(lfVarx) {
oomTest(function() { oomTest(function() {
let m = parseModule(lfVarx); let m = parseModule(lfVarx);
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);
}); });
} }

View file

@ -3,6 +3,6 @@ if (!('oomTest' in this))
oomTest(function() { oomTest(function() {
m = parseModule(`while (x && NaN) prototype; let x`); m = parseModule(`while (x && NaN) prototype; let x`);
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);
}) })

View file

@ -7,21 +7,21 @@ load(libdir + "dummyModuleResolveHook.js");
function checkModuleEval(source) { function checkModuleEval(source) {
let m = parseModule(source); let m = parseModule(source);
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);
return m; return m;
} }
function checkModuleSyntaxError(source) { function checkModuleSyntaxError(source) {
let m = parseModule(source); let m = parseModule(source);
assertThrowsInstanceOf(() => m.declarationInstantiation(), SyntaxError); assertThrowsInstanceOf(() => instantiateModule(m), SyntaxError);
} }
let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;"); let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;");
let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;"); let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;");
let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';"); let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");
c.declarationInstantiation(); instantiateModule(c);
c.evaluation(); evaluateModule(c);
// Check importing/exporting non-ambiguous name works. // Check importing/exporting non-ambiguous name works.
let d = checkModuleEval("import { a } from 'c';"); let d = checkModuleEval("import { a } from 'c';");
@ -34,9 +34,9 @@ checkModuleSyntaxError("export { b } from 'c';");
// Check that namespace objects include only non-ambiguous names. // Check that namespace objects include only non-ambiguous names.
let m = parseModule("import * as ns from 'c';"); let m = parseModule("import * as ns from 'c';");
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);
let ns = c.namespace; let ns = getModuleObject(c).namespace;
let names = Object.keys(ns); let names = Object.keys(ns);
assertEq(names.length, 2); assertEq(names.length, 2);
assertEq('a' in ns, true); assertEq('a' in ns, true);

View file

@ -14,4 +14,4 @@ moduleRepo['D'] = parseModule('export let x');
moduleRepo['E'] = parseModule('export let x'); moduleRepo['E'] = parseModule('export let x');
let m = moduleRepo['A']; let m = moduleRepo['A'];
assertThrowsInstanceOf(() => m.declarationInstantiation(), SyntaxError); assertThrowsInstanceOf(() => instantiateModule(m), SyntaxError);

View file

@ -7,5 +7,5 @@ g.eval("(" + function() {
}; };
} + ")()"); } + ")()");
m = parseModule(` s1 `); m = parseModule(` s1 `);
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);

View file

@ -1,2 +1,2 @@
let m = parseModule(`{ function x() {} }`); let m = parseModule(`{ function x() {} }`);
m.declarationInstantiation(); instantiateModule(m);

View file

@ -11,5 +11,5 @@ m = parseModule(`
function g() { return this.hours = 0; } function g() { return this.hours = 0; }
evalInFrame.call(0, 0, "g()") evalInFrame.call(0, 0, "g()")
`); `);
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);

View file

@ -6,4 +6,4 @@ setJitCompilerOption("ion.warmup.trigger", 50);
s = ""; s = "";
for (i = 0; i < 1024; i++) s += "export let e" + i + "\n"; for (i = 0; i < 1024; i++) s += "export let e" + i + "\n";
moduleRepo['a'] = parseModule(s); moduleRepo['a'] = parseModule(s);
parseModule("import * as ns from 'a'").declarationInstantiation(); instantiateModule(parseModule("import * as ns from 'a'"));

View file

@ -6,5 +6,5 @@ setModuleResolveHook(function(module, specifier) {
}); });
let a = moduleRepo['a'] = parseModule("var x = 1; export { x };"); let a = moduleRepo['a'] = parseModule("var x = 1; export { x };");
let b = moduleRepo['b'] = parseModule("import { x as y } from 'a';"); let b = moduleRepo['b'] = parseModule("import { x as y } from 'a';");
a.__proto__ = {15: 1337}; getModuleObject(a).__proto__ = {15: 1337};
b.declarationInstantiation(); instantiateModule(b);

View file

@ -15,7 +15,7 @@ let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");
let e1; let e1;
let threw = false; let threw = false;
try { try {
c.declarationInstantiation(); instantiateModule(c);
} catch (exc) { } catch (exc) {
threw = true; threw = true;
e1 = exc; e1 = exc;
@ -26,7 +26,7 @@ assertEq(typeof e1 === "undefined", false);
threw = false; threw = false;
let e2; let e2;
try { try {
c.declarationInstantiation(); instantiateModule(c);
} catch (exc) { } catch (exc) {
threw = true; threw = true;
e2 = exc; e2 = exc;

View file

@ -15,7 +15,7 @@ let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");
let e1; let e1;
let threw = false; let threw = false;
try { try {
c.declarationInstantiation(); instantiateModule(c);
} catch (exc) { } catch (exc) {
threw = true; threw = true;
e1 = exc; e1 = exc;
@ -28,7 +28,7 @@ let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;");
threw = false; threw = false;
try { try {
d.declarationInstantiation(); instantiateModule(d);
} catch (exc) { } catch (exc) {
threw = true; threw = true;
} }

View file

@ -9,7 +9,7 @@ setModuleResolveHook(function(module, specifier) {
let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;"); let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;");
let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;"); let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;");
let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';"); let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");
c.declarationInstantiation(); instantiateModule(c);
// Module 'a' is replaced with another module that has not been instantiated. // Module 'a' is replaced with another module that has not been instantiated.
// This should not happen and would be a bug in the module loader. // This should not happen and would be a bug in the module loader.
@ -19,5 +19,5 @@ let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;");
// Attempting to instantiate 'd' throws an error because depdency 'a' of // Attempting to instantiate 'd' throws an error because depdency 'a' of
// instantiated module 'c' is not instantiated. // instantiated module 'c' is not instantiated.
d.declarationInstantiation(); instantiateModule(d);
d.evaluation(); evaluateModule(d);

View file

@ -24,5 +24,5 @@ for (let i = 0; i < count; i++) {
} }
let b = moduleRepo['b'] = parseModule(s); let b = moduleRepo['b'] = parseModule(s);
b.declarationInstantiation(); instantiateModule(b);
b.evaluation(); evaluateModule(b);

View file

@ -3,5 +3,5 @@ if (!('stackTest' in this))
stackTest(function() { stackTest(function() {
let m = parseModule(``); let m = parseModule(``);
m.declarationInstantiation(); instantiateModule(m);
}); });

View file

@ -4,7 +4,7 @@ if (!('oomTest' in this))
loadFile(` loadFile(`
function parseAndEvaluate(source) { function parseAndEvaluate(source) {
let m = parseModule(source); let m = parseModule(source);
m.declarationInstantiation(); instantiateModule(m);
} }
parseAndEvaluate("async function a() { await 2 + 3; }") parseAndEvaluate("async function a() { await 2 + 3; }")
`); `);

View file

@ -1,5 +1,5 @@
// |jit-test| error: Error // |jit-test| error: Error
let m = parseModule(`for (var x of iterator) {}`); let m = parseModule(`for (var x of iterator) {}`);
m.declarationInstantiation(); instantiateModule(m);
try { m.evaluation(); } catch (e) {} try { evaluateModule(m); } catch (e) {}
getModuleEnvironmentValue(m, "r"); getModuleEnvironmentValue(m, "r");

View file

@ -14,5 +14,5 @@ moduleRepo["a"] = parseModule(`import* as ns from "good"; import {y} from "bad";
let b = moduleRepo["b"] = parseModule(`import "a";`); let b = moduleRepo["b"] = parseModule(`import "a";`);
let c = moduleRepo["c"] = parseModule(`import "a";`); let c = moduleRepo["c"] = parseModule(`import "a";`);
assertThrowsInstanceOf(() => b.declarationInstantiation(), SyntaxError); assertThrowsInstanceOf(() => instantiateModule(b), SyntaxError);
assertThrowsInstanceOf(() => c.declarationInstantiation(), SyntaxError); assertThrowsInstanceOf(() => instantiateModule(c), SyntaxError);

View file

@ -2,7 +2,7 @@ if (!('stackTest' in this))
quit(); quit();
let a = parseModule(`throw new Error`); let a = parseModule(`throw new Error`);
a.declarationInstantiation(); instantiateModule(a);
stackTest(function() { stackTest(function() {
a.evaluation(); evaluateModule(a);
}); });

View file

@ -6,10 +6,10 @@ moduleRepo["a"] = parseModule(`throw undefined`);
let b = moduleRepo["b"] = parseModule(`import "a";`); let b = moduleRepo["b"] = parseModule(`import "a";`);
let c = moduleRepo["c"] = parseModule(`import "a";`); let c = moduleRepo["c"] = parseModule(`import "a";`);
b.declarationInstantiation(); instantiateModule(b);
c.declarationInstantiation(); instantiateModule(c);
let count = 0; let count = 0;
try { b.evaluation() } catch (e) { count++; } try { evaluateModule(b) } catch (e) { count++; }
try { c.evaluation() } catch (e) { count++; } try { evaluateModule(c) } catch (e) { count++; }
assertEq(count, 2); assertEq(count, 2);

View file

@ -14,5 +14,5 @@ moduleRepo["a"] = parseModule(`import {x} from "good"; import {y} from "bad";`);
let b = moduleRepo["b"] = parseModule(`import "a";`); let b = moduleRepo["b"] = parseModule(`import "a";`);
let c = moduleRepo["c"] = parseModule(`import "a";`); let c = moduleRepo["c"] = parseModule(`import "a";`);
assertThrowsInstanceOf(() => b.declarationInstantiation(), SyntaxError); assertThrowsInstanceOf(() => instantiateModule(b), SyntaxError);
assertThrowsInstanceOf(() => c.declarationInstantiation(), SyntaxError); assertThrowsInstanceOf(() => instantiateModule(c), SyntaxError);

View file

@ -8,7 +8,7 @@ lfLogBuffer = `
}); });
let c = moduleRepo['c'] = parseModule(""); let c = moduleRepo['c'] = parseModule("");
let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;"); let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;");
d.declarationInstantiation(); instantiateModule(d);
`; `;
lfLogBuffer = lfLogBuffer.split('\n'); lfLogBuffer = lfLogBuffer.split('\n');
var lfCodeBuffer = ""; var lfCodeBuffer = "";
@ -25,8 +25,8 @@ function loadFile(lfVarx) {
try { try {
oomTest(function() { oomTest(function() {
let m = parseModule(lfVarx); let m = parseModule(lfVarx);
m.declarationInstantiation(); instantiateModule(m);
m.evaluation(); evaluateModule(m);
}); });
} catch (lfVare) {} } catch (lfVare) {}
} }

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