Bug 1364535 - Inverse source mapping for WebAssembly maps. r=jlast

MozReview-Commit-ID: JqEkdLpIv2o

--HG--
extra : rebase_source : 381c8ff7b754299c468c0e790177aace74bab44f
This commit is contained in:
Yury Delendik 2017-06-19 10:55:20 -05:00
Родитель 6294f37db4
Коммит 3c4f86517b
5 изменённых файлов: 212 добавлений и 0 удалений

Просмотреть файл

@ -15,6 +15,7 @@ loader.lazyRequireGetter(this, "SourceActor", "devtools/server/actors/source", t
loader.lazyRequireGetter(this, "isEvalSource", "devtools/server/actors/source", true);
loader.lazyRequireGetter(this, "SourceMapConsumer", "source-map", true);
loader.lazyRequireGetter(this, "SourceMapGenerator", "source-map", true);
loader.lazyRequireGetter(this, "WasmRemap", "devtools/shared/wasm-source-map", true);
/**
* Manages the sources for a thread. Handles source maps, locations in the
@ -409,6 +410,11 @@ TabSources.prototype = {
}
let result = this._fetchSourceMap(sourceMapURL, source.url);
let isWasm = source.introductionType == "wasm";
if (isWasm) {
result = result.then((map) => new WasmRemap(map));
}
// The promises in `_sourceMaps` must be the exact same instances
// as returned by `_fetchSourceMap` for `clearSourceMapCache` to
// work.

Просмотреть файл

@ -64,6 +64,7 @@ DevToolsModules(
'system.js',
'task.js',
'ThreadSafeDevToolsUtils.js',
'wasm-source-map.js',
)
with Files('**'):

Просмотреть файл

@ -0,0 +1,90 @@
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test WasmRemap
const { WasmRemap } = require("devtools/shared/wasm-source-map");
const { SourceMapConsumer } = require("source-map");
const testMap1 = {
version: 3,
file: "min.js",
names: [],
sources: ["one.js", "two.js"],
sourceRoot: "/the/root",
mappings: "CAAC,IAAM,SACU,GAAC"
};
const testMap1Entries = [
{ offset: 1, line: 1, column: 1 },
{ offset: 5, line: 1, column: 7 },
{ offset: 14, line: 2, column: 17 },
{ offset: 17, line: 2, column: 18 },
];
const testMap2 = {
version: 3,
file: "none.js",
names: [],
sources: ["zero.js"],
mappings: "",
sourcesContent: ["//test"]
};
function run_test() {
let map1 = new SourceMapConsumer(testMap1);
let remap1 = new WasmRemap(map1);
equal(remap1.file, "min.js");
equal(remap1.hasContentsOfAllSources(), false);
equal(remap1.sources.length, 2);
equal(remap1.sources[0], "/the/root/one.js");
equal(remap1.sources[1], "/the/root/two.js");
remap1.sourceRoot = "/newroot";
equal(remap1.sources.length, 2);
equal(remap1.sources[0], "/newroot/one.js");
equal(remap1.sources[1], "/newroot/two.js");
let expectedEntries = testMap1Entries.slice(0);
remap1.eachMapping(function (entry) {
let expected = expectedEntries.shift();
equal(entry.generatedLine, expected.offset);
equal(entry.generatedColumn, 0);
equal(entry.originalLine, expected.line);
equal(entry.originalColumn, expected.column);
equal(entry.name, null);
});
let pos1 = remap1.originalPositionFor({line: 5, column: 0});
equal(pos1.line, 1);
equal(pos1.column, 7);
equal(pos1.source, "/newroot/one.js");
let pos2 = remap1.generatedPositionFor({
source: "/newroot/one.js",
line: 2,
column: 18
});
equal(pos2.line, 17);
equal(pos2.column, 0);
equal(pos2.lastColumn, undefined);
remap1.computeColumnSpans();
let pos3 = remap1.allGeneratedPositionsFor({
source: "/newroot/one.js",
line: 2,
column: 17
});
equal(pos3.length, 1);
equal(pos3[0].line, 14);
equal(pos3[0].column, 0);
equal(pos3[0].lastColumn, Infinity);
let map2 = new SourceMapConsumer(testMap2);
let remap2 = new WasmRemap(map2);
equal(remap2.file, "none.js");
equal(remap2.hasContentsOfAllSources(), true);
equal(remap2.sourceContentFor("zero.js"), "//test");
}

Просмотреть файл

@ -37,3 +37,4 @@ run-if = nightly_build
[test_stack.js]
[test_defer.js]
[test_executeSoon.js]
[test_wasm-source-map.js]

Просмотреть файл

@ -0,0 +1,114 @@
/* 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/. */
"use strict";
/**
* SourceMapConsumer for WebAssembly source maps. It transposes columns with
* lines, which allows mapping data to be used with SpiderMonkey Debugger API.
*/
class WasmRemap {
/**
* @param map SourceMapConsumer
*/
constructor(map) {
this._map = map;
this.version = map.version;
this.file = map.file;
this._computeColumnSpans = false;
}
get sources() {
return this._map.sources;
}
get sourceRoot() {
return this._map.sourceRoot;
}
/**
* @param url string
*/
set sourceRoot(url) { // important, since sources are using this.
this._map.sourceRoot = url;
}
get names() {
return this._map.names;
}
get sourcesContent() {
return this._map.sourcesContent;
}
get mappings() {
throw new Error("not supported");
}
computeColumnSpans() {
this._computeColumnSpans = true;
}
originalPositionFor(generatedPosition) {
let result = this._map.originalPositionFor({
line: 1,
column: generatedPosition.line,
bias: generatedPosition.bias
});
return result;
}
_remapGeneratedPosition(position) {
let generatedPosition = {
line: position.column,
column: 0,
};
if (this._computeColumnSpans) {
generatedPosition.lastColumn = Infinity;
}
return generatedPosition;
}
generatedPositionFor(originalPosition) {
let position = this._map.generatedPositionFor(originalPosition);
return this._remapGeneratedPosition(position);
}
allGeneratedPositionsFor(originalPosition) {
let positions = this._map.allGeneratedPositionsFor(originalPosition);
return positions.map((position) => {
return this._remapGeneratedPosition(position);
});
}
hasContentsOfAllSources() {
return this._map.hasContentsOfAllSources();
}
sourceContentFor(source, returnNullOnMissing) {
return this._map.sourceContentFor(source, returnNullOnMissing);
}
eachMapping(callback, context, order) {
this._map.eachMapping((entry) => {
let {
source,
generatedColumn,
originalLine,
originalColumn,
name
} = entry;
callback({
source,
generatedLine: generatedColumn,
generatedColumn: 0,
originalLine,
originalColumn,
name,
});
}, context, order);
}
}
exports.WasmRemap = WasmRemap;