@@ -16,10 +16,13 @@ pub mod drc;
1616pub mod null;
1717
1818use crate :: {
19- WasmArrayType , WasmCompositeInnerType , WasmCompositeType , WasmStorageType , WasmStructType ,
20- WasmValType ,
19+ WasmArrayType , WasmCompositeInnerType , WasmCompositeType , WasmExnType , WasmStorageType ,
20+ WasmStructType , WasmValType ,
21+ collections:: { self , TryClone } ,
22+ error:: OutOfMemory ,
23+ prelude:: * ,
2124} ;
22- use crate :: { WasmExnType , prelude :: * } ;
25+ use alloc :: sync :: Arc ;
2326use core:: alloc:: Layout ;
2427
2528/// Discriminant to check whether GC reference is an `i31ref` or not.
@@ -122,7 +125,9 @@ fn common_struct_or_exn_layout(
122125 fields : & [ crate :: WasmFieldType ] ,
123126 header_size : u32 ,
124127 header_align : u32 ,
125- ) -> ( u32 , u32 , Vec < GcStructLayoutField > ) {
128+ ) -> ( u32 , u32 , collections:: Vec < GcStructLayoutField > ) {
129+ use crate :: PanicOnOom as _;
130+
126131 // Process each field, aligning it to its natural alignment.
127132 //
128133 // We don't try and do any fancy field reordering to minimize padding (yet?)
@@ -143,7 +148,8 @@ fn common_struct_or_exn_layout(
143148 let is_gc_ref = f. element_type . is_vmgcref_type_and_not_i31 ( ) ;
144149 GcStructLayoutField { offset, is_gc_ref }
145150 } )
146- . collect ( ) ;
151+ . try_collect :: < collections:: Vec < _ > , _ > ( )
152+ . panic_on_oom ( ) ;
147153
148154 // Ensure that the final size is a multiple of the alignment, for
149155 // simplicity.
@@ -228,12 +234,12 @@ pub trait GcTypeLayouts {
228234 assert ! ( !ty. shared) ;
229235 match & ty. inner {
230236 WasmCompositeInnerType :: Array ( ty) => Some ( self . array_layout ( ty) . into ( ) ) ,
231- WasmCompositeInnerType :: Struct ( ty) => Some ( self . struct_layout ( ty) . into ( ) ) ,
237+ WasmCompositeInnerType :: Struct ( ty) => Some ( Arc :: new ( self . struct_layout ( ty) ) . into ( ) ) ,
232238 WasmCompositeInnerType :: Func ( _) => None ,
233239 WasmCompositeInnerType :: Cont ( _) => {
234240 unimplemented ! ( "Stack switching feature not compatible with GC, yet" )
235241 }
236- WasmCompositeInnerType :: Exn ( ty) => Some ( self . exn_layout ( ty) . into ( ) ) ,
242+ WasmCompositeInnerType :: Exn ( ty) => Some ( Arc :: new ( self . exn_layout ( ty) ) . into ( ) ) ,
237243 }
238244 }
239245
@@ -254,7 +260,7 @@ pub enum GcLayout {
254260 Array ( GcArrayLayout ) ,
255261
256262 /// The layout of a GC-managed struct or exception object.
257- Struct ( GcStructLayout ) ,
263+ Struct ( Arc < GcStructLayout > ) ,
258264}
259265
260266impl From < GcArrayLayout > for GcLayout {
@@ -263,16 +269,22 @@ impl From<GcArrayLayout> for GcLayout {
263269 }
264270}
265271
266- impl From < GcStructLayout > for GcLayout {
267- fn from ( layout : GcStructLayout ) -> Self {
272+ impl From < Arc < GcStructLayout > > for GcLayout {
273+ fn from ( layout : Arc < GcStructLayout > ) -> Self {
268274 Self :: Struct ( layout)
269275 }
270276}
271277
278+ impl TryClone for GcLayout {
279+ fn try_clone ( & self ) -> core:: result:: Result < Self , wasmtime_core:: error:: OutOfMemory > {
280+ Ok ( self . clone ( ) )
281+ }
282+ }
283+
272284impl GcLayout {
273285 /// Get the underlying `GcStructLayout`, or panic.
274286 #[ track_caller]
275- pub fn unwrap_struct ( & self ) -> & GcStructLayout {
287+ pub fn unwrap_struct ( & self ) -> & Arc < GcStructLayout > {
276288 match self {
277289 Self :: Struct ( s) => s,
278290 _ => panic ! ( "GcLayout::unwrap_struct on non-struct GC layout" ) ,
@@ -368,12 +380,23 @@ pub struct GcStructLayout {
368380
369381 /// The fields of this struct. The `i`th entry contains information about
370382 /// the `i`th struct field's layout.
371- pub fields : Vec < GcStructLayoutField > ,
383+ pub fields : collections :: Vec < GcStructLayoutField > ,
372384
373385 /// Whether this is an exception object layout.
374386 pub is_exception : bool ,
375387}
376388
389+ impl TryClone for GcStructLayout {
390+ fn try_clone ( & self ) -> Result < Self , OutOfMemory > {
391+ Ok ( GcStructLayout {
392+ size : self . size ,
393+ align : self . align ,
394+ fields : self . fields . try_clone ( ) ?,
395+ is_exception : self . is_exception ,
396+ } )
397+ }
398+ }
399+
377400impl GcStructLayout {
378401 /// Get a `core::alloc::Layout` for a struct of this type.
379402 pub fn layout ( & self ) -> Layout {
@@ -397,6 +420,12 @@ pub struct GcStructLayoutField {
397420 pub is_gc_ref : bool ,
398421}
399422
423+ impl TryClone for GcStructLayoutField {
424+ fn try_clone ( & self ) -> Result < Self , OutOfMemory > {
425+ Ok ( * self )
426+ }
427+ }
428+
400429/// The kind of an object in a GC heap.
401430///
402431/// Note that this type is accessed from Wasm JIT code.
0 commit comments