Skip to content

Add wasm32v1-none support #541

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

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Allow normal use of "cargo run" and "cargo test" on these wasm32 platforms.
[target.wasm32-unknown-unknown]
runner = 'wasm-bindgen-test-runner'
[target.wasm32v1-unknown]
runner = 'wasm-bindgen-test-runner'
[target.wasm32-wasip1]
runner = 'wasmtime'
[target.wasm32-wasip2]
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,33 +245,33 @@ jobs:
- name: Test (Node)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
run: wasm-pack test --node
run: wasm-pack test --node -- --features std
- name: Test (Firefox)
env:
WASM_BINDGEN_USE_BROWSER: 1
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
run: wasm-pack test --headless --firefox
run: wasm-pack test --headless --firefox -- --features std
- name: Test (Chrome)
env:
WASM_BINDGEN_USE_BROWSER: 1
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
run: wasm-pack test --headless --chrome
run: wasm-pack test --headless --chrome -- --features std
- name: Test (dedicated worker)
env:
WASM_BINDGEN_USE_DEDICATED_WORKER: 1
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
run: wasm-pack test --headless --firefox
run: wasm-pack test --headless --firefox -- --features std
- name: Test (shared worker)
env:
WASM_BINDGEN_USE_SHARED_WORKER: 1
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
run: wasm-pack test --headless --firefox
run: wasm-pack test --headless --firefox -- --features std
- name: Test (service worker)
env:
WASM_BINDGEN_USE_SERVICE_WORKER: 1
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
# Firefox doesn't support module service workers and therefor can't import scripts
run: wasm-pack test --headless --chrome
run: wasm-pack test --headless --chrome -- --features std

