git ssb

0+

wanderer🌟 / js-primea-wasm-container



Tree: 0c6302f3b6cf83783870ae49f570c87c38ddb414

Files: 0c6302f3b6cf83783870ae49f570c87c38ddb414 / index.js

2779 bytesRaw
1const ReferanceMap = require('./referanceMap.js')
2
3module.exports = class WasmContainer {
4 /**
5 * The wasm container runs wasm code and provides a basic API for wasm
6 * interfaces for interacting with the exoInterface
7 * @param {object} exoInterface - the exoInterface instance
8 * @param {object} imports - a map of imports to expose to the wasm binary
9 */
10 constructor (kernel, imports) {
11 this.kernel = kernel
12 this.imports = imports
13 this.referanceMap = new ReferanceMap()
14 }
15
16 async initailize (message) {
17 if (!WebAssembly.validate(this.kernel.state.code)) {
18 throw new Error('invalid wasm binary')
19 }
20 return this._run(message, 'init')
21 }
22
23 /**
24 * Runs the wasm VM given a message
25 * @param {object} message
26 * @returns {Promise} a promise that resolves once the compuation is finished
27 */
28 async run (message) {
29 return this._run(message, 'main')
30 }
31
32 async _run (message, method) {
33 // Builds a import map with an array of given interfaces
34 const importMap = {}
35 for (const name in this.imports) {
36 importMap[name] = {}
37 const Import = this.imports[name]
38 const newInterface = new Import(this)
39 const props = Object.getOwnPropertyNames(Import.prototype)
40
41 // bind the methods to the correct 'this'
42 for (const prop of props) {
43 if (prop !== 'constructor') {
44 importMap[name][prop] = newInterface[prop].bind(newInterface)
45 }
46 }
47 }
48
49 const result = await WebAssembly.instantiate(this.kernel.state.code, importMap)
50 this.instance = result.instance
51 // runs the wasm code
52 this.instance.exports[method]()
53 return this.onDone()
54 }
55
56 /**
57 * returns a promise that resolves when the wasm instance is done running
58 * @returns {Promise}
59 */
60 async onDone () {
61 let prevOps
62 while (prevOps !== this._opsQueue) {
63 prevOps = this._opsQueue
64 await prevOps
65 }
66 this.referanceMap.clear()
67 }
68
69 /**
70 * Pushed an async operation to the a promise queue that
71 * @returns {Promise} the returned promise resolves in the order the intail
72 * operation was pushed to the queue
73 */
74 pushOpsQueue (promise) {
75 this._opsQueue = Promise.all([this._opsQueue, promise])
76 return this._opsQueue
77 }
78
79 /**
80 * executes a callback given an index in the exported callback container
81 * @param {integer} cb
82 * @param {*} val - a value to return to the callback function
83 */
84 execute (cb, val) {
85 this.instance.exports.table.get(cb)(val)
86 }
87
88 /**
89 * returns a section of memory from the wasm instance
90 * @param {integer} offset
91 * @param {integer} length
92 * @returns {Uint8Array}
93 */
94 getMemory (offset, length) {
95 return new Uint8Array(this.instance.exports.memory.buffer, offset, length)
96 }
97}
98

Built with git-ssb-web