Skip to content

Commit ae2616d

Browse files
committed
Don't use Uint8Array when not necessary
1 parent 254d512 commit ae2616d

File tree

3 files changed

+64
-35
lines changed

3 files changed

+64
-35
lines changed

.github/workflows/tests.yml

+29-14
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,28 @@ 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
steps:
235248
- uses: actions/checkout@v4
236-
- uses: dtolnay/rust-toolchain@stable
249+
- uses: dtolnay/rust-toolchain@master
237250
with:
251+
toolchain: ${{ matrix.rust.version }}
238252
targets: wasm32-unknown-unknown
253+
components: ${{ matrix.rust.components }}
239254
# - name: Install precompiled wasm-bindgen
240255
# shell: bash
241256
# run: |
@@ -251,39 +266,39 @@ jobs:
251266
- uses: Swatinem/rust-cache@v2
252267
- name: Test (Node)
253268
env:
254-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
255-
run: cargo test --target wasm32-unknown-unknown --features std
269+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
270+
run: cargo test --target wasm32-unknown-unknown --features std ${{ matrix.rust.args }}
256271
- name: Test (Firefox)
257272
env:
258273
GECKODRIVER: geckodriver
259274
WASM_BINDGEN_USE_BROWSER: 1
260-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
261-
run: cargo test --target wasm32-unknown-unknown --features std
275+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
276+
run: cargo test --target wasm32-unknown-unknown --features std ${{ matrix.rust.args }}
262277
- name: Test (Chrome)
263278
env:
264279
CHROMEDRIVER: chromedriver
265280
WASM_BINDGEN_USE_BROWSER: 1
266-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
267-
run: cargo test --target wasm32-unknown-unknown --features std
281+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
282+
run: cargo test --target wasm32-unknown-unknown --features std ${{ matrix.rust.args }}
268283
- name: Test (dedicated worker)
269284
env:
270285
GECKODRIVER: geckodriver
271286
WASM_BINDGEN_USE_DEDICATED_WORKER: 1
272-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
273-
run: cargo test --target wasm32-unknown-unknown --features std
287+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
288+
run: cargo test --target wasm32-unknown-unknown --features std ${{ matrix.rust.args }}
274289
- name: Test (shared worker)
275290
env:
276291
GECKODRIVER: geckodriver
277292
WASM_BINDGEN_USE_SHARED_WORKER: 1
278-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
279-
run: cargo test --target wasm32-unknown-unknown --features std
293+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
294+
run: cargo test --target wasm32-unknown-unknown --features std ${{ matrix.rust.args }}
280295
- name: Test (service worker)
281296
env:
282297
# Firefox doesn't support module service workers and therefor can't import scripts
283298
CHROMEDRIVER: chromedriver
284299
WASM_BINDGEN_USE_SERVICE_WORKER: 1
285-
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
286-
run: cargo test --target wasm32-unknown-unknown --features std
300+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" ${{ matrix.rust.flags }}
301+
run: cargo test --target wasm32-unknown-unknown --features std ${{ matrix.rust.args }}
287302

288303
wasi:
289304
name: WASI

.github/workflows/workspace.yml

+4
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

+31-21
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)