[6a3a178] | 1 | import { decode } from "@webassemblyjs/wasm-parser";
|
---|
| 2 | import { traverse } from "@webassemblyjs/ast";
|
---|
| 3 | import { cloneNode } from "@webassemblyjs/ast/lib/clone";
|
---|
| 4 | import { shrinkPaddedLEB128 } from "@webassemblyjs/wasm-opt";
|
---|
| 5 | import { getSectionForNode } from "@webassemblyjs/helper-wasm-bytecode";
|
---|
| 6 | import constants from "@webassemblyjs/helper-wasm-bytecode";
|
---|
| 7 | import { applyOperations } from "./apply";
|
---|
| 8 |
|
---|
| 9 | function hashNode(node) {
|
---|
| 10 | return JSON.stringify(node);
|
---|
| 11 | }
|
---|
| 12 |
|
---|
| 13 | function preprocess(ab) {
|
---|
| 14 | var optBin = shrinkPaddedLEB128(new Uint8Array(ab));
|
---|
| 15 | return optBin.buffer;
|
---|
| 16 | }
|
---|
| 17 |
|
---|
| 18 | function sortBySectionOrder(nodes) {
|
---|
| 19 | var originalOrder = new Map();
|
---|
| 20 | var _iteratorNormalCompletion = true;
|
---|
| 21 | var _didIteratorError = false;
|
---|
| 22 | var _iteratorError = undefined;
|
---|
| 23 |
|
---|
| 24 | try {
|
---|
| 25 | for (var _iterator = nodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
---|
| 26 | var _node = _step.value;
|
---|
| 27 | originalOrder.set(_node, originalOrder.size);
|
---|
| 28 | }
|
---|
| 29 | } catch (err) {
|
---|
| 30 | _didIteratorError = true;
|
---|
| 31 | _iteratorError = err;
|
---|
| 32 | } finally {
|
---|
| 33 | try {
|
---|
| 34 | if (!_iteratorNormalCompletion && _iterator.return != null) {
|
---|
| 35 | _iterator.return();
|
---|
| 36 | }
|
---|
| 37 | } finally {
|
---|
| 38 | if (_didIteratorError) {
|
---|
| 39 | throw _iteratorError;
|
---|
| 40 | }
|
---|
| 41 | }
|
---|
| 42 | }
|
---|
| 43 |
|
---|
| 44 | nodes.sort(function (a, b) {
|
---|
| 45 | var sectionA = getSectionForNode(a);
|
---|
| 46 | var sectionB = getSectionForNode(b);
|
---|
| 47 | var aId = constants.sections[sectionA];
|
---|
| 48 | var bId = constants.sections[sectionB];
|
---|
| 49 |
|
---|
| 50 | if (typeof aId !== "number" || typeof bId !== "number") {
|
---|
| 51 | throw new Error("Section id not found");
|
---|
| 52 | }
|
---|
| 53 |
|
---|
| 54 | if (aId === bId) {
|
---|
| 55 | // $FlowIgnore originalOrder is filled for all nodes
|
---|
| 56 | return originalOrder.get(a) - originalOrder.get(b);
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | return aId - bId;
|
---|
| 60 | });
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | export function edit(ab, visitors) {
|
---|
| 64 | ab = preprocess(ab);
|
---|
| 65 | var ast = decode(ab);
|
---|
| 66 | return editWithAST(ast, ab, visitors);
|
---|
| 67 | }
|
---|
| 68 | export function editWithAST(ast, ab, visitors) {
|
---|
| 69 | var operations = [];
|
---|
| 70 | var uint8Buffer = new Uint8Array(ab);
|
---|
| 71 | var nodeBefore;
|
---|
| 72 |
|
---|
| 73 | function before(type, path) {
|
---|
| 74 | nodeBefore = cloneNode(path.node);
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | function after(type, path) {
|
---|
| 78 | if (path.node._deleted === true) {
|
---|
| 79 | operations.push({
|
---|
| 80 | kind: "delete",
|
---|
| 81 | node: path.node
|
---|
| 82 | }); // $FlowIgnore
|
---|
| 83 | } else if (hashNode(nodeBefore) !== hashNode(path.node)) {
|
---|
| 84 | operations.push({
|
---|
| 85 | kind: "update",
|
---|
| 86 | oldNode: nodeBefore,
|
---|
| 87 | node: path.node
|
---|
| 88 | });
|
---|
| 89 | }
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | traverse(ast, visitors, before, after);
|
---|
| 93 | uint8Buffer = applyOperations(ast, uint8Buffer, operations);
|
---|
| 94 | return uint8Buffer.buffer;
|
---|
| 95 | }
|
---|
| 96 | export function add(ab, newNodes) {
|
---|
| 97 | ab = preprocess(ab);
|
---|
| 98 | var ast = decode(ab);
|
---|
| 99 | return addWithAST(ast, ab, newNodes);
|
---|
| 100 | }
|
---|
| 101 | export function addWithAST(ast, ab, newNodes) {
|
---|
| 102 | // Sort nodes by insertion order
|
---|
| 103 | sortBySectionOrder(newNodes);
|
---|
| 104 | var uint8Buffer = new Uint8Array(ab); // Map node into operations
|
---|
| 105 |
|
---|
| 106 | var operations = newNodes.map(function (n) {
|
---|
| 107 | return {
|
---|
| 108 | kind: "add",
|
---|
| 109 | node: n
|
---|
| 110 | };
|
---|
| 111 | });
|
---|
| 112 | uint8Buffer = applyOperations(ast, uint8Buffer, operations);
|
---|
| 113 | return uint8Buffer.buffer;
|
---|
| 114 | } |
---|