In webassembly, there's a type called externref
, which opaquely represents a javascript object. So, you could do this for example, with this javascript:
class Foo {
constructor(x) {
this.x = x;
}
}
const imports = {
env: {
fooNew: (x) => new Foo(x),
fooX: (foo) => foo.x,
fooSetX: (foo, x) => { foo.x = x; }
}
}
WebAssembly.instantiateStreaming(fetch("./foo.wasm"), imports).then(module => {
let foo = module.instance.exports.f();
console.log(foo.x); // 5
module.instance.exports.g(foo);
console.log(foo.x); // 8
});
and this webassembly:
(module
(import "env" "fooNew" (func $fooNew (param i32) (result externref)))
(import "env" "fooX" (func $fooX (result i32)))
(import "env" "fooSetX" (func $fooSetX (param externref) (param i32)))
(func (export "f") (result externref)
i32.const 5
call $fooNew)
(func (export "g") (param $foo externref)
local.get $foo
i32.const 8
call $fooSetX))
5 and 8 get logged. Equivalent D to the webassembly part would be:
extern(C):
// how to get this externref type?
externref fooNew(int);
externref fooX(externref);
void fooSetX(externref, int);
externref f() {
return fooNew();
}
void g(externref foo) {
fooSetX(foo, 8);
}
problem being, there exists no externref
type. So how would you achieve it with ldc2?
B) In the javascript WebAssembly API, you can pass in memory like so:
const imports = {
"mem": new WebAssembly.Memory({ initial: 1 })
}
WebAssembly.instantiateStreaming(fetch("bar.wasm"), imports, module => { ... });
then in WebAssembly
(import "mem" (memory 1))
so how could I do that in D? That is, I want the memory that D uses to be accessible to javascript (this way I can pass pointers between JS and D)