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

This commit is contained in:
Gurzau Raul 2018-08-23 15:31:37 +03:00
commit 80d0825239
21 changed files with 2016 additions and 322 deletions

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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) => {

View File

@ -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)

View File

@ -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

View File

@ -20,7 +20,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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;
}

View File

@ -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);
});

View File

@ -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()

View File

@ -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);

View File

@ -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);

View File

@ -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 => {

View File

@ -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);
}));
},

View File

@ -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

View File

@ -1,4 +0,0 @@
// In a debugger with no debuggees, findSources should return no scripts.
const dbg = new Debugger;
assertEq(dbg.findSources().length, 0);

View File

@ -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);

View File

@ -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);

View File

@ -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),

View File

@ -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);