Re: Web Assembly, struct to JavaScript Object and back

2020-06-24 Thread tirithen via Digitalmars-d-learn
On Wednesday, 24 June 2020 at 10:53:19 UTC, Sebastiaan Koppe 
wrote:

On Tuesday, 23 June 2020 at 18:15:25 UTC, tirithen wrote:

[...]


Passing anything besides int/double/bool between JS and wasm is 
hard work.


[...]


Thanks for a really good explanation, passing pointers over the 
structs matches well with the C examples I found.


Your repo has a lot of really good examples that I'll use as a 
guide.


Re: Web Assembly, struct to JavaScript Object and back

2020-06-24 Thread Sebastiaan Koppe via Digitalmars-d-learn

On Tuesday, 23 June 2020 at 18:15:25 UTC, tirithen wrote:

Anyone that has something similar working with struct objects?


Passing anything besides int/double/bool between JS and wasm is 
hard work.


Currently the ABI generated by LDC is so that arguments besides 
int/double/bool (and array/delegates are special too) are passed 
by pointer.


So if you want to call a wasm function that expects a struct, you 
instead pass a pointer to wasm memory where you have encoded that 
struct.


Similarly if you want to call a js function with rich objects you 
have to do some handling on the JS side.


Return values other than int/double/bool from wasm functions are 
special and it is expected that the function is called with a 
pointer as first argument.


There are a few gotcha but this basically describes it.

In https://github.com/skoppe/spasm I am using this approach as 
well. Except I don't actually move D struct to and from JS, 
instead only references to JS objects, strings, delegates, unions 
and arrays. Same principle applies though.


Web Assembly, struct to JavaScript Object and back

2020-06-23 Thread tirithen via Digitalmars-d-learn
I'm experimenting with generating wasm files with ldc2 but I'm 
having problems when trying to pass JavaScript Objects and 
receive them as structs and the other way around.


I found this super nice getting started guide that works fine for 
basic types like double and so on 
https://wiki.dlang.org/Generating_WebAssembly_with_LDC , but I'm 
puzzled on how to pass more advanced data structures.


I found this C example where it's mentioned that structs in that 
case will always be passed by pointer 
https://stackoverflow.com/questions/50615377/how-do-you-call-a-c-function-that-takes-or-returns-a-struct-by-value-from-js-v#answer-56405899 . Is something similar possible with D?


My setup so far:

test.d:

extern (C): // disable D mangling

void callback(double a, double b, double c);

double add(double a, double b) {
  const c = a + b;
  callback(a, b, c);
  return c;
}

struct Vector2 {
  double x;
  double y;
}

Vector2 addVectors(Vector2 a, Vector2 b) {
  return Vector2(a.x + b.x, a.y + b.y);
}

void _start() {
}

index.html:


  

  const callback = (a, b, c) => {
console.log(`callback from D: ${a} + ${b} = ${c}`);
  };

fetch('test.wasm').then((response) => response.arrayBuffer()).then((code) => {
const importObject = {env: {callback}};
WebAssembly.instantiate(code, importObject).then(result => {
  const {exports} = result.instance;

  const r = exports.add(42, -2.5);
  console.log('r = ' + r);

const r2 = exports.addVectors({x: 2, y: 4}, {x: 1, y: -1.5});
  console.log('r2 =', r2);
});
  });

  
  
Test page, open console to see the WASM results
  


Then I build test.d with:

$ ldc2 -mtriple=wasm32-unknown-unknown-wasm -L-allow-undefined 
-betterC test.d


When I serve and open the address in a browser and open the 
console I get:


r = 39.5
r2 = undefined

Anyone that has something similar working with struct objects?