Some questions with D and webassembly
ryuukk_
ryuukk.dev at gmail.com
Fri Mar 3 13:42:55 UTC 2023
On Friday, 3 March 2023 at 03:32:37 UTC, TheZipCreator wrote:
> In webassembly, there's a type called `externref`, which
> opaquely represents a javascript object. So, you could do this
> for example, with this javascript:
> ```js
> 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:
> ```wat
> (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:
> ```d
> 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:
> ```js
> const imports = {
> "mem": new WebAssembly.Memory({ initial: 1 })
> }
>
> WebAssembly.instantiateStreaming(fetch("bar.wasm"), imports,
> module => { ... });
> ```
> then in WebAssembly
> ```wat
> (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)
https://discourse.llvm.org/t/rfc-webassembly-reference-types-in-clang/66939
it says it is an opaque type, maybe just need to be ``void*``?
Also there are new intrinsics, maybe you can define them like
this:
```D
alias externref_t = void*;
pragma(LDC_intrinsic, "llvm.wasm.table.set.externref.i32")
extern(C) void llvm_wasm_table_set_externref(void*, int,
externref_t);
pragma(LDC_intrinsic, "llvm.wasm.table.get.externref.i32")
extern(C) externref_t llvm_wasm_table_get_externref(void*,
int);
```
More information about the Digitalmars-d-learn
mailing list