WebAssembly.jl icon indicating copy to clipboard operation
WebAssembly.jl copied to clipboard

JS Libraries

Open sjorn3 opened this issue 6 years ago • 0 comments

Add support for producing a js library out of a module.

Example output:

function wtype(i) {
  var t = typeof(i)
  if (t == "number") {
    return Number.isInteger(i) ? 'i32' : 'f64'
  } else if (t == "bigint") {
    return 'i64';
  }
  throw "Unsupported Type: " + i + " :: " + t;
}

const library = new ffi.Wrapper({
  addTwo_f64_i32: ['f64', ['f64', 'i32']], 
  addTwo_i32_f64: ['f64', ['i32', 'f64']], 
  addTwo_f64_f64: ['f64', ['f64', 'f64']], 
  addTwo_i32_i32: ['i32', ['i32', 'i32']]
}, {
  dialect: 'assemblyscript',
});

var addTwo_f64_i32, addTwo_i32_f64, addTwo_f64_f64, addTwo_i32_i32;

library.fetch_ = library.fetch;

library.fetch = (f => library.fetch_(f).then(() => {
  addTwo_f64_i32 = library.addTwo_f64_i32.bind(library);
  addTwo_i32_f64 = library.addTwo_i32_f64.bind(library);
  addTwo_f64_f64 = library.addTwo_f64_f64.bind(library);
  addTwo_i32_i32 = library.addTwo_i32_i32.bind(library);
}));

var addTwo = (...a) => eval("addTwo_" + a.map(wtype).join("_") + "(" + a.join() + ")");
library.addTwo = addTwo

export { addTwo_f64_i32, addTwo_i32_f64, addTwo_f64_f64, addTwo_i32_i32, addTwo };
export default library;

The library produced by wasm-ffi is exported, and the functions are all bound to their own names. addTwo is all of the different addTwos tied together, if the name addTwo was taken this wouldn't happen. It is also added to the library. I thought about the interface for dealing with the modules and this seems to be a good way. Used like so:

import JLAdd, { addTwo } from "./main.js"

JLAdd.fetch('./main.wasm').then(() => {
  console.log(addTwo(400, 400))
})

JLAdd could be any string, and then functions can be exported by name.

I think it would be safe to make wtype return i32 for anything else as it's probably a pointer if it's not one of those basic types, but it's not necessary yet.

sjorn3 avatar Jul 20 '18 21:07 sjorn3