All files index.js

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