AsyncWebAssemblyParser.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const t = require("@webassemblyjs/ast");
  7. const { decode } = require("@webassemblyjs/wasm-parser");
  8. const Parser = require("../Parser");
  9. const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
  10. const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
  11. /** @typedef {import("../Module").BuildInfo} BuildInfo */
  12. /** @typedef {import("../Module").BuildMeta} BuildMeta */
  13. /** @typedef {import("../Parser").ParserState} ParserState */
  14. /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
  15. const decoderOpts = {
  16. ignoreCodeSection: true,
  17. ignoreDataSection: true,
  18. // this will avoid having to lookup with identifiers in the ModuleContext
  19. ignoreCustomNameSection: true
  20. };
  21. class WebAssemblyParser extends Parser {
  22. /**
  23. * @param {{}=} options parser options
  24. */
  25. constructor(options) {
  26. super();
  27. this.hooks = Object.freeze({});
  28. this.options = options;
  29. }
  30. /**
  31. * @param {string | Buffer | PreparsedAst} source the source to parse
  32. * @param {ParserState} state the parser state
  33. * @returns {ParserState} the parser state
  34. */
  35. parse(source, state) {
  36. if (!Buffer.isBuffer(source)) {
  37. throw new Error("WebAssemblyParser input must be a Buffer");
  38. }
  39. // flag it as async module
  40. const buildInfo = /** @type {BuildInfo} */ (state.module.buildInfo);
  41. buildInfo.strict = true;
  42. const BuildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
  43. BuildMeta.exportsType = "namespace";
  44. BuildMeta.async = true;
  45. // parse it
  46. const program = decode(source, decoderOpts);
  47. const module = program.body[0];
  48. /** @type {Array<string>} */
  49. const exports = [];
  50. t.traverse(module, {
  51. ModuleExport({ node }) {
  52. exports.push(node.name);
  53. },
  54. ModuleImport({ node }) {
  55. const dep = new WebAssemblyImportDependency(
  56. node.module,
  57. node.name,
  58. node.descr,
  59. false
  60. );
  61. state.module.addDependency(dep);
  62. }
  63. });
  64. state.module.addDependency(new StaticExportsDependency(exports, false));
  65. return state;
  66. }
  67. }
  68. module.exports = WebAssemblyParser;