1
1
//! Implementation for WASM based on Web and Node.js
2
2
use crate :: Error ;
3
3
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 ;
6
8
7
9
use js_sys:: { global, Function , Uint8Array } ;
8
10
use wasm_bindgen:: { prelude:: wasm_bindgen, JsCast , JsValue } ;
@@ -20,14 +22,17 @@ enum RngSource {
20
22
21
23
// JsValues are always per-thread, so we initialize RngSource for each thread.
22
24
// See: https://github.com/rustwasm/wasm-bindgen/pull/955
23
- thread_local ! (
25
+ #[ cfg( std) ]
26
+ std:: thread_local!(
24
27
static RNG_SOURCE : Result <RngSource , Error > = getrandom_init( ) ;
25
28
) ;
26
29
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 ) ;
30
33
34
+ pub ( crate ) fn getrandom_inner ( dest : & mut [ MaybeUninit < u8 > ] ) -> Result < ( ) , Error > {
35
+ let mut getrandom_impl = |source : & RngSource | {
31
36
match source {
32
37
RngSource :: Node ( n) => {
33
38
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>
64
69
}
65
70
}
66
71
} ;
72
+
67
73
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) ?)
68
90
} )
69
91
}
70
92
0 commit comments