index.js 18 KB

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