forked from mirrors/gecko-dev
Merge mozilla-central to autoland. a=merge
--HG-- rename : testing/web-platform/tests/css/compositing/support/parsing-testcommon.js => testing/web-platform/tests/css/compositing/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-backgrounds/support/parsing-testcommon.js => testing/web-platform/tests/css/css-backgrounds/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-box/support/parsing-testcommon.js => testing/web-platform/tests/css/css-box/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-cascade/support/parsing-testcommon.js => testing/web-platform/tests/css/css-cascade/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-color/support/parsing-testcommon.js => testing/web-platform/tests/css/css-color/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-images/support/parsing-testcommon.js => testing/web-platform/tests/css/css-images/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-masking/support/parsing-testcommon.js => testing/web-platform/tests/css/css-masking/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-shapes/support/parsing-testcommon.js => testing/web-platform/tests/css/css-shapes/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-transforms/support/parsing-testcommon.js => testing/web-platform/tests/css/css-transforms/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-ui/support/parsing-testcommon.js => testing/web-platform/tests/css/css-ui/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/css-writing-modes/support/parsing-testcommon.js => testing/web-platform/tests/css/css-writing-modes/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/filter-effects/support/parsing-testcommon.js => testing/web-platform/tests/css/filter-effects/parsing/support/parsing-testcommon.js rename : testing/web-platform/tests/css/motion/support/parsing-testcommon.js => testing/web-platform/tests/css/motion/parsing/support/parsing-testcommon.js rename : third_party/rust/crossbeam-deque/.cargo-checksum.json => third_party/rust/crossbeam-deque-0.2.0/.cargo-checksum.json rename : third_party/rust/crossbeam-deque/.travis.yml => third_party/rust/crossbeam-deque-0.2.0/.travis.yml rename : third_party/rust/crossbeam-deque/CHANGELOG.md => third_party/rust/crossbeam-deque-0.2.0/CHANGELOG.md rename : third_party/rust/crossbeam-deque/Cargo.toml => third_party/rust/crossbeam-deque-0.2.0/Cargo.toml rename : third_party/rust/bitflags-0.7.0/LICENSE-APACHE => third_party/rust/crossbeam-deque-0.2.0/LICENSE-APACHE rename : third_party/rust/crossbeam-deque/README.md => third_party/rust/crossbeam-deque-0.2.0/README.md rename : third_party/rust/crossbeam-deque/src/lib.rs => third_party/rust/crossbeam-deque-0.2.0/src/lib.rs rename : third_party/rust/crossbeam-epoch/.cargo-checksum.json => third_party/rust/crossbeam-epoch-0.3.1/.cargo-checksum.json rename : third_party/rust/crossbeam-epoch/.travis.yml => third_party/rust/crossbeam-epoch-0.3.1/.travis.yml rename : third_party/rust/crossbeam-epoch/CHANGELOG.md => third_party/rust/crossbeam-epoch-0.3.1/CHANGELOG.md rename : third_party/rust/crossbeam-epoch/Cargo.toml => third_party/rust/crossbeam-epoch-0.3.1/Cargo.toml rename : third_party/rust/tokio-io/LICENSE-APACHE => third_party/rust/crossbeam-epoch-0.3.1/LICENSE-APACHE rename : third_party/rust/crossbeam-epoch/README.md => third_party/rust/crossbeam-epoch-0.3.1/README.md rename : third_party/rust/crossbeam-epoch/examples/sanitize.rs => third_party/rust/crossbeam-epoch-0.3.1/examples/sanitize.rs rename : third_party/rust/crossbeam-epoch/src/atomic.rs => third_party/rust/crossbeam-epoch-0.3.1/src/atomic.rs rename : third_party/rust/crossbeam-epoch/src/collector.rs => third_party/rust/crossbeam-epoch-0.3.1/src/collector.rs rename : third_party/rust/crossbeam-epoch/src/default.rs => third_party/rust/crossbeam-epoch-0.3.1/src/default.rs rename : third_party/rust/crossbeam-epoch/src/deferred.rs => third_party/rust/crossbeam-epoch-0.3.1/src/deferred.rs rename : third_party/rust/crossbeam-epoch/src/epoch.rs => third_party/rust/crossbeam-epoch-0.3.1/src/epoch.rs rename : third_party/rust/crossbeam-epoch/src/garbage.rs => third_party/rust/crossbeam-epoch-0.3.1/src/garbage.rs rename : third_party/rust/crossbeam-epoch/src/guard.rs => third_party/rust/crossbeam-epoch-0.3.1/src/guard.rs rename : third_party/rust/crossbeam-epoch/src/internal.rs => third_party/rust/crossbeam-epoch-0.3.1/src/internal.rs rename : third_party/rust/crossbeam-epoch/src/lib.rs => third_party/rust/crossbeam-epoch-0.3.1/src/lib.rs rename : third_party/rust/crossbeam-epoch/src/sync/list.rs => third_party/rust/crossbeam-epoch-0.3.1/src/sync/list.rs rename : third_party/rust/crossbeam-epoch/src/sync/queue.rs => third_party/rust/crossbeam-epoch-0.3.1/src/sync/queue.rs rename : third_party/rust/crossbeam-utils/.cargo-checksum.json => third_party/rust/crossbeam-utils-0.2.2/.cargo-checksum.json rename : third_party/rust/crossbeam-utils/CHANGELOG.md => third_party/rust/crossbeam-utils-0.2.2/CHANGELOG.md rename : third_party/rust/crossbeam-utils/Cargo.toml => third_party/rust/crossbeam-utils-0.2.2/Cargo.toml rename : third_party/rust/bitflags-0.7.0/LICENSE-APACHE => third_party/rust/crossbeam-utils-0.2.2/LICENSE-APACHE rename : third_party/rust/crossbeam-utils/src/atomic_option.rs => third_party/rust/crossbeam-utils-0.2.2/src/atomic_option.rs rename : third_party/rust/crossbeam-utils/src/lib.rs => third_party/rust/crossbeam-utils-0.2.2/src/lib.rs rename : third_party/rust/crossbeam-utils/src/scoped.rs => third_party/rust/crossbeam-utils-0.2.2/src/scoped.rs rename : third_party/rust/bitflags-0.7.0/LICENSE-APACHE => third_party/rust/indexmap/LICENSE-APACHE rename : third_party/rust/lazycell/.cargo-checksum.json => third_party/rust/lazycell-0.4.0/.cargo-checksum.json rename : third_party/rust/lazycell/CHANGELOG.md => third_party/rust/lazycell-0.4.0/CHANGELOG.md rename : third_party/rust/lazycell/Cargo.toml => third_party/rust/lazycell-0.4.0/Cargo.toml rename : third_party/rust/bitflags-0.7.0/LICENSE-APACHE => third_party/rust/lazycell-0.4.0/LICENSE-APACHE rename : third_party/rust/lazycell/LICENSE-MIT => third_party/rust/lazycell-0.4.0/LICENSE-MIT rename : third_party/rust/lazycell/README.md => third_party/rust/lazycell-0.4.0/README.md rename : third_party/rust/lazycell/src/lib.rs => third_party/rust/lazycell-0.4.0/src/lib.rs rename : third_party/rust/bitflags-0.7.0/LICENSE-APACHE => third_party/rust/rand-0.3.22/LICENSE-APACHE rename : third_party/rust/bitflags-0.7.0/LICENSE-MIT => third_party/rust/rand-0.3.22/LICENSE-MIT rename : third_party/rust/rand/appveyor.yml => third_party/rust/rand-0.3.22/appveyor.yml rename : third_party/rust/slab/.cargo-checksum.json => third_party/rust/slab-0.3.0/.cargo-checksum.json rename : third_party/rust/slab/Cargo.toml => third_party/rust/slab-0.3.0/Cargo.toml rename : third_party/rust/slab/README.md => third_party/rust/slab-0.3.0/README.md rename : third_party/rust/slab/src/lib.rs => third_party/rust/slab-0.3.0/src/lib.rs rename : third_party/rust/tokio-io/src/read_to_end.rs => third_party/rust/tokio-io/src/io/read_to_end.rs rename : third_party/rust/tokio-io/src/read_until.rs => third_party/rust/tokio-io/src/io/read_until.rs extra : rebase_source : 4c022c31e626832d12535d88e7caea452419ac2f
This commit is contained in:
commit
469b620e12
1614 changed files with 134342 additions and 36736 deletions
|
|
@ -48,12 +48,18 @@ tasks:
|
|||
|
||||
tags:
|
||||
$if: 'tasks_for == "hg-push"'
|
||||
then: {createdForUser: "${ownerEmail}"}
|
||||
then:
|
||||
createdForUser: "${ownerEmail}"
|
||||
kind: decision-task
|
||||
else:
|
||||
$if: 'tasks_for == "action"'
|
||||
then:
|
||||
createdForUser: '${ownerEmail}'
|
||||
kind: 'action-callback'
|
||||
else:
|
||||
$if: 'tasks_for == "cron"'
|
||||
then:
|
||||
kind: cron-task
|
||||
|
||||
routes:
|
||||
$flatten:
|
||||
|
|
|
|||
550
Cargo.lock
generated
550
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -416,7 +416,7 @@ skip-if = verify
|
|||
[browser_tab_drag_drop_perwindow.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[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.
|
||||
[browser_tab_dragdrop2.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
|
|
|
|||
|
|
@ -589,11 +589,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|||
// invoked regardless, thus this should be enough.
|
||||
if (this._formattingInstance != instance)
|
||||
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
|
||||
// char just after the domain, and in such a case we should not
|
||||
// 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;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -239,7 +239,6 @@
|
|||
}
|
||||
50% {
|
||||
transform: translateX(-1232px);
|
||||
fill: var(--tracking-protection-shield-color);
|
||||
}
|
||||
65% {
|
||||
fill: var(--tracking-protection-shield-color);
|
||||
|
|
@ -266,7 +265,6 @@
|
|||
}
|
||||
50% {
|
||||
transform: scaleX(-1) translateX(-1232px);
|
||||
fill: var(--tracking-protection-shield-color);
|
||||
}
|
||||
65% {
|
||||
fill: var(--tracking-protection-shield-color);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
This is the debugger.html project output.
|
||||
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:
|
||||
- babel-plugin-transform-es2015-modules-commonjs @6.26.2
|
||||
|
|
|
|||
1900
devtools/client/debugger/new/dist/vendors.js
vendored
1900
devtools/client/debugger/new/dist/vendors.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -8,7 +8,6 @@ exports.selectSourceURL = selectSourceURL;
|
|||
exports.selectSource = selectSource;
|
||||
exports.selectLocation = selectLocation;
|
||||
exports.selectSpecificLocation = selectSpecificLocation;
|
||||
exports.selectSpecificSource = selectSpecificSource;
|
||||
exports.jumpToMappedLocation = jumpToMappedLocation;
|
||||
exports.jumpToMappedSelectedLocation = jumpToMappedSelectedLocation;
|
||||
|
||||
|
|
@ -106,7 +105,7 @@ function selectSource(sourceId) {
|
|||
const location = (0, _location.createLocation)({
|
||||
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) {
|
||||
return async function ({
|
||||
dispatch,
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ async function checkServerSupportsListWorkers() {
|
|||
return false;
|
||||
}
|
||||
|
||||
const deviceFront = await (0, _frontsDevice.getDeviceFront)(debuggerClient, root);
|
||||
const deviceFront = await debuggerClient.mainRoot.getFront("device");
|
||||
const description = await deviceFront.getDescription();
|
||||
const isFennec = description.apptype === "mobile/android";
|
||||
|
||||
|
|
@ -438,4 +438,4 @@ const clientCommands = {
|
|||
setSkipPausing
|
||||
};
|
||||
exports.setupCommands = setupCommands;
|
||||
exports.clientCommands = clientCommands;
|
||||
exports.clientCommands = clientCommands;
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ class Tab extends _react.PureComponent {
|
|||
render() {
|
||||
const {
|
||||
selectedSource,
|
||||
selectSpecificSource,
|
||||
selectSource,
|
||||
closeTab,
|
||||
source,
|
||||
tabSources
|
||||
|
|
@ -149,7 +149,7 @@ class Tab extends _react.PureComponent {
|
|||
function handleTabClick(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return selectSpecificSource(sourceId);
|
||||
return selectSource(sourceId);
|
||||
}
|
||||
|
||||
const className = (0, _classnames2.default)("source-tab", {
|
||||
|
|
@ -190,7 +190,7 @@ const mapStateToProps = (state, {
|
|||
};
|
||||
|
||||
exports.default = (0, _reactRedux.connect)(mapStateToProps, {
|
||||
selectSpecificSource: _actions2.default.selectSpecificSource,
|
||||
selectSource: _actions2.default.selectSource,
|
||||
closeTab: _actions2.default.closeTab,
|
||||
closeTabs: _actions2.default.closeTabs,
|
||||
togglePrettyPrint: _actions2.default.togglePrettyPrint,
|
||||
|
|
|
|||
|
|
@ -67,11 +67,11 @@ class Tabs extends _react.PureComponent {
|
|||
|
||||
this.renderDropdownSource = source => {
|
||||
const {
|
||||
selectSpecificSource
|
||||
selectSource
|
||||
} = this.props;
|
||||
const filename = (0, _source.getFilename)(source);
|
||||
|
||||
const onClick = () => selectSpecificSource(source.id);
|
||||
const onClick = () => selectSource(source.id);
|
||||
|
||||
return _react2.default.createElement("li", {
|
||||
key: source.id,
|
||||
|
|
@ -206,7 +206,7 @@ const mapStateToProps = state => ({
|
|||
});
|
||||
|
||||
exports.default = (0, _reactRedux.connect)(mapStateToProps, {
|
||||
selectSpecificSource: _actions2.default.selectSpecificSource,
|
||||
selectSource: _actions2.default.selectSource,
|
||||
moveTab: _actions2.default.moveTab,
|
||||
closeTab: _actions2.default.closeTab,
|
||||
togglePaneCollapse: _actions2.default.togglePaneCollapse,
|
||||
|
|
|
|||
|
|
@ -247,17 +247,14 @@ var _initialiseProps = function () {
|
|||
|
||||
this.getPath = item => {
|
||||
const path = `${item.path}/${item.name}`;
|
||||
const source = this.getSource(item);
|
||||
|
||||
if ((0, _sourcesTree.isDirectory)(item)) {
|
||||
if (!source || (0, _sourcesTree.isDirectory)(item)) {
|
||||
return path;
|
||||
}
|
||||
|
||||
const source = this.getSource(item);
|
||||
const blackBoxedPart = source && source.isBlackBoxed ? ":blackboxed" : ""; // Original and generated sources can point to the same path
|
||||
// therefore necessary to distinguish as path is used as keys.
|
||||
|
||||
const generatedPart = source && source.sourceMapURL ? ":generated" : "";
|
||||
return `${path}${blackBoxedPart}${generatedPart}`;
|
||||
const blackBoxedPart = source.isBlackBoxed ? ":blackboxed" : "";
|
||||
return `${path}/${source.id}/${blackBoxedPart}`;
|
||||
};
|
||||
|
||||
this.onExpand = (item, expandedState) => {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
function findSource(dbg, url) {
|
||||
const sources = dbg.selectors.getSources();
|
||||
const source = sources.find(s => (s.url || "").includes(url));
|
||||
const sources = dbg.selectors.getSourceList();
|
||||
return sources.find(s => (s.url || "").includes(url));
|
||||
}
|
||||
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
return source;
|
||||
function findSources(dbg, url) {
|
||||
const sources = dbg.selectors.getSourceList();
|
||||
return sources.filter(s => (s.url || "").includes(url));
|
||||
}
|
||||
|
||||
function sendPacket(dbg, packet, callback) {
|
||||
|
|
@ -76,6 +75,7 @@ function setupHelper(obj) {
|
|||
getCM,
|
||||
helpers: {
|
||||
findSource: url => findSource(dbg, url),
|
||||
findSources: url => findSources(dbg, url),
|
||||
evaluate: (expression, cbk) => evaluate(dbg, expression, cbk),
|
||||
sendPacketToThread: (packet, cbk) => sendPacketToThread(dbg, packet, cbk),
|
||||
sendPacket: (packet, cbk) => sendPacket(dbg, packet, cbk)
|
||||
|
|
|
|||
|
|
@ -31,8 +31,13 @@ async function buildMappedScopes(source, frame, scopes, sourceMaps, client) {
|
|||
return null;
|
||||
}
|
||||
|
||||
const generatedAstBindings = (0, _buildGeneratedBindingList.buildGeneratedBindingList)(scopes, generatedAstScopes, frame.this);
|
||||
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 {
|
||||
mappedOriginalScopes,
|
||||
expressionLookup
|
||||
|
|
@ -104,6 +109,10 @@ function isReliableScope(scope) {
|
|||
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) {
|
||||
const precalculatedRanges = new Map();
|
||||
const precalculatedLocations = new Map(); // Explicitly dispatch all of the sourcemap requests synchronously up front so
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
const prefsSchemaVersion = "1.0.3";
|
||||
const prefsSchemaVersion = "1.0.4";
|
||||
const pref = _devtoolsServices2.default.pref;
|
||||
|
||||
if ((0, _devtoolsEnvironment.isDevelopment)()) {
|
||||
|
|
@ -128,5 +128,6 @@ const asyncStore = exports.asyncStore = (0, _asyncStoreHelper.asyncStoreHelper)(
|
|||
if (prefs.debuggerPrefsSchemaVersion !== prefsSchemaVersion) {
|
||||
// clear pending Breakpoints
|
||||
prefs.pendingBreakpoints = {};
|
||||
prefs.tabs = [];
|
||||
prefs.debuggerPrefsSchemaVersion = prefsSchemaVersion;
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ add_task(async function() {
|
|||
]);
|
||||
|
||||
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 assertNoTooltip(dbg);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ add_task(async function() {
|
|||
ok(true, "Original sources exist");
|
||||
const bundleSrc = findSource(dbg, "bundle.js");
|
||||
|
||||
await selectSpecificSource(dbg, bundleSrc);
|
||||
await selectSource(dbg, bundleSrc);
|
||||
|
||||
await clickGutter(dbg, 13);
|
||||
await waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
|
|
@ -61,7 +61,7 @@ add_task(async function() {
|
|||
|
||||
const entrySrc = findSource(dbg, "entry.js");
|
||||
|
||||
await selectSpecificSource(dbg, entrySrc);
|
||||
await selectSource(dbg, entrySrc);
|
||||
ok(
|
||||
getCM(dbg)
|
||||
.getValue()
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ add_task(async function() {
|
|||
ok(true, "Original sources exist");
|
||||
const mainSrc = findSource(dbg, "fib.c");
|
||||
|
||||
await selectSpecificSource(dbg, mainSrc);
|
||||
await selectSource(dbg, mainSrc);
|
||||
await addBreakpoint(dbg, "fib.c", 10);
|
||||
|
||||
resume(dbg);
|
||||
|
|
|
|||
|
|
@ -598,12 +598,6 @@ function waitForLoadedSources(dbg) {
|
|||
* @static
|
||||
*/
|
||||
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);
|
||||
await dbg.actions.selectLocation({ sourceId: source.id, line }, {keepContext: false});
|
||||
return waitForSelectedSource(dbg, url);
|
||||
|
|
|
|||
|
|
@ -53,30 +53,33 @@ function SourceMapURLService(toolbox, sourceMapService) {
|
|||
*/
|
||||
SourceMapURLService.prototype._getLoadingPromise = function() {
|
||||
if (!this._loadingPromise) {
|
||||
let styleSheetsLoadingPromise = null;
|
||||
this._stylesheetsFront = this._toolbox.initStyleSheetsFront();
|
||||
if (this._stylesheetsFront) {
|
||||
this._loadingPromise = (async () => {
|
||||
if (this._target.isWorkerTarget) {
|
||||
return;
|
||||
}
|
||||
this._stylesheetsFront = await this._target.getFront("stylesheets");
|
||||
this._stylesheetsFront.on("stylesheet-added", this._onNewStyleSheet);
|
||||
styleSheetsLoadingPromise =
|
||||
const styleSheetsLoadingPromise =
|
||||
this._stylesheetsFront.getStyleSheets().then(sheets => {
|
||||
sheets.forEach(this._onNewStyleSheet);
|
||||
}, () => {
|
||||
// Ignore any protocol-based errors.
|
||||
});
|
||||
}
|
||||
|
||||
// Start fetching the sources now.
|
||||
const loadingPromise = this._toolbox.threadClient.getSources().then(({sources}) => {
|
||||
// Ignore errors. Register the sources we got; we can't rely on
|
||||
// an event to arrive if the source actor already existed.
|
||||
for (const source of sources) {
|
||||
this._onSourceUpdated({source});
|
||||
}
|
||||
}, e => {
|
||||
// Also ignore any protocol-based errors.
|
||||
});
|
||||
// Start fetching the sources now.
|
||||
const loadingPromise = this._toolbox.threadClient.getSources().then(({sources}) => {
|
||||
// Ignore errors. Register the sources we got; we can't rely on
|
||||
// an event to arrive if the source actor already existed.
|
||||
for (const source of sources) {
|
||||
this._onSourceUpdated({source});
|
||||
}
|
||||
}, e => {
|
||||
// Also ignore any protocol-based errors.
|
||||
});
|
||||
|
||||
this._loadingPromise = Promise.all([styleSheetsLoadingPromise, loadingPromise]);
|
||||
await styleSheetsLoadingPromise;
|
||||
await loadingPromise;
|
||||
})();
|
||||
}
|
||||
return this._loadingPromise;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ loader.lazyRequireGetter(this, "DebuggerClient",
|
|||
"devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(this, "gDevTools",
|
||||
"devtools/client/framework/devtools", true);
|
||||
loader.lazyRequireGetter(this, "getFront", "devtools/shared/protocol", true);
|
||||
|
||||
const targets = new WeakMap();
|
||||
const promiseTargets = new WeakMap();
|
||||
|
|
@ -138,6 +139,9 @@ function TabTarget(tab) {
|
|||
} else {
|
||||
this._isBrowsingContext = true;
|
||||
}
|
||||
// Cache of already created targed-scoped fronts
|
||||
// [typeName:string => Front instance]
|
||||
this.fronts = new Map();
|
||||
}
|
||||
|
||||
exports.TabTarget = TabTarget;
|
||||
|
|
@ -271,26 +275,21 @@ TabTarget.prototype = {
|
|||
return this._form;
|
||||
},
|
||||
|
||||
// Get a promise of the root form returned by a getRoot request. This promise
|
||||
// is cached.
|
||||
// Get a promise of the RootActor's form
|
||||
get root() {
|
||||
if (!this._root) {
|
||||
this._root = this._getRoot();
|
||||
}
|
||||
return this._root;
|
||||
return this.client.mainRoot.rootForm;
|
||||
},
|
||||
|
||||
_getRoot: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.client.mainRoot.getRoot(response => {
|
||||
if (response.error) {
|
||||
reject(new Error(response.error + ": " + response.message));
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
// Get a Front for a target-scoped actor.
|
||||
// i.e. an actor served by RootActor.listTabs or RootActorActor.getTab requests
|
||||
getFront(typeName) {
|
||||
let front = this.fronts.get(typeName);
|
||||
if (front) {
|
||||
return front;
|
||||
}
|
||||
front = getFront(this.client, typeName, this.form);
|
||||
this.fronts.set(typeName, front);
|
||||
return front;
|
||||
},
|
||||
|
||||
get client() {
|
||||
|
|
@ -506,7 +505,6 @@ TabTarget.prototype = {
|
|||
*/
|
||||
_setupListeners: function() {
|
||||
this.tab.addEventListener("TabClose", this);
|
||||
this.tab.parentNode.addEventListener("TabSelect", this);
|
||||
this.tab.ownerDocument.defaultView.addEventListener("unload", this);
|
||||
this.tab.addEventListener("TabRemotenessChange", this);
|
||||
},
|
||||
|
|
@ -517,7 +515,6 @@ TabTarget.prototype = {
|
|||
_teardownListeners: function() {
|
||||
this._tab.ownerDocument.defaultView.removeEventListener("unload", this);
|
||||
this._tab.removeEventListener("TabClose", this);
|
||||
this._tab.parentNode.removeEventListener("TabSelect", this);
|
||||
this._tab.removeEventListener("TabRemotenessChange", this);
|
||||
},
|
||||
|
||||
|
|
@ -599,13 +596,6 @@ TabTarget.prototype = {
|
|||
case "unload":
|
||||
this.destroy();
|
||||
break;
|
||||
case "TabSelect":
|
||||
if (this.tab.selected) {
|
||||
this.emit("visible", event);
|
||||
} else {
|
||||
this.emit("hidden", event);
|
||||
}
|
||||
break;
|
||||
case "TabRemotenessChange":
|
||||
this.onRemotenessChange();
|
||||
break;
|
||||
|
|
@ -650,10 +640,14 @@ TabTarget.prototype = {
|
|||
return this._destroyer;
|
||||
}
|
||||
|
||||
this._destroyer = new Promise(resolve => {
|
||||
this._destroyer = new Promise(async (resolve) => {
|
||||
// Before taking any action, notify listeners that destruction is imminent.
|
||||
this.emit("close");
|
||||
|
||||
for (const [, front] of this.fronts) {
|
||||
await front.destroy();
|
||||
}
|
||||
|
||||
if (this._tab) {
|
||||
this._teardownListeners();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,16 +9,6 @@ add_task(async function() {
|
|||
await target.makeRemote();
|
||||
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 navigate = once(target, "navigate");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
|
||||
|
|
|
|||
|
|
@ -92,12 +92,21 @@ function test() {
|
|||
const target = await getTarget(client);
|
||||
await runTools(target);
|
||||
|
||||
const rootFronts = [...client.mainRoot.fronts.values()];
|
||||
|
||||
// Actor fronts should be destroyed now that the toolbox has closed, but
|
||||
// look for any that remain.
|
||||
for (const pool of client.__pools) {
|
||||
if (!pool.__poolMap) {
|
||||
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()) {
|
||||
// Bug 1056342: Profiler fails today because of framerate actor, but
|
||||
// this appears more complex to rework, so leave it for that bug to
|
||||
|
|
|
|||
|
|
@ -45,10 +45,6 @@ loader.lazyRequireGetter(this, "InspectorFront",
|
|||
"devtools/shared/fronts/inspector", true);
|
||||
loader.lazyRequireGetter(this, "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",
|
||||
"devtools/client/shared/key-shortcuts");
|
||||
loader.lazyRequireGetter(this, "ZoomKeys",
|
||||
|
|
@ -63,12 +59,8 @@ loader.lazyRequireGetter(this, "HUDService",
|
|||
"devtools/client/webconsole/hudservice", true);
|
||||
loader.lazyRequireGetter(this, "viewSource",
|
||||
"devtools/client/shared/view-source");
|
||||
loader.lazyRequireGetter(this, "StyleSheetsFront",
|
||||
"devtools/shared/fronts/stylesheets", true);
|
||||
loader.lazyRequireGetter(this, "buildHarLog",
|
||||
"devtools/client/netmonitor/src/har/har-builder-utils", true);
|
||||
loader.lazyRequireGetter(this, "getKnownDeviceFront",
|
||||
"devtools/shared/fronts/device", true);
|
||||
loader.lazyRequireGetter(this, "NetMonitorAPI",
|
||||
"devtools/client/netmonitor/src/api", true);
|
||||
loader.lazyRequireGetter(this, "sortPanelDefinitions",
|
||||
|
|
@ -125,7 +117,6 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId,
|
|||
|
||||
this._initInspector = null;
|
||||
this._inspector = null;
|
||||
this._styleSheets = null;
|
||||
this._netMonitorAPI = null;
|
||||
|
||||
// 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.
|
||||
*/
|
||||
get preferenceFront() {
|
||||
if (this._preferenceFront) {
|
||||
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;
|
||||
});
|
||||
});
|
||||
return this.target.client.mainRoot.getFront("preference");
|
||||
},
|
||||
|
||||
// Is the disable auto-hide of pop-ups feature available in this context?
|
||||
|
|
@ -2935,22 +2917,8 @@ Toolbox.prototype = {
|
|||
// Destroy the profiler connection
|
||||
outstanding.push(this.destroyPerformance());
|
||||
|
||||
// Destroy the preference front
|
||||
outstanding.push(this.destroyPreference());
|
||||
|
||||
// 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();
|
||||
}
|
||||
// Reset preferences set by the toolbox
|
||||
outstanding.push(this.resetPreference());
|
||||
|
||||
// Detach the thread
|
||||
detachThread(this._threadClient);
|
||||
|
|
@ -3104,7 +3072,7 @@ Toolbox.prototype = {
|
|||
resolvePerformance = resolve;
|
||||
});
|
||||
|
||||
this._performance = createPerformanceFront(this._target);
|
||||
this._performance = this.target.getFront("performance");
|
||||
await this.performance.connect();
|
||||
|
||||
// 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
|
||||
* style sheets front is not supported by the target, returns null.
|
||||
* Reset preferences set by the toolbox.
|
||||
*/
|
||||
initStyleSheetsFront: function() {
|
||||
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() {
|
||||
async resetPreference() {
|
||||
if (!this._preferenceFront) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -3159,7 +3116,6 @@ Toolbox.prototype = {
|
|||
await this._preferenceFront.clearUserPref(DISABLE_AUTOHIDE_PREF);
|
||||
}
|
||||
|
||||
this._preferenceFront.destroy();
|
||||
this._preferenceFront = null;
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
"use strict";
|
||||
|
||||
const { PerfFront } = require("devtools/shared/fronts/perf");
|
||||
const { getPreferenceFront } = require("devtools/shared/fronts/preference");
|
||||
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
|
||||
|
||||
class PerformancePanel {
|
||||
|
|
@ -32,7 +31,7 @@ class PerformancePanel {
|
|||
|
||||
const rootForm = await this.target.root;
|
||||
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.emit("ready");
|
||||
|
|
|
|||
|
|
@ -335,8 +335,8 @@ pref("devtools.aboutdebugging.network-locations", "[]");
|
|||
#endif
|
||||
|
||||
// Map top-level await expressions in the console
|
||||
#if defined(RELEASE_OR_BETA)
|
||||
pref("devtools.debugger.features.map-await-expression", false);
|
||||
#else
|
||||
#if defined(NIGHTLY_BUILD) || defined(MOZ_DEV_EDITION)
|
||||
pref("devtools.debugger.features.map-await-expression", true);
|
||||
#else
|
||||
pref("devtools.debugger.features.map-await-expression", false);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ StyleEditorPanel.prototype = {
|
|||
|
||||
this.target.on("close", this.destroy);
|
||||
|
||||
this._debuggee = this._toolbox.initStyleSheetsFront();
|
||||
this._debuggee = await this._target.getFront("stylesheets");
|
||||
|
||||
// Initialize the CSS properties database.
|
||||
const {cssProperties} = await initCssProperties(this._toolbox);
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ const {AppProjects} = require("devtools/client/webide/modules/app-projects");
|
|||
const TabStore = require("devtools/client/webide/modules/tab-store");
|
||||
const {AppValidator} = require("devtools/client/webide/modules/app-validator");
|
||||
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 {RuntimeTypes} = require("devtools/client/webide/modules/runtime-types");
|
||||
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);
|
||||
|
||||
if (this.connection.status == Connection.Status.DISCONNECTED) {
|
||||
|
|
@ -150,12 +148,21 @@ var AppManager = exports.AppManager = {
|
|||
|
||||
if (!this.connected) {
|
||||
this._listTabsResponse = null;
|
||||
this.deviceFront = null;
|
||||
this.preferenceFront = null;
|
||||
} else {
|
||||
this.connection.client.listTabs().then((response) => {
|
||||
this._listTabsResponse = response;
|
||||
this._recordRuntimeInfo();
|
||||
this.update("runtime-global-actors");
|
||||
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.deviceFront = await this.connection.client.mainRoot.getFront("device");
|
||||
this.preferenceFront = await this.connection.client.mainRoot.getFront("preference");
|
||||
this._recordRuntimeInfo();
|
||||
this.update("runtime-global-actors");
|
||||
}
|
||||
|
||||
this.update("connection");
|
||||
|
|
@ -509,20 +516,6 @@ var AppManager = exports.AppManager = {
|
|||
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() {
|
||||
if (!this.connected) {
|
||||
return Promise.resolve();
|
||||
|
|
|
|||
|
|
@ -33,10 +33,13 @@
|
|||
const docRuntime = getRuntimeDocument(win);
|
||||
win.AppManager.update("runtime-list");
|
||||
|
||||
const onGlobalActors = waitForUpdate(win, "runtime-global-actors");
|
||||
const onRuntimeTargets = waitForUpdate(win, "runtime-targets");
|
||||
connectToLocal(win, docRuntime);
|
||||
await onGlobalActors;
|
||||
await onRuntimeTargets;
|
||||
|
||||
// Select main process
|
||||
await waitForUpdate(win, "runtime-targets");
|
||||
SimpleTest.executeSoon(() => {
|
||||
docProject.querySelectorAll("#project-panel-runtimeapps .panel-item")[0].click();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -136,11 +136,13 @@
|
|||
ok(!isStopActive(), "stop button is disabled");
|
||||
|
||||
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();
|
||||
|
||||
await waitForUpdate(win, "runtime-targets");
|
||||
|
||||
await connectionsChanged;
|
||||
await onGlobalActors;
|
||||
await onRuntimeTargets;
|
||||
|
||||
is(Object.keys(DebuggerServer._connections).length, 2, "Locally connected");
|
||||
|
||||
ok(win.AppManager.isMainProcessDebuggable(), "Main process available");
|
||||
|
|
|
|||
|
|
@ -22,16 +22,14 @@ window.onload = function() {
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const {getDeviceFront} = require("devtools/shared/fronts/device");
|
||||
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.registerAllActors();
|
||||
|
||||
const client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
client.connect().then(function onConnect() {
|
||||
client.listTabs().then(function onListTabs(response) {
|
||||
const d = getDeviceFront(client, response);
|
||||
|
||||
return client.mainRoot.getFront("device");
|
||||
}).then(function(d) {
|
||||
let desc;
|
||||
const appInfo = Services.appinfo;
|
||||
const utils = window.windowUtils;
|
||||
|
|
|
|||
|
|
@ -22,16 +22,14 @@ function runTests() {
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const {getPreferenceFront} = require("devtools/shared/fronts/preference");
|
||||
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.registerAllActors();
|
||||
|
||||
const client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
client.connect().then(function onConnect() {
|
||||
client.listTabs().then(function onListTabs(response) {
|
||||
const p = getPreferenceFront(client, response);
|
||||
|
||||
return client.mainRoot.getFront("preference");
|
||||
}).then(function(p) {
|
||||
const prefs = {};
|
||||
|
||||
const localPref = {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
// Test the xpcshell-test debug support. Ideally we should have this test
|
||||
// next to the xpcshell support code, but that's tricky...
|
||||
|
||||
const {getDeviceFront} = require("devtools/shared/fronts/device");
|
||||
|
||||
add_task(async function() {
|
||||
const testFile = do_get_file("xpcshell_debugging_script.js");
|
||||
|
||||
|
|
@ -23,8 +21,7 @@ add_task(async function() {
|
|||
await client.connect();
|
||||
|
||||
// Ensure that global actors are available. Just test the device actor.
|
||||
const rootForm = await client.mainRoot.getRoot();
|
||||
const deviceFront = await getDeviceFront(client, rootForm);
|
||||
const deviceFront = await client.mainRoot.getFront("device");
|
||||
const desc = await deviceFront.getDescription();
|
||||
equal(desc.geckobuildid, Services.appinfo.platformBuildID, "device actor works");
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ const {
|
|||
loader.lazyRequireGetter(this, "Authentication", "devtools/shared/security/auth");
|
||||
loader.lazyRequireGetter(this, "DebuggerSocket", "devtools/shared/security/socket", true);
|
||||
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, "AddonClient", "devtools/shared/client/addon-client");
|
||||
|
|
@ -204,9 +203,7 @@ DebuggerClient.prototype = {
|
|||
async checkRuntimeVersion(listTabsForm) {
|
||||
let incompatible = null;
|
||||
|
||||
// Instead of requiring to pass `listTabsForm` here,
|
||||
// we can call getRoot() instead, but only once Firefox ESR59 is released
|
||||
const deviceFront = await getDeviceFront(this, listTabsForm);
|
||||
const deviceFront = await this.mainRoot.getFront("device");
|
||||
const desc = await deviceFront.getDescription();
|
||||
|
||||
// 1) Check for Firefox too recent on device.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
const { Ci } = require("chrome");
|
||||
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
|
||||
|
|
@ -32,6 +33,23 @@ function RootClient(client, greeting) {
|
|||
this.actor = greeting.from;
|
||||
this.applicationType = greeting.applicationType;
|
||||
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;
|
||||
|
||||
|
|
@ -43,7 +61,7 @@ RootClient.prototype = {
|
|||
* browser. This can replace usages of `listTabs` that only wanted the global actors
|
||||
* and didn't actually care about tabs.
|
||||
*/
|
||||
getRoot: DebuggerClient.requester({ type: "getRoot" }),
|
||||
_getRoot: DebuggerClient.requester({ type: "getRoot" }),
|
||||
|
||||
/**
|
||||
* List the open tabs.
|
||||
|
|
@ -259,6 +277,24 @@ RootClient.prototype = {
|
|||
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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -36,29 +36,4 @@ const DeviceFront = protocol.FrontClassWithSpec(deviceSpec, {
|
|||
},
|
||||
});
|
||||
|
||||
const _knownDeviceFronts = new WeakMap();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
exports.DeviceFront = DeviceFront;
|
||||
|
|
|
|||
|
|
@ -131,7 +131,3 @@ const PerformanceFront = FrontClassWithSpec(performanceSpec, {
|
|||
});
|
||||
|
||||
exports.PerformanceFront = PerformanceFront;
|
||||
|
||||
exports.createPerformanceFront = function createPerformanceFront(target) {
|
||||
return new PerformanceFront(target.client, target.form);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,18 +14,4 @@ const PreferenceFront = protocol.FrontClassWithSpec(preferenceSpec, {
|
|||
},
|
||||
});
|
||||
|
||||
const _knownPreferenceFronts = new WeakMap();
|
||||
|
||||
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;
|
||||
};
|
||||
exports.PreferenceFront = PreferenceFront;
|
||||
|
|
|
|||
|
|
@ -1642,3 +1642,15 @@ exports.dumpProtocolSpec = function() {
|
|||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -906,12 +906,10 @@ CopyingStructuredCloneReadCallback(JSContext* aCx,
|
|||
|
||||
if (aTag == SCTAG_DOM_BLOB) {
|
||||
MOZ_ASSERT(file.mType == StructuredCloneFile::eBlob);
|
||||
|
||||
RefPtr<Blob> blob = file.mBlob;
|
||||
MOZ_ASSERT(!blob->IsFile());
|
||||
MOZ_ASSERT(!file.mBlob->IsFile());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -923,19 +921,23 @@ CopyingStructuredCloneReadCallback(JSContext* aCx,
|
|||
if (aTag == SCTAG_DOM_FILE) {
|
||||
MOZ_ASSERT(file.mType == StructuredCloneFile::eBlob);
|
||||
|
||||
RefPtr<Blob> blob = file.mBlob;
|
||||
MOZ_ASSERT(blob->IsFile());
|
||||
{
|
||||
// Create a scope so ~RefPtr fires before returning an unwrapped
|
||||
// JS::Value.
|
||||
RefPtr<Blob> blob = file.mBlob;
|
||||
MOZ_ASSERT(blob->IsFile());
|
||||
|
||||
RefPtr<File> file = blob->ToFile();
|
||||
MOZ_ASSERT(file);
|
||||
RefPtr<File> file = blob->ToFile();
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
JS::Rooted<JS::Value> wrappedFile(aCx);
|
||||
if (NS_WARN_IF(!ToJSValue(aCx, file, &wrappedFile))) {
|
||||
return nullptr;
|
||||
JS::Rooted<JS::Value> wrappedFile(aCx);
|
||||
if (NS_WARN_IF(!ToJSValue(aCx, file, &wrappedFile))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
result.set(&wrappedFile.toObject());
|
||||
}
|
||||
|
||||
result.set(&wrappedFile.toObject());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@
|
|||
#include "CubebUtils.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
#include "mozilla/Sandbox.h"
|
||||
#elif defined(__OpenBSD__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -1783,6 +1785,8 @@ ContentChild::RecvSetProcessSandbox(const MaybeFileDesc& aBroker)
|
|||
mozilla::SandboxTarget::Instance()->StartSandbox();
|
||||
#elif defined(XP_MACOSX)
|
||||
sandboxEnabled = StartMacOSContentSandbox();
|
||||
#elif defined(__OpenBSD__)
|
||||
sandboxEnabled = StartOpenBSDSandbox(GeckoProcessType_Content);
|
||||
#endif
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
|
|
@ -3921,6 +3925,55 @@ ContentChild::OnMessageReceived(const Message& aMsg, Message*& aReply)
|
|||
|
||||
} // 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)
|
||||
bool IsDevelopmentBuild()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
function run_test()
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.datatransfer.moz", false],
|
||||
["dom.datatransfer.mozAtAPIs", false],
|
||||
]}, function() {
|
||||
let hiddenMethods = ["mozTypesAt", "mozClearDataAt", "mozGetDataAt", "mozSetDataAt", "mozItemCount"];
|
||||
let exposedMethods = Object.getOwnPropertyNames(DataTransfer.prototype);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -26,7 +26,6 @@ EXPORTS.mozilla += [
|
|||
UNIFIED_SOURCES += [
|
||||
'TransactionItem.cpp',
|
||||
'TransactionManager.cpp',
|
||||
'TransactionManagerFactory.cpp',
|
||||
'TransactionStack.cpp',
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -160,14 +160,3 @@ interface nsITransactionManager : nsISupports
|
|||
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++
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
#include "nsITransactionManager.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/TransactionManager.h"
|
||||
|
||||
using mozilla::TransactionManager;
|
||||
|
||||
static int32_t sConstructorCount = 0;
|
||||
static int32_t sDoCount = 0;
|
||||
|
|
@ -533,10 +536,7 @@ quick_test(TestTransactionFactory *factory)
|
|||
*
|
||||
*******************************************************************/
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsITransactionManager> mgr =
|
||||
do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &rv);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
nsCOMPtr<nsITransactionManager> mgr = new TransactionManager();
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
|
|
@ -544,7 +544,7 @@ quick_test(TestTransactionFactory *factory)
|
|||
*
|
||||
*******************************************************************/
|
||||
|
||||
rv = mgr->DoTransaction(0);
|
||||
nsresult rv = mgr->DoTransaction(0);
|
||||
EXPECT_EQ(rv, NS_ERROR_NULL_POINTER);
|
||||
|
||||
/*******************************************************************
|
||||
|
|
@ -1285,11 +1285,7 @@ quick_batch_test(TestTransactionFactory *factory)
|
|||
*
|
||||
*******************************************************************/
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsITransactionManager> mgr =
|
||||
do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &rv);
|
||||
ASSERT_TRUE(mgr);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
nsCOMPtr<nsITransactionManager> mgr = new TransactionManager();
|
||||
|
||||
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_EQ(numitems, 0);
|
||||
|
||||
|
|
@ -1920,12 +1916,9 @@ stress_test(TestTransactionFactory *factory, int32_t iterations)
|
|||
*
|
||||
*******************************************************************/
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsITransactionManager> mgr =
|
||||
do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &rv);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_TRUE(mgr);
|
||||
nsCOMPtr<nsITransactionManager> mgr = new TransactionManager();
|
||||
|
||||
nsresult rv;
|
||||
int32_t i, j;
|
||||
|
||||
for (i = 1; i <= iterations; i++) {
|
||||
|
|
|
|||
|
|
@ -1543,7 +1543,7 @@ gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet,
|
|||
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
|
||||
// policy.
|
||||
if (aPolicy && !(aPolicy->Lookup(reinterpret_cast<const char*>(path)) &
|
||||
|
|
@ -1705,7 +1705,7 @@ gfxFcPlatformFontList::InitFontListForPlatform()
|
|||
|
||||
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
|
||||
// check font paths; use a fake PID to avoid picking up any PID-specific
|
||||
// rules by accident.
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ public:
|
|||
protected:
|
||||
virtual ~gfxFcPlatformFontList();
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_LINUX)
|
||||
typedef mozilla::SandboxBroker::Policy SandboxPolicy;
|
||||
#else
|
||||
// Dummy type just so we can still have a SandboxPolicy* parameter.
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@
|
|||
#elif defined(__alpha__)
|
||||
#define ARCH_CPU_ALPHA 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_ARM64 1
|
||||
#define ARCH_CPU_64_BITS 1
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
#endif /* js_AllocPolicy_h */
|
||||
|
|
|
|||
|
|
@ -26,6 +26,12 @@
|
|||
// is not itself a GC pointer.
|
||||
# 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
|
||||
// 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
|
||||
|
|
@ -52,6 +58,7 @@
|
|||
# define JS_HAZ_GC_POINTER
|
||||
# define JS_HAZ_ROOTED
|
||||
# define JS_HAZ_GC_INVALIDATED
|
||||
# define JS_HAZ_ROOTED_BASE
|
||||
# define JS_HAZ_NON_GC_POINTER
|
||||
# define JS_HAZ_GC_CALL
|
||||
# define JS_HAZ_GC_SUPPRESSED
|
||||
|
|
|
|||
|
|
@ -945,7 +945,7 @@ class JS_PUBLIC_API(AutoGCRooter)
|
|||
/* No copy or assignment semantics. */
|
||||
AutoGCRooter(AutoGCRooter& ida) = delete;
|
||||
void operator=(AutoGCRooter& ida) = delete;
|
||||
};
|
||||
} JS_HAZ_ROOTED_BASE;
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
|
|
|||
|
|
@ -689,10 +689,10 @@ js::atomics_wait(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
|
||||
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.
|
||||
MOZ_ASSERT(sarb, "wake is only applicable to shared memory");
|
||||
MOZ_ASSERT(sarb, "notify is only applicable to shared memory");
|
||||
|
||||
AutoLockFutexAPI lock;
|
||||
|
||||
|
|
@ -706,7 +706,7 @@ js::atomics_wake_impl(SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t c
|
|||
iter = iter->lower_pri;
|
||||
if (c->offset != byteOffset || !c->cx->fx.isWaiting())
|
||||
continue;
|
||||
c->cx->fx.wake(FutexThread::WakeExplicit);
|
||||
c->cx->fx.notify(FutexThread::NotifyExplicit);
|
||||
// Overflow will be a problem only in two cases:
|
||||
// (1) 128-bit systems with substantially more than 2^64 bytes of
|
||||
// memory per process, and a very lightweight
|
||||
|
|
@ -723,7 +723,7 @@ js::atomics_wake_impl(SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t c
|
|||
}
|
||||
|
||||
bool
|
||||
js::atomics_wake(JSContext* cx, unsigned argc, Value* vp)
|
||||
js::atomics_notify(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
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 */) -
|
||||
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;
|
||||
}
|
||||
|
|
@ -830,7 +830,7 @@ js::FutexThread::isWaiting()
|
|||
// When a worker is awoken for an interrupt it goes into state
|
||||
// WaitingNotifiedForInterrupt for a short time before it actually
|
||||
// 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
|
||||
// FutexThread::wait().
|
||||
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.
|
||||
// To that end, we flag the thread as interrupted around
|
||||
// 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.
|
||||
//
|
||||
// - It is in principle possible for wait() to be
|
||||
// reentered on the same thread/runtime and waiting on the
|
||||
// same location and to yet again be interrupted and enter
|
||||
// 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
|
||||
// order; FIFO may be the required order, but FIFO would
|
||||
// fail to wake up the innermost call. Interrupts are
|
||||
|
|
@ -947,25 +947,25 @@ js::FutexThread::wait(JSContext* cx, js::UniqueLock<js::Mutex>& locked,
|
|||
}
|
||||
|
||||
void
|
||||
js::FutexThread::wake(WakeReason reason)
|
||||
js::FutexThread::notify(NotifyReason reason)
|
||||
{
|
||||
MOZ_ASSERT(isWaiting());
|
||||
|
||||
if ((state_ == WaitingInterrupted || state_ == WaitingNotifiedForInterrupt) && reason == WakeExplicit) {
|
||||
if ((state_ == WaitingInterrupted || state_ == WaitingNotifiedForInterrupt) && reason == NotifyExplicit) {
|
||||
state_ = Woken;
|
||||
return;
|
||||
}
|
||||
switch (reason) {
|
||||
case WakeExplicit:
|
||||
case NotifyExplicit:
|
||||
state_ = Woken;
|
||||
break;
|
||||
case WakeForJSInterrupt:
|
||||
case NotifyForJSInterrupt:
|
||||
if (state_ == WaitingNotifiedForInterrupt)
|
||||
return;
|
||||
state_ = WaitingNotifiedForInterrupt;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("bad WakeReason in FutexThread::wake()");
|
||||
MOZ_CRASH("bad NotifyReason in FutexThread::notify()");
|
||||
}
|
||||
cond_->notify_all();
|
||||
}
|
||||
|
|
@ -982,7 +982,8 @@ const JSFunctionSpec AtomicsMethods[] = {
|
|||
JS_INLINABLE_FN("xor", atomics_xor, 3,0, AtomicsXor),
|
||||
JS_INLINABLE_FN("isLockFree", atomics_isLockFree, 1,0, AtomicsIsLockFree),
|
||||
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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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_isLockFree(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
|
||||
{
|
||||
|
|
@ -56,10 +56,10 @@ public:
|
|||
MOZ_MUST_USE bool initInstance();
|
||||
void destroyInstance();
|
||||
|
||||
// Parameters to wake().
|
||||
enum WakeReason {
|
||||
WakeExplicit, // Being asked to wake up by another thread
|
||||
WakeForJSInterrupt // Interrupt requested
|
||||
// Parameters to notify().
|
||||
enum NotifyReason {
|
||||
NotifyExplicit, // Being asked to wake up by another thread
|
||||
NotifyForJSInterrupt // Interrupt requested
|
||||
};
|
||||
|
||||
// Result codes from wait() and atomics_wait_impl().
|
||||
|
|
@ -78,29 +78,27 @@ public:
|
|||
// times allowed; specify mozilla::Nothing() for an indefinite
|
||||
// wait.
|
||||
//
|
||||
// wait() will not wake up spuriously. It will return true and
|
||||
// set *result to a return code appropriate for
|
||||
// Atomics.wait() on success, and return false on error.
|
||||
// wait() will not wake up spuriously.
|
||||
MOZ_MUST_USE WaitResult wait(JSContext* cx, js::UniqueLock<js::Mutex>& locked,
|
||||
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
|
||||
// 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.)
|
||||
//
|
||||
// If the thread is not waiting then this method does nothing.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// of wait() must handle the interrupt.
|
||||
void wake(WakeReason reason);
|
||||
void notify(NotifyReason reason);
|
||||
|
||||
bool isWaiting();
|
||||
|
||||
|
|
@ -123,7 +121,7 @@ public:
|
|||
// interrupt handler
|
||||
WaitingInterrupted, // We are waiting, but have been interrupted
|
||||
// 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.
|
||||
|
|
@ -157,12 +155,12 @@ MOZ_MUST_USE FutexThread::WaitResult
|
|||
atomics_wait_impl(JSContext* cx, SharedArrayRawBuffer* sarb, uint32_t byteOffset, int64_t value,
|
||||
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
|
||||
// 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`.
|
||||
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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ bool
|
|||
DataViewObject::constructSameCompartment(JSContext* cx, HandleObject bufobj, const CallArgs& args)
|
||||
{
|
||||
MOZ_ASSERT(args.isConstructing());
|
||||
assertSameCompartment(cx, bufobj);
|
||||
cx->check(bufobj);
|
||||
|
||||
uint32_t byteOffset, byteLength;
|
||||
if (!getAndCheckConstructorArgs(cx, bufobj, args, &byteOffset, &byteLength))
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ static bool
|
|||
ExecuteInExtensibleLexicalEnvironment(JSContext* cx, HandleScript scriptArg, HandleObject env)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, env);
|
||||
cx->check(env);
|
||||
MOZ_ASSERT(IsExtensibleLexicalEnvironment(env));
|
||||
MOZ_RELEASE_ASSERT(scriptArg->hasNonSyntacticScope());
|
||||
|
||||
|
|
@ -518,7 +518,7 @@ JS_FRIEND_API(bool)
|
|||
js::ExecuteInJSMEnvironment(JSContext* cx, HandleScript scriptArg, HandleObject varEnv,
|
||||
AutoObjectVector& targetObj)
|
||||
{
|
||||
assertSameCompartment(cx, varEnv);
|
||||
cx->check(varEnv);
|
||||
MOZ_ASSERT(ObjectRealm::get(varEnv).getNonSyntacticLexicalEnvironment(varEnv));
|
||||
MOZ_DIAGNOSTIC_ASSERT(scriptArg->noScriptRval());
|
||||
|
||||
|
|
|
|||
|
|
@ -1711,7 +1711,7 @@ RetT
|
|||
CallObjFunc(RetT(*ObjFunc)(JSContext*, HandleObject), JSContext* cx, HandleObject obj)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
cx->check(obj);
|
||||
|
||||
// Always unwrap, in case this is an xray or cross-compartment wrapper.
|
||||
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)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, key);
|
||||
cx->check(obj, key);
|
||||
|
||||
// Always unwrap, in case this is an xray or cross-compartment wrapper.
|
||||
RootedObject unwrappedObj(cx);
|
||||
|
|
@ -1754,7 +1754,7 @@ CallObjFunc(bool(*ObjFunc)(JSContext* cx, Iter kind,
|
|||
JSContext *cx, Iter iterType, HandleObject obj, MutableHandleValue rval)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
cx->check(obj);
|
||||
|
||||
// Always unwrap, in case this is an xray or cross-compartment wrapper.
|
||||
RootedObject unwrappedObj(cx);
|
||||
|
|
@ -1794,7 +1794,7 @@ JS_PUBLIC_API(bool)
|
|||
JS::MapGet(JSContext* cx, HandleObject obj, HandleValue key, MutableHandleValue rval)
|
||||
{
|
||||
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,
|
||||
// this is essentially a noop.
|
||||
|
|
@ -1825,7 +1825,7 @@ JS_PUBLIC_API(bool)
|
|||
JS::MapSet(JSContext *cx, HandleObject obj, HandleValue key, HandleValue val)
|
||||
{
|
||||
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,
|
||||
// this is essentially a noop.
|
||||
|
|
@ -1906,7 +1906,7 @@ JS_PUBLIC_API(bool)
|
|||
JS::SetAdd(JSContext *cx, HandleObject obj, HandleValue key)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, key);
|
||||
cx->check(obj, key);
|
||||
|
||||
// Unwrap the object, and enter its compartment. If object isn't wrapped,
|
||||
// this is essentially a noop.
|
||||
|
|
|
|||
|
|
@ -1192,8 +1192,6 @@ GlobalObject::initModuleProto(JSContext* cx, Handle<GlobalObject*> global)
|
|||
static const JSFunctionSpec protoFunctions[] = {
|
||||
JS_SELF_HOSTED_FN("getExportedNames", "ModuleGetExportedNames", 1, 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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "jsapi.h"
|
||||
|
||||
#include "builtin/SelfHostingDefines.h"
|
||||
#include "gc/Zone.h"
|
||||
#include "js/GCVector.h"
|
||||
#include "js/Id.h"
|
||||
#include "js/UniquePtr.h"
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ static const JSFunctionSpec profiling_functions[] = {
|
|||
JS_PUBLIC_API(bool)
|
||||
JS_DefineProfilingFunctions(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
assertSameCompartment(cx, obj);
|
||||
cx->check(obj);
|
||||
#ifdef MOZ_PROFILING
|
||||
return JS_DefineFunctions(cx, obj, profiling_functions);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -232,9 +232,9 @@ NewPromiseAllDataHolder(JSContext* cx, HandleObject resultPromise, HandleValue v
|
|||
if (!dataHolder)
|
||||
return nullptr;
|
||||
|
||||
assertSameCompartment(cx, resultPromise);
|
||||
assertSameCompartment(cx, valuesArray);
|
||||
assertSameCompartment(cx, resolve);
|
||||
cx->check(resultPromise);
|
||||
cx->check(valuesArray);
|
||||
cx->check(resolve);
|
||||
|
||||
dataHolder->setFixedSlot(PromiseAllDataHolderSlot_Promise, ObjectValue(*resultPromise));
|
||||
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
|
||||
ResolvePromiseInternal(JSContext* cx, HandleObject promise, HandleValue resolutionVal)
|
||||
{
|
||||
assertSameCompartment(cx, promise, resolutionVal);
|
||||
cx->check(promise, resolutionVal);
|
||||
MOZ_ASSERT(!IsSettledMaybeWrappedPromise(promise));
|
||||
|
||||
// Step 7 (reordered).
|
||||
|
|
@ -935,7 +935,7 @@ EnqueuePromiseReactionJob(JSContext* cx, HandleObject reactionObj,
|
|||
// Must not enqueue a reaction job more than once.
|
||||
MOZ_ASSERT(reaction->targetState() == JS::PromiseState::Pending);
|
||||
|
||||
assertSameCompartment(cx, handlerArg);
|
||||
cx->check(handlerArg);
|
||||
reaction->setTargetStateAndHandlerArg(targetState, handlerArg);
|
||||
|
||||
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 thenable(cx, &job->getExtendedSlot(BuiltinThenableJobSlot_Thenable).toObject());
|
||||
|
||||
assertSameCompartment(cx, promise, thenable);
|
||||
cx->check(promise, thenable);
|
||||
MOZ_ASSERT(promise->is<PromiseObject>());
|
||||
MOZ_ASSERT(thenable->is<PromiseObject>());
|
||||
|
||||
|
|
@ -1740,7 +1740,7 @@ static MOZ_MUST_USE bool
|
|||
EnqueuePromiseResolveThenableBuiltinJob(JSContext* cx, HandleObject promiseToResolve,
|
||||
HandleObject thenable)
|
||||
{
|
||||
assertSameCompartment(cx, promiseToResolve, thenable);
|
||||
cx->check(promiseToResolve, thenable);
|
||||
MOZ_ASSERT(promiseToResolve->is<PromiseObject>());
|
||||
MOZ_ASSERT(thenable->is<PromiseObject>());
|
||||
|
||||
|
|
@ -2156,7 +2156,7 @@ js::GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises)
|
|||
#ifdef DEBUG
|
||||
for (size_t i = 0, len = promises.length(); i < len; i++) {
|
||||
JSObject* obj = promises[i];
|
||||
assertSameCompartment(cx, obj);
|
||||
cx->check(obj);
|
||||
MOZ_ASSERT(UncheckedUnwrap(obj)->is<PromiseObject>());
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2285,9 +2285,9 @@ RunResolutionFunction(JSContext *cx, HandleObject resolutionFun, HandleValue res
|
|||
// subclass constructor passes null/undefined to `super()`.)
|
||||
// There are also reactions where the Promise itself is missing. For
|
||||
// those, there's nothing left to do here.
|
||||
assertSameCompartment(cx, resolutionFun);
|
||||
assertSameCompartment(cx, result);
|
||||
assertSameCompartment(cx, promiseObj);
|
||||
cx->check(resolutionFun);
|
||||
cx->check(result);
|
||||
cx->check(promiseObj);
|
||||
if (resolutionFun) {
|
||||
RootedValue calleeOrRval(cx, ObjectValue(*resolutionFun));
|
||||
return Call(cx, calleeOrRval, UndefinedHandleValue, result, &calleeOrRval);
|
||||
|
|
@ -3080,12 +3080,12 @@ NewReactionRecord(JSContext* cx, Handle<PromiseCapability> resultCapability,
|
|||
if (!reaction)
|
||||
return nullptr;
|
||||
|
||||
assertSameCompartment(cx, resultCapability.promise());
|
||||
assertSameCompartment(cx, onFulfilled);
|
||||
assertSameCompartment(cx, onRejected);
|
||||
assertSameCompartment(cx, resultCapability.resolve());
|
||||
assertSameCompartment(cx, resultCapability.reject());
|
||||
assertSameCompartment(cx, incumbentGlobalObject);
|
||||
cx->check(resultCapability.promise());
|
||||
cx->check(onFulfilled);
|
||||
cx->check(onRejected);
|
||||
cx->check(resultCapability.resolve());
|
||||
cx->check(resultCapability.reject());
|
||||
cx->check(incumbentGlobalObject);
|
||||
|
||||
reaction->setFixedSlot(ReactionRecordSlot_Promise,
|
||||
ObjectOrNullValue(resultCapability.promise()));
|
||||
|
|
@ -3160,7 +3160,7 @@ static MOZ_MUST_USE bool
|
|||
OriginalPromiseThenWithoutSettleHandlers(JSContext* cx, Handle<PromiseObject*> promise,
|
||||
Handle<PromiseObject*> promiseToResolve)
|
||||
{
|
||||
assertSameCompartment(cx, promise);
|
||||
cx->check(promise);
|
||||
|
||||
// Steps 3-4.
|
||||
Rooted<PromiseCapability> resultCapability(cx);
|
||||
|
|
@ -3187,7 +3187,7 @@ static bool
|
|||
OriginalPromiseThenBuiltin(JSContext* cx, HandleValue promiseVal, HandleValue onFulfilled,
|
||||
HandleValue onRejected, MutableHandleValue rval, bool rvalUsed)
|
||||
{
|
||||
assertSameCompartment(cx, promiseVal, onFulfilled, onRejected);
|
||||
cx->check(promiseVal, onFulfilled, onRejected);
|
||||
MOZ_ASSERT(CanCallOriginalPromiseThenBuiltin(cx, promiseVal));
|
||||
|
||||
Rooted<PromiseObject*> promise(cx, &promiseVal.toObject().as<PromiseObject>());
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlag flags)
|
|||
// If we already have a RegExpShared for this pattern/flags, we can
|
||||
// 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
|
||||
// Assert the pattern is valid.
|
||||
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
|
||||
// next time.
|
||||
return cx->zone()->regExps.get(cx, pattern, flags);
|
||||
return cx->zone()->regExps().get(cx, pattern, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -205,6 +205,22 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp)
|
|||
if (!JS_SetProperty(cx, info, "arm64-simulator", value))
|
||||
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
|
||||
value = BooleanValue(true);
|
||||
#else
|
||||
|
|
@ -4397,96 +4413,6 @@ SetRNGState(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
#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
|
||||
static const char*
|
||||
AssertionTypeToString(irregexp::RegExpAssertion::AssertionType type)
|
||||
|
|
@ -6002,14 +5928,6 @@ gc::ZealModeHelpText),
|
|||
" Set this compartment's RNG state.\n"),
|
||||
#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)
|
||||
JS_FN_HELP("aflloop", AflLoop, 1, 0,
|
||||
"aflloop(max_cnt)",
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ JS::GetWeakMapEntry(JSContext* cx, HandleObject mapObj, HandleObject key,
|
|||
MutableHandleValue rval)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, key);
|
||||
cx->check(key);
|
||||
rval.setUndefined();
|
||||
ObjectValueMap* map = mapObj->as<WeakMapObject>().getMap();
|
||||
if (!map)
|
||||
|
|
@ -223,7 +223,7 @@ JS::SetWeakMapEntry(JSContext* cx, HandleObject mapObj, HandleObject key,
|
|||
HandleValue val)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, key, val);
|
||||
cx->check(key, val);
|
||||
Handle<WeakMapObject*> rootedMap = mapObj.as<WeakMapObject>();
|
||||
return WeakCollectionPutEntryInternal(cx, rootedMap, key, val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,6 +222,9 @@ function edgeUsesVariable(edge, variable, body)
|
|||
case "Loop":
|
||||
return 0;
|
||||
|
||||
case "Assembly":
|
||||
return 0;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,20 +176,9 @@ function process(functionName, functionBodies)
|
|||
if (markerPos > 0) {
|
||||
var inChargeXTor = functionName.replace(internalMarker, "");
|
||||
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:
|
||||
// C1 # complete 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
|
||||
// C3 isn't even used in current GCC, but add the edge anyway just in
|
||||
// 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);
|
||||
// E terminates the method name (and precedes the method parameters).
|
||||
// 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
|
||||
// is somewhat difficult to avoid, so we will live with it.
|
||||
for (let [synthetic, variant] of [['C4E', 'C1E'],
|
||||
['C4E', 'C2E'],
|
||||
['C4E', 'C3E'],
|
||||
['D4Ev', 'D1Ev'],
|
||||
['D4Ev', 'D2Ev'],
|
||||
['D4Ev', 'D3Ev']])
|
||||
// will create bogus edges in the callgraph. But it will affect little
|
||||
// and is somewhat difficult to avoid, so we will live with it.
|
||||
//
|
||||
// Another possibility! A templatized constructor will contain C4I...E
|
||||
// for template arguments.
|
||||
//
|
||||
for (let [synthetic, variant] of [
|
||||
['C4E', 'C1E'],
|
||||
['C4E', 'C2E'],
|
||||
['C4E', 'C3E'],
|
||||
['C4I', 'C1I'],
|
||||
['C4I', 'C2I'],
|
||||
['C4I', 'C3I']])
|
||||
{
|
||||
if (mangled.indexOf(synthetic) == -1)
|
||||
continue;
|
||||
|
|
@ -231,6 +237,30 @@ function process(functionName, functionBodies)
|
|||
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++) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ var typeInfo = {
|
|||
'NonGCPointers': {},
|
||||
'RootedGCThings': {},
|
||||
'RootedPointers': {},
|
||||
'RootedBases': {'JS::AutoGCRooter': true},
|
||||
|
||||
// RAII types within which we should assume GC is suppressed, eg
|
||||
// AutoSuppressGC.
|
||||
|
|
@ -36,6 +37,26 @@ var rootedPointers = {};
|
|||
|
||||
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 || []))
|
||||
addBaseClass(csu, base);
|
||||
|
||||
|
|
@ -52,31 +73,8 @@ function processCSU(csu, body)
|
|||
if (target.Kind == "CSU")
|
||||
addNestedStructure(csu, target.Name, fieldName);
|
||||
}
|
||||
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;
|
||||
if (type.Kind == "CSU")
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +84,8 @@ function addNestedStructure(csu, inner, field)
|
|||
if (!(inner in structureParents))
|
||||
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))
|
||||
return;
|
||||
|
||||
|
|
@ -140,6 +140,16 @@ for (const csu of typeInfo.GCThings)
|
|||
for (const csu of typeInfo.GCPointers)
|
||||
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
|
||||
// named 'child' of type 'why' (or pointer to 'why' if fieldPtrLevel == 1), which is
|
||||
// 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
|
||||
// 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.)
|
||||
function foreachContainingStruct(typeName, func, seen = new Set())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,15 +41,6 @@ BumpChunk::newWithCapacity(size_t size, bool protect)
|
|||
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
|
||||
|
||||
static const uint8_t*
|
||||
|
|
@ -186,25 +177,25 @@ LifoAlloc::newChunkWithCapacity(size_t n)
|
|||
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|
|
||||
// bytes in the newly allocated chunk, or default the |defaultChunkSize_|.
|
||||
size_t defaultChunkFreeSpace = defaultChunkSize_ - detail::BumpChunkReservedSpace;
|
||||
size_t chunkSize;
|
||||
if (n > defaultChunkFreeSpace) {
|
||||
MOZ_ASSERT(defaultChunkFreeSpace < defaultChunkSize_);
|
||||
size_t allocSizeWithCanaries = n + (defaultChunkSize_ - defaultChunkFreeSpace);
|
||||
// bytes in a newly allocated chunk, or default to |defaultChunkSize_|.
|
||||
uint8_t* u8begin = nullptr;
|
||||
uint8_t* u8end = u8begin + detail::BumpChunkReservedSpace;
|
||||
u8end = detail::BumpChunk::nextAllocEnd(detail::BumpChunk::nextAllocBase(u8end), n);
|
||||
size_t allocSizeWithCanaries = u8end - u8begin;
|
||||
|
||||
// Guard for overflow.
|
||||
if (allocSizeWithCanaries < n ||
|
||||
(allocSizeWithCanaries & (size_t(1) << (BitSize<size_t>::value - 1))))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
chunkSize = RoundUpPow2(allocSizeWithCanaries);
|
||||
} else {
|
||||
chunkSize = defaultChunkSize_;
|
||||
// Guard for overflow.
|
||||
if (allocSizeWithCanaries < n ||
|
||||
(allocSizeWithCanaries & (size_t(1) << (BitSize<size_t>::value - 1))))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t chunkSize;
|
||||
if (allocSizeWithCanaries > defaultChunkSize_)
|
||||
chunkSize = RoundUpPow2(allocSizeWithCanaries);
|
||||
else
|
||||
chunkSize = defaultChunkSize_;
|
||||
|
||||
bool protect = false;
|
||||
#ifdef LIFO_CHUNK_PROTECT
|
||||
protect = protect_;
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
|
|||
static constexpr uintptr_t magicNumber = uintptr_t(0x4c6966);
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) || defined(MOZ_ASAN)
|
||||
#if defined(DEBUG)
|
||||
# define LIFO_CHUNK_PROTECT 1
|
||||
#endif
|
||||
|
||||
|
|
@ -250,6 +250,7 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
|
|||
do { \
|
||||
uint8_t* base = (addr); \
|
||||
size_t sz = (size); \
|
||||
MOZ_MAKE_MEM_UNDEFINED(base, sz); \
|
||||
memset(base, undefinedChunkMemory, sz); \
|
||||
MOZ_MAKE_MEM_NOACCESS(base, sz); \
|
||||
} while (0)
|
||||
|
|
@ -269,6 +270,13 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
|
|||
# define LIFO_MAKE_MEM_UNDEFINED(addr, size) MOZ_MAKE_MEM_UNDEFINED((addr), (size))
|
||||
#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() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(magic_ == magicNumber);
|
||||
MOZ_ASSERT(begin() <= end());
|
||||
|
|
@ -319,10 +327,15 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
|
|||
MOZ_ASSERT(newBump <= capacity_);
|
||||
#if defined(LIFO_HAVE_MEM_CHECKS)
|
||||
// Poison/Unpoison memory that we just free'd/allocated.
|
||||
if (bump_ > newBump)
|
||||
if (bump_ > newBump) {
|
||||
LIFO_MAKE_MEM_NOACCESS(newBump, bump_ - newBump);
|
||||
else if (newBump > bump_)
|
||||
LIFO_MAKE_MEM_UNDEFINED(bump_, newBump - bump_);
|
||||
} else if (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
|
||||
bump_ = newBump;
|
||||
}
|
||||
|
|
@ -417,13 +430,27 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
|
|||
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
|
||||
// |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.
|
||||
size_t unused() const {
|
||||
uint8_t* aligned = AlignPtr(end());
|
||||
uint8_t* aligned = nextAllocBase(end());
|
||||
if (aligned < capacity_)
|
||||
return capacity_ - aligned;
|
||||
return 0;
|
||||
|
|
@ -432,8 +459,8 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
|
|||
// Try to perform an allocation of size |n|, returns nullptr if not possible.
|
||||
MOZ_ALWAYS_INLINE
|
||||
void* tryAlloc(size_t n) {
|
||||
uint8_t* aligned = AlignPtr(end());
|
||||
uint8_t* newBump = aligned + n;
|
||||
uint8_t* aligned = nextAllocBase(end());
|
||||
uint8_t* newBump = nextAllocEnd(aligned, n);
|
||||
|
||||
if (newBump > capacity_)
|
||||
return nullptr;
|
||||
|
|
@ -903,15 +930,15 @@ class LifoAlloc
|
|||
uint8_t* seekBaseAndAdvanceBy(size_t size) {
|
||||
MOZ_ASSERT(!empty());
|
||||
|
||||
uint8_t* aligned = detail::AlignPtr(head_);
|
||||
if (aligned + size > chunkIt_->end()) {
|
||||
uint8_t* aligned = detail::BumpChunk::nextAllocBase(head_);
|
||||
if (detail::BumpChunk::nextAllocEnd(aligned, size) > chunkIt_->end()) {
|
||||
++chunkIt_;
|
||||
aligned = chunkIt_->begin();
|
||||
// The current code assumes that if we have a chunk, then we
|
||||
// have allocated something it in.
|
||||
MOZ_ASSERT(!chunkIt_->empty());
|
||||
}
|
||||
head_ = aligned + size;
|
||||
head_ = detail::BumpChunk::nextAllocEnd(aligned, size);
|
||||
MOZ_ASSERT(head_ <= chunkIt_->end());
|
||||
return aligned;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#endif
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EnvironmentObject.h"
|
||||
#include "vm/RegExpObject.h"
|
||||
#include "vm/RegExpShared.h"
|
||||
#include "vm/Scope.h"
|
||||
#include "vm/Shape.h"
|
||||
|
|
|
|||
|
|
@ -116,6 +116,10 @@ JS_FOR_EACH_TRACEKIND(TRACE_ROOTS)
|
|||
#undef TRACE_ROOTS
|
||||
TracePersistentRootedList<jsid>(trc, heapRoots.ref()[JS::RootKind::Id], "persistent-id");
|
||||
TracePersistentRootedList<Value>(trc, heapRoots.ref()[JS::RootKind::Value], "persistent-value");
|
||||
|
||||
// ConcreteTraceable calls through a function pointer.
|
||||
JS::AutoSuppressGCAnalysis nogc;
|
||||
|
||||
TracePersistentRootedList<ConcreteTraceable>(
|
||||
trc, heapRoots.ref()[JS::RootKind::Traceable], "persistent-traceable");
|
||||
}
|
||||
|
|
@ -391,6 +395,9 @@ js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrM
|
|||
if (!JS::RuntimeHeapIsMinorCollecting()) {
|
||||
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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "gc/Barrier.h"
|
||||
#include "gc/DeletePolicy.h"
|
||||
#include "gc/Zone.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
namespace JS {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ JS::Zone::Zone(JSRuntime* rt)
|
|||
weakCaches_(this),
|
||||
gcWeakKeys_(this, SystemAllocPolicy(), rt->randomHashCodeScrambler()),
|
||||
typeDescrObjects_(this, this),
|
||||
regExps(this),
|
||||
markedAtoms_(this),
|
||||
atomCache_(this),
|
||||
externalStringCache_(this),
|
||||
|
|
@ -97,7 +96,7 @@ Zone::~Zone()
|
|||
// if the embedding leaked GC things.
|
||||
if (!rt->gc.shutdownCollectedEverything()) {
|
||||
gcWeakMapList().clear();
|
||||
regExps.clear();
|
||||
regExps().clear();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -106,7 +105,8 @@ bool
|
|||
Zone::init(bool isSystemArg)
|
||||
{
|
||||
isSystem = isSystemArg;
|
||||
return gcWeakKeys().init();
|
||||
regExps_.ref() = make_unique<RegExpZone>(this);
|
||||
return regExps_.ref() && gcWeakKeys().init();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -357,7 +357,7 @@ Zone::nextZone() const
|
|||
void
|
||||
Zone::clearTables()
|
||||
{
|
||||
MOZ_ASSERT(regExps.empty());
|
||||
MOZ_ASSERT(regExps().empty());
|
||||
|
||||
baseShapes().clear();
|
||||
initialShapes().clear();
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@
|
|||
#include "gc/GCRuntime.h"
|
||||
#include "js/GCHashTable.h"
|
||||
#include "vm/MallocProvider.h"
|
||||
#include "vm/RegExpShared.h"
|
||||
#include "vm/Runtime.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
class Debugger;
|
||||
class RegExpZone;
|
||||
|
||||
namespace jit {
|
||||
class JitZone;
|
||||
|
|
@ -459,8 +459,10 @@ class Zone : public JS::shadow::Zone,
|
|||
counter.recordTrigger(trigger);
|
||||
}
|
||||
|
||||
js::MainThreadData<js::UniquePtr<js::RegExpZone>> regExps_;
|
||||
|
||||
public:
|
||||
js::RegExpZone regExps;
|
||||
js::RegExpZone& regExps() { return *regExps_.ref(); }
|
||||
|
||||
JS::WeakCache<TypeDescrObjectSet>& typeDescrObjects() { return typeDescrObjects_.ref(); }
|
||||
|
||||
|
|
@ -755,47 +757,50 @@ class Zone : public JS::shadow::Zone,
|
|||
|
||||
namespace js {
|
||||
|
||||
template <typename T>
|
||||
inline T*
|
||||
ZoneAllocPolicy::maybe_pod_malloc(size_t numElems)
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
return zone->maybe_pod_malloc<T>(numElems);
|
||||
}
|
||||
JS::Zone* const zone;
|
||||
|
||||
template <typename T>
|
||||
inline T*
|
||||
ZoneAllocPolicy::maybe_pod_calloc(size_t numElems)
|
||||
{
|
||||
return zone->maybe_pod_calloc<T>(numElems);
|
||||
}
|
||||
public:
|
||||
MOZ_IMPLICIT ZoneAllocPolicy(JS::Zone* z) : zone(z) {}
|
||||
|
||||
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);
|
||||
}
|
||||
template <typename T> T* maybe_pod_malloc(size_t numElems) {
|
||||
return zone->maybe_pod_malloc<T>(numElems);
|
||||
}
|
||||
template <typename T> T* maybe_pod_calloc(size_t numElems) {
|
||||
return zone->maybe_pod_calloc<T>(numElems);
|
||||
}
|
||||
template <typename T> T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) {
|
||||
return zone->maybe_pod_realloc<T>(p, oldSize, newSize);
|
||||
}
|
||||
template <typename T> T* pod_malloc(size_t numElems) {
|
||||
return zone->pod_malloc<T>(numElems);
|
||||
}
|
||||
template <typename T> T* pod_calloc(size_t numElems) {
|
||||
return zone->pod_calloc<T>(numElems);
|
||||
}
|
||||
template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
|
||||
return zone->pod_realloc<T>(p, oldSize, newSize);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T*
|
||||
ZoneAllocPolicy::pod_malloc(size_t numElems)
|
||||
{
|
||||
return zone->pod_malloc<T>(numElems);
|
||||
}
|
||||
template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); }
|
||||
void reportAllocOverflow() const {}
|
||||
|
||||
template <typename T>
|
||||
inline T*
|
||||
ZoneAllocPolicy::pod_calloc(size_t numElems)
|
||||
{
|
||||
return zone->pod_calloc<T>(numElems);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T*
|
||||
ZoneAllocPolicy::pod_realloc(T* p, size_t oldSize, size_t newSize)
|
||||
{
|
||||
return zone->pod_realloc<T>(p, oldSize, newSize);
|
||||
}
|
||||
MOZ_MUST_USE bool checkSimulatedOOM() const {
|
||||
return !js::oom::ShouldFailWithOOM();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ while(i++ < 500) {
|
|||
assertFloat32(0x23456789 | 0, false);
|
||||
`);
|
||||
let m = parseModule("");
|
||||
m.declarationInstantiation();
|
||||
instantiateModule(m);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// |jit-test| --no-threads; --ion-eager; --ion-shared-stubs=off
|
||||
// |jit-test| --no-threads; --ion-eager;
|
||||
setJitCompilerOption('ion.forceinlineCaches', 1);
|
||||
function foo(t) {
|
||||
"use strict";
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ loadFile(lfLogBuffer);
|
|||
function loadFile(lfVarx) {
|
||||
try {
|
||||
let m = parseModule(lfVarx);
|
||||
m.declarationInstantiation();
|
||||
m.evaluation();
|
||||
instantiateModule(m);
|
||||
evaluateModule(m);
|
||||
} catch (lfVare) {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,5 +17,5 @@ let m = parseModule(`
|
|||
f(i);
|
||||
actual;
|
||||
`);
|
||||
m.declarationInstantiation();
|
||||
m.evaluation();
|
||||
instantiateModule(m);
|
||||
evaluateModule(m);
|
||||
|
|
|
|||
14
js/src/jit-test/tests/debug/bug1363233.js
Normal file
14
js/src/jit-test/tests/debug/bug1363233.js
Normal 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();
|
||||
|
|
@ -5,5 +5,5 @@ for (var i=0; i < 10000; ++i) {
|
|||
for (var x of iterator) {}
|
||||
}
|
||||
`);
|
||||
m.declarationInstantiation();
|
||||
m.evaluation();
|
||||
instantiateModule(m);
|
||||
evaluateModule(m);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ loadFile(lfLogBuffer);
|
|||
function loadFile(lfVarx) {
|
||||
oomTest(function() {
|
||||
let m = parseModule(lfVarx);
|
||||
m.declarationInstantiation();
|
||||
m.evaluation();
|
||||
instantiateModule(m);
|
||||
evaluateModule(m);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@ if (!('oomTest' in this))
|
|||
|
||||
oomTest(function() {
|
||||
m = parseModule(`while (x && NaN) prototype; let x`);
|
||||
m.declarationInstantiation();
|
||||
m.evaluation();
|
||||
instantiateModule(m);
|
||||
evaluateModule(m);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,21 +7,21 @@ load(libdir + "dummyModuleResolveHook.js");
|
|||
|
||||
function checkModuleEval(source) {
|
||||
let m = parseModule(source);
|
||||
m.declarationInstantiation();
|
||||
m.evaluation();
|
||||
instantiateModule(m);
|
||||
evaluateModule(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
function checkModuleSyntaxError(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 b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;");
|
||||
let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");
|
||||
c.declarationInstantiation();
|
||||
c.evaluation();
|
||||
instantiateModule(c);
|
||||
evaluateModule(c);
|
||||
|
||||
// Check importing/exporting non-ambiguous name works.
|
||||
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.
|
||||
let m = parseModule("import * as ns from 'c';");
|
||||
m.declarationInstantiation();
|
||||
m.evaluation();
|
||||
let ns = c.namespace;
|
||||
instantiateModule(m);
|
||||
evaluateModule(m);
|
||||
let ns = getModuleObject(c).namespace;
|
||||
let names = Object.keys(ns);
|
||||
assertEq(names.length, 2);
|
||||
assertEq('a' in ns, true);
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ moduleRepo['D'] = parseModule('export let x');
|
|||
moduleRepo['E'] = parseModule('export let x');
|
||||
|
||||
let m = moduleRepo['A'];
|
||||
assertThrowsInstanceOf(() => m.declarationInstantiation(), SyntaxError);
|
||||
assertThrowsInstanceOf(() => instantiateModule(m), SyntaxError);
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ g.eval("(" + function() {
|
|||
};
|
||||
} + ")()");
|
||||
m = parseModule(` s1 `);
|
||||
m.declarationInstantiation();
|
||||
m.evaluation();
|
||||
instantiateModule(m);
|
||||
evaluateModule(m);
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
let m = parseModule(`{ function x() {} }`);
|
||||
m.declarationInstantiation();
|
||||
instantiateModule(m);
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ m = parseModule(`
|
|||
function g() { return this.hours = 0; }
|
||||
evalInFrame.call(0, 0, "g()")
|
||||
`);
|
||||
m.declarationInstantiation();
|
||||
m.evaluation();
|
||||
instantiateModule(m);
|
||||
evaluateModule(m);
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ setJitCompilerOption("ion.warmup.trigger", 50);
|
|||
s = "";
|
||||
for (i = 0; i < 1024; i++) s += "export let e" + i + "\n";
|
||||
moduleRepo['a'] = parseModule(s);
|
||||
parseModule("import * as ns from 'a'").declarationInstantiation();
|
||||
instantiateModule(parseModule("import * as ns from 'a'"));
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ setModuleResolveHook(function(module, specifier) {
|
|||
});
|
||||
let a = moduleRepo['a'] = parseModule("var x = 1; export { x };");
|
||||
let b = moduleRepo['b'] = parseModule("import { x as y } from 'a';");
|
||||
a.__proto__ = {15: 1337};
|
||||
b.declarationInstantiation();
|
||||
getModuleObject(a).__proto__ = {15: 1337};
|
||||
instantiateModule(b);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");
|
|||
let e1;
|
||||
let threw = false;
|
||||
try {
|
||||
c.declarationInstantiation();
|
||||
instantiateModule(c);
|
||||
} catch (exc) {
|
||||
threw = true;
|
||||
e1 = exc;
|
||||
|
|
@ -26,7 +26,7 @@ assertEq(typeof e1 === "undefined", false);
|
|||
threw = false;
|
||||
let e2;
|
||||
try {
|
||||
c.declarationInstantiation();
|
||||
instantiateModule(c);
|
||||
} catch (exc) {
|
||||
threw = true;
|
||||
e2 = exc;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");
|
|||
let e1;
|
||||
let threw = false;
|
||||
try {
|
||||
c.declarationInstantiation();
|
||||
instantiateModule(c);
|
||||
} catch (exc) {
|
||||
threw = true;
|
||||
e1 = exc;
|
||||
|
|
@ -28,7 +28,7 @@ let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;");
|
|||
|
||||
threw = false;
|
||||
try {
|
||||
d.declarationInstantiation();
|
||||
instantiateModule(d);
|
||||
} catch (exc) {
|
||||
threw = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ setModuleResolveHook(function(module, specifier) {
|
|||
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 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.
|
||||
// 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
|
||||
// instantiated module 'c' is not instantiated.
|
||||
d.declarationInstantiation();
|
||||
d.evaluation();
|
||||
instantiateModule(d);
|
||||
evaluateModule(d);
|
||||
|
|
|
|||
|
|
@ -24,5 +24,5 @@ for (let i = 0; i < count; i++) {
|
|||
}
|
||||
let b = moduleRepo['b'] = parseModule(s);
|
||||
|
||||
b.declarationInstantiation();
|
||||
b.evaluation();
|
||||
instantiateModule(b);
|
||||
evaluateModule(b);
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@ if (!('stackTest' in this))
|
|||
|
||||
stackTest(function() {
|
||||
let m = parseModule(``);
|
||||
m.declarationInstantiation();
|
||||
instantiateModule(m);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ if (!('oomTest' in this))
|
|||
loadFile(`
|
||||
function parseAndEvaluate(source) {
|
||||
let m = parseModule(source);
|
||||
m.declarationInstantiation();
|
||||
instantiateModule(m);
|
||||
}
|
||||
parseAndEvaluate("async function a() { await 2 + 3; }")
|
||||
`);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// |jit-test| error: Error
|
||||
let m = parseModule(`for (var x of iterator) {}`);
|
||||
m.declarationInstantiation();
|
||||
try { m.evaluation(); } catch (e) {}
|
||||
instantiateModule(m);
|
||||
try { evaluateModule(m); } catch (e) {}
|
||||
getModuleEnvironmentValue(m, "r");
|
||||
|
|
|
|||
|
|
@ -14,5 +14,5 @@ moduleRepo["a"] = parseModule(`import* as ns from "good"; import {y} from "bad";
|
|||
let b = moduleRepo["b"] = parseModule(`import "a";`);
|
||||
let c = moduleRepo["c"] = parseModule(`import "a";`);
|
||||
|
||||
assertThrowsInstanceOf(() => b.declarationInstantiation(), SyntaxError);
|
||||
assertThrowsInstanceOf(() => c.declarationInstantiation(), SyntaxError);
|
||||
assertThrowsInstanceOf(() => instantiateModule(b), SyntaxError);
|
||||
assertThrowsInstanceOf(() => instantiateModule(c), SyntaxError);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ if (!('stackTest' in this))
|
|||
quit();
|
||||
|
||||
let a = parseModule(`throw new Error`);
|
||||
a.declarationInstantiation();
|
||||
instantiateModule(a);
|
||||
stackTest(function() {
|
||||
a.evaluation();
|
||||
evaluateModule(a);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ moduleRepo["a"] = parseModule(`throw undefined`);
|
|||
let b = moduleRepo["b"] = parseModule(`import "a";`);
|
||||
let c = moduleRepo["c"] = parseModule(`import "a";`);
|
||||
|
||||
b.declarationInstantiation();
|
||||
c.declarationInstantiation();
|
||||
instantiateModule(b);
|
||||
instantiateModule(c);
|
||||
|
||||
let count = 0;
|
||||
try { b.evaluation() } catch (e) { count++; }
|
||||
try { c.evaluation() } catch (e) { count++; }
|
||||
try { evaluateModule(b) } catch (e) { count++; }
|
||||
try { evaluateModule(c) } catch (e) { count++; }
|
||||
assertEq(count, 2);
|
||||
|
|
|
|||
|
|
@ -14,5 +14,5 @@ moduleRepo["a"] = parseModule(`import {x} from "good"; import {y} from "bad";`);
|
|||
let b = moduleRepo["b"] = parseModule(`import "a";`);
|
||||
let c = moduleRepo["c"] = parseModule(`import "a";`);
|
||||
|
||||
assertThrowsInstanceOf(() => b.declarationInstantiation(), SyntaxError);
|
||||
assertThrowsInstanceOf(() => c.declarationInstantiation(), SyntaxError);
|
||||
assertThrowsInstanceOf(() => instantiateModule(b), SyntaxError);
|
||||
assertThrowsInstanceOf(() => instantiateModule(c), SyntaxError);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue