@@ -498,7 +498,7 @@ protected ComputedInstanceFieldLayout ComputeSequentialFieldLayout(MetadataType
498498
499499 protected ComputedInstanceFieldLayout ComputeCStructFieldLayout ( MetadataType type , int numInstanceFields )
500500 {
501- if ( type . ContainsGCPointers || ! type . IsValueType )
501+ if ( type . ContainsGCPointers || type . IsByRefLike || ! type . IsValueType )
502502 {
503503 // CStruct layout algorithm does not support GC pointers.
504504 ThrowHelper . ThrowTypeLoadException ( ExceptionStringID . ClassLoadBadFormat , type ) ;
@@ -581,6 +581,91 @@ protected ComputedInstanceFieldLayout ComputeCStructFieldLayout(MetadataType typ
581581 return computedLayout ;
582582 }
583583
584+ protected ComputedInstanceFieldLayout ComputeCUnionFieldLayout ( MetadataType type , int numInstanceFields )
585+ {
586+ if ( type . ContainsGCPointers || type . IsByRefLike || ! type . IsValueType )
587+ {
588+ // CUnion layout algorithm does not support GC pointers.
589+ ThrowHelper . ThrowTypeLoadException ( ExceptionStringID . ClassLoadBadFormat , type ) ;
590+ }
591+
592+ var offsets = new FieldAndOffset [ numInstanceFields ] ;
593+
594+ LayoutInt largestFieldSize = LayoutInt . Zero ;
595+ LayoutInt largestAlignmentRequirement = LayoutInt . One ;
596+ int fieldOrdinal = 0 ;
597+ int packingSize = type . Context . Target . MaximumAlignment ;
598+ bool layoutAbiStable = true ;
599+ bool hasAutoLayoutField = false ;
600+ bool hasInt128Field = false ;
601+ bool hasVectorTField = false ;
602+
603+ foreach ( var field in type . GetFields ( ) )
604+ {
605+ if ( field . IsStatic )
606+ continue ;
607+
608+ var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment ( field . FieldType . UnderlyingType , hasLayout : true , packingSize , out ComputedFieldData fieldData ) ;
609+ if ( ! fieldData . LayoutAbiStable )
610+ layoutAbiStable = false ;
611+ if ( fieldData . HasAutoLayout )
612+ hasAutoLayoutField = true ;
613+ if ( fieldData . HasInt128Field )
614+ hasInt128Field = true ;
615+ if ( fieldData . HasVectorTField )
616+ hasVectorTField = true ;
617+
618+ largestAlignmentRequirement = LayoutInt . Max ( fieldSizeAndAlignment . Alignment , largestAlignmentRequirement ) ;
619+ largestFieldSize = LayoutInt . Max ( fieldSizeAndAlignment . Size , largestFieldSize ) ;
620+
621+ // All fields are placed at offset 0 in a union
622+ offsets [ fieldOrdinal ] = new FieldAndOffset ( field , LayoutInt . Zero ) ;
623+
624+ fieldOrdinal ++ ;
625+ }
626+
627+ if ( hasAutoLayoutField )
628+ {
629+ // CUnion does not support auto layout fields
630+ ThrowHelper . ThrowTypeLoadException ( ExceptionStringID . ClassLoadBadFormat , type ) ;
631+ }
632+
633+ if ( largestFieldSize == LayoutInt . Zero )
634+ {
635+ // CUnion cannot have zero size.
636+ ThrowHelper . ThrowTypeLoadException ( ExceptionStringID . ClassLoadBadFormat , type ) ;
637+ }
638+
639+ if ( type . IsInlineArray )
640+ {
641+ // CUnion types cannot be inline arrays
642+ ThrowHelper . ThrowTypeLoadException ( ExceptionStringID . ClassLoadBadFormat , type ) ;
643+ }
644+
645+ SizeAndAlignment instanceByteSizeAndAlignment ;
646+ var instanceSizeAndAlignment = ComputeInstanceSize (
647+ type ,
648+ largestFieldSize ,
649+ largestAlignmentRequirement ,
650+ classLayoutSize : 0 , // CUnion does not use the size from metadata.
651+ out instanceByteSizeAndAlignment ) ;
652+
653+ ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout
654+ {
655+ IsAutoLayoutOrHasAutoLayoutFields = false ,
656+ IsInt128OrHasInt128Fields = hasInt128Field ,
657+ IsVectorTOrHasVectorTFields = hasVectorTField ,
658+ FieldAlignment = instanceSizeAndAlignment . Alignment ,
659+ FieldSize = instanceSizeAndAlignment . Size ,
660+ ByteCountUnaligned = instanceByteSizeAndAlignment . Size ,
661+ ByteCountAlignment = instanceByteSizeAndAlignment . Alignment ,
662+ Offsets = offsets ,
663+ LayoutAbiStable = layoutAbiStable
664+ } ;
665+
666+ return computedLayout ;
667+ }
668+
584669 private static void AdjustForInlineArray (
585670 MetadataType type ,
586671 int instanceFieldCount ,
0 commit comments