Re: Some questions with D and webassembly

2023-03-03 Thread Johan via Digitalmars-d-learn

On Friday, 3 March 2023 at 18:34:24 UTC, TheZipCreator wrote:

On Friday, 3 March 2023 at 13:42:55 UTC, ryuukk_ wrote:

On Friday, 3 March 2023 at 03:32:37 UTC, TheZipCreator wrote:

[...]


https://discourse.llvm.org/t/rfc-webassembly-reference-types-in-clang/66939



It looks like this needs some more compiler support. Please 
submit the feature request (including the link to this LLVM page) 
on LDC's github page.


cheers,
  Johan



Re: Some questions with D and webassembly

2023-03-03 Thread TheZipCreator via Digitalmars-d-learn

On Friday, 3 March 2023 at 13:42:55 UTC, ryuukk_ wrote:

On Friday, 3 March 2023 at 03:32:37 UTC, TheZipCreator wrote:

[...]


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);

```


Using `void*` doesn't appear to work (and looking at the 
generated wasm it seems to reduce it to `i32`, which is not the 
right type unfortunately). I guess what I could do is have a 
global array in js which stores all objects I'll need to access, 
then just access them via the index into that array but that 
feels like a hack especially when `externref` is a thing that 
exists.


Re: Some questions with D and webassembly

2023-03-03 Thread ryuukk_ via Digitalmars-d-learn

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);

```


Some questions with D and webassembly

2023-03-02 Thread TheZipCreator via Digitalmars-d-learn
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)