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.

106 lines
3.2 KiB

4 years ago
  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. import { encodeNode } from "@webassemblyjs/wasm-gen";
  3. import { overrideBytesInBuffer } from "@webassemblyjs/helper-buffer";
  4. import constants from "@webassemblyjs/helper-wasm-bytecode";
  5. import * as t from "@webassemblyjs/ast";
  6. function findLastSection(ast, forSection) {
  7. var targetSectionId = constants.sections[forSection]; // $FlowIgnore: metadata can not be empty
  8. var moduleSections = ast.body[0].metadata.sections;
  9. var lastSection;
  10. var lastId = 0;
  11. for (var i = 0, len = moduleSections.length; i < len; i++) {
  12. var section = moduleSections[i]; // Ignore custom section since they can actually occur everywhere
  13. if (section.section === "custom") {
  14. continue;
  15. }
  16. var sectionId = constants.sections[section.section];
  17. if (targetSectionId > lastId && targetSectionId < sectionId) {
  18. return lastSection;
  19. }
  20. lastId = sectionId;
  21. lastSection = section;
  22. }
  23. return lastSection;
  24. }
  25. export function createEmptySection(ast, uint8Buffer, section) {
  26. // previous section after which we are going to insert our section
  27. var lastSection = findLastSection(ast, section);
  28. var start, end;
  29. /**
  30. * It's the first section
  31. */
  32. if (lastSection == null || lastSection.section === "custom") {
  33. start = 8
  34. /* wasm header size */
  35. ;
  36. end = start;
  37. } else {
  38. start = lastSection.startOffset + lastSection.size.value + 1;
  39. end = start;
  40. } // section id
  41. start += 1;
  42. var sizeStartLoc = {
  43. line: -1,
  44. column: start
  45. };
  46. var sizeEndLoc = {
  47. line: -1,
  48. column: start + 1
  49. }; // 1 byte for the empty vector
  50. var size = t.withLoc(t.numberLiteralFromRaw(1), sizeEndLoc, sizeStartLoc);
  51. var vectorOfSizeStartLoc = {
  52. line: -1,
  53. column: sizeEndLoc.column
  54. };
  55. var vectorOfSizeEndLoc = {
  56. line: -1,
  57. column: sizeEndLoc.column + 1
  58. };
  59. var vectorOfSize = t.withLoc(t.numberLiteralFromRaw(0), vectorOfSizeEndLoc, vectorOfSizeStartLoc);
  60. var sectionMetadata = t.sectionMetadata(section, start, size, vectorOfSize);
  61. var sectionBytes = encodeNode(sectionMetadata);
  62. uint8Buffer = overrideBytesInBuffer(uint8Buffer, start - 1, end, sectionBytes); // Add section into the AST for later lookups
  63. if (_typeof(ast.body[0].metadata) === "object") {
  64. // $FlowIgnore: metadata can not be empty
  65. ast.body[0].metadata.sections.push(sectionMetadata);
  66. t.sortSectionMetadata(ast.body[0]);
  67. }
  68. /**
  69. * Update AST
  70. */
  71. // Once we hit our section every that is after needs to be shifted by the delta
  72. var deltaBytes = +sectionBytes.length;
  73. var encounteredSection = false;
  74. t.traverse(ast, {
  75. SectionMetadata: function SectionMetadata(path) {
  76. if (path.node.section === section) {
  77. encounteredSection = true;
  78. return;
  79. }
  80. if (encounteredSection === true) {
  81. t.shiftSection(ast, path.node, deltaBytes);
  82. }
  83. }
  84. });
  85. return {
  86. uint8Buffer: uint8Buffer,
  87. sectionMetadata: sectionMetadata
  88. };
  89. }