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.imports
webassembly calls javascript, many value types want (note: count must known @ module compilation time, isn't array , isn't variadic).memory.buffer
,arraybuffer
can 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