chrome-devtools-frontend
Version:
Chrome DevTools UI
1,181 lines (1,179 loc) • 83.3 kB
JavaScript
/* Copyright 2016 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { bytesToString, OperatorCodeNames, } from "./WasmParser.js";
const NAME_SECTION_NAME = "name";
const INVALID_NAME_SYMBOLS_REGEX = /[^0-9A-Za-z!#$%&'*+.:<=>?@^_`|~\/\-]/;
const INVALID_NAME_SYMBOLS_REGEX_GLOBAL = new RegExp(INVALID_NAME_SYMBOLS_REGEX.source, "g");
function formatFloat32(n) {
if (n === 0)
return 1 / n < 0 ? "-0.0" : "0.0";
if (isFinite(n))
return n.toString();
if (!isNaN(n))
return n < 0 ? "-inf" : "inf";
var view = new DataView(new ArrayBuffer(8));
view.setFloat32(0, n, true);
var data = view.getInt32(0, true);
var payload = data & 0x7fffff;
const canonicalBits = 4194304; // 0x800..0
if (data > 0 && payload === canonicalBits)
return "nan";
// canonical NaN;
else if (payload === canonicalBits)
return "-nan";
return (data < 0 ? "-" : "+") + "nan:0x" + payload.toString(16);
}
function formatFloat64(n) {
if (n === 0)
return 1 / n < 0 ? "-0.0" : "0.0";
if (isFinite(n))
return n.toString();
if (!isNaN(n))
return n < 0 ? "-inf" : "inf";
var view = new DataView(new ArrayBuffer(8));
view.setFloat64(0, n, true);
var data1 = view.getUint32(0, true);
var data2 = view.getInt32(4, true);
var payload = data1 + (data2 & 0xfffff) * 4294967296;
const canonicalBits = 524288 * 4294967296; // 0x800..0
if (data2 > 0 && payload === canonicalBits)
return "nan";
// canonical NaN;
else if (payload === canonicalBits)
return "-nan";
return (data2 < 0 ? "-" : "+") + "nan:0x" + payload.toString(16);
}
function formatI32Array(bytes, count) {
var dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
var result = [];
for (var i = 0; i < count; i++)
result.push(`0x${formatHex(dv.getInt32(i << 2, true), 8)}`);
return result.join(" ");
}
function formatI8Array(bytes, count) {
var dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
var result = [];
for (var i = 0; i < count; i++)
result.push(`${dv.getInt8(i)}`);
return result.join(" ");
}
function memoryAddressToString(address, code) {
var defaultAlignFlags;
switch (code) {
case 64768 /* v128_load */:
case 64769 /* i16x8_load8x8_s */:
case 64770 /* i16x8_load8x8_u */:
case 64771 /* i32x4_load16x4_s */:
case 64772 /* i32x4_load16x4_u */:
case 64773 /* i64x2_load32x2_s */:
case 64774 /* i64x2_load32x2_u */:
case 64775 /* v8x16_load_splat */:
case 64776 /* v16x8_load_splat */:
case 64777 /* v32x4_load_splat */:
case 64778 /* v64x2_load_splat */:
case 64779 /* v128_store */:
defaultAlignFlags = 4;
break;
case 41 /* i64_load */:
case 55 /* i64_store */:
case 43 /* f64_load */:
case 57 /* f64_store */:
case 65026 /* i64_atomic_wait */:
case 65041 /* i64_atomic_load */:
case 65048 /* i64_atomic_store */:
case 65055 /* i64_atomic_rmw_add */:
case 65062 /* i64_atomic_rmw_sub */:
case 65069 /* i64_atomic_rmw_and */:
case 65076 /* i64_atomic_rmw_or */:
case 65083 /* i64_atomic_rmw_xor */:
case 65090 /* i64_atomic_rmw_xchg */:
case 65097 /* i64_atomic_rmw_cmpxchg */:
case 64861 /* v128_load64_zero */:
defaultAlignFlags = 3;
break;
case 40 /* i32_load */:
case 52 /* i64_load32_s */:
case 53 /* i64_load32_u */:
case 54 /* i32_store */:
case 62 /* i64_store32 */:
case 42 /* f32_load */:
case 56 /* f32_store */:
case 65024 /* atomic_notify */:
case 65025 /* i32_atomic_wait */:
case 65040 /* i32_atomic_load */:
case 65046 /* i64_atomic_load32_u */:
case 65047 /* i32_atomic_store */:
case 65053 /* i64_atomic_store32 */:
case 65054 /* i32_atomic_rmw_add */:
case 65060 /* i64_atomic_rmw32_add_u */:
case 65061 /* i32_atomic_rmw_sub */:
case 65067 /* i64_atomic_rmw32_sub_u */:
case 65068 /* i32_atomic_rmw_and */:
case 65074 /* i64_atomic_rmw32_and_u */:
case 65075 /* i32_atomic_rmw_or */:
case 65081 /* i64_atomic_rmw32_or_u */:
case 65082 /* i32_atomic_rmw_xor */:
case 65088 /* i64_atomic_rmw32_xor_u */:
case 65089 /* i32_atomic_rmw_xchg */:
case 65095 /* i64_atomic_rmw32_xchg_u */:
case 65096 /* i32_atomic_rmw_cmpxchg */:
case 65102 /* i64_atomic_rmw32_cmpxchg_u */:
case 64860 /* v128_load32_zero */:
defaultAlignFlags = 2;
break;
case 46 /* i32_load16_s */:
case 47 /* i32_load16_u */:
case 50 /* i64_load16_s */:
case 51 /* i64_load16_u */:
case 59 /* i32_store16 */:
case 61 /* i64_store16 */:
case 65043 /* i32_atomic_load16_u */:
case 65045 /* i64_atomic_load16_u */:
case 65050 /* i32_atomic_store16 */:
case 65052 /* i64_atomic_store16 */:
case 65057 /* i32_atomic_rmw16_add_u */:
case 65059 /* i64_atomic_rmw16_add_u */:
case 65064 /* i32_atomic_rmw16_sub_u */:
case 65066 /* i64_atomic_rmw16_sub_u */:
case 65071 /* i32_atomic_rmw16_and_u */:
case 65073 /* i64_atomic_rmw16_and_u */:
case 65078 /* i32_atomic_rmw16_or_u */:
case 65080 /* i64_atomic_rmw16_or_u */:
case 65085 /* i32_atomic_rmw16_xor_u */:
case 65087 /* i64_atomic_rmw16_xor_u */:
case 65092 /* i32_atomic_rmw16_xchg_u */:
case 65094 /* i64_atomic_rmw16_xchg_u */:
case 65099 /* i32_atomic_rmw16_cmpxchg_u */:
case 65101 /* i64_atomic_rmw16_cmpxchg_u */:
defaultAlignFlags = 1;
break;
case 44 /* i32_load8_s */:
case 45 /* i32_load8_u */:
case 48 /* i64_load8_s */:
case 49 /* i64_load8_u */:
case 58 /* i32_store8 */:
case 60 /* i64_store8 */:
case 65042 /* i32_atomic_load8_u */:
case 65044 /* i64_atomic_load8_u */:
case 65049 /* i32_atomic_store8 */:
case 65051 /* i64_atomic_store8 */:
case 65056 /* i32_atomic_rmw8_add_u */:
case 65058 /* i64_atomic_rmw8_add_u */:
case 65063 /* i32_atomic_rmw8_sub_u */:
case 65065 /* i64_atomic_rmw8_sub_u */:
case 65070 /* i32_atomic_rmw8_and_u */:
case 65072 /* i64_atomic_rmw8_and_u */:
case 65077 /* i32_atomic_rmw8_or_u */:
case 65079 /* i64_atomic_rmw8_or_u */:
case 65084 /* i32_atomic_rmw8_xor_u */:
case 65086 /* i64_atomic_rmw8_xor_u */:
case 65091 /* i32_atomic_rmw8_xchg_u */:
case 65093 /* i64_atomic_rmw8_xchg_u */:
case 65098 /* i32_atomic_rmw8_cmpxchg_u */:
case 65100 /* i64_atomic_rmw8_cmpxchg_u */:
defaultAlignFlags = 0;
break;
}
if (address.flags == defaultAlignFlags)
// hide default flags
return !address.offset ? null : `offset=${address.offset}`;
if (!address.offset)
// hide default offset
return `align=${1 << address.flags}`;
return `offset=${address.offset | 0} align=${1 << address.flags}`;
}
function limitsToString(limits) {
return (limits.initial + (limits.maximum !== undefined ? " " + limits.maximum : ""));
}
var paddingCache = ["0", "00", "000"];
function formatHex(n, width) {
var s = (n >>> 0).toString(16).toUpperCase();
if (width === undefined || s.length >= width)
return s;
var paddingIndex = width - s.length - 1;
while (paddingIndex >= paddingCache.length)
paddingCache.push(paddingCache[paddingCache.length - 1] + "0");
return paddingCache[paddingIndex] + s;
}
const IndentIncrement = " ";
function isValidName(name) {
return !INVALID_NAME_SYMBOLS_REGEX.test(name);
}
export class DefaultNameResolver {
getTypeName(index, isRef) {
return "$type" + index;
}
getTableName(index, isRef) {
return "$table" + index;
}
getMemoryName(index, isRef) {
return "$memory" + index;
}
getGlobalName(index, isRef) {
return "$global" + index;
}
getElementName(index, isRef) {
return `$elem${index}`;
}
getEventName(index, isRef) {
return `$event${index}`;
}
getFunctionName(index, isImport, isRef) {
return (isImport ? "$import" : "$func") + index;
}
getVariableName(funcIndex, index, isRef) {
return "$var" + index;
}
getFieldName(typeIndex, index, isRef) {
return "$field" + index;
}
getLabel(index) {
return "$label" + index;
}
}
const EMPTY_STRING_ARRAY = [];
class DevToolsExportMetadata {
constructor(functionExportNames, globalExportNames, memoryExportNames, tableExportNames, eventExportNames) {
this._functionExportNames = functionExportNames;
this._globalExportNames = globalExportNames;
this._memoryExportNames = memoryExportNames;
this._tableExportNames = tableExportNames;
this._eventExportNames = eventExportNames;
}
getFunctionExportNames(index) {
var _a;
return (_a = this._functionExportNames[index]) !== null && _a !== void 0 ? _a : EMPTY_STRING_ARRAY;
}
getGlobalExportNames(index) {
var _a;
return (_a = this._globalExportNames[index]) !== null && _a !== void 0 ? _a : EMPTY_STRING_ARRAY;
}
getMemoryExportNames(index) {
var _a;
return (_a = this._memoryExportNames[index]) !== null && _a !== void 0 ? _a : EMPTY_STRING_ARRAY;
}
getTableExportNames(index) {
var _a;
return (_a = this._tableExportNames[index]) !== null && _a !== void 0 ? _a : EMPTY_STRING_ARRAY;
}
getEventExportNames(index) {
var _a;
return (_a = this._eventExportNames[index]) !== null && _a !== void 0 ? _a : EMPTY_STRING_ARRAY;
}
}
export class NumericNameResolver {
getTypeName(index, isRef) {
return isRef ? "" + index : `(;${index};)`;
}
getTableName(index, isRef) {
return isRef ? "" + index : `(;${index};)`;
}
getMemoryName(index, isRef) {
return isRef ? "" + index : `(;${index};)`;
}
getGlobalName(index, isRef) {
return isRef ? "" + index : `(;${index};)`;
}
getElementName(index, isRef) {
return isRef ? "" + index : `(;${index};)`;
}
getEventName(index, isRef) {
return isRef ? "" + index : `(;${index};)`;
}
getFunctionName(index, isImport, isRef) {
return isRef ? "" + index : `(;${index};)`;
}
getVariableName(funcIndex, index, isRef) {
return isRef ? "" + index : `(;${index};)`;
}
getFieldName(typeIndex, index, isRef) {
return isRef ? "" : index + `(;${index};)`;
}
getLabel(index) {
return null;
}
}
export var LabelMode;
(function (LabelMode) {
LabelMode[LabelMode["Depth"] = 0] = "Depth";
LabelMode[LabelMode["WhenUsed"] = 1] = "WhenUsed";
LabelMode[LabelMode["Always"] = 2] = "Always";
})(LabelMode || (LabelMode = {}));
export class WasmDisassembler {
constructor() {
this._skipTypes = true;
this._exportMetadata = null;
this._lines = [];
this._offsets = [];
this._buffer = "";
this._indent = null;
this._indentLevel = 0;
this._addOffsets = false;
this._done = false;
this._currentPosition = 0;
this._nameResolver = new DefaultNameResolver();
this._labelMode = LabelMode.WhenUsed;
this._functionBodyOffsets = [];
this._currentFunctionBodyOffset = 0;
this._currentSectionId = -1 /* Unknown */;
this._logFirstInstruction = false;
this._reset();
}
_reset() {
this._types = [];
this._funcIndex = 0;
this._funcTypes = [];
this._importCount = 0;
this._globalCount = 0;
this._memoryCount = 0;
this._eventCount = 0;
this._tableCount = 0;
this._elementCount = 0;
this._expression = [];
this._backrefLabels = null;
this._labelIndex = 0;
}
get addOffsets() {
return this._addOffsets;
}
set addOffsets(value) {
if (this._currentPosition)
throw new Error("Cannot switch addOffsets during processing.");
this._addOffsets = value;
}
get skipTypes() {
return this._skipTypes;
}
set skipTypes(skipTypes) {
if (this._currentPosition)
throw new Error("Cannot switch skipTypes during processing.");
this._skipTypes = skipTypes;
}
get labelMode() {
return this._labelMode;
}
set labelMode(value) {
if (this._currentPosition)
throw new Error("Cannot switch labelMode during processing.");
this._labelMode = value;
}
get exportMetadata() {
return this._exportMetadata;
}
set exportMetadata(exportMetadata) {
if (this._currentPosition)
throw new Error("Cannot switch exportMetadata during processing.");
this._exportMetadata = exportMetadata;
}
get nameResolver() {
return this._nameResolver;
}
set nameResolver(resolver) {
if (this._currentPosition)
throw new Error("Cannot switch nameResolver during processing.");
this._nameResolver = resolver;
}
appendBuffer(s) {
this._buffer += s;
}
newLine() {
if (this.addOffsets)
this._offsets.push(this._currentPosition);
this._lines.push(this._buffer);
this._buffer = "";
}
logStartOfFunctionBodyOffset() {
if (this.addOffsets) {
this._currentFunctionBodyOffset = this._currentPosition;
}
}
logEndOfFunctionBodyOffset() {
if (this.addOffsets) {
this._functionBodyOffsets.push({
start: this._currentFunctionBodyOffset,
end: this._currentPosition,
});
}
}
typeIndexToString(typeIndex) {
if (typeIndex >= 0)
return this._nameResolver.getTypeName(typeIndex, true);
switch (typeIndex) {
case -16 /* funcref */:
return "func";
case -17 /* externref */:
return "extern";
case -18 /* anyref */:
return "any";
case -19 /* eqref */:
return "eq";
case -22 /* i31ref */:
return "i31";
case -25 /* dataref */:
return "data";
}
}
typeToString(type) {
switch (type.kind) {
case -1 /* i32 */:
return "i32";
case -2 /* i64 */:
return "i64";
case -3 /* f32 */:
return "f32";
case -4 /* f64 */:
return "f64";
case -5 /* v128 */:
return "v128";
case -6 /* i8 */:
return "i8";
case -7 /* i16 */:
return "i16";
case -16 /* funcref */:
return "funcref";
case -17 /* externref */:
return "externref";
case -18 /* anyref */:
return "anyref";
case -19 /* eqref */:
return "eqref";
case -22 /* i31ref */:
return "i31ref";
case -25 /* dataref */:
return "dataref";
case -21 /* ref */:
return `(ref ${this.typeIndexToString(type.index)})`;
case -20 /* optref */:
return `(ref null ${this.typeIndexToString(type.index)})`;
case -24 /* rtt */:
return `(rtt ${this.typeIndexToString(type.index)})`;
case -23 /* rtt_d */:
return `(rtt ${type.depth} ${this.typeIndexToString(type.index)})`;
default:
throw new Error(`Unexpected type ${JSON.stringify(type)}`);
}
}
maybeMut(type, mutability) {
return mutability ? `(mut ${type})` : type;
}
globalTypeToString(type) {
const typeStr = this.typeToString(type.contentType);
return this.maybeMut(typeStr, !!type.mutability);
}
printFuncType(typeIndex) {
var type = this._types[typeIndex];
if (type.params.length > 0) {
this.appendBuffer(" (param");
for (var i = 0; i < type.params.length; i++) {
this.appendBuffer(" ");
this.appendBuffer(this.typeToString(type.params[i]));
}
this.appendBuffer(")");
}
if (type.returns.length > 0) {
this.appendBuffer(" (result");
for (var i = 0; i < type.returns.length; i++) {
this.appendBuffer(" ");
this.appendBuffer(this.typeToString(type.returns[i]));
}
this.appendBuffer(")");
}
}
printStructType(typeIndex) {
var type = this._types[typeIndex];
if (type.fields.length === 0)
return;
for (var i = 0; i < type.fields.length; i++) {
const fieldType = this.maybeMut(this.typeToString(type.fields[i]), type.mutabilities[i]);
const fieldName = this._nameResolver.getFieldName(typeIndex, i, false);
this.appendBuffer(` (field ${fieldName} ${fieldType})`);
}
}
printArrayType(typeIndex) {
var type = this._types[typeIndex];
this.appendBuffer(" (field ");
this.appendBuffer(this.maybeMut(this.typeToString(type.elementType), type.mutability));
}
printBlockType(type) {
if (type.kind === -64 /* empty_block_type */) {
return;
}
if (type.kind === 0 /* unspecified */) {
return this.printFuncType(type.index);
}
this.appendBuffer(" (result ");
this.appendBuffer(this.typeToString(type));
this.appendBuffer(")");
}
printString(b) {
this.appendBuffer('"');
for (var i = 0; i < b.length; i++) {
var byte = b[i];
if (byte < 0x20 ||
byte >= 0x7f ||
byte == /* " */ 0x22 ||
byte == /* \ */ 0x5c) {
this.appendBuffer("\\" + (byte >> 4).toString(16) + (byte & 15).toString(16));
}
else {
this.appendBuffer(String.fromCharCode(byte));
}
}
this.appendBuffer('"');
}
printExpression(expression) {
for (const operator of expression) {
this.appendBuffer("(");
this.printOperator(operator);
this.appendBuffer(")");
}
}
// extraDepthOffset is used by "delegate" instructions.
useLabel(depth, extraDepthOffset = 0) {
if (!this._backrefLabels) {
return "" + depth;
}
var i = this._backrefLabels.length - depth - 1 - extraDepthOffset;
if (i < 0) {
return "" + depth;
}
var backrefLabel = this._backrefLabels[i];
if (!backrefLabel.useLabel) {
backrefLabel.useLabel = true;
backrefLabel.label = this._nameResolver.getLabel(this._labelIndex);
var line = this._lines[backrefLabel.line];
this._lines[backrefLabel.line] =
line.substring(0, backrefLabel.position) +
" " +
backrefLabel.label +
line.substring(backrefLabel.position);
this._labelIndex++;
}
return backrefLabel.label || "" + depth;
}
printOperator(operator) {
var code = operator.code;
this.appendBuffer(OperatorCodeNames[code]);
switch (code) {
case 2 /* block */:
case 3 /* loop */:
case 4 /* if */:
case 6 /* try */:
if (this._labelMode !== LabelMode.Depth) {
const backrefLabel = {
line: this._lines.length,
position: this._buffer.length,
useLabel: false,
label: null,
};
if (this._labelMode === LabelMode.Always) {
backrefLabel.useLabel = true;
backrefLabel.label = this._nameResolver.getLabel(this._labelIndex++);
if (backrefLabel.label) {
this.appendBuffer(" ");
this.appendBuffer(backrefLabel.label);
}
}
this._backrefLabels.push(backrefLabel);
}
this.printBlockType(operator.blockType);
break;
case 11 /* end */:
if (this._labelMode === LabelMode.Depth) {
break;
}
const backrefLabel = this._backrefLabels.pop();
if (backrefLabel.label) {
this.appendBuffer(" ");
this.appendBuffer(backrefLabel.label);
}
break;
case 12 /* br */:
case 13 /* br_if */:
case 212 /* br_on_null */:
case 214 /* br_on_non_null */:
case 64322 /* br_on_cast */:
case 64323 /* br_on_cast_fail */:
case 64352 /* br_on_func */:
case 64355 /* br_on_non_func */:
case 64353 /* br_on_data */:
case 64356 /* br_on_non_data */:
case 64354 /* br_on_i31 */:
case 64357 /* br_on_non_i31 */:
this.appendBuffer(" ");
this.appendBuffer(this.useLabel(operator.brDepth));
break;
case 64326 /* br_on_cast_static */:
case 64327 /* br_on_cast_static_fail */: {
const label = this.useLabel(operator.brDepth);
const refType = this._nameResolver.getTypeName(operator.refType, true);
this.appendBuffer(` ${label} ${refType}`);
break;
}
case 14 /* br_table */:
for (var i = 0; i < operator.brTable.length; i++) {
this.appendBuffer(" ");
this.appendBuffer(this.useLabel(operator.brTable[i]));
}
break;
case 9 /* rethrow */:
this.appendBuffer(" ");
this.appendBuffer(this.useLabel(operator.relativeDepth));
break;
case 24 /* delegate */:
this.appendBuffer(" ");
this.appendBuffer(this.useLabel(operator.relativeDepth, 1));
break;
case 7 /* catch */:
case 8 /* throw */:
var eventName = this._nameResolver.getEventName(operator.eventIndex, true);
this.appendBuffer(` ${eventName}`);
break;
case 208 /* ref_null */:
this.appendBuffer(" ");
this.appendBuffer(this.typeIndexToString(operator.refType));
break;
case 16 /* call */:
case 18 /* return_call */:
case 210 /* ref_func */:
var funcName = this._nameResolver.getFunctionName(operator.funcIndex, operator.funcIndex < this._importCount, true);
this.appendBuffer(` ${funcName}`);
break;
case 17 /* call_indirect */:
case 19 /* return_call_indirect */:
this.printFuncType(operator.typeIndex);
break;
case 28 /* select_with_type */: {
const selectType = this.typeToString(operator.selectType);
this.appendBuffer(` ${selectType}`);
break;
}
case 32 /* local_get */:
case 33 /* local_set */:
case 34 /* local_tee */:
var paramName = this._nameResolver.getVariableName(this._funcIndex, operator.localIndex, true);
this.appendBuffer(` ${paramName}`);
break;
case 35 /* global_get */:
case 36 /* global_set */:
var globalName = this._nameResolver.getGlobalName(operator.globalIndex, true);
this.appendBuffer(` ${globalName}`);
break;
case 40 /* i32_load */:
case 41 /* i64_load */:
case 42 /* f32_load */:
case 43 /* f64_load */:
case 44 /* i32_load8_s */:
case 45 /* i32_load8_u */:
case 46 /* i32_load16_s */:
case 47 /* i32_load16_u */:
case 48 /* i64_load8_s */:
case 49 /* i64_load8_u */:
case 50 /* i64_load16_s */:
case 51 /* i64_load16_u */:
case 52 /* i64_load32_s */:
case 53 /* i64_load32_u */:
case 54 /* i32_store */:
case 55 /* i64_store */:
case 56 /* f32_store */:
case 57 /* f64_store */:
case 58 /* i32_store8 */:
case 59 /* i32_store16 */:
case 60 /* i64_store8 */:
case 61 /* i64_store16 */:
case 62 /* i64_store32 */:
case 65024 /* atomic_notify */:
case 65025 /* i32_atomic_wait */:
case 65026 /* i64_atomic_wait */:
case 65040 /* i32_atomic_load */:
case 65041 /* i64_atomic_load */:
case 65042 /* i32_atomic_load8_u */:
case 65043 /* i32_atomic_load16_u */:
case 65044 /* i64_atomic_load8_u */:
case 65045 /* i64_atomic_load16_u */:
case 65046 /* i64_atomic_load32_u */:
case 65047 /* i32_atomic_store */:
case 65048 /* i64_atomic_store */:
case 65049 /* i32_atomic_store8 */:
case 65050 /* i32_atomic_store16 */:
case 65051 /* i64_atomic_store8 */:
case 65052 /* i64_atomic_store16 */:
case 65053 /* i64_atomic_store32 */:
case 65054 /* i32_atomic_rmw_add */:
case 65055 /* i64_atomic_rmw_add */:
case 65056 /* i32_atomic_rmw8_add_u */:
case 65057 /* i32_atomic_rmw16_add_u */:
case 65058 /* i64_atomic_rmw8_add_u */:
case 65059 /* i64_atomic_rmw16_add_u */:
case 65060 /* i64_atomic_rmw32_add_u */:
case 65061 /* i32_atomic_rmw_sub */:
case 65062 /* i64_atomic_rmw_sub */:
case 65063 /* i32_atomic_rmw8_sub_u */:
case 65064 /* i32_atomic_rmw16_sub_u */:
case 65065 /* i64_atomic_rmw8_sub_u */:
case 65066 /* i64_atomic_rmw16_sub_u */:
case 65067 /* i64_atomic_rmw32_sub_u */:
case 65068 /* i32_atomic_rmw_and */:
case 65069 /* i64_atomic_rmw_and */:
case 65070 /* i32_atomic_rmw8_and_u */:
case 65071 /* i32_atomic_rmw16_and_u */:
case 65072 /* i64_atomic_rmw8_and_u */:
case 65073 /* i64_atomic_rmw16_and_u */:
case 65074 /* i64_atomic_rmw32_and_u */:
case 65075 /* i32_atomic_rmw_or */:
case 65076 /* i64_atomic_rmw_or */:
case 65077 /* i32_atomic_rmw8_or_u */:
case 65078 /* i32_atomic_rmw16_or_u */:
case 65079 /* i64_atomic_rmw8_or_u */:
case 65080 /* i64_atomic_rmw16_or_u */:
case 65081 /* i64_atomic_rmw32_or_u */:
case 65082 /* i32_atomic_rmw_xor */:
case 65083 /* i64_atomic_rmw_xor */:
case 65084 /* i32_atomic_rmw8_xor_u */:
case 65085 /* i32_atomic_rmw16_xor_u */:
case 65086 /* i64_atomic_rmw8_xor_u */:
case 65087 /* i64_atomic_rmw16_xor_u */:
case 65088 /* i64_atomic_rmw32_xor_u */:
case 65089 /* i32_atomic_rmw_xchg */:
case 65090 /* i64_atomic_rmw_xchg */:
case 65091 /* i32_atomic_rmw8_xchg_u */:
case 65092 /* i32_atomic_rmw16_xchg_u */:
case 65093 /* i64_atomic_rmw8_xchg_u */:
case 65094 /* i64_atomic_rmw16_xchg_u */:
case 65095 /* i64_atomic_rmw32_xchg_u */:
case 65096 /* i32_atomic_rmw_cmpxchg */:
case 65097 /* i64_atomic_rmw_cmpxchg */:
case 65098 /* i32_atomic_rmw8_cmpxchg_u */:
case 65099 /* i32_atomic_rmw16_cmpxchg_u */:
case 65100 /* i64_atomic_rmw8_cmpxchg_u */:
case 65101 /* i64_atomic_rmw16_cmpxchg_u */:
case 65102 /* i64_atomic_rmw32_cmpxchg_u */:
case 64768 /* v128_load */:
case 64769 /* i16x8_load8x8_s */:
case 64770 /* i16x8_load8x8_u */:
case 64771 /* i32x4_load16x4_s */:
case 64772 /* i32x4_load16x4_u */:
case 64773 /* i64x2_load32x2_s */:
case 64774 /* i64x2_load32x2_u */:
case 64775 /* v8x16_load_splat */:
case 64776 /* v16x8_load_splat */:
case 64777 /* v32x4_load_splat */:
case 64778 /* v64x2_load_splat */:
case 64779 /* v128_store */:
case 64860 /* v128_load32_zero */:
case 64861 /* v128_load64_zero */:
var memoryAddress = memoryAddressToString(operator.memoryAddress, operator.code);
if (memoryAddress !== null) {
this.appendBuffer(" ");
this.appendBuffer(memoryAddress);
}
break;
case 63 /* current_memory */:
case 64 /* grow_memory */:
break;
case 65 /* i32_const */:
this.appendBuffer(` ${operator.literal.toString()}`);
break;
case 66 /* i64_const */:
this.appendBuffer(` ${operator.literal.toString()}`);
break;
case 67 /* f32_const */:
this.appendBuffer(` ${formatFloat32(operator.literal)}`);
break;
case 68 /* f64_const */:
this.appendBuffer(` ${formatFloat64(operator.literal)}`);
break;
case 64780 /* v128_const */:
this.appendBuffer(` i32x4 ${formatI32Array(operator.literal, 4)}`);
break;
case 64781 /* i8x16_shuffle */:
this.appendBuffer(` ${formatI8Array(operator.lines, 16)}`);
break;
case 64789 /* i8x16_extract_lane_s */:
case 64790 /* i8x16_extract_lane_u */:
case 64791 /* i8x16_replace_lane */:
case 64792 /* i16x8_extract_lane_s */:
case 64793 /* i16x8_extract_lane_u */:
case 64794 /* i16x8_replace_lane */:
case 64795 /* i32x4_extract_lane */:
case 64796 /* i32x4_replace_lane */:
case 64799 /* f32x4_extract_lane */:
case 64800 /* f32x4_replace_lane */:
case 64797 /* i64x2_extract_lane */:
case 64798 /* i64x2_replace_lane */:
case 64801 /* f64x2_extract_lane */:
case 64802 /* f64x2_replace_lane */:
this.appendBuffer(` ${operator.lineIndex}`);
break;
case 64520 /* memory_init */:
case 64521 /* data_drop */:
this.appendBuffer(` ${operator.segmentIndex}`);
break;
case 64525 /* elem_drop */:
const elementName = this._nameResolver.getElementName(operator.segmentIndex, true);
this.appendBuffer(` ${elementName}`);
break;
case 38 /* table_set */:
case 37 /* table_get */:
case 64529 /* table_fill */: {
const tableName = this._nameResolver.getTableName(operator.tableIndex, true);
this.appendBuffer(` ${tableName}`);
break;
}
case 64526 /* table_copy */: {
// Table index might be omitted and defaults to 0.
if (operator.tableIndex !== 0 || operator.destinationIndex !== 0) {
const tableName = this._nameResolver.getTableName(operator.tableIndex, true);
const destinationName = this._nameResolver.getTableName(operator.destinationIndex, true);
this.appendBuffer(` ${destinationName} ${tableName}`);
}
break;
}
case 64524 /* table_init */: {
// Table index might be omitted and defaults to 0.
if (operator.tableIndex !== 0) {
const tableName = this._nameResolver.getTableName(operator.tableIndex, true);
this.appendBuffer(` ${tableName}`);
}
const elementName = this._nameResolver.getElementName(operator.segmentIndex, true);
this.appendBuffer(` ${elementName}`);
break;
}
case 64259 /* struct_get */:
case 64260 /* struct_get_s */:
case 64261 /* struct_get_u */:
case 64262 /* struct_set */: {
const refType = this._nameResolver.getTypeName(operator.refType, true);
const fieldName = this._nameResolver.getFieldName(operator.refType, operator.fieldIndex, true);
this.appendBuffer(` ${refType} ${fieldName}`);
break;
}
case 64304 /* rtt_canon */:
case 64305 /* rtt_sub */:
case 64306 /* rtt_fresh_sub */:
case 64324 /* ref_test_static */:
case 64325 /* ref_cast_static */:
case 64264 /* struct_new_default */:
case 64258 /* struct_new_default_with_rtt */:
case 64263 /* struct_new */:
case 64257 /* struct_new_with_rtt */:
case 64284 /* array_new_default */:
case 64274 /* array_new_default_with_rtt */:
case 64283 /* array_new */:
case 64273 /* array_new_with_rtt */:
case 64275 /* array_get */:
case 64276 /* array_get_s */:
case 64277 /* array_get_u */:
case 64278 /* array_set */:
case 64279 /* array_len */: {
const refType = this._nameResolver.getTypeName(operator.refType, true);
this.appendBuffer(` ${refType}`);
break;
}
case 64280 /* array_copy */: {
const dstType = this._nameResolver.getTypeName(operator.refType, true);
const srcType = this._nameResolver.getTypeName(operator.srcType, true);
this.appendBuffer(` ${dstType} ${srcType}`);
break;
}
case 64281 /* array_init */:
case 64282 /* array_init_static */: {
const refType = this._nameResolver.getTypeName(operator.refType, true);
const length = operator.brDepth; // Overloaded field.
this.appendBuffer(` ${refType} ${length}`);
break;
}
}
}
printImportSource(info) {
this.printString(info.module);
this.appendBuffer(" ");
this.printString(info.field);
}
increaseIndent() {
this._indent += IndentIncrement;
this._indentLevel++;
}
decreaseIndent() {
this._indent = this._indent.slice(0, -IndentIncrement.length);
this._indentLevel--;
}
disassemble(reader) {
const done = this.disassembleChunk(reader);
if (!done)
return null;
let lines = this._lines;
if (this._addOffsets) {
lines = lines.map((line, index) => {
var position = formatHex(this._offsets[index], 4);
return line + " ;; @" + position;
});
}
lines.push(""); // we need '\n' after last line
const result = lines.join("\n");
this._lines.length = 0;
this._offsets.length = 0;
this._functionBodyOffsets.length = 0;
return result;
}
getResult() {
let linesReady = this._lines.length;
if (this._backrefLabels && this._labelMode === LabelMode.WhenUsed) {
this._backrefLabels.some((backrefLabel) => {
if (backrefLabel.useLabel)
return false;
linesReady = backrefLabel.line;
return true;
});
}
if (linesReady === 0) {
return {
lines: [],
offsets: this._addOffsets ? [] : undefined,
done: this._done,
functionBodyOffsets: this._addOffsets ? [] : undefined,
};
}
if (linesReady === this._lines.length) {
const result = {
lines: this._lines,
offsets: this._addOffsets ? this._offsets : undefined,
done: this._done,
functionBodyOffsets: this._addOffsets
? this._functionBodyOffsets
: undefined,
};
this._lines = [];
if (this._addOffsets) {
this._offsets = [];
this._functionBodyOffsets = [];
}
return result;
}
const result = {
lines: this._lines.splice(0, linesReady),
offsets: this._addOffsets
? this._offsets.splice(0, linesReady)
: undefined,
done: false,
functionBodyOffsets: this._addOffsets
? this._functionBodyOffsets
: undefined,
};
if (this._backrefLabels) {
this._backrefLabels.forEach((backrefLabel) => {
backrefLabel.line -= linesReady;
});
}
return result;
}
disassembleChunk(reader, offsetInModule = 0) {
if (this._done)
throw new Error("Invalid state: disassembly process was already finished.");
while (true) {
this._currentPosition = reader.position + offsetInModule;
if (!reader.read())
return false;
switch (reader.state) {
case 2 /* END_WASM */:
this.appendBuffer(")");
this.newLine();
this._reset();
if (!reader.hasMoreBytes()) {
this._done = true;
return true;
}
break;
case -1 /* ERROR */:
throw reader.error;
case 1 /* BEGIN_WASM */:
this.appendBuffer("(module");
this.newLine();
break;
case 4 /* END_SECTION */:
this._currentSectionId = -1 /* Unknown */;
break;
case 3 /* BEGIN_SECTION */:
var sectionInfo = reader.result;
switch (sectionInfo.id) {
case 1 /* Type */:
case 2 /* Import */:
case 7 /* Export */:
case 6 /* Global */:
case 3 /* Function */:
case 8 /* Start */:
case 10 /* Code */:
case 5 /* Memory */:
case 11 /* Data */:
case 4 /* Table */:
case 9 /* Element */:
case 13 /* Event */:
this._currentSectionId = sectionInfo.id;
break; // reading known section;
default:
reader.skipSection();
break;
}
break;
case 15 /* MEMORY_SECTION_ENTRY */:
var memoryInfo = reader.result;
var memoryIndex = this._memoryCount++;
var memoryName = this._nameResolver.getMemoryName(memoryIndex, false);
this.appendBuffer(` (memory ${memoryName}`);
if (this._exportMetadata !== null) {
for (const exportName of this._exportMetadata.getMemoryExportNames(memoryIndex)) {
this.appendBuffer(` (export ${JSON.stringify(exportName)})`);
}
}
this.appendBuffer(` ${limitsToString(memoryInfo.limits)}`);
if (memoryInfo.shared) {
this.appendBuffer(` shared`);
}
this.appendBuffer(")");
this.newLine();
break;
case 23 /* EVENT_SECTION_ENTRY */:
var eventInfo = reader.result;
var eventIndex = this._eventCount++;
var eventName = this._nameResolver.getEventName(eventIndex, false);
this.appendBuffer(` (event ${eventName}`);
if (this._exportMetadata !== null) {
for (const exportName of this._exportMetadata.getEventExportNames(eventIndex)) {
this.appendBuffer(` (export ${JSON.stringify(exportName)})`);
}
}
this.printFuncType(eventInfo.typeIndex);
this.appendBuffer(")");
this.newLine();
break;
case 14 /* TABLE_SECTION_ENTRY */:
var tableInfo = reader.result;
var tableIndex = this._tableCount++;
var tableName = this._nameResolver.getTableName(tableIndex, false);
this.appendBuffer(` (table ${tableName}`);
if (this._exportMetadata !== null) {
for (const exportName of this._exportMetadata.getTableExportNames(tableIndex)) {
this.appendBuffer(` (export ${JSON.stringify(exportName)})`);
}
}
this.appendBuffer(` ${limitsToString(tableInfo.limits)} ${this.typeToString(tableInfo.elementType)})`);
this.newLine();
break;
case 17 /* EXPORT_SECTION_ENTRY */:
// Skip printing exports here when we have export metadata
// which we can use to print export information inline.
if (this._exportMetadata === null) {
var exportInfo = reader.result;
this.appendBuffer(" (export ");
this.printString(exportInfo.field);
this.appendBuffer(" ");
switch (exportInfo.kind) {
case 0 /* Function */:
var funcName = this._nameResolver.getFunctionName(exportInfo.index, exportInfo.index < this._importCount, true);
this.appendBuffer(`(func ${funcName})`);
break;
case 1 /* Table */:
var tableName = this._nameResolver.getTableName(exportInfo.index, true);
this.appendBuffer(`(table ${tableName})`);
break;
case 2 /* Memory */:
var memoryName = this._nameResolver.getMemoryName(exportInfo.index, true);
this.appendBuffer(`(memory ${memoryName})`);
break;
case 3 /* Global */:
var globalName = this._nameResolver.getGlobalName(exportInfo.index, true);
this.appendBuffer(`(global ${globalName})`);
break;
case 4 /* Event */:
var eventName = this._nameResolver.getEventName(exportInfo.index, true);
this.appendBuffer(`(event ${eventName})`);
break;
default:
throw new Error(`Unsupported export ${exportInfo.kind}`);
}
this.appendBuffer(")");
this.newLine();
}
break;
case 12 /* IMPORT_SECTION_ENTRY */:
var importInfo = reader.result;
switch (importInfo.kind) {
case 0 /* Function */:
this._importCount++;
var funcIndex = this._funcIndex++;
var funcName = this._nameResolver.getFunctionName(funcIndex, true, false);
this.appendBuffer(` (func ${funcName}`);
if (this._exportMetadata !== null) {
for (const exportName of this._exportMetadata.getFunctionExportNames(funcIndex)) {
this.appendBuffer(` (export ${JSON.stringify(exportName)})`);
}
}
this.appendBuffer(` (import `);
this.printImportSource(importInfo);
this.appendBuffer(")");
this.printFuncType(importInfo.funcTypeIndex);
this.appendBuffer(")");
break;
case 3 /* Global */:
var globalImportInfo = importInfo.type;
var globalIndex = this._globalCount++;
var globalName = this._nameResolver.getGlobalName(globalIndex, false);
this.appendBuffer(` (global ${globalName}`);
if (this._exportMetadata !== null) {
for (const exportName of this._exportMetadata.getGlobalExportNames(globalIndex)) {
this.appendBuffer(` (export ${JSON.stringify(exportName)})`);
}
}
this.appendBuffer(` (import `);
this.printImportSource(importInfo);
this.appendBuffer(`) ${this.globalTypeToString(globalImportInfo)})`);
break;
case 2 /* Memory */:
var memoryImportInfo = importInfo.type;
var memoryIndex = this._memoryCount++;
var memoryName = this._nameResolver.getMemoryName(memoryIndex, false);
this.appendBuffer(` (memory ${memoryName}`);
if (this._exportMetadata !== null) {
for (const exportName of this._exportMetadata.getMemoryExportNames(memoryIndex)) {
this.appendBuffer(` (export ${JSON.stringify(exportName)})`);
}
}
this.appendBuffer(` (import `);
this.printImportSource(importInfo);
this.appendBuffer(`) ${limitsToString(memoryImportInfo.limits)}`);
if (memoryImportInfo.shared) {
this.appendBuffer(` shared`);
}
this.appendBuffer(")");
break;
case 1 /* Table */:
var tableImportInfo = importInfo.type;
var tableIndex = this._tableCount++;
var tableName = this._nameResolver.getTableName(tableIndex, false);
this.appendBuffer(` (table ${tableName}`);
if (this._exportMetadata !== null) {
for (const exportName of this._exportMetadata.getTableExportNames(tableIndex)) {
this.appendBuffer(` (export ${JSON.stringify(exportName)})`);
}
}
this.appendBuffer(` (import `);
this.printImportSource(importInfo);
this.appendBuffer(`) ${limitsToString(tableImportInfo.limits)} ${this.typeToString(tableImportInfo.elementType)})`);
break;
case 4 /* Event */:
var eventImportInfo = importInfo.type;
var eventIndex = this._eventCount++;
var eventName = this._nameResolver.getEventName(eventIndex, false);
this.appendBuffer(` (event ${eventName}`);