@@ -729,6 +729,62 @@ extern "C" unsigned swift_enumSimple_getEnumTag(swift::OpaqueValue *address,
729
729
reader, addr, extraTagBytesHandler, xihandler);
730
730
}
731
731
732
+ extern " C" void swift_enumSimple_destructiveInjectEnumTag (
733
+ swift::OpaqueValue *address, unsigned tag, const Metadata *metadata) {
734
+ auto addr = reinterpret_cast <uint8_t *>(address);
735
+ LayoutStringReader reader{metadata->getLayoutString (),
736
+ layoutStringHeaderSize + sizeof (uint64_t )};
737
+
738
+ auto extraTagBytesHandler =
739
+ [addr, tag](size_t payloadNumExtraInhabitants, size_t payloadSize,
740
+ uint8_t numExtraTagBytes) -> std::optional<bool > {
741
+ if (tag <= payloadNumExtraInhabitants) {
742
+ return std::nullopt;
743
+ }
744
+
745
+ unsigned noPayloadIndex = tag - 1 ;
746
+ unsigned caseIndex = noPayloadIndex - payloadNumExtraInhabitants;
747
+ unsigned payloadIndex, extraTagIndex;
748
+ if (payloadSize >= 4 ) {
749
+ extraTagIndex = 1 ;
750
+ payloadIndex = caseIndex;
751
+ } else {
752
+ unsigned payloadBits = payloadSize * 8U ;
753
+ extraTagIndex = 1U + (caseIndex >> payloadBits);
754
+ payloadIndex = caseIndex & ((1U << payloadBits) - 1U );
755
+ }
756
+
757
+ // Store into the value.
758
+ if (payloadSize)
759
+ storeEnumElement (addr, payloadIndex, payloadSize);
760
+ if (numExtraTagBytes)
761
+ storeEnumElement (addr + payloadSize, extraTagIndex, numExtraTagBytes);
762
+
763
+ return true ;
764
+ };
765
+
766
+ auto xihandler = [addr, tag](size_t payloadNumExtraInhabitants,
767
+ uint64_t zeroTagValue, uint8_t xiTagBytesPattern,
768
+ unsigned xiTagBytesOffset, size_t payloadSize,
769
+ uint8_t numExtraTagBytes) -> bool {
770
+ auto xiTagBytes = 1 << (xiTagBytesPattern - 1 );
771
+ if (tag <= payloadNumExtraInhabitants) {
772
+ if (numExtraTagBytes != 0 )
773
+ storeEnumElement (addr + payloadSize, 0 , numExtraTagBytes);
774
+
775
+ if (tag == 0 )
776
+ return true ;
777
+
778
+ storeEnumElement (addr + xiTagBytesOffset, tag - 1 + zeroTagValue,
779
+ xiTagBytes);
780
+ }
781
+ return true ;
782
+ };
783
+
784
+ handleSinglePayloadEnumSimpleTag<bool >(reader, addr, extraTagBytesHandler,
785
+ xihandler);
786
+ }
787
+
732
788
extern " C"
733
789
unsigned swift_enumFn_getEnumTag (swift::OpaqueValue *address,
734
790
const Metadata *metadata) {
0 commit comments