@webassemblyjs/wasm-edit
Advanced tools
Comparing version 1.1.2-y.9 to 1.1.2-y.10
276
lib/apply.js
@@ -6,5 +6,3 @@ "use strict"; | ||
}); | ||
exports.applyToNodeToUpdate = applyToNodeToUpdate; | ||
exports.applyToNodeToDelete = applyToNodeToDelete; | ||
exports.applyToNodeToAdd = applyToNodeToAdd; | ||
exports.applyOperations = applyOperations; | ||
@@ -31,142 +29,202 @@ var _wasmGen = require("@webassemblyjs/wasm-gen"); | ||
function applyToNodeToUpdate(ast, uint8Buffer, nodes) { | ||
nodes.forEach(function (_ref) { | ||
var _ref2 = _slicedToArray(_ref, 2), | ||
oldNode = _ref2[0], | ||
newNode = _ref2[1]; | ||
function shiftLocNodeByDelta(node, delta) { | ||
assertNodeHasLoc(node); | ||
node.loc.start.column += delta; | ||
node.loc.end.column += delta; | ||
} | ||
assertNodeHasLoc(oldNode); | ||
var sectionName = (0, _helperWasmSection.getSectionForNode)(newNode); | ||
var replacementByteArray = (0, _wasmGen.encodeNode)(newNode); | ||
/** | ||
* Replace new node as bytes | ||
*/ | ||
function applyUpdate(ast, uint8Buffer, _ref) { | ||
var _ref2 = _slicedToArray(_ref, 2), | ||
oldNode = _ref2[0], | ||
newNode = _ref2[1]; | ||
uint8Buffer = (0, _helperBuffer.overrideBytesInBuffer)(uint8Buffer, // $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.start.column, // $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.end.column, replacementByteArray); | ||
/** | ||
* Update function body size if needed | ||
*/ | ||
assertNodeHasLoc(oldNode); | ||
var sectionName = (0, _helperWasmSection.getSectionForNode)(newNode); | ||
var replacementByteArray = (0, _wasmGen.encodeNode)(newNode); | ||
/** | ||
* Replace new node as bytes | ||
*/ | ||
if (sectionName === "code") { | ||
// Find the parent func | ||
(0, _ast.traverse)(ast, { | ||
Func: function Func(_ref3) { | ||
var node = _ref3.node; | ||
var funcHasThisIntr = node.body.find(function (n) { | ||
return n === newNode; | ||
}) !== undefined; // Update func's body size if needed | ||
uint8Buffer = (0, _helperBuffer.overrideBytesInBuffer)(uint8Buffer, // $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.start.column, // $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.end.column, replacementByteArray); | ||
/** | ||
* Update function body size if needed | ||
*/ | ||
if (funcHasThisIntr === true) { | ||
// These are the old functions locations informations | ||
assertNodeHasLoc(node); | ||
var oldNodeSize = (0, _wasmGen.encodeNode)(oldNode).length; | ||
var bodySizeDeltaBytes = replacementByteArray.length - oldNodeSize; | ||
if (sectionName === "code") { | ||
// Find the parent func | ||
(0, _ast.traverse)(ast, { | ||
Func: function Func(_ref3) { | ||
var node = _ref3.node; | ||
var funcHasThisIntr = node.body.find(function (n) { | ||
return n === newNode; | ||
}) !== undefined; // Update func's body size if needed | ||
if (bodySizeDeltaBytes !== 0) { | ||
var newValue = node.metadata.bodySize + bodySizeDeltaBytes; | ||
var newByteArray = (0, _encoder.encodeU32)(newValue); // function body size byte | ||
// FIXME(sven): only handles one byte u32 | ||
if (funcHasThisIntr === true) { | ||
// These are the old functions locations informations | ||
assertNodeHasLoc(node); | ||
var oldNodeSize = (0, _wasmGen.encodeNode)(oldNode).length; | ||
var bodySizeDeltaBytes = replacementByteArray.length - oldNodeSize; | ||
var start = node.loc.start.column; | ||
var end = start + 1; | ||
uint8Buffer = (0, _helperBuffer.overrideBytesInBuffer)(uint8Buffer, start, end, newByteArray); | ||
} | ||
if (bodySizeDeltaBytes !== 0) { | ||
var newValue = node.metadata.bodySize + bodySizeDeltaBytes; | ||
var newByteArray = (0, _encoder.encodeU32)(newValue); // function body size byte | ||
// FIXME(sven): only handles one byte u32 | ||
var start = node.loc.start.column; | ||
var end = start + 1; | ||
uint8Buffer = (0, _helperBuffer.overrideBytesInBuffer)(uint8Buffer, start, end, newByteArray); | ||
} | ||
} | ||
}); | ||
} | ||
/** | ||
* Update section size | ||
*/ | ||
} | ||
}); | ||
} | ||
/** | ||
* Update section size | ||
*/ | ||
var deltaBytes = replacementByteArray.length - ( // $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.end.column - oldNode.loc.start.column); | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionByteSize)(ast, uint8Buffer, sectionName, deltaBytes); // Init location informations | ||
var deltaBytes = replacementByteArray.length - ( // $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.end.column - oldNode.loc.start.column); | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionByteSize)(ast, uint8Buffer, sectionName, deltaBytes); // Init location informations | ||
newNode.loc = { | ||
start: { | ||
line: -1, | ||
column: -1 | ||
}, | ||
end: { | ||
line: -1, | ||
column: -1 | ||
} | ||
}; // Update new node end position | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
newNode.loc = { | ||
start: { | ||
line: -1, | ||
column: -1 | ||
}, | ||
end: { | ||
line: -1, | ||
column: -1 | ||
} | ||
}; // Update new node end position | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
newNode.loc.start.column = oldNode.loc.start.column; | ||
newNode.loc.end.column = // $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.start.column + replacementByteArray.length; | ||
}); | ||
return uint8Buffer; | ||
newNode.loc.start.column = oldNode.loc.start.column; | ||
newNode.loc.end.column = // $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.start.column + replacementByteArray.length; | ||
return { | ||
uint8Buffer: uint8Buffer, | ||
deltaBytes: deltaBytes | ||
}; | ||
} | ||
function applyToNodeToDelete(ast, uint8Buffer, nodes) { | ||
function applyDelete(ast, uint8Buffer, node) { | ||
var deltaElements = -1; // since we removed an element | ||
nodes.forEach(function (node) { | ||
assertNodeHasLoc(node); | ||
var sectionName = (0, _helperWasmSection.getSectionForNode)(node); | ||
assertNodeHasLoc(node); | ||
var sectionName = (0, _helperWasmSection.getSectionForNode)(node); | ||
if (sectionName === "start") { | ||
/** | ||
* The start section only contains one element, | ||
* we need to remove the whole section | ||
*/ | ||
uint8Buffer = (0, _helperWasmSection.removeSection)(ast, uint8Buffer, "start"); | ||
return; | ||
} // replacement is nothing | ||
var replacement = []; | ||
uint8Buffer = (0, _helperBuffer.overrideBytesInBuffer)(uint8Buffer, // $FlowIgnore: assertNodeHasLoc ensures that | ||
node.loc.start.column, // $FlowIgnore: assertNodeHasLoc ensures that | ||
node.loc.end.column, replacement); | ||
if (sectionName === "start") { | ||
var sectionMetadata = (0, _ast.getSectionMetadata)(ast, "start"); | ||
/** | ||
* Update section | ||
* The start section only contains one element, | ||
* we need to remove the whole section | ||
*/ | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
var deltaBytes = -(node.loc.end.column - node.loc.start.column); | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionByteSize)(ast, uint8Buffer, sectionName, deltaBytes); | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionVecSize)(ast, uint8Buffer, sectionName, deltaElements); | ||
}); | ||
return uint8Buffer; | ||
uint8Buffer = (0, _helperWasmSection.removeSection)(ast, uint8Buffer, "start"); | ||
var _deltaBytes = -sectionMetadata.size; | ||
return { | ||
uint8Buffer: uint8Buffer, | ||
deltaBytes: _deltaBytes | ||
}; | ||
} // replacement is nothing | ||
var replacement = []; | ||
uint8Buffer = (0, _helperBuffer.overrideBytesInBuffer)(uint8Buffer, // $FlowIgnore: assertNodeHasLoc ensures that | ||
node.loc.start.column, // $FlowIgnore: assertNodeHasLoc ensures that | ||
node.loc.end.column, replacement); | ||
/** | ||
* Update section | ||
*/ | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
var deltaBytes = -(node.loc.end.column - node.loc.start.column); | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionByteSize)(ast, uint8Buffer, sectionName, deltaBytes); | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionVecSize)(ast, uint8Buffer, sectionName, deltaElements); | ||
return { | ||
uint8Buffer: uint8Buffer, | ||
deltaBytes: deltaBytes | ||
}; | ||
} | ||
function applyToNodeToAdd(ast, uint8Buffer, nodes) { | ||
function applyAdd(ast, uint8Buffer, node) { | ||
var deltaElements = +1; // since we added an element | ||
nodes.forEach(function (node) { | ||
var sectionName = (0, _helperWasmSection.getSectionForNode)(node); | ||
var sectionMetadata = (0, _ast.getSectionMetadata)(ast, sectionName); // Section doesn't exists, we create an empty one | ||
var sectionName = (0, _helperWasmSection.getSectionForNode)(node); | ||
var sectionMetadata = (0, _ast.getSectionMetadata)(ast, sectionName); // Section doesn't exists, we create an empty one | ||
if (typeof sectionMetadata === "undefined") { | ||
var res = (0, _helperWasmSection.createEmptySection)(ast, uint8Buffer, sectionName); | ||
uint8Buffer = res.uint8Buffer; | ||
sectionMetadata = res.sectionMetadata; | ||
if (typeof sectionMetadata === "undefined") { | ||
var res = (0, _helperWasmSection.createEmptySection)(ast, uint8Buffer, sectionName); | ||
uint8Buffer = res.uint8Buffer; | ||
sectionMetadata = res.sectionMetadata; | ||
} | ||
/** | ||
* Add nodes | ||
*/ | ||
var newByteArray = (0, _wasmGen.encodeNode)(node); // start at the end of the section | ||
var start = sectionMetadata.startOffset + sectionMetadata.size + 1; | ||
var end = start; | ||
uint8Buffer = (0, _helperBuffer.overrideBytesInBuffer)(uint8Buffer, start, end, newByteArray); | ||
/** | ||
* Update section | ||
*/ | ||
var deltaBytes = newByteArray.length; | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionByteSize)(ast, uint8Buffer, sectionName, deltaBytes); | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionVecSize)(ast, uint8Buffer, sectionName, deltaElements); | ||
return { | ||
uint8Buffer: uint8Buffer, | ||
deltaBytes: deltaBytes | ||
}; | ||
} // TODO(sven): we could resize the section here instead, it's generic enough | ||
function applyOperations(ast, uint8Buffer, ops) { | ||
ops.forEach(function (op) { | ||
var state; | ||
switch (op.kind) { | ||
case "update": | ||
state = applyUpdate(ast, uint8Buffer, [op.oldNode, op.node]); | ||
break; | ||
case "delete": | ||
state = applyDelete(ast, uint8Buffer, op.node); | ||
break; | ||
case "add": | ||
state = applyAdd(ast, uint8Buffer, op.node); | ||
break; | ||
default: | ||
throw new Error("Unknown operation"); | ||
} | ||
/** | ||
* Add nodes | ||
* Shift following operation's nodes | ||
*/ | ||
var newByteArray = (0, _wasmGen.encodeNode)(node); // start at the end of the section | ||
if (state.deltaBytes !== 0) { | ||
ops.forEach(function (op) { | ||
switch (op.kind) { | ||
case "update": | ||
return shiftLocNodeByDelta(op.oldNode, state.deltaBytes); | ||
var start = sectionMetadata.startOffset + sectionMetadata.size + 1; | ||
var end = start; | ||
uint8Buffer = (0, _helperBuffer.overrideBytesInBuffer)(uint8Buffer, start, end, newByteArray); | ||
/** | ||
* Update section | ||
*/ | ||
case "delete": | ||
return shiftLocNodeByDelta(op.node, state.deltaBytes); | ||
} | ||
}); | ||
} | ||
var deltaBytes = newByteArray.length; | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionByteSize)(ast, uint8Buffer, sectionName, deltaBytes); | ||
uint8Buffer = (0, _helperWasmSection.resizeSectionVecSize)(ast, uint8Buffer, sectionName, deltaElements); | ||
uint8Buffer = state.uint8Buffer; | ||
}); | ||
return uint8Buffer; | ||
} |
@@ -28,4 +28,3 @@ "use strict"; | ||
function edit(ab, visitors) { | ||
var nodesToDelete = []; | ||
var nodesToUpdate = []; | ||
var operations = []; | ||
var ast = (0, _wasmParser.decode)(ab, decoderOpts); | ||
@@ -41,5 +40,12 @@ var uint8Buffer = new Uint8Array(ab); | ||
if (path.node._deleted === true) { | ||
nodesToDelete.push(path.node); // $FlowIgnore | ||
operations.push({ | ||
kind: "delete", | ||
node: path.node | ||
}); // $FlowIgnore | ||
} else if (hashNode(nodeBefore) !== hashNode(path.node)) { | ||
nodesToUpdate.push([nodeBefore, path.node]); | ||
operations.push({ | ||
kind: "update", | ||
oldNode: nodeBefore, | ||
node: path.node | ||
}); | ||
} | ||
@@ -49,4 +55,3 @@ } | ||
(0, _ast.traverseWithHooks)(ast, visitors, before, after); | ||
uint8Buffer = (0, _apply.applyToNodeToUpdate)(ast, uint8Buffer, nodesToUpdate); | ||
uint8Buffer = (0, _apply.applyToNodeToDelete)(ast, uint8Buffer, nodesToDelete); | ||
uint8Buffer = (0, _apply.applyOperations)(ast, uint8Buffer, operations); | ||
return uint8Buffer.buffer; | ||
@@ -58,4 +63,10 @@ } | ||
var uint8Buffer = new Uint8Array(ab); | ||
uint8Buffer = (0, _apply.applyToNodeToAdd)(ast, uint8Buffer, newNodes); | ||
var operations = newNodes.map(function (n) { | ||
return { | ||
kind: "add", | ||
node: n | ||
}; | ||
}); | ||
uint8Buffer = (0, _apply.applyOperations)(ast, uint8Buffer, operations); | ||
return uint8Buffer.buffer; | ||
} |
{ | ||
"name": "@webassemblyjs/wasm-edit", | ||
"version": "1.1.2-y.9", | ||
"version": "1.1.2-y.10", | ||
"description": "", | ||
@@ -19,10 +19,10 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"@webassemblyjs/ast": "1.1.2-y.9", | ||
"@webassemblyjs/helper-buffer": "1.1.2-y.9", | ||
"@webassemblyjs/helper-wasm-bytecode": "1.1.2-y.9", | ||
"@webassemblyjs/helper-wasm-section": "1.1.2-y.9", | ||
"@webassemblyjs/wasm-gen": "1.1.2-y.9", | ||
"@webassemblyjs/wasm-parser": "1.1.2-y.9", | ||
"@webassemblyjs/wast-printer": "1.1.2-y.9" | ||
"@webassemblyjs/ast": "1.1.2-y.10", | ||
"@webassemblyjs/helper-buffer": "1.1.2-y.10", | ||
"@webassemblyjs/helper-wasm-bytecode": "1.1.2-y.10", | ||
"@webassemblyjs/helper-wasm-section": "1.1.2-y.10", | ||
"@webassemblyjs/wasm-gen": "1.1.2-y.10", | ||
"@webassemblyjs/wasm-parser": "1.1.2-y.10", | ||
"@webassemblyjs/wast-printer": "1.1.2-y.10" | ||
} | ||
} |
359
src/apply.js
@@ -15,2 +15,7 @@ // @flow | ||
type State = { | ||
uint8Buffer: Uint8Array, | ||
deltaBytes: number | ||
}; | ||
function assertNodeHasLoc(n: Node) { | ||
@@ -26,206 +31,248 @@ if (n.loc == null || n.loc.start == null || n.loc.end == null) { | ||
export function applyToNodeToUpdate( | ||
function shiftLocNodeByDelta(node: Node, delta: number): Array<Node> { | ||
assertNodeHasLoc(node); | ||
node.loc.start.column += delta; | ||
node.loc.end.column += delta; | ||
} | ||
function applyUpdate( | ||
ast: Program, | ||
uint8Buffer: Uint8Array, | ||
nodes: Array<[Node, Node]> | ||
) { | ||
nodes.forEach(([oldNode, newNode]) => { | ||
assertNodeHasLoc(oldNode); | ||
[oldNode, newNode]: [Node, Node] | ||
): State { | ||
assertNodeHasLoc(oldNode); | ||
const sectionName = getSectionForNode(newNode); | ||
const replacementByteArray = encodeNode(newNode); | ||
const sectionName = getSectionForNode(newNode); | ||
const replacementByteArray = encodeNode(newNode); | ||
/** | ||
* Replace new node as bytes | ||
*/ | ||
uint8Buffer = overrideBytesInBuffer( | ||
uint8Buffer, | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.start.column, | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.end.column, | ||
replacementByteArray | ||
); | ||
/** | ||
* Replace new node as bytes | ||
*/ | ||
uint8Buffer = overrideBytesInBuffer( | ||
uint8Buffer, | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.start.column, | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.end.column, | ||
replacementByteArray | ||
); | ||
/** | ||
* Update function body size if needed | ||
*/ | ||
if (sectionName === "code") { | ||
// Find the parent func | ||
traverse(ast, { | ||
Func({ node }) { | ||
const funcHasThisIntr = | ||
node.body.find(n => n === newNode) !== undefined; | ||
/** | ||
* Update function body size if needed | ||
*/ | ||
if (sectionName === "code") { | ||
// Find the parent func | ||
traverse(ast, { | ||
Func({ node }) { | ||
const funcHasThisIntr = | ||
node.body.find(n => n === newNode) !== undefined; | ||
// Update func's body size if needed | ||
if (funcHasThisIntr === true) { | ||
// These are the old functions locations informations | ||
assertNodeHasLoc(node); | ||
// Update func's body size if needed | ||
if (funcHasThisIntr === true) { | ||
// These are the old functions locations informations | ||
assertNodeHasLoc(node); | ||
const oldNodeSize = encodeNode(oldNode).length; | ||
const bodySizeDeltaBytes = | ||
replacementByteArray.length - oldNodeSize; | ||
const oldNodeSize = encodeNode(oldNode).length; | ||
const bodySizeDeltaBytes = replacementByteArray.length - oldNodeSize; | ||
if (bodySizeDeltaBytes !== 0) { | ||
const newValue = node.metadata.bodySize + bodySizeDeltaBytes; | ||
const newByteArray = encodeU32(newValue); | ||
if (bodySizeDeltaBytes !== 0) { | ||
const newValue = node.metadata.bodySize + bodySizeDeltaBytes; | ||
const newByteArray = encodeU32(newValue); | ||
// function body size byte | ||
// FIXME(sven): only handles one byte u32 | ||
const start = node.loc.start.column; | ||
const end = start + 1; | ||
// function body size byte | ||
// FIXME(sven): only handles one byte u32 | ||
const start = node.loc.start.column; | ||
const end = start + 1; | ||
uint8Buffer = overrideBytesInBuffer( | ||
uint8Buffer, | ||
start, | ||
end, | ||
newByteArray | ||
); | ||
} | ||
uint8Buffer = overrideBytesInBuffer( | ||
uint8Buffer, | ||
start, | ||
end, | ||
newByteArray | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
}); | ||
} | ||
/** | ||
* Update section size | ||
*/ | ||
const deltaBytes = | ||
replacementByteArray.length - | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
(oldNode.loc.end.column - oldNode.loc.start.column); | ||
/** | ||
* Update section size | ||
*/ | ||
const deltaBytes = | ||
replacementByteArray.length - | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
(oldNode.loc.end.column - oldNode.loc.start.column); | ||
uint8Buffer = resizeSectionByteSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaBytes | ||
); | ||
uint8Buffer = resizeSectionByteSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaBytes | ||
); | ||
// Init location informations | ||
newNode.loc = { | ||
start: { line: -1, column: -1 }, | ||
end: { line: -1, column: -1 } | ||
}; | ||
// Init location informations | ||
newNode.loc = { | ||
start: { line: -1, column: -1 }, | ||
end: { line: -1, column: -1 } | ||
}; | ||
// Update new node end position | ||
// Update new node end position | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
newNode.loc.start.column = oldNode.loc.start.column; | ||
newNode.loc.end.column = | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
newNode.loc.start.column = oldNode.loc.start.column; | ||
newNode.loc.end.column = | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
oldNode.loc.start.column + replacementByteArray.length; | ||
}); | ||
oldNode.loc.start.column + replacementByteArray.length; | ||
return uint8Buffer; | ||
return { uint8Buffer, deltaBytes }; | ||
} | ||
export function applyToNodeToDelete( | ||
ast: Program, | ||
uint8Buffer: Uint8Array, | ||
nodes: Array<Node> | ||
) { | ||
function applyDelete(ast: Program, uint8Buffer: Uint8Array, node: Node): State { | ||
const deltaElements = -1; // since we removed an element | ||
nodes.forEach(node => { | ||
assertNodeHasLoc(node); | ||
assertNodeHasLoc(node); | ||
const sectionName = getSectionForNode(node); | ||
const sectionName = getSectionForNode(node); | ||
if (sectionName === "start") { | ||
/** | ||
* The start section only contains one element, | ||
* we need to remove the whole section | ||
*/ | ||
if (sectionName === "start") { | ||
const sectionMetadata = getSectionMetadata(ast, "start"); | ||
uint8Buffer = removeSection(ast, uint8Buffer, "start"); | ||
return; | ||
} | ||
/** | ||
* The start section only contains one element, | ||
* we need to remove the whole section | ||
*/ | ||
uint8Buffer = removeSection(ast, uint8Buffer, "start"); | ||
const deltaBytes = -sectionMetadata.size; | ||
// replacement is nothing | ||
const replacement = []; | ||
return { uint8Buffer, deltaBytes }; | ||
} | ||
uint8Buffer = overrideBytesInBuffer( | ||
uint8Buffer, | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
node.loc.start.column, | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
node.loc.end.column, | ||
replacement | ||
); | ||
// replacement is nothing | ||
const replacement = []; | ||
/** | ||
* Update section | ||
*/ | ||
uint8Buffer = overrideBytesInBuffer( | ||
uint8Buffer, | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
const deltaBytes = -(node.loc.end.column - node.loc.start.column); | ||
node.loc.start.column, | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
node.loc.end.column, | ||
replacement | ||
); | ||
uint8Buffer = resizeSectionByteSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaBytes | ||
); | ||
/** | ||
* Update section | ||
*/ | ||
uint8Buffer = resizeSectionVecSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaElements | ||
); | ||
}); | ||
// $FlowIgnore: assertNodeHasLoc ensures that | ||
const deltaBytes = -(node.loc.end.column - node.loc.start.column); | ||
return uint8Buffer; | ||
uint8Buffer = resizeSectionByteSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaBytes | ||
); | ||
uint8Buffer = resizeSectionVecSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaElements | ||
); | ||
return { uint8Buffer, deltaBytes }; | ||
} | ||
export function applyToNodeToAdd( | ||
ast: Program, | ||
uint8Buffer: Uint8Array, | ||
nodes: Array<Node> | ||
) { | ||
function applyAdd(ast: Program, uint8Buffer: Uint8Array, node: Node): State { | ||
const deltaElements = +1; // since we added an element | ||
nodes.forEach(node => { | ||
const sectionName = getSectionForNode(node); | ||
const sectionName = getSectionForNode(node); | ||
let sectionMetadata = getSectionMetadata(ast, sectionName); | ||
let sectionMetadata = getSectionMetadata(ast, sectionName); | ||
// Section doesn't exists, we create an empty one | ||
if (typeof sectionMetadata === "undefined") { | ||
const res = createEmptySection(ast, uint8Buffer, sectionName); | ||
// Section doesn't exists, we create an empty one | ||
if (typeof sectionMetadata === "undefined") { | ||
const res = createEmptySection(ast, uint8Buffer, sectionName); | ||
uint8Buffer = res.uint8Buffer; | ||
sectionMetadata = res.sectionMetadata; | ||
} | ||
uint8Buffer = res.uint8Buffer; | ||
sectionMetadata = res.sectionMetadata; | ||
} | ||
/** | ||
* Add nodes | ||
*/ | ||
const newByteArray = encodeNode(node); | ||
/** | ||
* Add nodes | ||
*/ | ||
const newByteArray = encodeNode(node); | ||
// start at the end of the section | ||
const start = sectionMetadata.startOffset + sectionMetadata.size + 1; | ||
// start at the end of the section | ||
const start = sectionMetadata.startOffset + sectionMetadata.size + 1; | ||
const end = start; | ||
const end = start; | ||
uint8Buffer = overrideBytesInBuffer(uint8Buffer, start, end, newByteArray); | ||
uint8Buffer = overrideBytesInBuffer(uint8Buffer, start, end, newByteArray); | ||
/** | ||
* Update section | ||
*/ | ||
const deltaBytes = newByteArray.length; | ||
uint8Buffer = resizeSectionByteSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaBytes | ||
); | ||
uint8Buffer = resizeSectionVecSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaElements | ||
); | ||
return { uint8Buffer, deltaBytes }; | ||
} | ||
// TODO(sven): we could resize the section here instead, it's generic enough | ||
export function applyOperations( | ||
ast: Program, | ||
uint8Buffer: Uint8Array, | ||
ops: Array<Operation> | ||
): Uint8Array { | ||
ops.forEach(op => { | ||
let state; | ||
switch (op.kind) { | ||
case "update": | ||
state = applyUpdate(ast, uint8Buffer, [op.oldNode, op.node]); | ||
break; | ||
case "delete": | ||
state = applyDelete(ast, uint8Buffer, op.node); | ||
break; | ||
case "add": | ||
state = applyAdd(ast, uint8Buffer, op.node); | ||
break; | ||
default: | ||
throw new Error("Unknown operation"); | ||
} | ||
/** | ||
* Update section | ||
* Shift following operation's nodes | ||
*/ | ||
const deltaBytes = newByteArray.length; | ||
if (state.deltaBytes !== 0) { | ||
ops.forEach(op => { | ||
switch (op.kind) { | ||
case "update": | ||
return shiftLocNodeByDelta(op.oldNode, state.deltaBytes); | ||
uint8Buffer = resizeSectionByteSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaBytes | ||
); | ||
case "delete": | ||
return shiftLocNodeByDelta(op.node, state.deltaBytes); | ||
} | ||
}); | ||
} | ||
uint8Buffer = resizeSectionVecSize( | ||
ast, | ||
uint8Buffer, | ||
sectionName, | ||
deltaElements | ||
); | ||
uint8Buffer = state.uint8Buffer; | ||
}); | ||
@@ -232,0 +279,0 @@ |
@@ -6,7 +6,3 @@ // @flow | ||
import { cloneNode } from "@webassemblyjs/ast/lib/clone"; | ||
import { | ||
applyToNodeToDelete, | ||
applyToNodeToUpdate, | ||
applyToNodeToAdd | ||
} from "./apply"; | ||
import { applyOperations } from "./apply"; | ||
@@ -24,4 +20,3 @@ function hashNode(node: Node): string { | ||
export function edit(ab: ArrayBuffer, visitors: Object): ArrayBuffer { | ||
const nodesToDelete = []; | ||
const nodesToUpdate: Array<[Node /* old */, Node /* new */]> = []; | ||
const operations: Array<Operation> = []; | ||
@@ -40,6 +35,13 @@ const ast = decode(ab, decoderOpts); | ||
if (path.node._deleted === true) { | ||
nodesToDelete.push(path.node); | ||
operations.push({ | ||
kind: "delete", | ||
node: path.node | ||
}); | ||
// $FlowIgnore | ||
} else if (hashNode(nodeBefore) !== hashNode(path.node)) { | ||
nodesToUpdate.push([nodeBefore, path.node]); | ||
operations.push({ | ||
kind: "update", | ||
oldNode: nodeBefore, | ||
node: path.node | ||
}); | ||
} | ||
@@ -50,4 +52,3 @@ } | ||
uint8Buffer = applyToNodeToUpdate(ast, uint8Buffer, nodesToUpdate); | ||
uint8Buffer = applyToNodeToDelete(ast, uint8Buffer, nodesToDelete); | ||
uint8Buffer = applyOperations(ast, uint8Buffer, operations); | ||
@@ -62,5 +63,10 @@ return uint8Buffer.buffer; | ||
uint8Buffer = applyToNodeToAdd(ast, uint8Buffer, newNodes); | ||
const operations = newNodes.map(n => ({ | ||
kind: "add", | ||
node: n | ||
})); | ||
uint8Buffer = applyOperations(ast, uint8Buffer, operations); | ||
return uint8Buffer.buffer; | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19276
511
+ Added@webassemblyjs/ast@1.1.2-y.10(transitive)
+ Added@webassemblyjs/helper-buffer@1.1.2-y.10(transitive)
+ Added@webassemblyjs/helper-leb128@1.1.2-y.10(transitive)
+ Added@webassemblyjs/helper-wasm-bytecode@1.1.2-y.10(transitive)
+ Added@webassemblyjs/helper-wasm-section@1.1.2-y.10(transitive)
+ Added@webassemblyjs/wasm-gen@1.1.2-y.10(transitive)
+ Added@webassemblyjs/wasm-parser@1.1.2-y.10(transitive)
+ Added@webassemblyjs/wast-parser@1.1.2-y.10(transitive)
+ Added@webassemblyjs/wast-printer@1.1.2-y.10(transitive)
+ Addedwebassemblyjs@1.1.2-y.10(transitive)
- Removed@webassemblyjs/ast@1.1.2-y.9(transitive)
- Removed@webassemblyjs/helper-buffer@1.1.2-y.9(transitive)
- Removed@webassemblyjs/helper-leb128@1.1.2-y.9(transitive)
- Removed@webassemblyjs/helper-wasm-bytecode@1.1.2-y.9(transitive)
- Removed@webassemblyjs/helper-wasm-section@1.1.2-y.9(transitive)
- Removed@webassemblyjs/wasm-gen@1.1.2-y.9(transitive)
- Removed@webassemblyjs/wasm-parser@1.1.2-y.9(transitive)
- Removed@webassemblyjs/wast-parser@1.1.2-y.9(transitive)
- Removed@webassemblyjs/wast-printer@1.1.2-y.9(transitive)
- Removedwebassemblyjs@1.1.2-y.9(transitive)