@@ -175,30 +175,30 @@ fn common_struct_layout(
175175 size,
176176 align,
177177 fields,
178+ is_exception : false ,
178179 }
179180}
180181
181182/// Common code to define a GC exception object's layout, given the
182183/// size and alignment of the collector's GC header and its expected
183184/// offset of the array length field.
184185#[ cfg( any( feature = "gc-null" , feature = "gc-drc" ) ) ]
185- fn common_exn_layout ( ty : & WasmExnType , header_size : u32 , header_align : u32 ) -> GcExceptionLayout {
186+ fn common_exn_layout ( ty : & WasmExnType , header_size : u32 , header_align : u32 ) -> GcStructLayout {
186187 assert ! ( header_size >= crate :: VM_GC_HEADER_SIZE ) ;
187188 assert ! ( header_align >= crate :: VM_GC_HEADER_ALIGN ) ;
188189
189190 // Compute a struct layout, with extra header size for the
190191 // `(instance_idx, tag_idx)` fields.
191- let tag_offset = header_size;
192192 assert ! ( header_align >= 8 ) ;
193193 let header_size = header_size + 2 * u32:: try_from ( core:: mem:: size_of :: < u32 > ( ) ) . unwrap ( ) ;
194194
195195 let ( size, align, fields) = common_struct_or_exn_layout ( & ty. fields , header_size, header_align) ;
196196
197- GcExceptionLayout {
197+ GcStructLayout {
198198 size,
199199 align,
200- tag_offset,
201200 fields,
201+ is_exception : true ,
202202 }
203203}
204204
@@ -211,6 +211,12 @@ pub trait GcTypeLayouts {
211211 /// element type.
212212 fn array_length_field_offset ( & self ) -> u32 ;
213213
214+ /// The offset of an exception object's tag reference.
215+ ///
216+ /// This msut be the same for all exception objects in the heap,
217+ /// regardless of their specific signature.
218+ fn exception_tag_offset ( & self ) -> u32 ;
219+
214220 /// Get this collector's layout for the given composite type.
215221 ///
216222 /// Returns `None` if the type is a function type, as functions are not
@@ -235,7 +241,7 @@ pub trait GcTypeLayouts {
235241 fn struct_layout ( & self , ty : & WasmStructType ) -> GcStructLayout ;
236242
237243 /// Get this collector's layout for the given exception type.
238- fn exn_layout ( & self , ty : & WasmExnType ) -> GcExceptionLayout ;
244+ fn exn_layout ( & self , ty : & WasmExnType ) -> GcStructLayout ;
239245}
240246
241247/// The layout of a GC-managed object.
@@ -244,11 +250,8 @@ pub enum GcLayout {
244250 /// The layout of a GC-managed array object.
245251 Array ( GcArrayLayout ) ,
246252
247- /// The layout of a GC-managed struct object.
253+ /// The layout of a GC-managed struct or exception object.
248254 Struct ( GcStructLayout ) ,
249-
250- /// The layout of a GC-managed exception object.
251- Exception ( GcExceptionLayout ) ,
252255}
253256
254257impl From < GcArrayLayout > for GcLayout {
@@ -263,12 +266,6 @@ impl From<GcStructLayout> for GcLayout {
263266 }
264267}
265268
266- impl From < GcExceptionLayout > for GcLayout {
267- fn from ( layout : GcExceptionLayout ) -> Self {
268- Self :: Exception ( layout)
269- }
270- }
271-
272269impl GcLayout {
273270 /// Get the underlying `GcStructLayout`, or panic.
274271 #[ track_caller]
@@ -287,15 +284,6 @@ impl GcLayout {
287284 _ => panic ! ( "GcLayout::unwrap_array on non-array GC layout" ) ,
288285 }
289286 }
290-
291- /// Get the underlying `GcExceptionLayout`, or panic.
292- #[ track_caller]
293- pub fn unwrap_exception ( & self ) -> & GcExceptionLayout {
294- match self {
295- Self :: Exception ( e) => e,
296- _ => panic ! ( "GcLayout::unwrap_exception on a non-exception GC layout" ) ,
297- }
298- }
299287}
300288
301289/// The layout of a GC-managed array.
@@ -352,7 +340,7 @@ impl GcArrayLayout {
352340 }
353341}
354342
355- /// The layout for a GC-managed struct type.
343+ /// The layout for a GC-managed struct type or exception type .
356344///
357345/// This layout is only valid for use with the GC runtime that created it. It is
358346/// not valid to use one GC runtime's layout with another GC runtime, doing so
@@ -361,6 +349,12 @@ impl GcArrayLayout {
361349///
362350/// All offsets are from the start of the object; that is, the size of the GC
363351/// header (for example) is included in the offset.
352+ ///
353+ /// Note that these are reused between structs and exceptions to avoid
354+ /// unnecessary code duplication. In both cases, the objects are
355+ /// tuples of typed fields with a certain size. The only difference in
356+ /// practice is that an exception object also carries a tag reference
357+ /// (at a fixed offset as per `GcTypeLayouts::exception_tag_offset`).
364358#[ derive( Clone , Debug ) ]
365359pub struct GcStructLayout {
366360 /// The size (in bytes) of this struct.
@@ -372,6 +366,9 @@ pub struct GcStructLayout {
372366 /// The fields of this struct. The `i`th entry contains information about
373367 /// the `i`th struct field's layout.
374368 pub fields : Vec < GcStructLayoutField > ,
369+
370+ /// Whether this is an exception object layout.
371+ pub is_exception : bool ,
375372}
376373
377374impl GcStructLayout {
@@ -397,41 +394,6 @@ pub struct GcStructLayoutField {
397394 pub is_gc_ref : bool ,
398395}
399396
400- /// The layout for a GC-managed exception object.
401- ///
402- /// This layout is only valid for use with the GC runtime that created it. It is
403- /// not valid to use one GC runtime's layout with another GC runtime, doing so
404- /// is memory safe but will lead to general incorrectness like panics and wrong
405- /// results.
406- ///
407- /// All offsets are from the start of the object; that is, the size of the GC
408- /// header (for example) is included in the offset.
409- #[ derive( Clone , Debug ) ]
410- pub struct GcExceptionLayout {
411- /// The size (in bytes) of this struct.
412- pub size : u32 ,
413-
414- /// The alignment (in bytes) of this struct.
415- pub align : u32 ,
416-
417- /// The offset of the VMTagImport pointer.
418- pub tag_offset : u32 ,
419-
420- /// The fields of this exception object. The `i`th entry contains
421- /// information about the `i`th parameter in the associated tag
422- /// type.
423- pub fields : Vec < GcStructLayoutField > ,
424- }
425-
426- impl GcExceptionLayout {
427- /// Get a `core::alloc::Layout` for an exception object of this type.
428- pub fn layout ( & self ) -> Layout {
429- let size = usize:: try_from ( self . size ) . unwrap ( ) ;
430- let align = usize:: try_from ( self . align ) . unwrap ( ) ;
431- Layout :: from_size_align ( size, align) . unwrap ( )
432- }
433- }
434-
435397/// The kind of an object in a GC heap.
436398///
437399/// Note that this type is accessed from Wasm JIT code.
0 commit comments