@@ -751,29 +751,29 @@ static inline T handleSinglePayloadEnumGenericTag(
751751 LayoutStringReader &reader, uint8_t *addr,
752752 std::function<std::optional<T>(const Metadata *, size_t , uint8_t )>
753753 extraTagBytesHandler,
754- std::function<T(const Metadata *, unsigned , unsigned )> xiHandler) {
754+ std::function<T(const Metadata *, unsigned , unsigned , size_t , uint8_t )>
755+ xiHandler) {
755756 auto tagBytesAndOffset = reader.readBytes <uint64_t >();
756757 auto extraTagBytesPattern = (uint8_t )(tagBytesAndOffset >> 62 );
757758 auto xiTagBytesOffset =
758759 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 *>();
760763
761764 if (extraTagBytesPattern) {
762- auto numExtraTagBytes = 1 << (extraTagBytesPattern - 1 );
763- auto payloadSize = reader.readBytes <size_t >();
764- xiType = reader.readBytes <const Metadata *>();
765765 if (auto result =
766766 extraTagBytesHandler (xiType, payloadSize, numExtraTagBytes)) {
767767 return *result;
768768 }
769769 } else {
770770 reader.skip (sizeof (size_t ));
771- xiType = reader.readBytes <const Metadata *>();
772771 }
773772
774773 auto numEmptyCases = reader.readBytes <unsigned >();
775774
776- return xiHandler (xiType, xiTagBytesOffset, numEmptyCases);
775+ return xiHandler (xiType, xiTagBytesOffset, numEmptyCases, payloadSize,
776+ numExtraTagBytes);
777777}
778778
779779extern " C" unsigned
@@ -803,7 +803,8 @@ swift_singlePayloadEnumGeneric_getEnumTag(swift::OpaqueValue *address,
803803 };
804804
805805 auto xihandler = [addr](const Metadata *xiType, unsigned xiTagBytesOffset,
806- unsigned numEmptyCases) -> unsigned {
806+ unsigned numEmptyCases, size_t payloadSize,
807+ uint8_t numExtraTagBytes) -> unsigned {
807808 if (xiType) {
808809 return xiType->vw_getEnumTagSinglePayload (
809810 (const OpaqueValue *)(addr + xiTagBytesOffset), numEmptyCases);
@@ -816,6 +817,64 @@ swift_singlePayloadEnumGeneric_getEnumTag(swift::OpaqueValue *address,
816817 reader, addr, extraTagBytesHandler, xihandler);
817818}
818819
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+
819878extern " C" swift::OpaqueValue *
820879swift_generic_initializeBufferWithCopyOfBuffer (swift::ValueBuffer *dest,
821880 swift::ValueBuffer *src,
0 commit comments