Files: 6a5f857a376a1e31ae18a4fd65720456f048c611 / index.js
2086 bytesRaw
1 | module.exports = class WasmContainer { |
2 | /** |
3 | * The interface API is the api the exposed to interfaces. All queries about |
4 | * the enviroment and call to the kernel go through this API |
5 | */ |
6 | constructor (code) { |
7 | this._module = WebAssembly.Module(code) |
8 | } |
9 | |
10 | static get name () { |
11 | return 'wasm' |
12 | } |
13 | /** |
14 | * Runs the core VM with a given environment and imports |
15 | */ |
16 | async run (message, kernel, imports = []) { |
17 | const responses = {} |
18 | /** |
19 | * Builds a import map with an array of given interfaces |
20 | */ |
21 | function buildImports (opts, imports) { |
22 | const importMap = {} |
23 | for (const Import of imports) { |
24 | const name = Import.name |
25 | opts.response = responses[name] = {} |
26 | const newInterface = new Import(opts) |
27 | const props = Object.getOwnPropertyNames(Import.prototype) |
28 | |
29 | // bind the methods to the correct 'this' |
30 | importMap[name] = {} |
31 | for (const prop of props) { |
32 | importMap[name][prop] = newInterface[prop].bind(newInterface) |
33 | } |
34 | } |
35 | return importMap |
36 | } |
37 | |
38 | let instance |
39 | |
40 | const opts = { |
41 | vm: { |
42 | /** |
43 | * adds an aync operation to the operations queue |
44 | */ |
45 | pushOpsQueue: (promise, callbackIndex) => { |
46 | this._opsQueue = Promise.all([this._opsQueue, promise]).then(values => { |
47 | const result = values.pop() |
48 | instance.exports.callback.get(callbackIndex)(result) |
49 | }) |
50 | }, |
51 | memory: () => { |
52 | return instance.exports.memory.buffer |
53 | } |
54 | }, |
55 | kernel: kernel, |
56 | message: message |
57 | } |
58 | const initializedImports = buildImports(opts, imports) |
59 | instance = WebAssembly.Instance(this._module, initializedImports) |
60 | |
61 | if (instance.exports.main) { |
62 | instance.exports.main() |
63 | } |
64 | await this.onDone() |
65 | return responses |
66 | } |
67 | |
68 | /** |
69 | * returns a promise that resolves when the wasm instance is done running |
70 | */ |
71 | async onDone () { |
72 | let prevOps |
73 | while (prevOps !== this._opsQueue) { |
74 | prevOps = this._opsQueue |
75 | await this._opsQueue |
76 | } |
77 | } |
78 | } |
79 |
Built with git-ssb-web