Files: 8fb216c62276f508a5fd349383be046d162baaa7 / index.js
3695 bytesRaw
1 | const inject = require('./injectGettersSetters.js') |
2 | |
3 | /** |
4 | * Prepares a binary by injecting getter and setter function for memory, globals and tables. |
5 | * @param {ArrayBuffer} binary - a wasm binary |
6 | * @param {Object} include |
7 | * @param {Boolean} [include.memory=true] - whether or not to include memory |
8 | * @param {Boolean} [include.table=true] - whether or not to include the function table |
9 | * @param {Array.<Boolean>} [include.globals=Array.<true>] - whether or not to |
10 | * include a given global. Each index in the array stands for a global index. |
11 | * Indexes that are set to false or left undefined will not be persisted. By |
12 | * default all globals are persisted. |
13 | * @param {String} [symbol = '_'] - a string used to prefix the injected setter and getter functions |
14 | * @return {ArrayBuffer} the resulting wasm binary |
15 | */ |
16 | function prepare (binary, include = {memory: true, table: true}, symbol = '_') { |
17 | return inject(binary, include, symbol) |
18 | } |
19 | |
20 | /** |
21 | * Given a Webassembly Instance this will produce an Object containing the current state of |
22 | * the instance |
23 | * @param {Webassembly.Instance} instance |
24 | * @param {String} symbol - the symbol that will be used to find the injected functions |
25 | * @return {Object} the state of the wasm instance |
26 | */ |
27 | function hibernate (instance, symbol = '_') { |
28 | const json = { |
29 | globals: [], |
30 | table: [], |
31 | symbol |
32 | } |
33 | for (const key in instance.exports) { |
34 | const val = instance.exports[key] |
35 | if (key.startsWith(symbol)) { |
36 | const keyElems = key.slice(symbol.length).split('_') |
37 | // save the memory |
38 | if (val instanceof WebAssembly.Memory) { |
39 | json.memory = new Uint32Array(val.buffer) |
40 | } else if (val instanceof WebAssembly.Table) { |
41 | // mark the tables, (do something for external function?) |
42 | // the external functions should have a callback |
43 | for (let i = 0; i < val.length; i++) { |
44 | const func = val.get(i) |
45 | if (func === instance.exports[`${symbol}func_${func.name}`]) { |
46 | json.table.push(func.name) |
47 | } |
48 | } |
49 | } else if (keyElems[0] === 'global' && keyElems[1] === 'getter') { |
50 | // save the globals |
51 | const last = keyElems.pop() |
52 | if (last === 'high') { |
53 | json.globals.push([instance.exports[key]()]) |
54 | } else if (last === 'low') { |
55 | json.globals[json.globals.length - 1].push(instance.exports[key]()) |
56 | } else { |
57 | json.globals.push(instance.exports[key]()) |
58 | } |
59 | } |
60 | } |
61 | } |
62 | instance.__hibernated = true |
63 | return json |
64 | } |
65 | |
66 | /** |
67 | * Resumes a previously hibernated Webassembly instance |
68 | * @param {WebAssembly.Instance} instance |
69 | * @param {Object} state - the previous state of the wasm instance |
70 | * @return {WebAssembly.Instance} |
71 | */ |
72 | function resume (instance, state) { |
73 | if (instance.__hibernated) { |
74 | instance.__hibernated = false |
75 | } else { |
76 | // initialize memory |
77 | const mem = instance.exports[`${state.symbol}memory`] |
78 | if (mem) { |
79 | // console.log(mem.length) |
80 | (new Uint32Array(mem.buffer)).set(state.memory, 0) |
81 | } |
82 | |
83 | // initialize table |
84 | if (instance.exports._table) { |
85 | for (const index in state.table) { |
86 | const funcIndex = state.table[index] |
87 | instance.exports._table.set(index, instance.exports[`${state.symbol}func_${funcIndex}`]) |
88 | } |
89 | } |
90 | |
91 | // initialize globals |
92 | for (const index in state.globals) { |
93 | const val = state.globals[index] |
94 | if (Array.isArray(val)) { |
95 | instance.exports[`${state.symbol}global_setter_i64_${index}`](val[1], val[0]) |
96 | } else { |
97 | instance.exports[`${state.symbol}global_setter_i32_${index}`](val) |
98 | } |
99 | } |
100 | } |
101 | return instance |
102 | } |
103 | |
104 | module.exports = { |
105 | prepare, |
106 | hibernate, |
107 | resume |
108 | } |
109 |
Built with git-ssb-web