11use crate :: Trap ;
22use crate :: prelude:: * ;
3- use crate :: runtime:: vm:: { self , VMStore } ;
3+ use crate :: runtime:: vm:: { self , ExportMemory , VMStore } ;
44use crate :: store:: { StoreInstanceId , StoreOpaque , StoreResourceLimiter } ;
55use crate :: trampoline:: generate_memory_export;
66use crate :: { AsContext , AsContextMut , Engine , MemoryType , StoreContext , StoreContextMut } ;
@@ -285,7 +285,13 @@ impl Memory {
285285 limiter : Option < & mut StoreResourceLimiter < ' _ > > ,
286286 ty : MemoryType ,
287287 ) -> Result < Memory > {
288- generate_memory_export ( store, limiter, & ty, None ) . await
288+ if ty. is_shared ( ) {
289+ bail ! ( "shared memories must be created through `SharedMemory`" )
290+ }
291+ Ok ( generate_memory_export ( store, limiter, & ty, None )
292+ . await ?
293+ . unshared ( )
294+ . unwrap ( ) )
289295 }
290296
291297 /// Returns the underlying type of this memory.
@@ -638,7 +644,14 @@ impl Memory {
638644 }
639645 }
640646
641- pub ( crate ) fn from_raw ( instance : StoreInstanceId , index : DefinedMemoryIndex ) -> Memory {
647+ /// Creates a new memory from its raw component parts.
648+ ///
649+ /// # Safety
650+ ///
651+ /// The caller must ensure that the memory pointed to by `instance` and
652+ /// `index` is not a shared memory. For that `SharedMemory` must be used
653+ /// instead.
654+ pub ( crate ) unsafe fn from_raw ( instance : StoreInstanceId , index : DefinedMemoryIndex ) -> Memory {
642655 Memory { instance, index }
643656 }
644657
@@ -649,12 +662,7 @@ impl Memory {
649662 }
650663
651664 pub ( crate ) fn vmimport ( & self , store : & StoreOpaque ) -> crate :: runtime:: vm:: VMMemoryImport {
652- let instance = & store[ self . instance ] ;
653- crate :: runtime:: vm:: VMMemoryImport {
654- from : instance. memory_ptr ( self . index ) . into ( ) ,
655- vmctx : instance. vmctx ( ) . into ( ) ,
656- index : self . index ,
657- }
665+ store[ self . instance ] . get_defined_memory_vmimport ( self . index )
658666 }
659667
660668 pub ( crate ) fn comes_from_same_store ( & self , store : & StoreOpaque ) -> bool {
@@ -804,7 +812,6 @@ pub unsafe trait MemoryCreator: Send + Sync {
804812pub struct SharedMemory {
805813 vm : crate :: runtime:: vm:: SharedMemory ,
806814 engine : Engine ,
807- page_size_log2 : u8 ,
808815}
809816
810817impl SharedMemory {
@@ -820,13 +827,11 @@ impl SharedMemory {
820827
821828 let tunables = engine. tunables ( ) ;
822829 let ty = ty. wasmtime_memory ( ) ;
823- let page_size_log2 = ty. page_size_log2 ;
824830 let memory = crate :: runtime:: vm:: SharedMemory :: new ( ty, tunables) ?;
825831
826832 Ok ( Self {
827833 vm : memory,
828834 engine : engine. clone ( ) ,
829- page_size_log2,
830835 } )
831836 }
832837
@@ -838,7 +843,7 @@ impl SharedMemory {
838843 /// Returns the size, in WebAssembly pages, of this wasm memory.
839844 pub fn size ( & self ) -> u64 {
840845 let byte_size = u64:: try_from ( self . data_size ( ) ) . unwrap ( ) ;
841- let page_size = u64 :: from ( self . page_size ( ) ) ;
846+ let page_size = self . page_size ( ) ;
842847 byte_size / page_size
843848 }
844849
@@ -849,9 +854,8 @@ impl SharedMemory {
849854 /// `1`. Future extensions might allow any power of two as a page size.
850855 ///
851856 /// [the custom-page-sizes proposal]: https://github.com/WebAssembly/custom-page-sizes
852- pub fn page_size ( & self ) -> u32 {
853- debug_assert ! ( self . page_size_log2 == 0 || self . page_size_log2 == 16 ) ;
854- 1 << self . page_size_log2
857+ pub fn page_size ( & self ) -> u64 {
858+ self . ty ( ) . page_size ( )
855859 }
856860
857861 /// Returns the byte length of this memory.
@@ -912,7 +916,7 @@ impl SharedMemory {
912916 Some ( ( old_size, _new_size) ) => {
913917 // For shared memory, the `VMMemoryDefinition` is updated inside
914918 // the locked region.
915- Ok ( u64:: try_from ( old_size) . unwrap ( ) / u64 :: from ( self . page_size ( ) ) )
919+ Ok ( u64:: try_from ( old_size) . unwrap ( ) / self . page_size ( ) )
916920 }
917921 None => bail ! ( "failed to grow memory by `{delta}`" ) ,
918922 }
@@ -1010,41 +1014,22 @@ impl SharedMemory {
10101014 // Note `vm::assert_ready` shouldn't panic here because this isn't
10111015 // actually allocating any new memory (also no limiter), so resource
10121016 // limiting shouldn't kick in.
1013- vm:: assert_ready ( generate_memory_export (
1017+ let memory = vm:: assert_ready ( generate_memory_export (
10141018 store,
10151019 None ,
10161020 & self . ty ( ) ,
10171021 Some ( & self . vm ) ,
10181022 ) )
1019- . unwrap ( )
1020- . vmimport ( store)
1023+ . unwrap ( ) ;
1024+ match memory {
1025+ ExportMemory :: Unshared ( _) => unreachable ! ( ) ,
1026+ ExportMemory :: Shared ( _shared, vmimport) => vmimport,
1027+ }
10211028 }
10221029
1023- /// Create a [`SharedMemory`] from an [`ExportMemory`] definition. This
1024- /// function is available to handle the case in which a Wasm module exports
1025- /// shared memory and the user wants host-side access to it.
1026- pub ( crate ) fn from_memory ( mem : Memory , store : & StoreOpaque ) -> Self {
1027- #![ cfg_attr(
1028- not( feature = "threads" ) ,
1029- expect(
1030- unused_variables,
1031- unreachable_code,
1032- reason = "definitions cfg'd to dummy" ,
1033- )
1034- ) ]
1035-
1036- let instance = mem. instance . get ( store) ;
1037- let memory = instance. get_defined_memory ( mem. index ) ;
1038- let module = instance. env_module ( ) ;
1039- let page_size_log2 = module. memories [ module. memory_index ( mem. index ) ] . page_size_log2 ;
1040- match memory. as_shared_memory ( ) {
1041- Some ( mem) => Self {
1042- vm : mem. clone ( ) ,
1043- engine : store. engine ( ) . clone ( ) ,
1044- page_size_log2,
1045- } ,
1046- None => panic ! ( "unable to convert from a shared memory" ) ,
1047- }
1030+ /// Creates a [`SharedMemory`] from its constituent parts.
1031+ pub ( crate ) fn from_raw ( vm : crate :: runtime:: vm:: SharedMemory , engine : Engine ) -> Self {
1032+ SharedMemory { vm, engine }
10481033 }
10491034}
10501035
0 commit comments