26
26
#include " swift/Runtime/HeapObject.h"
27
27
#include " llvm/Support/SwapByteOrder.h"
28
28
#include < cstdint>
29
+ #include < functional>
29
30
#include < limits>
31
+ #include < optional>
30
32
#include < type_traits>
31
33
#if SWIFT_OBJC_INTEROP
32
34
#include " swift/Runtime/ObjCBridge.h"
@@ -744,25 +746,48 @@ swift_multiPayloadEnumGeneric_getEnumTag(swift::OpaqueValue *address,
744
746
}
745
747
}
746
748
747
- extern " C" unsigned
748
- swift_singlePayloadEnumGeneric_getEnumTag (swift::OpaqueValue *address,
749
- const Metadata *metadata) {
750
- auto addr = reinterpret_cast <const uint8_t *>(address);
751
- LayoutStringReader reader{metadata->getLayoutString (),
752
- layoutStringHeaderSize + sizeof (uint64_t )};
753
-
749
+ template <typename T>
750
+ static inline T handleSinglePayloadEnumGenericTag (
751
+ LayoutStringReader &reader, uint8_t *addr,
752
+ std::function<std::optional<T>(const Metadata *, size_t , uint8_t )>
753
+ extraTagBytesHandler,
754
+ std::function<T(const Metadata *, unsigned , unsigned )> xiHandler) {
754
755
auto tagBytesAndOffset = reader.readBytes <uint64_t >();
755
756
auto extraTagBytesPattern = (uint8_t )(tagBytesAndOffset >> 62 );
756
757
auto xiTagBytesOffset =
757
758
tagBytesAndOffset & std::numeric_limits<uint32_t >::max ();
758
759
const Metadata *xiType = nullptr ;
759
760
760
761
if (extraTagBytesPattern) {
761
- auto extraTagBytes = 1 << (extraTagBytesPattern - 1 );
762
+ auto numExtraTagBytes = 1 << (extraTagBytesPattern - 1 );
762
763
auto payloadSize = reader.readBytes <size_t >();
763
- auto tagBytes = readTagBytes (addr + payloadSize, extraTagBytes);
764
+ xiType = reader.readBytes <const Metadata *>();
765
+ if (auto result =
766
+ extraTagBytesHandler (xiType, payloadSize, numExtraTagBytes)) {
767
+ return *result;
768
+ }
769
+ } else {
770
+ reader.skip (sizeof (size_t ));
771
+ xiType = reader.readBytes <const Metadata *>();
772
+ }
773
+
774
+ auto numEmptyCases = reader.readBytes <unsigned >();
775
+
776
+ return xiHandler (xiType, xiTagBytesOffset, numEmptyCases);
777
+ }
778
+
779
+ extern " C" unsigned
780
+ swift_singlePayloadEnumGeneric_getEnumTag (swift::OpaqueValue *address,
781
+ const Metadata *metadata) {
782
+ auto addr = reinterpret_cast <uint8_t *>(address);
783
+ LayoutStringReader reader{metadata->getLayoutString (),
784
+ layoutStringHeaderSize + sizeof (uint64_t )};
785
+
786
+ auto extraTagBytesHandler =
787
+ [addr](const Metadata *xiType, size_t payloadSize,
788
+ uint8_t numExtraTagBytes) -> std::optional<unsigned > {
789
+ auto tagBytes = readTagBytes (addr + payloadSize, numExtraTagBytes);
764
790
if (tagBytes) {
765
- xiType = reader.readBytes <const Metadata *>();
766
791
unsigned payloadNumExtraInhabitants =
767
792
xiType ? xiType->vw_getNumExtraInhabitants () : 0 ;
768
793
unsigned caseIndexFromExtraTagBits =
@@ -773,20 +798,22 @@ swift_singlePayloadEnumGeneric_getEnumTag(swift::OpaqueValue *address,
773
798
payloadNumExtraInhabitants;
774
799
return noPayloadIndex + 1 ;
775
800
}
776
- } else {
777
- reader.skip (sizeof (size_t ));
778
- }
779
801
780
- xiType = reader.readBytes <const Metadata *>();
802
+ return std::nullopt;
803
+ };
781
804
782
- if (xiType) {
783
- auto numEmptyCases = reader.readBytes <unsigned >();
805
+ auto xihandler = [addr](const Metadata *xiType, unsigned xiTagBytesOffset,
806
+ unsigned numEmptyCases) -> unsigned {
807
+ if (xiType) {
808
+ return xiType->vw_getEnumTagSinglePayload (
809
+ (const OpaqueValue *)(addr + xiTagBytesOffset), numEmptyCases);
810
+ }
784
811
785
- return xiType->vw_getEnumTagSinglePayload (
786
- (const OpaqueValue *)(addr + xiTagBytesOffset), numEmptyCases);
787
- }
812
+ return 0 ;
813
+ };
788
814
789
- return 0 ;
815
+ return handleSinglePayloadEnumGenericTag<unsigned >(
816
+ reader, addr, extraTagBytesHandler, xihandler);
790
817
}
791
818
792
819
extern " C" swift::OpaqueValue *
0 commit comments