Skip to content

Commit fd4ef74

Browse files
authored
Merge pull request #67067 from drexin/wip-refactor-simple-enum-tag
[Runtime] Abstract handling of simple single payload enum handling
2 parents f5399af + 13930c9 commit fd4ef74

File tree

1 file changed

+43
-20
lines changed

1 file changed

+43
-20
lines changed

stdlib/public/runtime/BytecodeLayouts.cpp

+43-20
Original file line numberDiff line numberDiff line change
@@ -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

709732
extern "C"

0 commit comments

Comments
 (0)