11//! Implementation for WASM based on Web and Node.js
22use crate :: Error ;
33
4- extern crate std;
5- use std:: { mem:: MaybeUninit , thread_local} ;
4+ use core:: mem:: MaybeUninit ;
5+
6+ #[ cfg( not( std) ) ]
7+ use core:: cell:: RefCell ;
68
79use js_sys:: { global, Function , Uint8Array } ;
810use wasm_bindgen:: { prelude:: wasm_bindgen, JsCast , JsValue } ;
@@ -20,14 +22,17 @@ enum RngSource {
2022
2123// JsValues are always per-thread, so we initialize RngSource for each thread.
2224// See: https://github.com/rustwasm/wasm-bindgen/pull/955
23- thread_local ! (
25+ #[ cfg( std) ]
26+ std:: thread_local!(
2427 static RNG_SOURCE : Result <RngSource , Error > = getrandom_init( ) ;
2528) ;
2629
27- pub ( crate ) fn getrandom_inner ( dest : & mut [ MaybeUninit < u8 > ] ) -> Result < ( ) , Error > {
28- RNG_SOURCE . with ( |result| {
29- let source = result . as_ref ( ) . map_err ( | & e| e ) ? ;
30+ # [ cfg ( not ( std ) ) ]
31+ # [ thread_local ]
32+ static RNG_SOURCE : RefCell < Option < RngSource > > = RefCell :: new ( None ) ;
3033
34+ pub ( crate ) fn getrandom_inner ( dest : & mut [ MaybeUninit < u8 > ] ) -> Result < ( ) , Error > {
35+ let mut getrandom_impl = |source : & RngSource | {
3136 match source {
3237 RngSource :: Node ( n) => {
3338 for chunk in dest. chunks_mut ( NODE_MAX_BUFFER_SIZE ) {
@@ -64,7 +69,24 @@ pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>
6469 }
6570 }
6671 } ;
72+
6773 Ok ( ( ) )
74+ } ;
75+
76+ #[ cfg( not( std) ) ]
77+ {
78+ if RNG_SOURCE . borrow ( ) . is_none ( ) {
79+ let rng_source = getrandom_init ( ) ?;
80+ * RNG_SOURCE . borrow_mut ( ) = Some ( rng_source) ;
81+ }
82+
83+ let binding = RNG_SOURCE . borrow ( ) ;
84+ getrandom_impl ( binding. as_ref ( ) . expect ( "initialized above" ) )
85+ }
86+
87+ #[ cfg( std) ]
88+ RNG_SOURCE . with ( |result| {
89+ getrandom_impl ( result. as_ref ( ) . map_err ( |& e| e) ?)
6890 } )
6991}
7092
0 commit comments