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