1
1
//! Implementation for WASM based on Web and Node.js
2
2
use crate :: Error ;
3
3
4
+ #[ cfg( feature = "std" ) ]
4
5
extern crate std;
5
- use std :: { mem:: MaybeUninit , thread_local } ;
6
+ use core :: mem:: MaybeUninit ;
6
7
7
8
pub use crate :: util:: { inner_u32, inner_u64} ;
8
9
@@ -13,6 +14,8 @@ pub use crate::util::{inner_u32, inner_u64};
13
14
compile_error ! ( "`wasm_js` backend can be enabled only for OS-less WASM targets!" ) ;
14
15
15
16
use js_sys:: { global, Function , Uint8Array } ;
17
+ #[ cfg( not( feature = "std" ) ) ]
18
+ use once_cell:: unsync:: Lazy ;
16
19
use wasm_bindgen:: { prelude:: wasm_bindgen, JsCast , JsValue } ;
17
20
18
21
// Size of our temporary Uint8Array buffer used with WebCrypto methods
@@ -28,12 +31,37 @@ enum RngSource {
28
31
29
32
// JsValues are always per-thread, so we initialize RngSource for each thread.
30
33
// See: https://github.com/rustwasm/wasm-bindgen/pull/955
31
- thread_local ! (
32
- static RNG_SOURCE : Result <RngSource , Error > = getrandom_init( ) ;
33
- ) ;
34
+ struct Local ;
35
+
36
+ impl Local {
37
+ #[ cfg( feature = "std" ) ]
38
+ fn with < R > ( f : impl FnOnce ( & Result < RngSource , Error > ) -> R ) -> R {
39
+ std:: thread_local!(
40
+ static RNG_SOURCE : Result <RngSource , Error > = getrandom_init( ) ;
41
+ ) ;
42
+ RNG_SOURCE . with ( f)
43
+ }
44
+
45
+ #[ cfg( all( not( feature = "std" ) , not( target_feature = "atomics" ) ) ) ]
46
+ fn with < R > ( f : impl FnOnce ( & Result < RngSource , Error > ) -> R ) -> R {
47
+ struct Wrapper < T > ( T ) ;
48
+ unsafe impl < T > Send for Wrapper < T > { }
49
+ unsafe impl < T > Sync for Wrapper < T > { }
50
+ static RNG_SOURCE : Wrapper < Lazy < Result < RngSource , Error > > > =
51
+ Wrapper ( Lazy :: new ( getrandom_init) ) ;
52
+ f ( & RNG_SOURCE . 0 )
53
+ }
54
+
55
+ #[ cfg( all( not( feature = "std" ) , target_feature = "atomics" ) ) ]
56
+ fn with < R > ( f : impl FnOnce ( & Result < RngSource , Error > ) -> R ) -> R {
57
+ #[ thread_local]
58
+ static RNG_SOURCE : Lazy < Result < RngSource , Error > > = Lazy :: new ( getrandom_init) ;
59
+ f ( & RNG_SOURCE )
60
+ }
61
+ }
34
62
35
63
pub fn fill_inner ( dest : & mut [ MaybeUninit < u8 > ] ) -> Result < ( ) , Error > {
36
- RNG_SOURCE . with ( |result| {
64
+ Local :: with ( |result| {
37
65
let source = result. as_ref ( ) . map_err ( |& e| e) ?;
38
66
39
67
match source {
0 commit comments