author | James Long <longster@gmail.com> |
Mon, 06 Oct 2014 11:42:00 +0200 | |
changeset 232341 | 6dc2eaf50c04bfab8f98b13756bb28c421674cf7 |
parent 232340 | 124b04c01c7127593f89408edf82db7e22122735 |
child 232342 | 3b1edb52423b044c7dbcda694bf46cd3648b8d6c |
push id | 4187 |
push user | bhearsum@mozilla.com |
push date | Fri, 28 Nov 2014 15:29:12 +0000 |
treeherder | mozilla-beta@f23cc6a30c11 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jorendorff |
bugs | 1056409 |
milestone | 35.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/base/test/chrome/test_bug765993.html +++ b/content/base/test/chrome/test_bug765993.html @@ -41,17 +41,17 @@ window.onload = function () { var dbg = new Debugger(iframe.contentWindow); ok(dbg, "Should be able to create debugger"); var scripts = dbg.findScripts({ url: "http://mochi.test:8888/tests/content/base/test/chrome/nochrome_bug765993.js" }); ok(scripts.length > 0, "Should be able to find script"); - is(scripts[0].sourceMapURL, "foo.js.map"); + is(scripts[0].source.sourceMapURL, "foo.js.map"); SimpleTest.finish(); } iframe.contentWindow.document.body.appendChild(script); }; document.body.appendChild(iframe); };
--- a/js/src/doc/Debugger/Debugger.Script.md +++ b/js/src/doc/Debugger/Debugger.Script.md @@ -110,27 +110,16 @@ from its prototype: contains code at that line. In such a case, the most deeply nested script—the one with the highest static level—should receive the breakpoint. `strictMode` : This is `true` if this script's code is ECMAScript strict mode code, and `false` otherwise. -`sourceMapURL` -: If this script was produced by a minimizer or translated from some other - language, and we know the URL of a <b>source map</b> document relating - the source positions in this script to the corresponding source - positions in the original source, then this property's value is that - URL. Otherwise, this is `null`. - - (On the web, the translator may provide the source map URL in a - specially formatted comment in the JavaScript source code, or via a - header in the HTTP reply that carried the generated JavaScript.) - ## Function Properties of the Debugger.Script Prototype Object The functions described below may only be called with a `this` value referring to a `Debugger.Script` instance; they may not be used as methods of other kinds of objects. <code>decompile([<i>pretty</i>])</code> : Return a string containing JavaScript source code equivalent to this
--- a/js/src/doc/Debugger/Debugger.Source.md +++ b/js/src/doc/Debugger/Debugger.Source.md @@ -69,16 +69,27 @@ from its prototype: * The URL may be the name of a XPCOM JavaScript module or subscript. (Note that code passed to `eval`, the `Function` constructor, or a similar function is <i>not</i> considered to be loaded from a URL; the `url` accessor on `Debugger.Source` instances for such sources should return `undefined`.) +`sourceMapURL` +: If this source was produced by a minimizer or translated from some other + language, and we know the URL of a <b>source map</b> document relating + the source positions in this source to the corresponding source + positions in the original source, then this property's value is that + URL. Otherwise, this is `null`. + + (On the web, the translator may provide the source map URL in a + specially formatted comment in the JavaScript source code, or via a + header in the HTTP reply that carried the generated JavaScript.) + `element` : The [`Debugger.Object`][object] instance referring to the DOM element to which this source code belongs, if any, or `undefined` if it belongs to no DOM element. Source belongs to a DOM element in the following cases: * Source belongs to a `<script>` element if it is the element's text content (that is, it is written out as the body of the `<script>` element in the markup text), or is the source document referenced by its
deleted file mode 100644 --- a/js/src/jit-test/tests/debug/Script-sourceMapURL-deprecated.js +++ /dev/null @@ -1,70 +0,0 @@ -// Script.prototype.sourceMapURL can be a string or null. - -let g = newGlobal(); -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); - -function getSourceMapURL() { - let fw = gw.makeDebuggeeValue(g.f); - return fw.script.sourceMapURL; -} - -// Without a source map -g.evaluate("function f(x) { return 2*x; }"); -assertEq(getSourceMapURL(), null); - -// With a source map -g.evaluate("function f(x) { return 2*x; }", {sourceMapURL: 'file:///var/foo.js.map'}); -assertEq(getSourceMapURL(), 'file:///var/foo.js.map'); - -// Nested functions -let fired = false; -dbg.onDebuggerStatement = function (frame) { - fired = true; - assertEq(frame.script.sourceMapURL, 'file:///var/bar.js.map'); -}; -g.evaluate('(function () { (function () { debugger; })(); })();', - {sourceMapURL: 'file:///var/bar.js.map'}); -assertEq(fired, true); - -// Comment pragmas -g.evaluate('function f() {}\n' + - '//@ sourceMappingURL=file:///var/quux.js.map'); -assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); - -g.evaluate('function f() {}\n' + - '/*//@ sourceMappingURL=file:///var/quux.js.map*/'); -assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); - -g.evaluate('function f() {}\n' + - '/*\n' + - '//@ sourceMappingURL=file:///var/quux.js.map\n' + - '*/'); -assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); - -// Spaces are disallowed by the URL spec (they should have been -// percent-encoded). -g.evaluate('function f() {}\n' + - '//@ sourceMappingURL=http://example.com/has illegal spaces.map'); -assertEq(getSourceMapURL(), 'http://example.com/has'); - -// When the URL is missing, we don't set the sourceMapURL and we don't skip the -// next line of input. -g.evaluate('function f() {}\n' + - '//@ sourceMappingURL=\n' + - 'function z() {}'); -assertEq(getSourceMapURL(), null); -assertEq('z' in g, true); - -// The last comment pragma we see should be the one which sets the source map's -// URL. -g.evaluate('function f() {}\n' + - '//@ sourceMappingURL=http://example.com/foo.js.map\n' + - '//@ sourceMappingURL=http://example.com/bar.js.map'); -assertEq(getSourceMapURL(), 'http://example.com/bar.js.map'); - -// With both a comment and the evaluate option. -g.evaluate('function f() {}\n' + - '//@ sourceMappingURL=http://example.com/foo.js.map', - {sourceMapURL: 'http://example.com/bar.js.map'}); -assertEq(getSourceMapURL(), 'http://example.com/foo.js.map');
deleted file mode 100644 --- a/js/src/jit-test/tests/debug/Script-sourceMapURL.js +++ /dev/null @@ -1,70 +0,0 @@ -// Script.prototype.sourceMapURL can be a string or null. - -let g = newGlobal(); -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); - -function getSourceMapURL() { - let fw = gw.makeDebuggeeValue(g.f); - return fw.script.sourceMapURL; -} - -// Without a source map -g.evaluate("function f(x) { return 2*x; }"); -assertEq(getSourceMapURL(), null); - -// With a source map -g.evaluate("function f(x) { return 2*x; }", {sourceMapURL: 'file:///var/foo.js.map'}); -assertEq(getSourceMapURL(), 'file:///var/foo.js.map'); - -// Nested functions -let fired = false; -dbg.onDebuggerStatement = function (frame) { - fired = true; - assertEq(frame.script.sourceMapURL, 'file:///var/bar.js.map'); -}; -g.evaluate('(function () { (function () { debugger; })(); })();', - {sourceMapURL: 'file:///var/bar.js.map'}); -assertEq(fired, true); - -// Comment pragmas -g.evaluate('function f() {}\n' + - '//# sourceMappingURL=file:///var/quux.js.map'); -assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); - -g.evaluate('function f() {}\n' + - '/*//# sourceMappingURL=file:///var/quux.js.map*/'); -assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); - -g.evaluate('function f() {}\n' + - '/*\n' + - '//# sourceMappingURL=file:///var/quux.js.map\n' + - '*/'); -assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); - -// Spaces are disallowed by the URL spec (they should have been -// percent-encoded). -g.evaluate('function f() {}\n' + - '//# sourceMappingURL=http://example.com/has illegal spaces.map'); -assertEq(getSourceMapURL(), 'http://example.com/has'); - -// When the URL is missing, we don't set the sourceMapURL and we don't skip the -// next line of input. -g.evaluate('function f() {}\n' + - '//# sourceMappingURL=\n' + - 'function z() {}'); -assertEq(getSourceMapURL(), null); -assertEq('z' in g, true); - -// The last comment pragma we see should be the one which sets the source map's -// URL. -g.evaluate('function f() {}\n' + - '//# sourceMappingURL=http://example.com/foo.js.map\n' + - '//# sourceMappingURL=http://example.com/bar.js.map'); -assertEq(getSourceMapURL(), 'http://example.com/bar.js.map'); - -// With both a comment and the evaluate option. -g.evaluate('function f() {}\n' + - '//# sourceMappingURL=http://example.com/foo.js.map', - {sourceMapURL: 'http://example.com/bar.js.map'}); -assertEq(getSourceMapURL(), 'http://example.com/foo.js.map');
--- a/js/src/jit-test/tests/debug/Source-displayURL.js +++ b/js/src/jit-test/tests/debug/Source-displayURL.js @@ -73,19 +73,19 @@ assertEq(getDisplayURL(), 'http://exampl // Bug 981987 reported that we hadn't set sourceURL yet when firing onNewScript // from the Function constructor. var capturedScript; var capturedDisplayURL; var capturedSourceMapURL; dbg.onNewScript = function (script) { capturedScript = script; capturedDisplayURL = script.source.displayURL; - capturedSourceMapURL = script.sourceMapURL; + capturedSourceMapURL = script.source.sourceMapURL; dbg.onNewScript = undefined; }; var fun = gw.makeDebuggeeValue(g.Function('//# sourceURL=munge.js\n//# sourceMappingURL=grunge.map\n')); assertEq(capturedScript, fun.script); assertEq(capturedDisplayURL, fun.script.source.displayURL); assertEq(capturedDisplayURL, 'munge.js'); -assertEq(capturedSourceMapURL, fun.script.sourceMapURL); +assertEq(capturedSourceMapURL, fun.script.source.sourceMapURL); assertEq(capturedSourceMapURL, 'grunge.map');
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/debug/Source-sourceMapURL-deprecated.js @@ -0,0 +1,70 @@ +// Source.prototype.sourceMapURL can be a string or null. + +let g = newGlobal(); +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); + +function getSourceMapURL() { + let fw = gw.makeDebuggeeValue(g.f); + return fw.script.source.sourceMapURL; +} + +// Without a source map +g.evaluate("function f(x) { return 2*x; }"); +assertEq(getSourceMapURL(), null); + +// With a source map +g.evaluate("function f(x) { return 2*x; }", {sourceMapURL: 'file:///var/foo.js.map'}); +assertEq(getSourceMapURL(), 'file:///var/foo.js.map'); + +// Nested functions +let fired = false; +dbg.onDebuggerStatement = function (frame) { + fired = true; + assertEq(frame.script.source.sourceMapURL, 'file:///var/bar.js.map'); +}; +g.evaluate('(function () { (function () { debugger; })(); })();', + {sourceMapURL: 'file:///var/bar.js.map'}); +assertEq(fired, true); + +// Comment pragmas +g.evaluate('function f() {}\n' + + '//@ sourceMappingURL=file:///var/quux.js.map'); +assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); + +g.evaluate('function f() {}\n' + + '/*//@ sourceMappingURL=file:///var/quux.js.map*/'); +assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); + +g.evaluate('function f() {}\n' + + '/*\n' + + '//@ sourceMappingURL=file:///var/quux.js.map\n' + + '*/'); +assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); + +// Spaces are disallowed by the URL spec (they should have been +// percent-encoded). +g.evaluate('function f() {}\n' + + '//@ sourceMappingURL=http://example.com/has illegal spaces.map'); +assertEq(getSourceMapURL(), 'http://example.com/has'); + +// When the URL is missing, we don't set the sourceMapURL and we don't skip the +// next line of input. +g.evaluate('function f() {}\n' + + '//@ sourceMappingURL=\n' + + 'function z() {}'); +assertEq(getSourceMapURL(), null); +assertEq('z' in g, true); + +// The last comment pragma we see should be the one which sets the source map's +// URL. +g.evaluate('function f() {}\n' + + '//@ sourceMappingURL=http://example.com/foo.js.map\n' + + '//@ sourceMappingURL=http://example.com/bar.js.map'); +assertEq(getSourceMapURL(), 'http://example.com/bar.js.map'); + +// With both a comment and the evaluate option. +g.evaluate('function f() {}\n' + + '//@ sourceMappingURL=http://example.com/foo.js.map', + {sourceMapURL: 'http://example.com/bar.js.map'}); +assertEq(getSourceMapURL(), 'http://example.com/foo.js.map');
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/debug/Source-sourceMapURL.js @@ -0,0 +1,70 @@ +// Source.prototype.sourceMapURL can be a string or null. + +let g = newGlobal(); +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); + +function getSourceMapURL() { + let fw = gw.makeDebuggeeValue(g.f); + return fw.script.source.sourceMapURL; +} + +// Without a source map +g.evaluate("function f(x) { return 2*x; }"); +assertEq(getSourceMapURL(), null); + +// With a source map +g.evaluate("function f(x) { return 2*x; }", {sourceMapURL: 'file:///var/foo.js.map'}); +assertEq(getSourceMapURL(), 'file:///var/foo.js.map'); + +// Nested functions +let fired = false; +dbg.onDebuggerStatement = function (frame) { + fired = true; + assertEq(frame.script.source.sourceMapURL, 'file:///var/bar.js.map'); +}; +g.evaluate('(function () { (function () { debugger; })(); })();', + {sourceMapURL: 'file:///var/bar.js.map'}); +assertEq(fired, true); + +// Comment pragmas +g.evaluate('function f() {}\n' + + '//# sourceMappingURL=file:///var/quux.js.map'); +assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); + +g.evaluate('function f() {}\n' + + '/*//# sourceMappingURL=file:///var/quux.js.map*/'); +assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); + +g.evaluate('function f() {}\n' + + '/*\n' + + '//# sourceMappingURL=file:///var/quux.js.map\n' + + '*/'); +assertEq(getSourceMapURL(), 'file:///var/quux.js.map'); + +// Spaces are disallowed by the URL spec (they should have been +// percent-encoded). +g.evaluate('function f() {}\n' + + '//# sourceMappingURL=http://example.com/has illegal spaces.map'); +assertEq(getSourceMapURL(), 'http://example.com/has'); + +// When the URL is missing, we don't set the sourceMapURL and we don't skip the +// next line of input. +g.evaluate('function f() {}\n' + + '//# sourceMappingURL=\n' + + 'function z() {}'); +assertEq(getSourceMapURL(), null); +assertEq('z' in g, true); + +// The last comment pragma we see should be the one which sets the source map's +// URL. +g.evaluate('function f() {}\n' + + '//# sourceMappingURL=http://example.com/foo.js.map\n' + + '//# sourceMappingURL=http://example.com/bar.js.map'); +assertEq(getSourceMapURL(), 'http://example.com/bar.js.map'); + +// With both a comment and the evaluate option. +g.evaluate('function f() {}\n' + + '//# sourceMappingURL=http://example.com/foo.js.map', + {sourceMapURL: 'http://example.com/bar.js.map'}); +assertEq(getSourceMapURL(), 'http://example.com/foo.js.map');
--- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -3257,36 +3257,16 @@ static bool DebuggerScript_getStaticLevel(JSContext *cx, unsigned argc, Value *vp) { THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get staticLevel)", args, obj, script); args.rval().setNumber(uint32_t(script->staticLevel())); return true; } static bool -DebuggerScript_getSourceMapUrl(JSContext *cx, unsigned argc, Value *vp) -{ - THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get sourceMapURL)", args, obj, script); - - ScriptSource *source = script->scriptSource(); - MOZ_ASSERT(source); - - if (source->hasSourceMapURL()) { - JSString *str = JS_NewUCStringCopyZ(cx, source->sourceMapURL()); - if (!str) - return false; - args.rval().setString(str); - } else { - args.rval().setNull(); - } - - return true; -} - -static bool DebuggerScript_getGlobal(JSContext *cx, unsigned argc, Value *vp) { THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get global)", args, obj, script); Debugger *dbg = Debugger::fromChildJSObject(obj); RootedValue v(cx, ObjectValue(script->global())); if (!dbg->wrapDebuggeeValue(cx, &v)) return false; @@ -4006,17 +3986,16 @@ DebuggerScript_construct(JSContext *cx, static const JSPropertySpec DebuggerScript_properties[] = { JS_PSG("url", DebuggerScript_getUrl, 0), JS_PSG("startLine", DebuggerScript_getStartLine, 0), JS_PSG("lineCount", DebuggerScript_getLineCount, 0), JS_PSG("source", DebuggerScript_getSource, 0), JS_PSG("sourceStart", DebuggerScript_getSourceStart, 0), JS_PSG("sourceLength", DebuggerScript_getSourceLength, 0), JS_PSG("staticLevel", DebuggerScript_getStaticLevel, 0), - JS_PSG("sourceMapURL", DebuggerScript_getSourceMapUrl, 0), JS_PSG("global", DebuggerScript_getGlobal, 0), JS_PS_END }; static const JSFunctionSpec DebuggerScript_methods[] = { JS_FN("getChildScripts", DebuggerScript_getChildScripts, 0, 0), JS_FN("getAllOffsets", DebuggerScript_getAllOffsets, 0, 0), JS_FN("getAllColumnOffsets", DebuggerScript_getAllColumnOffsets, 0, 0), @@ -4275,25 +4254,46 @@ DebuggerSource_getIntroductionType(JSCon return false; args.rval().setString(str); } else { args.rval().setUndefined(); } return true; } +static bool +DebuggerSource_getSourceMapUrl(JSContext *cx, unsigned argc, Value *vp) +{ + THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get sourceMapURL)", args, obj, sourceObject); + + ScriptSource *ss = sourceObject->source(); + MOZ_ASSERT(ss); + + if (ss->hasSourceMapURL()) { + JSString *str = JS_NewUCStringCopyZ(cx, ss->sourceMapURL()); + if (!str) + return false; + args.rval().setString(str); + } else { + args.rval().setNull(); + } + + return true; +} + static const JSPropertySpec DebuggerSource_properties[] = { JS_PSG("text", DebuggerSource_getText, 0), JS_PSG("url", DebuggerSource_getUrl, 0), JS_PSG("element", DebuggerSource_getElement, 0), JS_PSG("displayURL", DebuggerSource_getDisplayURL, 0), JS_PSG("introductionScript", DebuggerSource_getIntroductionScript, 0), JS_PSG("introductionOffset", DebuggerSource_getIntroductionOffset, 0), JS_PSG("introductionType", DebuggerSource_getIntroductionType, 0), JS_PSG("elementAttributeName", DebuggerSource_getElementProperty, 0), + JS_PSG("sourceMapURL", DebuggerSource_getSourceMapUrl, 0), JS_PS_END }; static const JSFunctionSpec DebuggerSource_methods[] = { JS_FS_END };
--- a/toolkit/devtools/server/actors/script.js +++ b/toolkit/devtools/server/actors/script.js @@ -5021,17 +5021,17 @@ ThreadSources.prototype = { * Return a promise of an array of source actors representing all the * sources of |aScript|. * * If source map handling is enabled and |aScript| has a source map, then * use it to find all of |aScript|'s *original* sources; return a promise * of an array of source actors for those. */ sourcesForScript: function (aScript) { - if (!this._useSourceMaps || !aScript.sourceMapURL) { + if (!this._useSourceMaps || !aScript.source.sourceMapURL) { return resolve([this._sourceForScript(aScript)].filter(isNotNull)); } return this.sourceMap(aScript) .then((aSourceMap) => { return [ this.source({ url: s, sourceMap: aSourceMap, @@ -5048,18 +5048,18 @@ ThreadSources.prototype = { }, /** * Return a promise of a SourceMapConsumer for the source map for * |aScript|; if we already have such a promise extant, return that. * |aScript| must have a non-null sourceMapURL. */ sourceMap: function (aScript) { - dbg_assert(aScript.sourceMapURL, "Script should have a sourceMapURL"); - let sourceMapURL = this._normalize(aScript.sourceMapURL, aScript.url); + dbg_assert(aScript.source.sourceMapURL, "Script should have a sourceMapURL"); + let sourceMapURL = this._normalize(aScript.source.sourceMapURL, aScript.url); let map = this._fetchSourceMap(sourceMapURL, aScript.url) .then(aSourceMap => this.saveSourceMap(aSourceMap, aScript.url)); this._sourceMapsByGeneratedSource[aScript.url] = map; return map; }, /** * Save the given source map so that we can use it to query source locations