@@ -659,25 +659,45 @@ extern "C" unsigned swift_singletonEnum_getEnumTag(swift::OpaqueValue *address,
659659 return 0 ;
660660}
661661
662- extern " C"
663- unsigned swift_enumSimple_getEnumTag (swift::OpaqueValue *address,
664- const Metadata *metadata) {
665- auto addr = reinterpret_cast <uint8_t *>(address);
666- LayoutStringReader reader{metadata->getLayoutString (),
667- layoutStringHeaderSize + sizeof (uint64_t )};
662+ template <typename T>
663+ static inline T handleSinglePayloadEnumSimpleTag (
664+ LayoutStringReader &reader, uint8_t *addr,
665+ std::function<std::optional<T>(size_t , size_t , uint8_t )>
666+ extraTagBytesHandler,
667+ std::function<T(size_t , uint64_t , uint8_t , unsigned , size_t , uint8_t )>
668+ xiHandler) {
668669 auto byteCountsAndOffset = reader.readBytes <uint64_t >();
669670 auto extraTagBytesPattern = (uint8_t )(byteCountsAndOffset >> 62 );
670671 auto xiTagBytesPattern = ((uint8_t )(byteCountsAndOffset >> 59 )) & 0x7 ;
671672 auto xiTagBytesOffset =
672673 byteCountsAndOffset & std::numeric_limits<uint32_t >::max ();
674+ auto numExtraTagBytes = 1 << (extraTagBytesPattern - 1 );
675+ auto payloadSize = reader.readBytes <size_t >();
676+ auto zeroTagValue = reader.readBytes <uint64_t >();
677+ auto payloadNumExtraInhabitants = reader.readBytes <size_t >();
673678
674679 if (extraTagBytesPattern) {
675- auto extraTagBytes = 1 << (extraTagBytesPattern - 1 );
676- auto payloadSize = reader.readBytes <size_t >();
677- auto tagBytes = readTagBytes (addr + payloadSize, extraTagBytes);
680+ if (auto result = extraTagBytesHandler (payloadNumExtraInhabitants,
681+ payloadSize, numExtraTagBytes)) {
682+ return *result;
683+ }
684+ }
685+
686+ return xiHandler (payloadNumExtraInhabitants, zeroTagValue, xiTagBytesPattern,
687+ xiTagBytesOffset, payloadSize, numExtraTagBytes);
688+ }
689+
690+ extern " C" unsigned swift_enumSimple_getEnumTag (swift::OpaqueValue *address,
691+ const Metadata *metadata) {
692+ auto addr = reinterpret_cast <uint8_t *>(address);
693+ LayoutStringReader reader{metadata->getLayoutString (),
694+ layoutStringHeaderSize + sizeof (uint64_t )};
695+
696+ auto extraTagBytesHandler =
697+ [addr](size_t payloadNumExtraInhabitants, size_t payloadSize,
698+ uint8_t numExtraTagBytes) -> std::optional<unsigned > {
699+ auto tagBytes = readTagBytes (addr + payloadSize, numExtraTagBytes);
678700 if (tagBytes) {
679- reader.skip (sizeof (uint64_t ));
680- auto payloadNumExtraInhabitants = reader.readBytes <size_t >();
681701 unsigned caseIndexFromExtraTagBits =
682702 payloadSize >= 4 ? 0 : (tagBytes - 1U ) << (payloadSize * 8U );
683703 unsigned caseIndexFromValue = loadEnumElement (addr, payloadSize);
@@ -686,24 +706,27 @@ unsigned swift_enumSimple_getEnumTag(swift::OpaqueValue *address,
686706 payloadNumExtraInhabitants;
687707 return noPayloadIndex + 1 ;
688708 }
689- } else {
690- reader.skip (sizeof (size_t ));
691- }
692709
693- if (xiTagBytesPattern) {
694- auto zeroTagValue = reader.readBytes <uint64_t >();
695- auto xiTagValues = reader.readBytes <size_t >();
710+ return std::nullopt ;
711+ };
696712
713+ auto xihandler = [addr](size_t payloadNumExtraInhabitants,
714+ uint64_t zeroTagValue, uint8_t xiTagBytesPattern,
715+ unsigned xiTagBytesOffset, size_t payloadSize,
716+ uint8_t numExtraTagBytes) -> unsigned {
697717 auto xiTagBytes = 1 << (xiTagBytesPattern - 1 );
698718 uint64_t tagBytes =
699719 readTagBytes (addr + xiTagBytesOffset, xiTagBytes) -
700720 zeroTagValue;
701- if (tagBytes < xiTagValues ) {
721+ if (tagBytes < payloadNumExtraInhabitants ) {
702722 return tagBytes + 1 ;
703723 }
704- }
705724
706- return 0 ;
725+ return 0 ;
726+ };
727+
728+ return handleSinglePayloadEnumSimpleTag<unsigned >(
729+ reader, addr, extraTagBytesHandler, xihandler);
707730}
708731
709732extern " C"
0 commit comments