Skip to content

Add support for number slices of type MaybeUninit<T>#4316

Merged
daxpedda merged 3 commits intowasm-bindgen:mainfrom
daxpedda:maybe-uninit
Dec 6, 2024
Merged

Add support for number slices of type MaybeUninit<T>#4316
daxpedda merged 3 commits intowasm-bindgen:mainfrom
daxpedda:maybe-uninit

Conversation

@daxpedda
Copy link
Copy Markdown
Member

@daxpedda daxpedda commented Dec 5, 2024

This PR adds support for numeric slice types with MaybeUninit<T>. While, generally in Rust, unsafety requirements have to be kept by the user, this isn't unsafe in Wasm to begin with, so there is no concern in this regard.

The use case here is interfacing with cross-platform Rust code where using this type probably made much more sense.

@daxpedda daxpedda force-pushed the maybe-uninit branch 2 times, most recently from a23c511 to 2c6b2d0 Compare December 6, 2024 07:56
@daxpedda daxpedda marked this pull request as ready for review December 6, 2024 08:02
Copy link
Copy Markdown
Contributor

@RunDevelopment RunDevelopment left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document the behavior of reading MaybeUninit<T> values in JS. I think a small paragraph saying that it's not UB, but that the value is unspecified would be enough.

Also, please add a CLI reference test, so we can see the generated JS and TS.

Copy link
Copy Markdown
Contributor

@RunDevelopment RunDevelopment left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last comment, then gtg 👍

Comment on lines +7 to +8
> **Note:** While reading from an uninitialized `MaybeUninit` is unsafe in
> Rust, it is not in Wasm. Though they might contain unspecified values.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor corrections:

  1. Reading uninitialized memory in Rust isn't just unsafe, it's UB.
  2. WASM doesn't do the reading, the JS users do.
Suggested change
> **Note:** While reading from an uninitialized `MaybeUninit` is unsafe in
> Rust, it is not in Wasm. Though they might contain unspecified values.
> **Note:** While reading from an uninitialized `MaybeUninit` is UB in Rust, it is safe in JavaScript. Though they might contain unspecified values.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm ... I was making a note for Rust users as well, that when receiving MaybeUninit there is nothing to worry about. But does that even make sense?

Maybe the note should only talk to JS users?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, that's a good idea. I think it would be good to say that data coming from JS is always initialized, so taking a &[MaybeUninit<u8>], while supported, typically doesn't make sense.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, after a lot of different tries I arrived at the current state. I was trying not to explain Rust or Wasm but stay concise to what users need to know only for this feature and nothing else.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you want me to improve anything still, we can do that in a follow-up.

@daxpedda daxpedda force-pushed the maybe-uninit branch 3 times, most recently from e36290e to 8275a98 Compare December 6, 2024 18:10
daxpedda and others added 3 commits December 7, 2024 00:26
Co-Authored-By: Michael Schmidt <msrd0000@gmail.com>
Co-Authored-By: Michael Schmidt <msrd0000@gmail.com>
@daxpedda daxpedda merged commit 8fe5bf1 into wasm-bindgen:main Dec 6, 2024
newpavlov pushed a commit to rust-random/getrandom that referenced this pull request Dec 9, 2024
As discussed in #541. This PR adds the following improvements:
- Caching of the global `Crypto` object.
- Detecting if our Wasm memory is based on a `SharedArrayBuffer`. If
not, we can copy bytes directly into our memory instead of having to go
through JS. This saves allocating the buffer in JS and copying the bytes
into Wasm memory. This is also the most common path. `SharedArrayBuffer`
requires `target_feature = "atomics"`, which is unstable and requires
Rust nightly. See
#559 (comment)
for full context.
- The atomic path only creates a sub-array when necessary, potentially
saving another FFI call.
- The atomic path will now allocate an `Uint8Array` with the minimum
amount of bytes necessary instead of a fixed size.
- The maximum chunk size for the non-atomic path and the maximum
`Uint8Array` size for the atomic paths have been increased to 65536
bytes: the maximum allowed buffer size for `Crypto.getRandomValues()`.

All in all this should give a performance improvement of ~5% to ~500%
depending on the amount of requested bytes and which path is taken. See
#559 (comment)
for some benchmark results.

This spawned a bunch of improvements and fixes in `wasm-bindgen` that
are being used here:
- wasm-bindgen/wasm-bindgen#4315
- wasm-bindgen/wasm-bindgen#4316
- wasm-bindgen/wasm-bindgen#4318
- wasm-bindgen/wasm-bindgen#4319
- wasm-bindgen/wasm-bindgen#4340
takumi-earth pushed a commit to earthlings-dev/getrandom that referenced this pull request Jan 27, 2026
As discussed in rust-random#541. This PR adds the following improvements:
- Caching of the global `Crypto` object.
- Detecting if our Wasm memory is based on a `SharedArrayBuffer`. If
not, we can copy bytes directly into our memory instead of having to go
through JS. This saves allocating the buffer in JS and copying the bytes
into Wasm memory. This is also the most common path. `SharedArrayBuffer`
requires `target_feature = "atomics"`, which is unstable and requires
Rust nightly. See
rust-random#559 (comment)
for full context.
- The atomic path only creates a sub-array when necessary, potentially
saving another FFI call.
- The atomic path will now allocate an `Uint8Array` with the minimum
amount of bytes necessary instead of a fixed size.
- The maximum chunk size for the non-atomic path and the maximum
`Uint8Array` size for the atomic paths have been increased to 65536
bytes: the maximum allowed buffer size for `Crypto.getRandomValues()`.

All in all this should give a performance improvement of ~5% to ~500%
depending on the amount of requested bytes and which path is taken. See
rust-random#559 (comment)
for some benchmark results.

This spawned a bunch of improvements and fixes in `wasm-bindgen` that
are being used here:
- wasm-bindgen/wasm-bindgen#4315
- wasm-bindgen/wasm-bindgen#4316
- wasm-bindgen/wasm-bindgen#4318
- wasm-bindgen/wasm-bindgen#4319
- wasm-bindgen/wasm-bindgen#4340
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

Successfully merging this pull request may close these issues.

2 participants