@@ -659,25 +659,45 @@ extern "C" unsigned swift_singletonEnum_getEnumTag(swift::OpaqueValue *address,
659
659
return 0 ;
660
660
}
661
661
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) {
668
669
auto byteCountsAndOffset = reader.readBytes <uint64_t >();
669
670
auto extraTagBytesPattern = (uint8_t )(byteCountsAndOffset >> 62 );
670
671
auto xiTagBytesPattern = ((uint8_t )(byteCountsAndOffset >> 59 )) & 0x7 ;
671
672
auto xiTagBytesOffset =
672
673
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 >();
673
678
674
679
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);
678
700
if (tagBytes) {
679
- reader.skip (sizeof (uint64_t ));
680
- auto payloadNumExtraInhabitants = reader.readBytes <size_t >();
681
701
unsigned caseIndexFromExtraTagBits =
682
702
payloadSize >= 4 ? 0 : (tagBytes - 1U ) << (payloadSize * 8U );
683
703
unsigned caseIndexFromValue = loadEnumElement (addr, payloadSize);
@@ -686,24 +706,27 @@ unsigned swift_enumSimple_getEnumTag(swift::OpaqueValue *address,
686
706
payloadNumExtraInhabitants;
687
707
return noPayloadIndex + 1 ;
688
708
}
689
- } else {
690
- reader.skip (sizeof (size_t ));
691
- }
692
709
693
- if (xiTagBytesPattern) {
694
- auto zeroTagValue = reader.readBytes <uint64_t >();
695
- auto xiTagValues = reader.readBytes <size_t >();
710
+ return std::nullopt;
711
+ };
696
712
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 {
697
717
auto xiTagBytes = 1 << (xiTagBytesPattern - 1 );
698
718
uint64_t tagBytes =
699
719
readTagBytes (addr + xiTagBytesOffset, xiTagBytes) -
700
720
zeroTagValue;
701
- if (tagBytes < xiTagValues ) {
721
+ if (tagBytes < payloadNumExtraInhabitants ) {
702
722
return tagBytes + 1 ;
703
723
}
704
- }
705
724
706
- return 0 ;
725
+ return 0 ;
726
+ };
727
+
728
+ return handleSinglePayloadEnumSimpleTag<unsigned >(
729
+ reader, addr, extraTagBytesHandler, xihandler);
707
730
}
708
731
709
732
extern " C"
0 commit comments