@@ -29,15 +29,22 @@ use core::alloc::{
2929/// A page in Wasm is `64KiB`
3030const PAGE_SIZE : usize = 64 * 1024 ;
3131
32- static mut INNER : InnerAlloc = InnerAlloc :: new ( ) ;
32+ static mut INNER : Option < InnerAlloc > = None ;
3333
3434/// A bump allocator suitable for use in a Wasm environment.
3535pub struct BumpAllocator ;
3636
3737unsafe impl GlobalAlloc for BumpAllocator {
3838 #[ inline]
3939 unsafe fn alloc ( & self , layout : Layout ) -> * mut u8 {
40- match INNER . alloc ( layout) {
40+ if INNER . is_none ( ) {
41+ INNER = Some ( InnerAlloc :: new ( ) ) ;
42+ } ;
43+ match INNER
44+ . as_mut ( )
45+ . expect ( "We just set the value above; qed" )
46+ . alloc ( layout)
47+ {
4148 Some ( start) => start as * mut u8 ,
4249 None => core:: ptr:: null_mut ( ) ,
4350 }
@@ -66,7 +73,7 @@ struct InnerAlloc {
6673}
6774
6875impl InnerAlloc {
69- const fn new ( ) -> Self {
76+ fn new ( ) -> Self {
7077 Self {
7178 next : Self :: heap_start ( ) ,
7279 upper_limit : Self :: heap_end ( ) ,
@@ -75,11 +82,11 @@ impl InnerAlloc {
7582
7683 cfg_if:: cfg_if! {
7784 if #[ cfg( test) ] {
78- const fn heap_start( ) -> usize {
85+ fn heap_start( ) -> usize {
7986 0
8087 }
8188
82- const fn heap_end( ) -> usize {
89+ fn heap_end( ) -> usize {
8390 0
8491 }
8592
@@ -93,11 +100,11 @@ impl InnerAlloc {
93100 Some ( self . upper_limit)
94101 }
95102 } else if #[ cfg( feature = "std" ) ] {
96- const fn heap_start( ) -> usize {
103+ fn heap_start( ) -> usize {
97104 0
98105 }
99106
100- const fn heap_end( ) -> usize {
107+ fn heap_end( ) -> usize {
101108 0
102109 }
103110
@@ -108,12 +115,24 @@ impl InnerAlloc {
108115 )
109116 }
110117 } else if #[ cfg( target_arch = "wasm32" ) ] {
111- const fn heap_start( ) -> usize {
112- 0
118+ fn heap_start( ) -> usize {
119+ extern "C" {
120+ static __heap_base: usize ;
121+ }
122+ // # SAFETY
123+ //
124+ // The `__heap_base` symbol is defined by the wasm linker and is guaranteed
125+ // to point to the start of the heap.
126+ let heap_start = unsafe { & __heap_base as * const usize as usize } ;
127+ // if the symbol isn't found it will resolve to 0
128+ // for that to happen the rust compiler or linker need to break or change
129+ assert_ne!( heap_start, 0 , "Can't find `__heap_base` symbol." ) ;
130+ heap_start
113131 }
114132
115- const fn heap_end( ) -> usize {
116- 0
133+ fn heap_end( ) -> usize {
134+ // Cannot overflow on this architecture
135+ core:: arch:: wasm32:: memory_size( 0 ) * PAGE_SIZE
117136 }
118137
119138 /// Request a `pages` number of pages of Wasm memory. Each page is `64KiB` in size.
@@ -125,7 +144,8 @@ impl InnerAlloc {
125144 return None ;
126145 }
127146
128- prev_page. checked_mul( PAGE_SIZE )
147+ // Cannot overflow on this architecture
148+ Some ( prev_page * PAGE_SIZE )
129149 }
130150 } else if #[ cfg( target_arch = "riscv32" ) ] {
131151 const fn heap_start( ) -> usize {
0 commit comments