@@ -751,29 +751,29 @@ static inline T handleSinglePayloadEnumGenericTag(
751
751
LayoutStringReader &reader, uint8_t *addr,
752
752
std::function<std::optional<T>(const Metadata *, size_t , uint8_t )>
753
753
extraTagBytesHandler,
754
- std::function<T(const Metadata *, unsigned , unsigned )> xiHandler) {
754
+ std::function<T(const Metadata *, unsigned , unsigned , size_t , uint8_t )>
755
+ xiHandler) {
755
756
auto tagBytesAndOffset = reader.readBytes <uint64_t >();
756
757
auto extraTagBytesPattern = (uint8_t )(tagBytesAndOffset >> 62 );
757
758
auto xiTagBytesOffset =
758
759
tagBytesAndOffset & std::numeric_limits<uint32_t >::max ();
759
- const Metadata *xiType = nullptr ;
760
+ auto numExtraTagBytes = 1 << (extraTagBytesPattern - 1 );
761
+ auto payloadSize = reader.readBytes <size_t >();
762
+ auto xiType = reader.readBytes <const Metadata *>();
760
763
761
764
if (extraTagBytesPattern) {
762
- auto numExtraTagBytes = 1 << (extraTagBytesPattern - 1 );
763
- auto payloadSize = reader.readBytes <size_t >();
764
- xiType = reader.readBytes <const Metadata *>();
765
765
if (auto result =
766
766
extraTagBytesHandler (xiType, payloadSize, numExtraTagBytes)) {
767
767
return *result;
768
768
}
769
769
} else {
770
770
reader.skip (sizeof (size_t ));
771
- xiType = reader.readBytes <const Metadata *>();
772
771
}
773
772
774
773
auto numEmptyCases = reader.readBytes <unsigned >();
775
774
776
- return xiHandler (xiType, xiTagBytesOffset, numEmptyCases);
775
+ return xiHandler (xiType, xiTagBytesOffset, numEmptyCases, payloadSize,
776
+ numExtraTagBytes);
777
777
}
778
778
779
779
extern " C" unsigned
@@ -803,7 +803,8 @@ swift_singlePayloadEnumGeneric_getEnumTag(swift::OpaqueValue *address,
803
803
};
804
804
805
805
auto xihandler = [addr](const Metadata *xiType, unsigned xiTagBytesOffset,
806
- unsigned numEmptyCases) -> unsigned {
806
+ unsigned numEmptyCases, size_t payloadSize,
807
+ uint8_t numExtraTagBytes) -> unsigned {
807
808
if (xiType) {
808
809
return xiType->vw_getEnumTagSinglePayload (
809
810
(const OpaqueValue *)(addr + xiTagBytesOffset), numEmptyCases);
@@ -816,6 +817,64 @@ swift_singlePayloadEnumGeneric_getEnumTag(swift::OpaqueValue *address,
816
817
reader, addr, extraTagBytesHandler, xihandler);
817
818
}
818
819
820
+ extern " C" void swift_singlePayloadEnumGeneric_destructiveInjectEnumTag (
821
+ swift::OpaqueValue *address, unsigned tag, const Metadata *metadata) {
822
+ auto addr = reinterpret_cast <uint8_t *>(address);
823
+ LayoutStringReader reader{metadata->getLayoutString (),
824
+ layoutStringHeaderSize + sizeof (uint64_t )};
825
+
826
+ auto extraTagBytesHandler =
827
+ [=](const Metadata *xiType, size_t payloadSize,
828
+ uint8_t numExtraTagBytes) -> std::optional<bool > {
829
+ unsigned payloadNumExtraInhabitants =
830
+ xiType ? xiType->vw_getNumExtraInhabitants () : 0 ;
831
+ if (tag <= payloadNumExtraInhabitants) {
832
+ return std::nullopt;
833
+ }
834
+
835
+ unsigned noPayloadIndex = tag - 1 ;
836
+ unsigned caseIndex = noPayloadIndex - payloadNumExtraInhabitants;
837
+ unsigned payloadIndex, extraTagIndex;
838
+ if (payloadSize >= 4 ) {
839
+ extraTagIndex = 1 ;
840
+ payloadIndex = caseIndex;
841
+ } else {
842
+ unsigned payloadBits = payloadSize * 8U ;
843
+ extraTagIndex = 1U + (caseIndex >> payloadBits);
844
+ payloadIndex = caseIndex & ((1U << payloadBits) - 1U );
845
+ }
846
+
847
+ // Store into the value.
848
+ if (payloadSize)
849
+ storeEnumElement (addr, payloadIndex, payloadSize);
850
+ if (numExtraTagBytes)
851
+ storeEnumElement (addr + payloadSize, extraTagIndex, numExtraTagBytes);
852
+
853
+ return true ;
854
+ };
855
+
856
+ auto xihandler = [=](const Metadata *xiType, unsigned xiTagBytesOffset,
857
+ unsigned numEmptyCases, size_t payloadSize,
858
+ uint8_t numExtraTagBytes) -> bool {
859
+ unsigned payloadNumExtraInhabitants =
860
+ xiType ? xiType->vw_getNumExtraInhabitants () : 0 ;
861
+ if (tag <= payloadNumExtraInhabitants) {
862
+ if (numExtraTagBytes != 0 )
863
+ storeEnumElement (addr + payloadSize, 0 , numExtraTagBytes);
864
+
865
+ if (tag == 0 )
866
+ return true ;
867
+
868
+ xiType->vw_storeEnumTagSinglePayload (
869
+ (swift::OpaqueValue *)(addr + xiTagBytesOffset), tag, numEmptyCases);
870
+ }
871
+ return true ;
872
+ };
873
+
874
+ handleSinglePayloadEnumGenericTag<bool >(reader, addr, extraTagBytesHandler,
875
+ xihandler);
876
+ }
877
+
819
878
extern " C" swift::OpaqueValue *
820
879
swift_generic_initializeBufferWithCopyOfBuffer (swift::ValueBuffer *dest,
821
880
swift::ValueBuffer *src,
0 commit comments