wasm-bindgen: Allow returning fixed-size tuples and arrays

It appears that returning (f32, f32, f32, f32) or [f32; 4] in a #[wasm_bindgen] function does not currently work. Would be great if fixed size arrays and tuples (maybe up to length 32) were supported.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 53
  • Comments: 19 (6 by maintainers)

Most upvoted comments

As another use-case, I think tuples support could improve interfaces for js-sys iterators too.

In particular, .entries() on Map / Set / Array could produce an iterator over tuples of (JsValue, JsValue) right away instead of users having to repeat same boilerplate with JsArray + Reflect::get_u32(..., 0) + Reflect::get_u32(..., 1) to extract key and value on each iteration.

This would be great.

In my use case, I wanted to return RGB value as 3 elements tuple or array of u8. However, they are not yet supported so I needed to create a struct like

#[wasm_bindgen]
pub struct Rgb { pub r: u8, pub g: u8, pub b: u8 }

But it is not so efficient since in JavaScript, accessing each field causes interaction between wasm and JS.

console.log(color.r, color.g, color.b);

For this use case, I could finally use 0xrrggbb format of u32 values for RGB values. But it’s a solution only for this use case.


I also think mapping tuples to JS array is fine and reasonable. TypeScript supports tuples and actually it is transpiled into array.

https://www.typescriptlang.org/docs/handbook/basic-types.html

We currently have fixed size arrays for most numeric primitives working when using the WASM_BINDGEN_MULTI_VALUE=true option! Still a bit of work to be done (testing, clean up, making it work when multi value is disabled, etc), but I think we’re close! I’ve opened a draft PR in the meantime if anyone wants to take a look at what we have so far: #3458.

Any examples on where this is implemented? Couldn’t get it working from current documentation

We’re currently doing the wasm-bindgen work here: https://github.com/staratlasmeta/wasm-bindgen. It’s not in a working state at the moment and there’s still work we’ll need to do, but its getting there.

I think fixed-size-arrays are in theory easy enough (we’d probably pass them through allocated memory), tuples are a bit odder though. You’re mostly looking for homogenous tuples, right? And both of these in JS would pop out as arrays?

Thank you for the update! 🚀

Would proceeding like that and throwing a runtime error on wasm-bindgen-cli if fixed size arrays exist and multi value is off be an acceptable change?

Sounds good then!

@stegaBOB I’m not entirely sure how easy or hard to implement this really is, but I’m happy to review a PR!

@josephrocca, Tuples refer to Rust tuples, Wasm multi-value tuples return JavaScript arrays, and it would make the most sense to target the Wasm feature so that some cases won’t need a wasm-bindgen shim at all.