@@ -13,7 +13,7 @@ use crate::runtime::vm::vmcontext::{
1313 VMTableDefinition , VMTableImport , VMTagDefinition , VMTagImport ,
1414} ;
1515use crate :: runtime:: vm:: {
16- GcStore , HostResult , Imports , ModuleRuntimeInfo , SendSyncPtr , VMGcRef , VMGlobalKind , VMStore ,
16+ GcStore , HostResult , Imports , ModuleRuntimeInfo , SendSyncPtr , VMGlobalKind , VMStore ,
1717 VMStoreRawPtr , VmPtr , VmSafe , WasmFault , catch_unwind_and_record_trap,
1818} ;
1919use crate :: store:: {
@@ -133,7 +133,7 @@ pub struct Instance {
133133 //
134134 // TODO(#12621): This should be a `TrySecondaryMap<PassiveElemIndex, _>`
135135 // but that type is currently footgun-y / isn't actually OOM-safe yet.
136- passive_elements : TryVec < PassiveElementSegment > ,
136+ passive_elements : TryVec < Option < ( NeedsGcRooting , TryVec < ValRaw > ) > > ,
137137
138138 /// Stores the dropped passive data segments in this instantiation by index.
139139 /// If the index is present in the set, the segment has been dropped.
@@ -225,8 +225,8 @@ impl Instance {
225225 gc_roots : & mut crate :: vm:: GcRootsList ,
226226 ) {
227227 for segment in self . passive_elements_mut ( ) . iter_mut ( ) {
228- if segment . needs_gc_rooting ( ) == NeedsGcRooting :: Yes {
229- for e in segment . elements ( ) {
228+ if let Some ( ( wasmtime_environ :: NeedsGcRooting :: Yes , elems ) ) = segment {
229+ for e in elems {
230230 let Some ( root) = e. as_vmgc_ref_ptr ( ) else {
231231 continue ;
232232 } ;
@@ -912,12 +912,16 @@ impl Instance {
912912 return & [ ] ;
913913 } ;
914914
915- self . passive_elements [ passive. index ( ) ] . elements ( )
915+ let Some ( ( _, seg) ) = & self . passive_elements [ passive. index ( ) ] else {
916+ return & [ ] ;
917+ } ;
918+
919+ & * * seg
916920 }
917921
918922 pub ( crate ) fn passive_elements_mut (
919923 self : Pin < & mut Self > ,
920- ) -> Pin < & mut TryVec < PassiveElementSegment > > {
924+ ) -> Pin < & mut TryVec < Option < ( NeedsGcRooting , TryVec < ValRaw > ) > > > {
921925 // SAFETY: Not moving data out of `self`.
922926 Pin :: new ( & mut unsafe { self . get_unchecked_mut ( ) } . passive_elements )
923927 }
@@ -992,7 +996,6 @@ impl Instance {
992996 /// Drop an element.
993997 pub ( crate ) fn elem_drop (
994998 self : Pin < & mut Self > ,
995- gc_store : Option < & mut GcStore > ,
996999 elem_index : ElemIndex ,
9971000 ) -> Result < ( ) , OutOfMemory > {
9981001 // https://webassembly.github.io/reference-types/core/exec/instructions.html#exec-elem-drop
@@ -1007,7 +1010,7 @@ impl Instance {
10071010 return Ok ( ( ) ) ;
10081011 } ;
10091012
1010- self . passive_elements_mut ( ) [ passive_index. index ( ) ] . clear ( gc_store ) ;
1013+ self . passive_elements_mut ( ) [ passive_index. index ( ) ] = None ;
10111014 Ok ( ( ) )
10121015 }
10131016
@@ -1919,77 +1922,3 @@ impl<T: InstanceLayout> Drop for OwnedInstance<T> {
19191922 }
19201923 }
19211924}
1922-
1923- #[ derive( Debug ) ]
1924- pub ( crate ) struct PassiveElementSegment {
1925- needs_gc_rooting : NeedsGcRooting ,
1926- elements : TryVec < ValRaw > ,
1927- }
1928-
1929- impl PassiveElementSegment {
1930- /// Create a new passive element segment with the given capacity.
1931- pub ( crate ) fn new (
1932- needs_gc_rooting : NeedsGcRooting ,
1933- capacity : usize ,
1934- ) -> Result < Self , OutOfMemory > {
1935- Ok ( Self {
1936- needs_gc_rooting,
1937- elements : TryVec :: with_capacity ( capacity) ?,
1938- } )
1939- }
1940-
1941- /// Push a value onto this passive element segment.
1942- ///
1943- /// NB: Does not type check the value, relies on callers to ensure the value
1944- /// is of the correct type (generally, due to validation).
1945- pub ( crate ) fn push ( & mut self , store : & mut StoreOpaque , val : Val ) -> Result < ( ) > {
1946- let val = {
1947- let mut store = AutoAssertNoGc :: new ( store) ;
1948- val. to_raw_ ( & mut store) ?
1949- } ;
1950- let val = self . clone_gc_ref ( store, val) ;
1951- self . elements . push ( val) ?;
1952- Ok ( ( ) )
1953- }
1954-
1955- fn clone_gc_ref ( & mut self , store : & mut StoreOpaque , val : ValRaw ) -> ValRaw {
1956- if let NeedsGcRooting :: Yes = self . needs_gc_rooting {
1957- let gc_ref = val. get_anyref ( ) ;
1958- if let Some ( gc_ref) = VMGcRef :: from_raw_u32 ( gc_ref) {
1959- if let Some ( gc_store) = store. optional_gc_store_mut ( ) {
1960- return ValRaw :: anyref ( gc_store. clone_gc_ref ( & gc_ref) . as_raw_u32 ( ) ) ;
1961- }
1962- }
1963- }
1964- val
1965- }
1966-
1967- /// Clear this segment's elements.
1968- pub ( crate ) fn clear ( & mut self , mut gc_store : Option < & mut GcStore > ) {
1969- for val in mem:: take ( & mut self . elements ) {
1970- self . drop_gc_ref ( & mut gc_store, val) ;
1971- }
1972- }
1973-
1974- fn drop_gc_ref ( & mut self , gc_store : & mut Option < & mut GcStore > , val : ValRaw ) {
1975- if let NeedsGcRooting :: Yes = self . needs_gc_rooting {
1976- let gc_ref = val. get_anyref ( ) ;
1977- if let Some ( gc_ref) = VMGcRef :: from_raw_u32 ( gc_ref) {
1978- if let Some ( gc_store) = gc_store. as_deref_mut ( ) {
1979- let _ = gc_store. drop_gc_ref ( gc_ref) ;
1980- }
1981- }
1982- }
1983- }
1984-
1985- /// Whether this segment needs GC rooting and tracing.
1986- #[ cfg( feature = "gc" ) ]
1987- pub ( crate ) fn needs_gc_rooting ( & self ) -> NeedsGcRooting {
1988- self . needs_gc_rooting
1989- }
1990-
1991- /// The elements of this segment.
1992- pub ( crate ) fn elements ( & self ) -> & [ ValRaw ] {
1993- & self . elements
1994- }
1995- }
0 commit comments