mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Merge mozilla-central to inbound. a=merge CLOSED TREE
This commit is contained in:
commit
80d0825239
@ -1,9 +1,9 @@
|
||||
This is the debugger.html project output.
|
||||
See https://github.com/devtools-html/debugger.html
|
||||
|
||||
Version 85
|
||||
Version 84
|
||||
|
||||
Comparison: https://github.com/devtools-html/debugger.html/compare/release-84...release-85
|
||||
Comparison: https://github.com/devtools-html/debugger.html/compare/release-83...release-84
|
||||
|
||||
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,6 +8,7 @@ exports.selectSourceURL = selectSourceURL;
|
||||
exports.selectSource = selectSource;
|
||||
exports.selectLocation = selectLocation;
|
||||
exports.selectSpecificLocation = selectSpecificLocation;
|
||||
exports.selectSpecificSource = selectSpecificSource;
|
||||
exports.jumpToMappedLocation = jumpToMappedLocation;
|
||||
exports.jumpToMappedSelectedLocation = jumpToMappedSelectedLocation;
|
||||
|
||||
@ -105,7 +106,7 @@ function selectSource(sourceId) {
|
||||
const location = (0, _location.createLocation)({
|
||||
sourceId
|
||||
});
|
||||
return await dispatch(selectSpecificLocation(location));
|
||||
return await dispatch(selectLocation(location));
|
||||
};
|
||||
}
|
||||
/**
|
||||
@ -195,6 +196,22 @@ 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,
|
||||
|
@ -132,7 +132,7 @@ class Tab extends _react.PureComponent {
|
||||
render() {
|
||||
const {
|
||||
selectedSource,
|
||||
selectSource,
|
||||
selectSpecificSource,
|
||||
closeTab,
|
||||
source,
|
||||
tabSources
|
||||
@ -149,7 +149,7 @@ class Tab extends _react.PureComponent {
|
||||
function handleTabClick(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return selectSource(sourceId);
|
||||
return selectSpecificSource(sourceId);
|
||||
}
|
||||
|
||||
const className = (0, _classnames2.default)("source-tab", {
|
||||
@ -190,7 +190,7 @@ const mapStateToProps = (state, {
|
||||
};
|
||||
|
||||
exports.default = (0, _reactRedux.connect)(mapStateToProps, {
|
||||
selectSource: _actions2.default.selectSource,
|
||||
selectSpecificSource: _actions2.default.selectSpecificSource,
|
||||
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 {
|
||||
selectSource
|
||||
selectSpecificSource
|
||||
} = this.props;
|
||||
const filename = (0, _source.getFilename)(source);
|
||||
|
||||
const onClick = () => selectSource(source.id);
|
||||
const onClick = () => selectSpecificSource(source.id);
|
||||
|
||||
return _react2.default.createElement("li", {
|
||||
key: source.id,
|
||||
@ -206,7 +206,7 @@ const mapStateToProps = state => ({
|
||||
});
|
||||
|
||||
exports.default = (0, _reactRedux.connect)(mapStateToProps, {
|
||||
selectSource: _actions2.default.selectSource,
|
||||
selectSpecificSource: _actions2.default.selectSpecificSource,
|
||||
moveTab: _actions2.default.moveTab,
|
||||
closeTab: _actions2.default.closeTab,
|
||||
togglePaneCollapse: _actions2.default.togglePaneCollapse,
|
||||
|
@ -247,14 +247,17 @@ var _initialiseProps = function () {
|
||||
|
||||
this.getPath = item => {
|
||||
const path = `${item.path}/${item.name}`;
|
||||
const source = this.getSource(item);
|
||||
|
||||
if (!source || (0, _sourcesTree.isDirectory)(item)) {
|
||||
if ((0, _sourcesTree.isDirectory)(item)) {
|
||||
return path;
|
||||
}
|
||||
|
||||
const blackBoxedPart = source.isBlackBoxed ? ":blackboxed" : "";
|
||||
return `${path}/${source.id}/${blackBoxedPart}`;
|
||||
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}`;
|
||||
};
|
||||
|
||||
this.onExpand = (item, expandedState) => {
|
||||
|
@ -21,13 +21,14 @@ 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.getSourceList();
|
||||
return sources.find(s => (s.url || "").includes(url));
|
||||
}
|
||||
const sources = dbg.selectors.getSources();
|
||||
const source = sources.find(s => (s.url || "").includes(url));
|
||||
|
||||
function findSources(dbg, url) {
|
||||
const sources = dbg.selectors.getSourceList();
|
||||
return sources.filter(s => (s.url || "").includes(url));
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
function sendPacket(dbg, packet, callback) {
|
||||
@ -75,7 +76,6 @@ 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,13 +31,8 @@ async function buildMappedScopes(source, frame, scopes, sourceMaps, client) {
|
||||
return null;
|
||||
}
|
||||
|
||||
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 originalRanges = await (0, _rangeMetadata.loadRangeMetadata)(source, frame, originalAstScopes, sourceMaps);
|
||||
const {
|
||||
mappedOriginalScopes,
|
||||
expressionLookup
|
||||
@ -109,10 +104,6 @@ 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.4";
|
||||
const prefsSchemaVersion = "1.0.3";
|
||||
const pref = _devtoolsServices2.default.pref;
|
||||
|
||||
if ((0, _devtoolsEnvironment.isDevelopment)()) {
|
||||
@ -128,6 +128,5 @@ 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 selectSource(dbg, "output");
|
||||
await selectSpecificSource(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 selectSource(dbg, bundleSrc);
|
||||
await selectSpecificSource(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 selectSource(dbg, entrySrc);
|
||||
await selectSpecificSource(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 selectSource(dbg, mainSrc);
|
||||
await selectSpecificSource(dbg, mainSrc);
|
||||
await addBreakpoint(dbg, "fib.c", 10);
|
||||
|
||||
resume(dbg);
|
||||
|
@ -603,7 +603,7 @@ async function selectSource(dbg, url, line) {
|
||||
return waitForSelectedSource(dbg, url);
|
||||
}
|
||||
|
||||
async function selectSource(dbg, url, line) {
|
||||
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);
|
||||
|
@ -65,8 +65,8 @@ var PromisesActor = protocol.ActorClassWithSpec(promisesSpec, {
|
||||
this._newPromises = [];
|
||||
this._promisesSettled = [];
|
||||
|
||||
this.dbg.findSources().forEach(source => {
|
||||
this.parentActor.sources.createSourceActors(source);
|
||||
this.dbg.findScripts().forEach(s => {
|
||||
this.parentActor.sources.createSourceActors(s.source);
|
||||
});
|
||||
|
||||
this.dbg.onNewScript = s => {
|
||||
|
@ -1111,12 +1111,22 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the source lists from the debugger.
|
||||
* Get the script and source lists from the debugger.
|
||||
*/
|
||||
_discoverSources: function() {
|
||||
const sources = this.dbg.findSources();
|
||||
return Promise.all(sources.map(source => {
|
||||
return this.sources.createSourceActors(source);
|
||||
// Only get one script per Debugger.Source.
|
||||
const sourcesToScripts = new Map();
|
||||
const scripts = this.dbg.findScripts();
|
||||
|
||||
for (let i = 0, len = scripts.length; i < len; i++) {
|
||||
const s = scripts[i];
|
||||
if (s.source) {
|
||||
sourcesToScripts.set(s.source, s);
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all([...sourcesToScripts.values()].map(script => {
|
||||
return this.sources.createSourceActors(script.source);
|
||||
}));
|
||||
},
|
||||
|
||||
|
@ -357,10 +357,26 @@ other kinds of objects.
|
||||
[visible frame][vf] currently on the calling thread's stack, or `null`
|
||||
if there are no visible frames on the stack.
|
||||
|
||||
<code>findSources()</code>
|
||||
: Return an array of all [`Debugger.Source`][source] instances of all debuggee
|
||||
<code>findSources([<i>query</i>]) <i>(not yet implemented)</i></code>
|
||||
: Return an array of all [`Debugger.Source`][source] instances matching
|
||||
<i>query</i>. Each source appears only once in the array. <i>Query</i>
|
||||
is an object whose properties restrict which sources are returned; a
|
||||
source must meet all the criteria given by <i>query</i> to be returned.
|
||||
If <i>query</i> is omitted, we return all sources of all debuggee
|
||||
scripts.
|
||||
|
||||
<i>Query</i> may have the following properties:
|
||||
|
||||
`url`
|
||||
: The source's `url` property must be equal to this value.
|
||||
|
||||
`global`
|
||||
: The source must have been evaluated in the scope of the given global
|
||||
object. If this property's value is a [`Debugger.Object`][object] instance
|
||||
belonging to this `Debugger` instance, then its referent is used. If the
|
||||
object is not a global object, then the global in whose scope it was
|
||||
allocated is used.
|
||||
|
||||
Note that the result may include sources that can no longer ever be
|
||||
used by the debuggee: say, eval code that has finished running, or
|
||||
source for unreachable functions. Whether such sources appear can be
|
||||
|
@ -1,4 +0,0 @@
|
||||
// In a debugger with no debuggees, findSources should return no scripts.
|
||||
|
||||
const dbg = new Debugger;
|
||||
assertEq(dbg.findSources().length, 0);
|
@ -1,15 +0,0 @@
|
||||
// In a debugger with scripts, findSources finds the script source.
|
||||
|
||||
const g = newGlobal();
|
||||
// Declare a function in order to keep the script source alive across GC.
|
||||
g.evaluate(`function fa() {}`, { fileName: "a.js" });
|
||||
g.evaluate(`function fb() {}`, { fileName: "b.js" });
|
||||
g.evaluate(`function fc() {}`, { fileName: "c.js" });
|
||||
|
||||
const dbg = new Debugger();
|
||||
const gw = dbg.addDebuggee(g);
|
||||
|
||||
const sources = dbg.findSources();
|
||||
assertEq(sources.filter(s => s.url == "a.js").length, 1);
|
||||
assertEq(sources.filter(s => s.url == "b.js").length, 1);
|
||||
assertEq(sources.filter(s => s.url == "c.js").length, 1);
|
@ -1,19 +0,0 @@
|
||||
// In a debugger with multiple debuggees, findSources finds script sources across all debuggees.
|
||||
|
||||
const g1 = newGlobal();
|
||||
const g2 = newGlobal();
|
||||
// Declare a function in order to keep the script source alive across GC.
|
||||
g1.evaluate(`function fa() {}`, { fileName: "a.js" });
|
||||
g1.evaluate(`function fb() {}`, { fileName: "b.js" });
|
||||
g2.evaluate(`function fc() {}`, { fileName: "c.js" });
|
||||
g2.evaluate(`function fd() {}`, { fileName: "d.js" });
|
||||
|
||||
const dbg = new Debugger();
|
||||
const g1w = dbg.addDebuggee(g1);
|
||||
const g2w = dbg.addDebuggee(g2);
|
||||
|
||||
const sources = dbg.findSources();
|
||||
assertEq(dbg.findSources().filter(s => s.url == "a.js").length, 1);
|
||||
assertEq(dbg.findSources().filter(s => s.url == "b.js").length, 1);
|
||||
assertEq(dbg.findSources().filter(s => s.url == "c.js").length, 1);
|
||||
assertEq(dbg.findSources().filter(s => s.url == "d.js").length, 1);
|
@ -4188,73 +4188,19 @@ Debugger::removeDebuggeeGlobal(FreeOp* fop, GlobalObject* global,
|
||||
|
||||
static inline DebuggerSourceReferent GetSourceReferent(JSObject* obj);
|
||||
|
||||
class MOZ_STACK_CLASS Debugger::QueryBase
|
||||
{
|
||||
protected:
|
||||
QueryBase(JSContext* cx, Debugger* dbg)
|
||||
: cx(cx),
|
||||
debugger(dbg),
|
||||
iterMarker(&cx->runtime()->gc),
|
||||
realms(cx->zone()),
|
||||
oom(false)
|
||||
{}
|
||||
|
||||
// The context in which we should do our work.
|
||||
JSContext* cx;
|
||||
|
||||
// The debugger for which we conduct queries.
|
||||
Debugger* debugger;
|
||||
|
||||
// Require the set of realms to stay fixed while this query is alive.
|
||||
gc::AutoEnterIteration iterMarker;
|
||||
|
||||
using RealmSet = HashSet<Realm*, DefaultHasher<Realm*>, ZoneAllocPolicy>;
|
||||
|
||||
// A script must be in one of these realms to match the query.
|
||||
RealmSet realms;
|
||||
|
||||
// Indicates whether OOM has occurred while matching.
|
||||
bool oom;
|
||||
|
||||
bool addRealm(Realm* realm) {
|
||||
return realms.put(realm);
|
||||
}
|
||||
|
||||
// Arrange for this query to match only scripts that run in |global|.
|
||||
bool matchSingleGlobal(GlobalObject* global) {
|
||||
MOZ_ASSERT(realms.count() == 0);
|
||||
if (!addRealm(global->realm())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Arrange for this ScriptQuery to match all scripts running in debuggee
|
||||
// globals.
|
||||
bool matchAllDebuggeeGlobals() {
|
||||
MOZ_ASSERT(realms.count() == 0);
|
||||
// Build our realm set from the debugger's set of debuggee globals.
|
||||
for (WeakGlobalObjectSet::Range r = debugger->debuggees.all(); !r.empty(); r.popFront()) {
|
||||
if (!addRealm(r.front()->realm())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* A class for parsing 'findScripts' query arguments and searching for
|
||||
* scripts that match the criteria they represent.
|
||||
*/
|
||||
class MOZ_STACK_CLASS Debugger::ScriptQuery : public Debugger::QueryBase
|
||||
class MOZ_STACK_CLASS Debugger::ScriptQuery
|
||||
{
|
||||
public:
|
||||
/* Construct a ScriptQuery to use matching scripts for |dbg|. */
|
||||
ScriptQuery(JSContext* cx, Debugger* dbg)
|
||||
: QueryBase(cx, dbg),
|
||||
ScriptQuery(JSContext* cx, Debugger* dbg):
|
||||
cx(cx),
|
||||
debugger(dbg),
|
||||
iterMarker(&cx->runtime()->gc),
|
||||
realms(cx->zone()),
|
||||
url(cx),
|
||||
displayURLString(cx),
|
||||
hasSource(false),
|
||||
@ -4265,7 +4211,8 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery : public Debugger::QueryBase
|
||||
innermostForRealm(cx->zone()),
|
||||
scriptVector(cx, ScriptVector(cx)),
|
||||
lazyScriptVector(cx, LazyScriptVector(cx)),
|
||||
wasmInstanceVector(cx, WasmInstanceObjectVector(cx))
|
||||
wasmInstanceVector(cx, WasmInstanceObjectVector(cx)),
|
||||
oom(false)
|
||||
{}
|
||||
|
||||
/*
|
||||
@ -4489,6 +4436,20 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery : public Debugger::QueryBase
|
||||
}
|
||||
|
||||
private:
|
||||
/* The context in which we should do our work. */
|
||||
JSContext* cx;
|
||||
|
||||
/* The debugger for which we conduct queries. */
|
||||
Debugger* debugger;
|
||||
|
||||
/* Require the set of realms to stay fixed while the ScriptQuery is alive. */
|
||||
gc::AutoEnterIteration iterMarker;
|
||||
|
||||
using RealmSet = HashSet<Realm*, DefaultHasher<Realm*>, ZoneAllocPolicy>;
|
||||
|
||||
/* A script must be in one of these realms to match the query. */
|
||||
RealmSet realms;
|
||||
|
||||
/* If this is a string, matching scripts have urls equal to it. */
|
||||
RootedValue url;
|
||||
|
||||
@ -4538,6 +4499,39 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery : public Debugger::QueryBase
|
||||
*/
|
||||
Rooted<WasmInstanceObjectVector> wasmInstanceVector;
|
||||
|
||||
/* Indicates whether OOM has occurred while matching. */
|
||||
bool oom;
|
||||
|
||||
bool addRealm(Realm* realm) {
|
||||
return realms.put(realm);
|
||||
}
|
||||
|
||||
/* Arrange for this ScriptQuery to match only scripts that run in |global|. */
|
||||
bool matchSingleGlobal(GlobalObject* global) {
|
||||
MOZ_ASSERT(realms.count() == 0);
|
||||
if (!addRealm(global->realm())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Arrange for this ScriptQuery to match all scripts running in debuggee
|
||||
* globals.
|
||||
*/
|
||||
bool matchAllDebuggeeGlobals() {
|
||||
MOZ_ASSERT(realms.count() == 0);
|
||||
// Build our realm set from the debugger's set of debuggee globals.
|
||||
for (WeakGlobalObjectSet::Range r = debugger->debuggees.all(); !r.empty(); r.popFront()) {
|
||||
if (!addRealm(r.front()->realm())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given that parseQuery or omittedQuery has been called, prepare to match
|
||||
* scripts. Set urlCString and displayURLChars as appropriate.
|
||||
@ -4771,160 +4765,6 @@ Debugger::findScripts(JSContext* cx, unsigned argc, Value* vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* A class for searching sources for 'findSources'.
|
||||
*/
|
||||
class MOZ_STACK_CLASS Debugger::SourceQuery : public Debugger::QueryBase
|
||||
{
|
||||
public:
|
||||
using SourceSet = JS::GCHashSet<JSObject*,
|
||||
js::MovableCellHasher<JSObject*>,
|
||||
ZoneAllocPolicy>;
|
||||
|
||||
SourceQuery(JSContext* cx, Debugger* dbg)
|
||||
: QueryBase(cx, dbg),
|
||||
sources(cx, SourceSet(cx->zone()))
|
||||
{}
|
||||
|
||||
bool findSources() {
|
||||
if (!matchAllDebuggeeGlobals())
|
||||
return false;
|
||||
|
||||
Realm* singletonRealm = nullptr;
|
||||
if (realms.count() == 1)
|
||||
singletonRealm = realms.all().front();
|
||||
|
||||
// Search each realm for debuggee scripts.
|
||||
MOZ_ASSERT(sources.empty());
|
||||
oom = false;
|
||||
IterateScripts(cx, singletonRealm, this, considerScript);
|
||||
IterateLazyScripts(cx, singletonRealm, this, considerLazyScript);
|
||||
if (oom) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Until such time that wasm modules are real ES6 modules,
|
||||
// unconditionally consider all wasm toplevel instance scripts.
|
||||
for (WeakGlobalObjectSet::Range r = debugger->allDebuggees(); !r.empty(); r.popFront()) {
|
||||
for (wasm::Instance* instance : r.front()->realm()->wasm.instances()) {
|
||||
consider(instance->object());
|
||||
if (oom) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Handle<SourceSet> foundSources() const {
|
||||
return sources;
|
||||
}
|
||||
|
||||
private:
|
||||
Rooted<SourceSet> sources;
|
||||
|
||||
static void considerScript(JSRuntime* rt, void* data, JSScript* script,
|
||||
const JS::AutoRequireNoGC& nogc) {
|
||||
SourceQuery* self = static_cast<SourceQuery*>(data);
|
||||
self->consider(script, nogc);
|
||||
}
|
||||
|
||||
static void considerLazyScript(JSRuntime* rt, void* data, LazyScript* lazyScript,
|
||||
const JS::AutoRequireNoGC& nogc) {
|
||||
SourceQuery* self = static_cast<SourceQuery*>(data);
|
||||
self->consider(lazyScript, nogc);
|
||||
}
|
||||
|
||||
void consider(JSScript* script, const JS::AutoRequireNoGC& nogc) {
|
||||
if (oom || script->selfHosted())
|
||||
return;
|
||||
Realm* realm = script->realm();
|
||||
if (!realms.has(realm))
|
||||
return;
|
||||
|
||||
if (!script->sourceObject())
|
||||
return;
|
||||
|
||||
ScriptSourceObject* source =
|
||||
&UncheckedUnwrap(script->sourceObject())->as<ScriptSourceObject>();
|
||||
if (!sources.put(source))
|
||||
oom = true;
|
||||
}
|
||||
|
||||
void consider(LazyScript* lazyScript, const JS::AutoRequireNoGC& nogc) {
|
||||
if (oom)
|
||||
return;
|
||||
Realm* realm = lazyScript->realm();
|
||||
if (!realms.has(realm))
|
||||
return;
|
||||
|
||||
// If the script is already delazified, it should already be handled.
|
||||
if (lazyScript->maybeScript())
|
||||
return;
|
||||
|
||||
ScriptSourceObject* source = &lazyScript->sourceObject();
|
||||
if (!sources.put(source))
|
||||
oom = true;
|
||||
}
|
||||
|
||||
void consider(WasmInstanceObject* instanceObject) {
|
||||
if (oom)
|
||||
return;
|
||||
|
||||
if (!sources.put(instanceObject))
|
||||
oom = true;
|
||||
}
|
||||
};
|
||||
|
||||
static inline DebuggerSourceReferent
|
||||
AsSourceReferent(JSObject* obj)
|
||||
{
|
||||
if (obj->is<ScriptSourceObject>()) {
|
||||
return AsVariant(&obj->as<ScriptSourceObject>());
|
||||
}
|
||||
return AsVariant(&obj->as<WasmInstanceObject>());
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Debugger::findSources(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
THIS_DEBUGGER(cx, argc, vp, "findSources", args, dbg);
|
||||
|
||||
if (gc::GCRuntime::temporaryAbortIfWasmGc(cx)) {
|
||||
JS_ReportErrorASCII(cx, "API temporarily unavailable under wasm gc");
|
||||
return false;
|
||||
}
|
||||
|
||||
SourceQuery query(cx, dbg);
|
||||
if (!query.findSources())
|
||||
return false;
|
||||
|
||||
Handle<SourceQuery::SourceSet> sources(query.foundSources());
|
||||
|
||||
size_t resultLength = sources.count();
|
||||
RootedArrayObject result(cx, NewDenseFullyAllocatedArray(cx, resultLength));
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
result->ensureDenseInitializedLength(cx, 0, resultLength);
|
||||
|
||||
size_t i = 0;
|
||||
for (auto iter = sources.get().iter(); !iter.done(); iter.next()) {
|
||||
Rooted<DebuggerSourceReferent> sourceReferent(cx, AsSourceReferent(iter.get()));
|
||||
RootedObject sourceObject(cx, dbg->wrapVariantReferent(cx, sourceReferent));
|
||||
if (!sourceObject)
|
||||
return false;
|
||||
result->setDenseElement(i, ObjectValue(*sourceObject));
|
||||
i++;
|
||||
}
|
||||
|
||||
args.rval().setObject(*result);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* A class for parsing 'findObjects' query arguments and searching for objects
|
||||
* that match the criteria they represent.
|
||||
@ -5341,7 +5181,6 @@ const JSFunctionSpec Debugger::methods[] = {
|
||||
JS_FN("getNewestFrame", Debugger::getNewestFrame, 0, 0),
|
||||
JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 0, 0),
|
||||
JS_FN("findScripts", Debugger::findScripts, 1, 0),
|
||||
JS_FN("findSources", Debugger::findSources, 1, 0),
|
||||
JS_FN("findObjects", Debugger::findObjects, 1, 0),
|
||||
JS_FN("findAllGlobals", Debugger::findAllGlobals, 0, 0),
|
||||
JS_FN("makeGlobalObjectReference", Debugger::makeGlobalObjectReference, 1, 0),
|
||||
|
@ -566,9 +566,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
uint32_t traceLoggerScriptedCallsLastDrainedSize;
|
||||
uint32_t traceLoggerScriptedCallsLastDrainedIteration;
|
||||
|
||||
class QueryBase;
|
||||
class ScriptQuery;
|
||||
class SourceQuery;
|
||||
class ObjectQuery;
|
||||
|
||||
MOZ_MUST_USE bool addDebuggeeGlobal(JSContext* cx, Handle<GlobalObject*> obj);
|
||||
@ -720,7 +718,6 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
static bool getNewestFrame(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool clearAllBreakpoints(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool findScripts(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool findSources(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool findObjects(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool findAllGlobals(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool makeGlobalObjectReference(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
Loading…
Reference in New Issue
Block a user