Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/src/source_map_support.js
4128 views
1
/**
2
* @license
3
* Copyright 2019 The Emscripten Authors
4
* SPDX-License-Identifier: MIT
5
*/
6
7
class WasmSourceMap {
8
mapping = {};
9
offsets = [];
10
11
constructor(sourceMap) {
12
this.version = sourceMap.version;
13
this.sources = sourceMap.sources;
14
this.names = sourceMap.names;
15
16
var vlqMap = {};
17
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split('').forEach((c, i) => vlqMap[c] = i);
18
19
// based on https://github.com/Rich-Harris/vlq/blob/master/src/vlq.ts
20
function decodeVLQ(string) {
21
var result = [];
22
var shift = 0;
23
var value = 0;
24
25
for (var ch of string) {
26
var integer = vlqMap[ch];
27
if (integer === undefined) {
28
throw new Error(`Invalid character (${ch})`);
29
}
30
31
value += (integer & 31) << shift;
32
33
if (integer & 32) {
34
shift += 5;
35
} else {
36
var negate = value & 1;
37
value >>= 1;
38
result.push(negate ? -value : value);
39
value = shift = 0;
40
}
41
}
42
return result;
43
}
44
45
var offset = 0, src = 0, line = 1, col = 1, name = 0;
46
sourceMap.mappings.split(',').forEach(function (segment, index) {
47
if (!segment) return;
48
var data = decodeVLQ(segment);
49
var info = {};
50
51
offset += data[0];
52
if (data.length >= 2) info.source = src += data[1];
53
if (data.length >= 3) info.line = line += data[2];
54
if (data.length >= 4) info.column = col += data[3];
55
if (data.length >= 5) info.name = name += data[4];
56
this.mapping[offset] = info;
57
this.offsets.push(offset);
58
}, this);
59
this.offsets.sort((a, b) => a - b);
60
}
61
62
lookup(offset) {
63
var normalized = this.normalizeOffset(offset);
64
var info = this.mapping[normalized];
65
if (!info) {
66
return null;
67
}
68
return {
69
file: this.sources[info.source],
70
line: info.line,
71
column: info.column,
72
name: this.names[info.name],
73
};
74
}
75
76
normalizeOffset(offset) {
77
var lo = 0;
78
var hi = this.offsets.length;
79
var mid;
80
81
while (lo < hi) {
82
mid = Math.floor((lo + hi) / 2);
83
if (this.offsets[mid] > offset) {
84
hi = mid;
85
} else {
86
lo = mid + 1;
87
}
88
}
89
return this.offsets[lo - 1];
90
}
91
}
92
93
var wasmSourceMap;
94
var wasmSourceMapFile = locateFile('{{{ WASM_BINARY_FILE }}}.map');
95
96
function receiveSourceMapJSON(sourceMap) {
97
wasmSourceMap = new WasmSourceMap(sourceMap);
98
}
99
100
function getSourceMap() {
101
var buf = readBinary(wasmSourceMapFile);
102
return JSON.parse(UTF8ArrayToString(buf));
103
}
104
105
async function getSourceMapAsync() {
106
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
107
try {
108
var response = await fetch(wasmSourceMapFile, {{{ makeModuleReceiveExpr('fetchSettings', "{ credentials: 'same-origin' }") }}});
109
return response.json();
110
} catch {
111
// Fall back to getSourceMap below
112
}
113
}
114
return getSourceMap();
115
}
116
117
118
#if PTHREADS || WASM_WORKERS
119
// Source map is received via postMessage on worker threads.
120
if ({{{ ENVIRONMENT_IS_MAIN_THREAD() }}}) {
121
#endif
122
123
#if WASM_ASYNC_COMPILATION
124
addRunDependency('source-map');
125
getSourceMapAsync().then((json) => {
126
receiveSourceMapJSON(json);
127
removeRunDependency('source-map');
128
});
129
#else
130
receiveSourceMapJSON(getSourceMap());
131
#endif
132
133
#if PTHREADS || WASM_WORKERS
134
}
135
#endif
136
137