wasi:
name: WASI
Expand Down
20 changes: 18 additions & 2 deletions .github/workflows/workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
# Fixed Nigthly version is used to prevent
# CI failures which are not relevant to PR changes
# on introduction of new Clippy lints.
toolchain: nightly-2024-10-08
toolchain: nightly-2024-10-24
components: clippy,rust-src
- name: std feature
run: cargo clippy --features std
Expand All @@ -48,7 +48,23 @@ jobs:
- name: Web WASM (wasm_js.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
run: cargo clippy -Zbuild-std --target wasm32-unknown-unknown
run: cargo clippy --features std -Zbuild-std=panic_abort,std --target wasm32-unknown-unknown
- name: Web WASM no_std (wasm_js.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
run: cargo clippy -Zbuild-std=core,alloc --target wasm32-unknown-unknown
- name: Web WASM no_std with atomics (wasm_js.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" -Ctarget-feature=+atomics,+bulk-memory
run: cargo clippy -Zbuild-std=core,alloc --target wasm32-unknown-unknown
- name: Web WASMv1 (wasm_js.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js"
run: cargo clippy -Zbuild-std=core,alloc --target wasm32v1-none
- name: Web WASMv1 with atomics (wasm_js.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" -Ctarget-feature=+atomics,+bulk-memory
run: cargo clippy -Zbuild-std=core,alloc --target wasm32v1-none
- name: Linux (linux_android.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_getrandom"
Expand Down
13 changes: 7 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,17 @@ wasi = { version = "0.13", default-features = false }
windows-targets = "0.52"

# wasm_js
[target.'cfg(all(getrandom_backend = "wasm_js", target_arch = "wasm32", target_os = "unknown"))'.dependencies]
wasm-bindgen = { version = "0.2.89", default-features = false }
js-sys = "0.3"
[target.'cfg(all(getrandom_backend = "wasm_js", target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies]
wasm-bindgen-test = "0.3.39"
[target.'cfg(all(getrandom_backend = "wasm_js", target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dependencies]
wasm-bindgen = { version = "0.2.96", default-features = false }
js-sys = { version = "0.3.73", default-features = false }
once_cell = { version = "1", default-features = false }
[target.'cfg(all(getrandom_backend = "wasm_js", target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dev-dependencies]
wasm-bindgen-test = { version = "0.3", default-features = false }

[features]
# Implement std::error::Error for getrandom::Error and
# use std to retrieve OS error descriptions
std = []
std = ["wasm-bindgen/std", "js-sys/std", "wasm-bindgen-test/std"]
# Unstable feature to support being a libstd dependency
rustc-dep-of-std = ["compiler_builtins", "core"]

Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,15 @@ Pull Requests that add support for new targets to `getrandom` are always welcome
`getrandom` also provides optional (opt-in) backends, which allow users to customize the source
of randomness based on their specific needs:

| Backend name | Target | Target Triple | Implementation
| ----------------- | -------------------- | ------------------------ | --------------
| `linux_getrandom` | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call (without `/dev/urandom` fallback). Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow).
| `linux_rustix` | Linux, Android | `*‑linux‑*` | Same as `linux_getrandom`, but uses [`rustix`] instead of `libc`.
| `rdrand` | x86, x86-64 | `x86_64-*`, `i686-*` | [`RDRAND`] instruction
| `rndr` | AArch64 | `aarch64-*` | [`RNDR`] register
| `esp_idf` | ESP-IDF | `*‑espidf` | [`esp_fill_random`]. WARNING: can return low-quality entropy without proper hardware configuration!
| `wasm_js` | Web Browser, Node.js | `wasm32‑unknown‑unknown` | [`Crypto.getRandomValues`] if available, then [`crypto.randomFillSync`] if on Node.js (see [WebAssembly support])
| `custom` | All targets | `*` | User-provided custom implementation (see [custom backend])
| Backend name | Target | Target Triple | Implementation
| ----------------- | -------------------- | ----------------------------------------- | --------------
| `linux_getrandom` | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call (without `/dev/urandom` fallback). Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow).
| `linux_rustix` | Linux, Android | `*‑linux‑*` | Same as `linux_getrandom`, but uses [`rustix`] instead of `libc`.
| `rdrand` | x86, x86-64 | `x86_64-*`, `i686-*` | [`RDRAND`] instruction
| `rndr` | AArch64 | `aarch64-*` | [`RNDR`] register
| `esp_idf` | ESP-IDF | `*‑espidf` | [`esp_fill_random`]. WARNING: can return low-quality entropy without proper hardware configuration!
| `wasm_js` | Web Browser, Node.js | `wasm32‑unknown‑unknown`, `wasm32v1-none` | [`Crypto.getRandomValues`] if available, then [`crypto.randomFillSync`] if on Node.js (see [WebAssembly support])
| `custom` | All targets | `*` | User-provided custom implementation (see [custom backend])

Opt-in backends can be enabled using the `getrandom_backend` configuration flag.
The flag can be set either by specifying the `rustflags` field in
Expand Down
9 changes: 5 additions & 4 deletions src/backends.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,12 @@ cfg_if! {
pub use rdrand::*;
} else if #[cfg(all(
target_arch = "wasm32",
target_os = "unknown",
any(target_os = "unknown", target_os = "none"),
))] {
compile_error!("the wasm32-unknown-unknown targets are not supported \
by default, you may need to enable the \"wasm_js\" \
configuration flag. For more information see: \
compile_error!("the wasm32-unknown-unknown and wasm32v1-none targets \
are not supported by default, you may need to enable \
the \"wasm_js\" configuration flag. For more \
information see: \
https://docs.rs/getrandom/#webassembly-support");
} else {
compile_error!("target is not supported. You may need to define \
Expand Down
40 changes: 34 additions & 6 deletions src/backends/wasm_js.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
//! Implementation for WASM based on Web and Node.js
use crate::Error;

#[cfg(feature = "std")]
extern crate std;
use std::{mem::MaybeUninit, thread_local};
use core::mem::MaybeUninit;

pub use crate::util::{inner_u32, inner_u64};

#[cfg(not(all(target_arch = "wasm32", target_os = "unknown",)))]
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"),)))]
compile_error!("`wasm_js` backend can be enabled only for OS-less WASM targets!");

use js_sys::{global, Function, Uint8Array};
#[cfg(not(feature = "std"))]
use once_cell::unsync::Lazy;
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};

// Size of our temporary Uint8Array buffer used with WebCrypto methods
Expand All @@ -25,12 +28,37 @@ enum RngSource {

// JsValues are always per-thread, so we initialize RngSource for each thread.
// See: https://github.com/rustwasm/wasm-bindgen/pull/955
thread_local!(
static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
);
struct Local;

impl Local {
#[cfg(feature = "std")]
fn with<R>(f: impl FnOnce(&Result<RngSource, Error>) -> R) -> R {
std::thread_local!(
static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
);
RNG_SOURCE.with(f)
}

#[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
fn with<R>(f: impl FnOnce(&Result<RngSource, Error>) -> R) -> R {
struct Wrapper<T>(T);
unsafe impl<T> Send for Wrapper<T> {}
unsafe impl<T> Sync for Wrapper<T> {}
static RNG_SOURCE: Wrapper<Lazy<Result<RngSource, Error>>> =
Wrapper(Lazy::new(getrandom_init));
f(&RNG_SOURCE.0)
}

#[cfg(all(not(feature = "std"), target_feature = "atomics"))]
fn with<R>(f: impl FnOnce(&Result<RngSource, Error>) -> R) -> R {
#[thread_local]
static RNG_SOURCE: Lazy<Result<RngSource, Error>> = Lazy::new(getrandom_init);
f(&RNG_SOURCE)
}
}

pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
RNG_SOURCE.with(|result| {
Local::with(|result| {
let source = result.as_ref().map_err(|&e| e)?;

match source {
Expand Down
10 changes: 10 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@
#![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(getrandom_sanitize, feature(cfg_sanitize))]
#![cfg_attr(
all(
getrandom_backend = "wasm_js",
target_arch = "wasm32",
any(target_os = "unknown", target_os = "none"),
not(feature = "std"),
target_feature = "atomics"
),
feature(thread_local)
)]
#![deny(
clippy::cast_lossless,
clippy::cast_possible_truncation,
Expand Down