Flow Coverage Report - src/utils/wasm.js

FilenamePercentTotalCoveredUncovered
src/utils/wasm.js 88 % 243 214 29
x
 
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
4
5
/* @flow */
6
7
import { BinaryReader } from "wasmparser/dist/WasmParser";
8
import { WasmDisassembler } from "wasmparser/dist/WasmDis";
9
10
type WasmState = {
11
  lines: Array<number>,
12
  offsets: Array<number>
13
};
14
15
1x
var wasmStates: { [string]: WasmState } = (Object.create(null): any);
16
17
/**
18
 * @memberof utils/wasm
19
 * @static
20
 */
21
function getWasmText(sourceId: string, data: Uint8Array) {
22
3x
  const parser = new BinaryReader();
23
2x
  parser.setData(data.buffer, 0, data.length);
24
3x
  const dis = new WasmDisassembler();
25
1x
  dis.addOffsets = true;
26
4x
  const done = dis.disassembleChunk(parser);
27
2x
  let result = dis.getResult();
28
3x
  if (result.lines.length === 0) {
29
1x
    result = { lines: ["No luck with wast conversion"], offsets: [0], done };
30
  }
31
32
  const offsets = result.offsets;
33
  const lines = [];
34
  for (let i = 0; i < offsets.length; i++) {
35
    lines[offsets[i]] = i;
36
  }
37
38
  wasmStates[sourceId] = { offsets, lines };
39
40
1x
  return { lines: result.lines, done: result.done };
41
}
42
43
/**
44
 * @memberof utils/wasm
45
 * @static
46
 */
47
function getWasmLineNumberFormatter(sourceId: string) {
48
  const codeOf0 = 48,
49
    codeOfA = 65;
50
  const buffer = [
51
    codeOf0,
52
    codeOf0,
53
    codeOf0,
54
    codeOf0,
55
    codeOf0,
56
    codeOf0,
57
    codeOf0,
58
    codeOf0
59
  ];
60
  let last0 = 7;
61
  return function(number: number) {
62
    const offset = lineToWasmOffset(sourceId, number - 1);
63
    if (offset == undefined) {
64
      return "";
65
    }
66
    let i = 7;
67
    for (let n = offset; n !== 0 && i >= 0; n >>= 4, i--) {
68
      const nibble = n & 15;
69
      buffer[i] = nibble < 10 ? codeOf0 + nibble : codeOfA - 10 + nibble;
70
    }
71
    for (let j = i; j > last0; j--) {
72
      buffer[j] = codeOf0;
73
    }
74
    last0 = i;
75
    return String.fromCharCode.apply(null, buffer);
76
  };
77
}
78
79
/**
80
 * @memberof utils/wasm
81
 * @static
82
 */
83
function isWasm(sourceId: string) {
84
  return sourceId in wasmStates;
85
}
86
87
/**
88
 * @memberof utils/wasm
89
 * @static
90
 */
91
function lineToWasmOffset(sourceId: string, number: number): ?number {
92
  const wasmState = wasmStates[sourceId];
93
  if (!wasmState) {
94
    return undefined;
95
  }
96
  let offset = wasmState.offsets[number];
97
  while (offset === undefined && number > 0) {
98
    offset = wasmState.offsets[--number];
99
  }
100
  return offset;
101
}
102
103
/**
104
 * @memberof utils/wasm
105
 * @static
106
 */
107
function wasmOffsetToLine(sourceId: string, offset: number): ?number {
108
  const wasmState = wasmStates[sourceId];
109
  if (!wasmState) {
110
    return undefined;
111
  }
112
  return wasmState.lines[offset];
113
}
114
115
/**
116
 * @memberof utils/wasm
117
 * @static
118
 */
119
function clearWasmStates() {
120
2x
  wasmStates = (Object.create(null): any);
121
}
122
123
1x
function renderWasmText(sourceId: string, { binary }: Object) {
124
  // binary does not survive as Uint8Array, converting from string
125
2x
  const data = new Uint8Array(binary.length);
126
  for (let i = 0; i < data.length; i++) {
127
3x
    data[i] = binary.charCodeAt(i);
128
  }
129
  const { lines } = getWasmText(sourceId, data);
130
  const MAX_LINES = 1000000;
131
  if (lines.length > MAX_LINES) {
132
    lines.splice(MAX_LINES, lines.length - MAX_LINES);
133
    lines.push(";; .... text is truncated due to the size");
134
  }
135
  return lines;
136
}
137
138
export {
139
  getWasmText,
140
  getWasmLineNumberFormatter,
141
  isWasm,
142
  lineToWasmOffset,
143
  wasmOffsetToLine,
144
  clearWasmStates,
145
  renderWasmText
146
};
147