Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for u8 slices #5

Closed
nickbabcock opened this issue Jan 19, 2018 · 11 comments
Closed

Support for u8 slices #5

nickbabcock opened this issue Jan 19, 2018 · 11 comments

Comments

@nickbabcock
Copy link
Contributor

wasm_bindgen! {
    pub fn parse_data(data: &[u8]) -> i32 {
        data.len() as i32
    }
}

Returns

unsupported reference type

I'm hoping that you'd be open to more borrowed types (specifically &[u8]) in addition to BorrowedStr. This could be part of a larger issue to support Vec and other slices, but I figure &[u8] might be easiest and would be implemented very closely to BorrowedStr.

Use case:

After I use a FileReader to read a binary file into an ArrayBuffer and create WebAssembly.Memory (I believe that flow is correct), I want to send the data to rust for parsing.

@alexcrichton
Copy link
Contributor

alexcrichton commented Jan 19, 2018

Ah yes, definitely!

Just to confirm (as I'm not so sure myself), what types would work on the JS side of things? Or rather, what type would this expect from JS?

@nickbabcock
Copy link
Contributor Author

If I had to choose one: Uint8Array as "array of 8-bit unsigned integers" certainly is a close to fit for &[u8]. ArrayBuffer may also work, but maybe not as important.

@TimHambourger
Copy link

Besides Uint8Array, it'd be great to have conventions for targeting all the JS TypedArray types with both borrowed (&[T]) and owned (Vec<T> ??) variants on the Rust side.

@alexcrichton
Copy link
Contributor

Er sorry meant to respond, but @nickbabcock sounds good to me! @TimHambourger also I'd totally be down with that as well, sounds like a great idea!

I think we could pretty easily add bindings for both &[u32] and Vec<u32> (and other integer types) like &str and String work today. Keep in mind though that whenever an array crosses the wasm boundary it'll copy the entire array!

@MaxGraey
Copy link

I very interesting in use this great project, but lack of array binding forcing me to use stdweb. It will be great have borrowed or/and owned arrays.

@itsybitesyspider
Copy link

The README for this issue says "Vectors and slices of supported integer types", however, the change in git history (3c58aa7) extensively mentions floating point types.

@alexcrichton
Copy link
Contributor

@clanehin ah yes indeed, all of the primitive typed array views are supported, including floats!

@aschampion
Copy link

Likely I'm missing something obvious, but while this works great across the js boundary, I can't seem to find the right traits to get this to work within Rust itself for these js_sys types, e.g.:

some_fetch_request.and_then(|resp_value| {
    assert!(resp_value.is_instance_of::<Response>());
    let resp: Response = resp_value.dyn_into().unwrap();

    JsFuture::from(resp.array_buffer().unwrap())
}).map(|arrbuff_value| {
    assert!(arrbuff_value.is_instance_of::<ArrayBuffer>());
    // let arrbuff: ArrayBuffer = arrbuff_value.dyn_into().unwrap();
    let typebuff: js_sys::Uint8Array = js_sys::Uint8Array::new(&arrbuff_value);

    // Great so far...
    // Now imagine we have some function `foo(&[u8])` or `foo<T: std::io::Read>(T)`, none of the normal tricks work:
    foo(&typebuff);
    foo((&typebuff).into());
    foo(&typebuff[..]);
    foo(typebuff.as_ref());
    // etc, etc.
});

@alexcrichton
Copy link
Contributor

@aschampion ah currently that's not supported unfortunately! Want to open a separate issue for that though? (converting Uint8Array to Vec<u8>)

alexcrichton added a commit to alexcrichton/wasm-bindgen that referenced this issue Nov 8, 2018
This commit implements the first half of [RFC rustwasm#5] where the `Deref`
trait is implemented for all imported types. The target of `Deref` is
either the first entry of the list of `extends` attribute or `JsValue`.

All examples using `.as_ref()` with various `web-sys` types have been
updated to the more ergonomic deref casts now. Additionally the
`web-sys` generation of the `extends` array has been fixed slightly to
explicitly list implementatoins in the hierarchy order to ensure the
correct target for `Deref` is chosen.

[RFC rustwasm#5]: https://github.com/rustwasm/rfcs/blob/master/text/005-structural-and-deref.md
alexcrichton added a commit to alexcrichton/wasm-bindgen that referenced this issue Nov 8, 2018
This commit removes shims, where possible, for `structural` items.
Instead of generating code that looks like:

    const target = function() { this.foo(); };
    exports.__wbg_thing = function(a) { target.call(getObject(a)); };

we now instead generate:

    exports.__wbg_thing = function(a) { getObject(a).foo(); };

Note that this only applies to `structural` bindings, all default
bindings (as of this commit) are still using imported targets to ensure
that their binding can't change after instantiation.

This change was [detailed in RFC rustwasm#5][link] as an important optimization
for `structural` bindings to ensure they've got performance parity with
today's non-`structural` default bindings.

[link]: https://rustwasm.github.io/rfcs/005-structural-and-deref.html#why-is-it-ok-to-make-structural-the-default
@jvallikivi
Copy link

Is there an update to the issue mentioned by @aschampion (getting Uint8Array -> &[u8]/&mut [u8] without having to copy into a vector)?

@kartva
Copy link
Contributor

kartva commented Apr 16, 2021

You may find this useful:
#1079 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants