chrome-devtools-frontend
Version:
Chrome DevTools UI
126 lines (112 loc) • 4.79 kB
text/typescript
/*
* Copyright (C) 2020 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import * as Common from '../../core/common/common.js';
import * as WasmParser from '../../third_party/wasmparser/wasmparser.js';
export function dissambleWASM(
params: {
content: string,
},
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
postMessage: (arg0: any) => void): void {
try {
const dataBuffer = Common.Base64.decode(params.content);
let parser: WasmParser.WasmParser.BinaryReader = new WasmParser.WasmParser.BinaryReader();
parser.setData(dataBuffer, 0, dataBuffer.byteLength);
const nameGenerator = new WasmParser.WasmDis.DevToolsNameGenerator();
nameGenerator.read(parser);
const data = new Uint8Array(dataBuffer);
parser = new WasmParser.WasmParser.BinaryReader();
const dis = new WasmParser.WasmDis.WasmDisassembler();
dis.addOffsets = true;
dis.exportMetadata = nameGenerator.getExportMetadata();
dis.nameResolver = nameGenerator.getNameResolver();
const lines = [];
const offsets = [];
const functionBodyOffsets = [];
let chunkSize: number = 128 * 1024;
let buffer: Uint8Array = new Uint8Array(chunkSize);
let pendingSize = 0;
let offsetInModule = 0;
for (let i = 0; i < data.length;) {
if (chunkSize > data.length - i) {
chunkSize = data.length - i;
}
const bufferSize = pendingSize + chunkSize;
if (buffer.byteLength < bufferSize) {
const newBuffer = new Uint8Array(bufferSize);
newBuffer.set(buffer);
buffer = newBuffer;
}
while (pendingSize < bufferSize) {
buffer[pendingSize++] = data[i++];
}
parser.setData(buffer.buffer, 0, bufferSize, i === data.length);
// The disassemble will attemp to fetch the data as much as possible.
const finished = dis.disassembleChunk(parser, offsetInModule);
const result = (dis.getResult() as {
lines: Array<string>,
offsets: Array<number>,
functionBodyOffsets: Array<{
start: number,
end: number,
}>,
});
for (const line of result.lines) {
lines.push(line);
}
for (const offset of result.offsets) {
offsets.push(offset);
}
for (const functionBodyOffset of result.functionBodyOffsets) {
functionBodyOffsets.push(functionBodyOffset);
}
if (finished) {
break;
}
if (parser.position === 0) {
// Parser did not consume anything, needs more data.
pendingSize = bufferSize;
continue;
}
// Shift the data to the beginning of the buffer.
const pending = parser.data.subarray(parser.position, parser.length);
pendingSize = pending.length;
buffer.set(pending);
offsetInModule += parser.position;
const percentage = Math.floor((offsetInModule / data.length) * 100);
postMessage({event: 'progress', params: {percentage}});
}
postMessage({event: 'progress', params: {percentage: 100}});
postMessage({method: 'disassemble', result: {lines, offsets, functionBodyOffsets}});
} catch (error) {
postMessage({method: 'disassemble', error});
}
}