@@ -746,6 +746,41 @@ swift_multiPayloadEnumGeneric_getEnumTag(swift::OpaqueValue *address,
746746 }
747747}
748748
749+ extern " C" void swift_multiPayloadEnumGeneric_destructiveInjectEnumTag (
750+ swift::OpaqueValue *address, unsigned tag, const Metadata *metadata) {
751+ auto addr = reinterpret_cast <uint8_t *>(address);
752+ LayoutStringReader reader{metadata->getLayoutString (),
753+ layoutStringHeaderSize + sizeof (uint64_t )};
754+
755+ auto numTagBytes = reader.readBytes <size_t >();
756+ auto numPayloads = reader.readBytes <size_t >();
757+ reader.skip (sizeof (size_t ));
758+ auto enumSize = reader.readBytes <size_t >();
759+ auto payloadSize = enumSize - numTagBytes;
760+
761+ if (tag < numPayloads) {
762+ // For a payload case, store the tag after the payload area.
763+ auto tagBytes = addr + payloadSize;
764+ storeEnumElement (tagBytes, tag, numTagBytes);
765+ } else {
766+ // For an empty case, factor out the parts that go in the payload and
767+ // tag areas.
768+ unsigned whichEmptyCase = tag - numPayloads;
769+ unsigned whichTag, whichPayloadValue;
770+ if (payloadSize >= 4 ) {
771+ whichTag = numPayloads;
772+ whichPayloadValue = whichEmptyCase;
773+ } else {
774+ unsigned numPayloadBits = payloadSize * CHAR_BIT;
775+ whichTag = numPayloads + (whichEmptyCase >> numPayloadBits);
776+ whichPayloadValue = whichEmptyCase & ((1U << numPayloadBits) - 1U );
777+ }
778+ auto tagBytes = addr + payloadSize;
779+ storeEnumElement (tagBytes, whichTag, numTagBytes);
780+ storeEnumElement (addr, whichPayloadValue, payloadSize);
781+ }
782+ }
783+
749784template <typename T>
750785static inline T handleSinglePayloadEnumGenericTag (
751786 LayoutStringReader &reader, uint8_t *addr,
0 commit comments