today while doing some rust wasm vs js speed benchmarking with wasm-bindgen, I ran into a problem.
I had made a simple struct as you can see here:
I used this struct in a simple function called gimmeDirections
as shown here:
After compiling this into browser javascript, I looked into the .d.ts file that was compiled into it and noticed that the gimmeDirections function returned a number.
even though in the js, it states in the JSDOC that it returned the class of XY which was defined earlier in the compiled code.
here is the class:
export class XY {
static __wrap(ptr) {
const obj = Object.create(XY.prototype);
obj.ptr = ptr;
return obj;
}
free() {
const ptr = this.ptr;
this.ptr = 0;
wasm.__wbg_xy_free(ptr);
}
/**
* @returns {number}
*/
get x() {
var ret = wasm.__wbg_get_xy_x(this.ptr);
return ret;
}
/**
* @param {number} arg0
*/
set x(arg0) {
wasm.__wbg_set_xy_x(this.ptr, arg0);
}
/**
* @returns {number}
*/
get y() {
var ret = wasm.__wbg_get_xy_y(this.ptr);
return ret;
}
/**
* @param {number} arg0
*/
set y(arg0) {
wasm.__wbg_set_xy_y(this.ptr, arg0);
}
}
after being very confused, due to the fact of how the typescript said it would return a number but the js said it would return a class, I decided to run it... and got a number back.
The object below is my javascript function running identical code for the benchmark, as you can see, I got an object, not a number.
Here is my JS code:
import * as funcs from './wasm/wildz.js';
// compiled wasm js file
function directionsJS(x, y) {
let xX = x;
let yY = y;
if (Math.abs(xX) === Math.abs(yY)) {
xX /= Math.SQRT2;
yY /= Math.SQRT2;
}
return {
x: x,
y: yY
};
}
(async() => {
const game = await funcs.default();
console.time('Rust Result'); console.log(game.gimmeDirections(10, 10));
console.timeEnd('Rust Result'); console.time('JS Result');
console.log(directionsJS(10, 10)); console.timeEnd('JS Result');
})();
I'm still very confused on why it's returning a number when clearly I'm returning a object. Help is much needed, and appreciated
Much of this and more is explained in Exporting a struct to JS in the wasm-bindgen guide, but I'll summarize.
Rust structs are "returned" by allocating space for them dynamically and returning a pointer to it. What you're seeing, in regards to the function returning number
, is the "raw" ffi function that binds the JS runtime and wasm module. It just returns that pointer value.
The generated XY
Javascript class is a wrapper around that pointer value and provides functions for interacting with it. The generated gimmeDirections
function is a wrapper around that wasm module call that creates that class.