You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

910 lines
17 KiB

4 years ago
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.print = print;
  6. var _ast = require("@webassemblyjs/ast");
  7. var _long = _interopRequireDefault(require("@xtuc/long"));
  8. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  9. 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); }
  10. 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; }
  11. 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"); } }
  12. var compact = false;
  13. var space = " ";
  14. var quote = function quote(str) {
  15. return "\"".concat(str, "\"");
  16. };
  17. function indent(nb) {
  18. return Array(nb).fill(space + space).join("");
  19. } // TODO(sven): allow arbitrary ast nodes
  20. function print(n) {
  21. if (n.type === "Program") {
  22. return printProgram(n, 0);
  23. } else {
  24. throw new Error("Unsupported node in print of type: " + String(n.type));
  25. }
  26. }
  27. function printProgram(n, depth) {
  28. return n.body.reduce(function (acc, child) {
  29. if (child.type === "Module") {
  30. acc += printModule(child, depth + 1);
  31. }
  32. if (child.type === "Func") {
  33. acc += printFunc(child, depth + 1);
  34. }
  35. if (child.type === "BlockComment") {
  36. acc += printBlockComment(child);
  37. }
  38. if (child.type === "LeadingComment") {
  39. acc += printLeadingComment(child);
  40. }
  41. if (compact === false) {
  42. acc += "\n";
  43. }
  44. return acc;
  45. }, "");
  46. }
  47. function printTypeInstruction(n) {
  48. var out = "";
  49. out += "(";
  50. out += "type";
  51. out += space;
  52. if (n.id != null) {
  53. out += printIndex(n.id);
  54. out += space;
  55. }
  56. out += "(";
  57. out += "func";
  58. n.functype.params.forEach(function (param) {
  59. out += space;
  60. out += "(";
  61. out += "param";
  62. out += space;
  63. out += printFuncParam(param);
  64. out += ")";
  65. });
  66. n.functype.results.forEach(function (result) {
  67. out += space;
  68. out += "(";
  69. out += "result";
  70. out += space;
  71. out += result;
  72. out += ")";
  73. });
  74. out += ")"; // func
  75. out += ")";
  76. return out;
  77. }
  78. function printModule(n, depth) {
  79. var out = "(";
  80. out += "module";
  81. if (typeof n.id === "string") {
  82. out += space;
  83. out += n.id;
  84. }
  85. if (compact === false) {
  86. out += "\n";
  87. } else {
  88. out += space;
  89. }
  90. n.fields.forEach(function (field) {
  91. if (compact === false) {
  92. out += indent(depth);
  93. }
  94. switch (field.type) {
  95. case "Func":
  96. {
  97. out += printFunc(field, depth + 1);
  98. break;
  99. }
  100. case "TypeInstruction":
  101. {
  102. out += printTypeInstruction(field);
  103. break;
  104. }
  105. case "Table":
  106. {
  107. out += printTable(field);
  108. break;
  109. }
  110. case "Global":
  111. {
  112. out += printGlobal(field, depth + 1);
  113. break;
  114. }
  115. case "ModuleExport":
  116. {
  117. out += printModuleExport(field);
  118. break;
  119. }
  120. case "ModuleImport":
  121. {
  122. out += printModuleImport(field);
  123. break;
  124. }
  125. case "Memory":
  126. {
  127. out += printMemory(field);
  128. break;
  129. }
  130. case "BlockComment":
  131. {
  132. out += printBlockComment(field);
  133. break;
  134. }
  135. case "LeadingComment":
  136. {
  137. out += printLeadingComment(field);
  138. break;
  139. }
  140. case "Start":
  141. {
  142. out += printStart(field);
  143. break;
  144. }
  145. case "Elem":
  146. {
  147. out += printElem(field, depth);
  148. break;
  149. }
  150. case "Data":
  151. {
  152. out += printData(field, depth);
  153. break;
  154. }
  155. default:
  156. throw new Error("Unsupported node in printModule: " + String(field.type));
  157. }
  158. if (compact === false) {
  159. out += "\n";
  160. }
  161. });
  162. out += ")";
  163. return out;
  164. }
  165. function printData(n, depth) {
  166. var out = "";
  167. out += "(";
  168. out += "data";
  169. out += space;
  170. out += printIndex(n.memoryIndex);
  171. out += space;
  172. out += printInstruction(n.offset, depth);
  173. out += space;
  174. out += '"';
  175. n.init.values.forEach(function (byte) {
  176. // Avoid non-displayable characters
  177. if (byte <= 31 || byte == 34 || byte == 92 || byte >= 127) {
  178. out += "\\";
  179. out += ("00" + byte.toString(16)).substr(-2);
  180. } else if (byte > 255) {
  181. throw new Error("Unsupported byte in data segment: " + byte);
  182. } else {
  183. out += String.fromCharCode(byte);
  184. }
  185. });
  186. out += '"';
  187. out += ")";
  188. return out;
  189. }
  190. function printElem(n, depth) {
  191. var out = "";
  192. out += "(";
  193. out += "elem";
  194. out += space;
  195. out += printIndex(n.table);
  196. var _n$offset = _slicedToArray(n.offset, 1),
  197. firstOffset = _n$offset[0];
  198. out += space;
  199. out += "(";
  200. out += "offset";
  201. out += space;
  202. out += printInstruction(firstOffset, depth);
  203. out += ")";
  204. n.funcs.forEach(function (func) {
  205. out += space;
  206. out += printIndex(func);
  207. });
  208. out += ")";
  209. return out;
  210. }
  211. function printStart(n) {
  212. var out = "";
  213. out += "(";
  214. out += "start";
  215. out += space;
  216. out += printIndex(n.index);
  217. out += ")";
  218. return out;
  219. }
  220. function printLeadingComment(n) {
  221. // Don't print leading comments in compact mode
  222. if (compact === true) {
  223. return "";
  224. }
  225. var out = "";
  226. out += ";;";
  227. out += n.value;
  228. out += "\n";
  229. return out;
  230. }
  231. function printBlockComment(n) {
  232. // Don't print block comments in compact mode
  233. if (compact === true) {
  234. return "";
  235. }
  236. var out = "";
  237. out += "(;";
  238. out += n.value;
  239. out += ";)";
  240. out += "\n";
  241. return out;
  242. }
  243. function printSignature(n) {
  244. var out = "";
  245. n.params.forEach(function (param) {
  246. out += space;
  247. out += "(";
  248. out += "param";
  249. out += space;
  250. out += printFuncParam(param);
  251. out += ")";
  252. });
  253. n.results.forEach(function (result) {
  254. out += space;
  255. out += "(";
  256. out += "result";
  257. out += space;
  258. out += result;
  259. out += ")";
  260. });
  261. return out;
  262. }
  263. function printModuleImportDescr(n) {
  264. var out = "";
  265. if (n.type === "FuncImportDescr") {
  266. out += "(";
  267. out += "func";
  268. if ((0, _ast.isAnonymous)(n.id) === false) {
  269. out += space;
  270. out += printIdentifier(n.id);
  271. }
  272. out += printSignature(n.signature);
  273. out += ")";
  274. }
  275. if (n.type === "GlobalType") {
  276. out += "(";
  277. out += "global";
  278. out += space;
  279. out += printGlobalType(n);
  280. out += ")";
  281. }
  282. if (n.type === "Table") {
  283. out += printTable(n);
  284. }
  285. return out;
  286. }
  287. function printModuleImport(n) {
  288. var out = "";
  289. out += "(";
  290. out += "import";
  291. out += space;
  292. out += quote(n.module);
  293. out += space;
  294. out += quote(n.name);
  295. out += space;
  296. out += printModuleImportDescr(n.descr);
  297. out += ")";
  298. return out;
  299. }
  300. function printGlobalType(n) {
  301. var out = "";
  302. if (n.mutability === "var") {
  303. out += "(";
  304. out += "mut";
  305. out += space;
  306. out += n.valtype;
  307. out += ")";
  308. } else {
  309. out += n.valtype;
  310. }
  311. return out;
  312. }
  313. function printGlobal(n, depth) {
  314. var out = "";
  315. out += "(";
  316. out += "global";
  317. out += space;
  318. if (n.name != null && (0, _ast.isAnonymous)(n.name) === false) {
  319. out += printIdentifier(n.name);
  320. out += space;
  321. }
  322. out += printGlobalType(n.globalType);
  323. out += space;
  324. n.init.forEach(function (i) {
  325. out += printInstruction(i, depth + 1);
  326. });
  327. out += ")";
  328. return out;
  329. }
  330. function printTable(n) {
  331. var out = "";
  332. out += "(";
  333. out += "table";
  334. out += space;
  335. if (n.name != null && (0, _ast.isAnonymous)(n.name) === false) {
  336. out += printIdentifier(n.name);
  337. out += space;
  338. }
  339. out += printLimit(n.limits);
  340. out += space;
  341. out += n.elementType;
  342. out += ")";
  343. return out;
  344. }
  345. function printFuncParam(n) {
  346. var out = "";
  347. if (typeof n.id === "string") {
  348. out += "$" + n.id;
  349. out += space;
  350. }
  351. out += n.valtype;
  352. return out;
  353. }
  354. function printFunc(n, depth) {
  355. var out = "";
  356. out += "(";
  357. out += "func";
  358. if (n.name != null) {
  359. if (n.name.type === "Identifier" && (0, _ast.isAnonymous)(n.name) === false) {
  360. out += space;
  361. out += printIdentifier(n.name);
  362. }
  363. }
  364. if (n.signature.type === "Signature") {
  365. out += printSignature(n.signature);
  366. } else {
  367. var index = n.signature;
  368. out += space;
  369. out += "(";
  370. out += "type";
  371. out += space;
  372. out += printIndex(index);
  373. out += ")";
  374. }
  375. if (n.body.length > 0) {
  376. // func is empty since we ignore the default end instruction
  377. if (n.body.length === 1 && n.body[0].id === "end") {
  378. out += ")";
  379. return out;
  380. }
  381. if (compact === false) {
  382. out += "\n";
  383. }
  384. n.body.forEach(function (i) {
  385. if (i.id !== "end") {
  386. out += indent(depth);
  387. out += printInstruction(i, depth);
  388. if (compact === false) {
  389. out += "\n";
  390. }
  391. }
  392. });
  393. out += indent(depth - 1) + ")";
  394. } else {
  395. out += ")";
  396. }
  397. return out;
  398. }
  399. function printInstruction(n, depth) {
  400. switch (n.type) {
  401. case "Instr":
  402. // $FlowIgnore
  403. return printGenericInstruction(n, depth + 1);
  404. case "BlockInstruction":
  405. // $FlowIgnore
  406. return printBlockInstruction(n, depth + 1);
  407. case "IfInstruction":
  408. // $FlowIgnore
  409. return printIfInstruction(n, depth + 1);
  410. case "CallInstruction":
  411. // $FlowIgnore
  412. return printCallInstruction(n, depth + 1);
  413. case "CallIndirectInstruction":
  414. // $FlowIgnore
  415. return printCallIndirectIntruction(n, depth + 1);
  416. case "LoopInstruction":
  417. // $FlowIgnore
  418. return printLoopInstruction(n, depth + 1);
  419. default:
  420. throw new Error("Unsupported instruction: " + JSON.stringify(n.type));
  421. }
  422. }
  423. function printCallIndirectIntruction(n, depth) {
  424. var out = "";
  425. out += "(";
  426. out += "call_indirect";
  427. if (n.signature.type === "Signature") {
  428. out += printSignature(n.signature);
  429. } else if (n.signature.type === "Identifier") {
  430. out += space;
  431. out += "(";
  432. out += "type";
  433. out += space;
  434. out += printIdentifier(n.signature);
  435. out += ")";
  436. } else {
  437. throw new Error("CallIndirectInstruction: unsupported signature " + JSON.stringify(n.signature.type));
  438. }
  439. out += space;
  440. if (n.intrs != null) {
  441. // $FlowIgnore
  442. n.intrs.forEach(function (i, index) {
  443. // $FlowIgnore
  444. out += printInstruction(i, depth + 1); // $FlowIgnore
  445. if (index !== n.intrs.length - 1) {
  446. out += space;
  447. }
  448. });
  449. }
  450. out += ")";
  451. return out;
  452. }
  453. function printLoopInstruction(n, depth) {
  454. var out = "";
  455. out += "(";
  456. out += "loop";
  457. if (n.label != null && (0, _ast.isAnonymous)(n.label) === false) {
  458. out += space;
  459. out += printIdentifier(n.label);
  460. }
  461. if (typeof n.resulttype === "string") {
  462. out += space;
  463. out += "(";
  464. out += "result";
  465. out += space;
  466. out += n.resulttype;
  467. out += ")";
  468. }
  469. if (n.instr.length > 0) {
  470. n.instr.forEach(function (e) {
  471. if (compact === false) {
  472. out += "\n";
  473. }
  474. out += indent(depth);
  475. out += printInstruction(e, depth + 1);
  476. });
  477. if (compact === false) {
  478. out += "\n";
  479. out += indent(depth - 1);
  480. }
  481. }
  482. out += ")";
  483. return out;
  484. }
  485. function printCallInstruction(n, depth) {
  486. var out = "";
  487. out += "(";
  488. out += "call";
  489. out += space;
  490. out += printIndex(n.index);
  491. if (_typeof(n.instrArgs) === "object") {
  492. // $FlowIgnore
  493. n.instrArgs.forEach(function (arg) {
  494. out += space;
  495. out += printFuncInstructionArg(arg, depth + 1);
  496. });
  497. }
  498. out += ")";
  499. return out;
  500. }
  501. function printIfInstruction(n, depth) {
  502. var out = "";
  503. out += "(";
  504. out += "if";
  505. if (n.testLabel != null && (0, _ast.isAnonymous)(n.testLabel) === false) {
  506. out += space;
  507. out += printIdentifier(n.testLabel);
  508. }
  509. if (typeof n.result === "string") {
  510. out += space;
  511. out += "(";
  512. out += "result";
  513. out += space;
  514. out += n.result;
  515. out += ")";
  516. }
  517. if (n.test.length > 0) {
  518. out += space;
  519. n.test.forEach(function (i) {
  520. out += printInstruction(i, depth + 1);
  521. });
  522. }
  523. if (n.consequent.length > 0) {
  524. if (compact === false) {
  525. out += "\n";
  526. }
  527. out += indent(depth);
  528. out += "(";
  529. out += "then";
  530. depth++;
  531. n.consequent.forEach(function (i) {
  532. if (compact === false) {
  533. out += "\n";
  534. }
  535. out += indent(depth);
  536. out += printInstruction(i, depth + 1);
  537. });
  538. depth--;
  539. if (compact === false) {
  540. out += "\n";
  541. out += indent(depth);
  542. }
  543. out += ")";
  544. } else {
  545. if (compact === false) {
  546. out += "\n";
  547. out += indent(depth);
  548. }
  549. out += "(";
  550. out += "then";
  551. out += ")";
  552. }
  553. if (n.alternate.length > 0) {
  554. if (compact === false) {
  555. out += "\n";
  556. }
  557. out += indent(depth);
  558. out += "(";
  559. out += "else";
  560. depth++;
  561. n.alternate.forEach(function (i) {
  562. if (compact === false) {
  563. out += "\n";
  564. }
  565. out += indent(depth);
  566. out += printInstruction(i, depth + 1);
  567. });
  568. depth--;
  569. if (compact === false) {
  570. out += "\n";
  571. out += indent(depth);
  572. }
  573. out += ")";
  574. } else {
  575. if (compact === false) {
  576. out += "\n";
  577. out += indent(depth);
  578. }
  579. out += "(";
  580. out += "else";
  581. out += ")";
  582. }
  583. if (compact === false) {
  584. out += "\n";
  585. out += indent(depth - 1);
  586. }
  587. out += ")";
  588. return out;
  589. }
  590. function printBlockInstruction(n, depth) {
  591. var out = "";
  592. out += "(";
  593. out += "block";
  594. if (n.label != null && (0, _ast.isAnonymous)(n.label) === false) {
  595. out += space;
  596. out += printIdentifier(n.label);
  597. }
  598. if (typeof n.result === "string") {
  599. out += space;
  600. out += "(";
  601. out += "result";
  602. out += space;
  603. out += n.result;
  604. out += ")";
  605. }
  606. if (n.instr.length > 0) {
  607. n.instr.forEach(function (i) {
  608. if (compact === false) {
  609. out += "\n";
  610. }
  611. out += indent(depth);
  612. out += printInstruction(i, depth + 1);
  613. });
  614. if (compact === false) {
  615. out += "\n";
  616. }
  617. out += indent(depth - 1);
  618. out += ")";
  619. } else {
  620. out += ")";
  621. }
  622. return out;
  623. }
  624. function printGenericInstruction(n, depth) {
  625. var out = "";
  626. out += "(";
  627. if (typeof n.object === "string") {
  628. out += n.object;
  629. out += ".";
  630. }
  631. out += n.id;
  632. n.args.forEach(function (arg) {
  633. out += space;
  634. out += printFuncInstructionArg(arg, depth + 1);
  635. });
  636. out += ")";
  637. return out;
  638. }
  639. function printLongNumberLiteral(n) {
  640. if (typeof n.raw === "string") {
  641. return n.raw;
  642. }
  643. var _n$value = n.value,
  644. low = _n$value.low,
  645. high = _n$value.high;
  646. var v = new _long.default(low, high);
  647. return v.toString();
  648. }
  649. function printFloatLiteral(n) {
  650. if (typeof n.raw === "string") {
  651. return n.raw;
  652. }
  653. return String(n.value);
  654. }
  655. function printFuncInstructionArg(n, depth) {
  656. var out = "";
  657. if (n.type === "NumberLiteral") {
  658. out += printNumberLiteral(n);
  659. }
  660. if (n.type === "LongNumberLiteral") {
  661. out += printLongNumberLiteral(n);
  662. }
  663. if (n.type === "Identifier" && (0, _ast.isAnonymous)(n) === false) {
  664. out += printIdentifier(n);
  665. }
  666. if (n.type === "ValtypeLiteral") {
  667. out += n.name;
  668. }
  669. if (n.type === "FloatLiteral") {
  670. out += printFloatLiteral(n);
  671. }
  672. if ((0, _ast.isInstruction)(n)) {
  673. out += printInstruction(n, depth + 1);
  674. }
  675. return out;
  676. }
  677. function printNumberLiteral(n) {
  678. if (typeof n.raw === "string") {
  679. return n.raw;
  680. }
  681. return String(n.value);
  682. }
  683. function printModuleExport(n) {
  684. var out = "";
  685. out += "(";
  686. out += "export";
  687. out += space;
  688. out += quote(n.name);
  689. if (n.descr.exportType === "Func") {
  690. out += space;
  691. out += "(";
  692. out += "func";
  693. out += space;
  694. out += printIndex(n.descr.id);
  695. out += ")";
  696. } else if (n.descr.exportType === "Global") {
  697. out += space;
  698. out += "(";
  699. out += "global";
  700. out += space;
  701. out += printIndex(n.descr.id);
  702. out += ")";
  703. } else if (n.descr.exportType === "Memory" || n.descr.exportType === "Mem") {
  704. out += space;
  705. out += "(";
  706. out += "memory";
  707. out += space;
  708. out += printIndex(n.descr.id);
  709. out += ")";
  710. } else if (n.descr.exportType === "Table") {
  711. out += space;
  712. out += "(";
  713. out += "table";
  714. out += space;
  715. out += printIndex(n.descr.id);
  716. out += ")";
  717. } else {
  718. throw new Error("printModuleExport: unknown type: " + n.descr.exportType);
  719. }
  720. out += ")";
  721. return out;
  722. }
  723. function printIdentifier(n) {
  724. return "$" + n.value;
  725. }
  726. function printIndex(n) {
  727. if (n.type === "Identifier") {
  728. return printIdentifier(n);
  729. } else if (n.type === "NumberLiteral") {
  730. return printNumberLiteral(n);
  731. } else {
  732. throw new Error("Unsupported index: " + n.type);
  733. }
  734. }
  735. function printMemory(n) {
  736. var out = "";
  737. out += "(";
  738. out += "memory";
  739. if (n.id != null) {
  740. out += space;
  741. out += printIndex(n.id);
  742. out += space;
  743. }
  744. out += printLimit(n.limits);
  745. out += ")";
  746. return out;
  747. }
  748. function printLimit(n) {
  749. var out = "";
  750. out += n.min + "";
  751. if (n.max != null) {
  752. out += space;
  753. out += String(n.max);
  754. }
  755. return out;
  756. }