index.js 17 KB

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