|
|
"use strict";
Object.defineProperty(exports, "__esModule", { value: true }); exports.print = print;
var _ast = require("@webassemblyjs/ast");
var _long = _interopRequireDefault(require("@xtuc/long"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return _sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }
var compact = false; var space = " ";
var quote = function quote(str) { return "\"".concat(str, "\""); };
function indent(nb) { return Array(nb).fill(space + space).join(""); } // TODO(sven): allow arbitrary ast nodes
function print(n) { if (n.type === "Program") { return printProgram(n, 0); } else { throw new Error("Unsupported node in print of type: " + String(n.type)); } }
function printProgram(n, depth) { return n.body.reduce(function (acc, child) { if (child.type === "Module") { acc += printModule(child, depth + 1); }
if (child.type === "Func") { acc += printFunc(child, depth + 1); }
if (child.type === "BlockComment") { acc += printBlockComment(child); }
if (child.type === "LeadingComment") { acc += printLeadingComment(child); }
if (compact === false) { acc += "\n"; }
return acc; }, ""); }
function printTypeInstruction(n) { var out = ""; out += "("; out += "type"; out += space;
if (n.id != null) { out += printIndex(n.id); out += space; }
out += "("; out += "func"; n.functype.params.forEach(function (param) { out += space; out += "("; out += "param"; out += space; out += printFuncParam(param); out += ")"; }); n.functype.results.forEach(function (result) { out += space; out += "("; out += "result"; out += space; out += result; out += ")"; }); out += ")"; // func
out += ")"; return out; }
function printModule(n, depth) { var out = "("; out += "module";
if (typeof n.id === "string") { out += space; out += n.id; }
if (compact === false) { out += "\n"; } else { out += space; }
n.fields.forEach(function (field) { if (compact === false) { out += indent(depth); }
switch (field.type) { case "Func": { out += printFunc(field, depth + 1); break; }
case "TypeInstruction": { out += printTypeInstruction(field); break; }
case "Table": { out += printTable(field); break; }
case "Global": { out += printGlobal(field, depth + 1); break; }
case "ModuleExport": { out += printModuleExport(field); break; }
case "ModuleImport": { out += printModuleImport(field); break; }
case "Memory": { out += printMemory(field); break; }
case "BlockComment": { out += printBlockComment(field); break; }
case "LeadingComment": { out += printLeadingComment(field); break; }
case "Start": { out += printStart(field); break; }
case "Elem": { out += printElem(field, depth); break; }
case "Data": { out += printData(field, depth); break; }
default: throw new Error("Unsupported node in printModule: " + String(field.type)); }
if (compact === false) { out += "\n"; } }); out += ")"; return out; }
function printData(n, depth) { var out = ""; out += "("; out += "data"; out += space; out += printIndex(n.memoryIndex); out += space; out += printInstruction(n.offset, depth); out += space; out += '"'; n.init.values.forEach(function (byte) { // Avoid non-displayable characters
if (byte <= 31 || byte == 34 || byte == 92 || byte >= 127) { out += "\\"; out += ("00" + byte.toString(16)).substr(-2); } else if (byte > 255) { throw new Error("Unsupported byte in data segment: " + byte); } else { out += String.fromCharCode(byte); } }); out += '"'; out += ")"; return out; }
function printElem(n, depth) { var out = ""; out += "("; out += "elem"; out += space; out += printIndex(n.table);
var _n$offset = _slicedToArray(n.offset, 1), firstOffset = _n$offset[0];
out += space; out += "("; out += "offset"; out += space; out += printInstruction(firstOffset, depth); out += ")"; n.funcs.forEach(function (func) { out += space; out += printIndex(func); }); out += ")"; return out; }
function printStart(n) { var out = ""; out += "("; out += "start"; out += space; out += printIndex(n.index); out += ")"; return out; }
function printLeadingComment(n) { // Don't print leading comments in compact mode
if (compact === true) { return ""; }
var out = ""; out += ";;"; out += n.value; out += "\n"; return out; }
function printBlockComment(n) { // Don't print block comments in compact mode
if (compact === true) { return ""; }
var out = ""; out += "(;"; out += n.value; out += ";)"; out += "\n"; return out; }
function printSignature(n) { var out = ""; n.params.forEach(function (param) { out += space; out += "("; out += "param"; out += space; out += printFuncParam(param); out += ")"; }); n.results.forEach(function (result) { out += space; out += "("; out += "result"; out += space; out += result; out += ")"; }); return out; }
function printModuleImportDescr(n) { var out = "";
if (n.type === "FuncImportDescr") { out += "("; out += "func";
if ((0, _ast.isAnonymous)(n.id) === false) { out += space; out += printIdentifier(n.id); }
out += printSignature(n.signature); out += ")"; }
if (n.type === "GlobalType") { out += "("; out += "global"; out += space; out += printGlobalType(n); out += ")"; }
if (n.type === "Table") { out += printTable(n); }
return out; }
function printModuleImport(n) { var out = ""; out += "("; out += "import"; out += space; out += quote(n.module); out += space; out += quote(n.name); out += space; out += printModuleImportDescr(n.descr); out += ")"; return out; }
function printGlobalType(n) { var out = "";
if (n.mutability === "var") { out += "("; out += "mut"; out += space; out += n.valtype; out += ")"; } else { out += n.valtype; }
return out; }
function printGlobal(n, depth) { var out = ""; out += "("; out += "global"; out += space;
if (n.name != null && (0, _ast.isAnonymous)(n.name) === false) { out += printIdentifier(n.name); out += space; }
out += printGlobalType(n.globalType); out += space; n.init.forEach(function (i) { out += printInstruction(i, depth + 1); }); out += ")"; return out; }
function printTable(n) { var out = ""; out += "("; out += "table"; out += space;
if (n.name != null && (0, _ast.isAnonymous)(n.name) === false) { out += printIdentifier(n.name); out += space; }
out += printLimit(n.limits); out += space; out += n.elementType; out += ")"; return out; }
function printFuncParam(n) { var out = "";
if (typeof n.id === "string") { out += "$" + n.id; out += space; }
out += n.valtype; return out; }
function printFunc(n, depth) { var out = ""; out += "("; out += "func";
if (n.name != null) { if (n.name.type === "Identifier" && (0, _ast.isAnonymous)(n.name) === false) { out += space; out += printIdentifier(n.name); } }
if (n.signature.type === "Signature") { out += printSignature(n.signature); } else { var index = n.signature; out += space; out += "("; out += "type"; out += space; out += printIndex(index); out += ")"; }
if (n.body.length > 0) { // func is empty since we ignore the default end instruction
if (n.body.length === 1 && n.body[0].id === "end") { out += ")"; return out; }
if (compact === false) { out += "\n"; }
n.body.forEach(function (i) { if (i.id !== "end") { out += indent(depth); out += printInstruction(i, depth);
if (compact === false) { out += "\n"; } } }); out += indent(depth - 1) + ")"; } else { out += ")"; }
return out; }
function printInstruction(n, depth) { switch (n.type) { case "Instr": // $FlowIgnore
return printGenericInstruction(n, depth + 1);
case "BlockInstruction": // $FlowIgnore
return printBlockInstruction(n, depth + 1);
case "IfInstruction": // $FlowIgnore
return printIfInstruction(n, depth + 1);
case "CallInstruction": // $FlowIgnore
return printCallInstruction(n, depth + 1);
case "CallIndirectInstruction": // $FlowIgnore
return printCallIndirectIntruction(n, depth + 1);
case "LoopInstruction": // $FlowIgnore
return printLoopInstruction(n, depth + 1);
default: throw new Error("Unsupported instruction: " + JSON.stringify(n.type)); } }
function printCallIndirectIntruction(n, depth) { var out = ""; out += "("; out += "call_indirect";
if (n.signature.type === "Signature") { out += printSignature(n.signature); } else if (n.signature.type === "Identifier") { out += space; out += "("; out += "type"; out += space; out += printIdentifier(n.signature); out += ")"; } else { throw new Error("CallIndirectInstruction: unsupported signature " + JSON.stringify(n.signature.type)); }
out += space;
if (n.intrs != null) { // $FlowIgnore
n.intrs.forEach(function (i, index) { // $FlowIgnore
out += printInstruction(i, depth + 1); // $FlowIgnore
if (index !== n.intrs.length - 1) { out += space; } }); }
out += ")"; return out; }
function printLoopInstruction(n, depth) { var out = ""; out += "("; out += "loop";
if (n.label != null && (0, _ast.isAnonymous)(n.label) === false) { out += space; out += printIdentifier(n.label); }
if (typeof n.resulttype === "string") { out += space; out += "("; out += "result"; out += space; out += n.resulttype; out += ")"; }
if (n.instr.length > 0) { n.instr.forEach(function (e) { if (compact === false) { out += "\n"; }
out += indent(depth); out += printInstruction(e, depth + 1); });
if (compact === false) { out += "\n"; out += indent(depth - 1); } }
out += ")"; return out; }
function printCallInstruction(n, depth) { var out = ""; out += "("; out += "call"; out += space; out += printIndex(n.index);
if (_typeof(n.instrArgs) === "object") { // $FlowIgnore
n.instrArgs.forEach(function (arg) { out += space; out += printFuncInstructionArg(arg, depth + 1); }); }
out += ")"; return out; }
function printIfInstruction(n, depth) { var out = ""; out += "("; out += "if";
if (n.testLabel != null && (0, _ast.isAnonymous)(n.testLabel) === false) { out += space; out += printIdentifier(n.testLabel); }
if (typeof n.result === "string") { out += space; out += "("; out += "result"; out += space; out += n.result; out += ")"; }
if (n.test.length > 0) { out += space; n.test.forEach(function (i) { out += printInstruction(i, depth + 1); }); }
if (n.consequent.length > 0) { if (compact === false) { out += "\n"; }
out += indent(depth); out += "("; out += "then"; depth++; n.consequent.forEach(function (i) { if (compact === false) { out += "\n"; }
out += indent(depth); out += printInstruction(i, depth + 1); }); depth--;
if (compact === false) { out += "\n"; out += indent(depth); }
out += ")"; } else { if (compact === false) { out += "\n"; out += indent(depth); }
out += "("; out += "then"; out += ")"; }
if (n.alternate.length > 0) { if (compact === false) { out += "\n"; }
out += indent(depth); out += "("; out += "else"; depth++; n.alternate.forEach(function (i) { if (compact === false) { out += "\n"; }
out += indent(depth); out += printInstruction(i, depth + 1); }); depth--;
if (compact === false) { out += "\n"; out += indent(depth); }
out += ")"; } else { if (compact === false) { out += "\n"; out += indent(depth); }
out += "("; out += "else"; out += ")"; }
if (compact === false) { out += "\n"; out += indent(depth - 1); }
out += ")"; return out; }
function printBlockInstruction(n, depth) { var out = ""; out += "("; out += "block";
if (n.label != null && (0, _ast.isAnonymous)(n.label) === false) { out += space; out += printIdentifier(n.label); }
if (typeof n.result === "string") { out += space; out += "("; out += "result"; out += space; out += n.result; out += ")"; }
if (n.instr.length > 0) { n.instr.forEach(function (i) { if (compact === false) { out += "\n"; }
out += indent(depth); out += printInstruction(i, depth + 1); });
if (compact === false) { out += "\n"; }
out += indent(depth - 1); out += ")"; } else { out += ")"; }
return out; }
function printGenericInstruction(n, depth) { var out = ""; out += "(";
if (typeof n.object === "string") { out += n.object; out += "."; }
out += n.id; n.args.forEach(function (arg) { out += space; out += printFuncInstructionArg(arg, depth + 1); }); out += ")"; return out; }
function printLongNumberLiteral(n) { if (typeof n.raw === "string") { return n.raw; }
var _n$value = n.value, low = _n$value.low, high = _n$value.high; var v = new _long.default(low, high); return v.toString(); }
function printFloatLiteral(n) { if (typeof n.raw === "string") { return n.raw; }
return String(n.value); }
function printFuncInstructionArg(n, depth) { var out = "";
if (n.type === "NumberLiteral") { out += printNumberLiteral(n); }
if (n.type === "LongNumberLiteral") { out += printLongNumberLiteral(n); }
if (n.type === "Identifier" && (0, _ast.isAnonymous)(n) === false) { out += printIdentifier(n); }
if (n.type === "ValtypeLiteral") { out += n.name; }
if (n.type === "FloatLiteral") { out += printFloatLiteral(n); }
if ((0, _ast.isInstruction)(n)) { out += printInstruction(n, depth + 1); }
return out; }
function printNumberLiteral(n) { if (typeof n.raw === "string") { return n.raw; }
return String(n.value); }
function printModuleExport(n) { var out = ""; out += "("; out += "export"; out += space; out += quote(n.name);
if (n.descr.exportType === "Func") { out += space; out += "("; out += "func"; out += space; out += printIndex(n.descr.id); out += ")"; } else if (n.descr.exportType === "Global") { out += space; out += "("; out += "global"; out += space; out += printIndex(n.descr.id); out += ")"; } else if (n.descr.exportType === "Memory" || n.descr.exportType === "Mem") { out += space; out += "("; out += "memory"; out += space; out += printIndex(n.descr.id); out += ")"; } else if (n.descr.exportType === "Table") { out += space; out += "("; out += "table"; out += space; out += printIndex(n.descr.id); out += ")"; } else { throw new Error("printModuleExport: unknown type: " + n.descr.exportType); }
out += ")"; return out; }
function printIdentifier(n) { return "$" + n.value; }
function printIndex(n) { if (n.type === "Identifier") { return printIdentifier(n); } else if (n.type === "NumberLiteral") { return printNumberLiteral(n); } else { throw new Error("Unsupported index: " + n.type); } }
function printMemory(n) { var out = ""; out += "("; out += "memory";
if (n.id != null) { out += space; out += printIndex(n.id); out += space; }
out += printLimit(n.limits); out += ")"; return out; }
function printLimit(n) { var out = ""; out += n.min + "";
if (n.max != null) { out += space; out += String(n.max); }
return out; }
|