Skip to content

Commit

Permalink
adjust to no_std environments
Browse files Browse the repository at this point in the history
  • Loading branch information
gshep committed Feb 13, 2024
1 parent d102c36 commit 752f8d2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ js-sys = { version = "0.3", optional = true }
wasm-bindgen-test = "0.3.18"

[features]
default = ["std"]
# Implement std-only traits for getrandom::Error
std = []
# Feature to enable fallback RDRAND-based implementation on x86/x86_64
Expand Down
34 changes: 28 additions & 6 deletions src/js.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! Implementation for WASM based on Web and Node.js
use crate::Error;

extern crate std;
use std::{mem::MaybeUninit, thread_local};
use core::mem::MaybeUninit;

#[cfg(not(std))]
use core::cell::RefCell;

use js_sys::{global, Function, Uint8Array};
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
Expand All @@ -20,14 +22,17 @@ 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!(
#[cfg(std)]
std::thread_local!(
static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
);

pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
RNG_SOURCE.with(|result| {
let source = result.as_ref().map_err(|&e| e)?;
#[cfg(not(std))]
#[thread_local]
static RNG_SOURCE: RefCell<Option<RngSource>> = RefCell::new(None);

pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let mut getrandom_impl = |source: &RngSource| {
match source {
RngSource::Node(n) => {
for chunk in dest.chunks_mut(NODE_MAX_BUFFER_SIZE) {
Expand Down Expand Up @@ -64,7 +69,24 @@ pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>
}
}
};

Ok(())
};

#[cfg(not(std))]
{
if RNG_SOURCE.borrow().is_none() {
let rng_source = getrandom_init()?;
*RNG_SOURCE.borrow_mut() = Some(rng_source);
}

let binding = RNG_SOURCE.borrow();
getrandom_impl(binding.as_ref().expect("initialized above"))
}

#[cfg(std)]
RNG_SOURCE.with(|result| {
getrandom_impl(result.as_ref().map_err(|&e| e)?)
})
}

Expand Down
9 changes: 8 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,16 @@
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
html_root_url = "https://docs.rs/getrandom/0.2.12"
)]
#![no_std]
#![cfg_attr(not(std), no_std)]
#![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(
all(not(std),
feature = "js",
any(target_arch = "wasm32", target_arch = "wasm64"),
target_os = "unknown"),
feature(thread_local)
)]

#[macro_use]
extern crate cfg_if;
Expand Down

0 comments on commit 752f8d2

Please sign in to comment.