How can I return a JavaScript string from a WebAssembly function -
how can return javascript string webassembly function?
can following module written in c(++) ?
export function foo() { return 'hello world!'; } also: can pass js engine garbage collected?
webassembly doesn't natively support string type, rather supports i32 / i64 / f32 / f64 value types i8 / i16 storage.
you can interact webassembly instance using:
exports, javascript call webassembly, , webassembly returns single value type.importswebassembly calls javascript, many value types want (note: count must known @ module compilation time, isn't array , isn't variadic).memory.buffer,arraybuffercan indexed using (among others)uint8array.
it depends on want do, seems accessing buffer directly easiest:
const bin = ...; // webassembly binary, assume below imports memory module "imports", field "memory". const module = new webassembly.module(bin); const memory = new webassembly.memory({ initial: 2 }); // size in pages. const instance = new webassembly.instance(module, { imports: { memory: memory } }); const arraybuffer = memory.buffer; const buffer = new uint8array(arraybuffer); if module had start function got executed @ instantiation time. otherwise you'll have export call, e.g. instance.exports.doit().
once that's done, need string size + index in memory, expose through export:
const size = instance.exports.mystringsize(); const index = instance.exports.mystringindex(); you'd read out of buffer:
let s = ""; (let = index; < index + size; ++i) s += string.fromcharcode(buffer[i]); note i'm reading 8-bit values buffer, i'm therefore assuming strings ascii. that's std::string give (index in memory .c_str() returns), expose else such utf-8 you'd need use c++ library supporting utf-8, , read utf-8 javascript, obtain codepoints, , use string.fromcodepoint.
you rely on string being null-terminated, didn't here.
you use textdecoder api once it's available more in browsers creating arraybufferview webassembly.memory's buffer (which arraybuffer).
if, instead, you're doing logging webassembly javascript, can expose memory above, , webassembly declare import calls javascript size + position. instantiate module as:
const memory = new webassembly.memory({ initial: 2 }); const arraybuffer = memory.buffer; const buffer = new uint8array(arraybuffer); const instance = new webassembly.instance(module, { imports: { memory: memory, logstring: (size, index) => { let s = ""; (let = index; < index + size; ++i) s += string.fromcharcode(buffer[i]); console.log(s); } }); this has caveat if ever grow memory (either through javascript using memory.prototype.grow, or using grow_memory opcode) arraybuffer gets neutered , need create anew.
on garbage collection: webassembly.module / webassembly.instance / webassembly.memory garbage collected javascript engine, that's pretty big hammer. want gc strings, , that's not possible objects live inside webassembly.memory. we've discussed adding gc support in future.
Comments
Post a Comment