Skip to content

Commit 20885b4

Browse files
committed
Don't use Uint8Array when not necessary
1 parent 7adc287 commit 20885b4

File tree

3 files changed

+65
-35
lines changed

3 files changed

+65
-35
lines changed

.github/workflows/tests.yml

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,29 @@ jobs:
229229
# run: cargo test
230230

231231
web:
232-
name: Web
232+
name: Web ${{ matrix.rust.description }}
233233
runs-on: ubuntu-24.04
234+
strategy:
235+
fail-fast: false
236+
matrix:
237+
rust:
238+
- { version: stable, atomics: false }
239+
- {
240+
description: with Atomics,
241+
atomics: true,
242+
version: nightly,
243+
components: rust-src,
244+
flags: '-Ctarget-feature=+atomics,+bulk-memory',
245+
args: '-Zbuild-std=panic_abort,std',
246+
}
234247
env:
235248
CARGO_BUILD_TARGET: wasm32-unknown-unknown
236249
steps:
237250
- uses: actions/checkout@v4
238-
- uses: dtolnay/rust-toolchain@stable
251+
- uses: dtolnay/rust-toolchain@master
252+
with:
253+
toolchain: ${{ matrix.rust.version }}
254+
components: ${{ matrix.rust.components }}
239255
# - name: Install precompiled wasm-bindgen
240256
# shell: bash
241257
# run: |
@@ -251,39 +267,39 @@ jobs:
251267
- uses: Swatinem/rust-cache@v2
252268
- name: Test (Node)
253269
env:
254-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
255-
run: cargo test --features std
270+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
271+
run: cargo test --features std ${{ matrix.rust.args }}
256272
- name: Test (Firefox)
257273
env:
258274
GECKODRIVER: geckodriver
259275
WASM_BINDGEN_USE_BROWSER: 1
260-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
261-
run: cargo test --features std
276+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
277+
run: cargo test --features std ${{ matrix.rust.args }}
262278
- name: Test (Chrome)
263279
env:
264280
CHROMEDRIVER: chromedriver
265281
WASM_BINDGEN_USE_BROWSER: 1
266-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
267-
run: cargo test --features std
282+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
283+
run: cargo test --features std ${{ matrix.rust.args }}
268284
- name: Test (dedicated worker)
269285
env:
270286
GECKODRIVER: geckodriver
271287
WASM_BINDGEN_USE_DEDICATED_WORKER: 1
272-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
273-
run: cargo test --features std
288+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
289+
run: cargo test --features std ${{ matrix.rust.args }}
274290
- name: Test (shared worker)
275291
env:
276292
GECKODRIVER: geckodriver
277293
WASM_BINDGEN_USE_SHARED_WORKER: 1
278-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
279-
run: cargo test --features std
294+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
295+
run: cargo test --features std ${{ matrix.rust.args }}
280296
- name: Test (service worker)
281297
env:
282298
# Firefox doesn't support module service workers and therefor can't import scripts
283299
CHROMEDRIVER: chromedriver
284300
WASM_BINDGEN_USE_SERVICE_WORKER: 1
285-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
286-
run: cargo test --features std
301+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
302+
run: cargo test --features std ${{ matrix.rust.args }}
287303

288304
wasi:
289305
name: WASI

.github/workflows/workspace.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ jobs:
4949
env:
5050
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
5151
run: cargo clippy -Zbuild-std --target wasm32-unknown-unknown
52+
- name: Web WASM with atomics (wasm_js.rs)
53+
env:
54+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" -Ctarget-feature=+atomics,+bulk-memory
55+
run: cargo clippy -Zbuild-std --target wasm32-unknown-unknown
5256
- name: Linux (linux_android.rs)
5357
env:
5458
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_getrandom"

src/backends/wasm_js.rs

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,36 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
1919
CRYPTO.with(|crypto| {
2020
let crypto = crypto.as_ref().ok_or(Error::WEB_CRYPTO)?;
2121

22-
// getRandomValues does not work with all types of WASM memory,
23-
// so we initially write to browser memory to avoid exceptions.
24-
let buf = Uint8Array::new_with_length(CRYPTO_BUFFER_SIZE.into());
25-
for chunk in dest.chunks_mut(CRYPTO_BUFFER_SIZE.into()) {
26-
let chunk_len: u32 = chunk
27-
.len()
28-
.try_into()
29-
.expect("chunk length is bounded by CRYPTO_BUFFER_SIZE");
30-
// The chunk can be smaller than buf's length, so we call to
31-
// JS to create a smaller view of buf without allocation.
32-
let sub_buf = if chunk_len == u32::from(CRYPTO_BUFFER_SIZE) {
33-
buf.clone()
34-
} else {
35-
buf.subarray(0, chunk_len)
36-
};
37-
38-
if crypto.get_random_values(&sub_buf).is_err() {
39-
return Err(Error::WEB_GET_RANDOM_VALUES);
40-
}
22+
if wasm_bindgen::is_memory_shared() {
23+
// getRandomValues does not work with all types of WASM memory,
24+
// so we initially write to browser memory to avoid exceptions.
25+
let buf = Uint8Array::new_with_length(CRYPTO_BUFFER_SIZE.into());
26+
for chunk in dest.chunks_mut(CRYPTO_BUFFER_SIZE.into()) {
27+
let chunk_len: u32 = chunk
28+
.len()
29+
.try_into()
30+
.expect("chunk length is bounded by CRYPTO_BUFFER_SIZE");
31+
// The chunk can be smaller than buf's length, so we call to
32+
// JS to create a smaller view of buf without allocation.
33+
let sub_buf = if chunk_len == u32::from(CRYPTO_BUFFER_SIZE) {
34+
buf.clone()
35+
} else {
36+
buf.subarray(0, chunk_len)
37+
};
38+
39+
if crypto.get_random_values(&sub_buf).is_err() {
40+
return Err(Error::WEB_GET_RANDOM_VALUES);
41+
}
4142

42-
// SAFETY: `sub_buf`'s length is the same length as `chunk`
43-
unsafe { sub_buf.raw_copy_to_ptr(chunk.as_mut_ptr().cast::<u8>()) };
43+
// SAFETY: `sub_buf`'s length is the same length as `chunk`
44+
unsafe { sub_buf.raw_copy_to_ptr(chunk.as_mut_ptr().cast::<u8>()) };
45+
}
46+
} else {
47+
for chunk in dest.chunks_mut(CRYPTO_BUFFER_SIZE.into()) {
48+
if crypto.get_random_values_ref(chunk).is_err() {
49+
return Err(Error::WEB_GET_RANDOM_VALUES);
50+
}
51+
}
4452
}
4553
Ok(())
4654
})
@@ -56,4 +64,6 @@ extern "C" {
5664
// Crypto.getRandomValues()
5765
#[wasm_bindgen(method, js_name = getRandomValues, catch)]
5866
fn get_random_values(this: &Crypto, buf: &Uint8Array) -> Result<(), JsValue>;
67+
#[wasm_bindgen(method, js_name = getRandomValues, catch)]
68+
fn get_random_values_ref(this: &Crypto, buf: &mut [MaybeUninit<u8>]) -> Result<(), JsValue>;
5969
}

0 commit comments

Comments
 (0)