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 | } |
---|