Skip to content

Commit 964a51f

Browse files
authored
[Runtime] Abstract tag handling for generic single payload enums (#67002)
* [Runtime] Abstract tag handling for generic single payload enums This functionality will be shared across multiple functions, so adding the abstraction in preparation of that. * Update BytecodeLayouts.cpp
1 parent 9d76be8 commit 964a51f

File tree

1 file changed

+47
-20
lines changed

1 file changed

+47
-20
lines changed

stdlib/public/runtime/BytecodeLayouts.cpp

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
#include "swift/Runtime/HeapObject.h"
2727
#include "llvm/Support/SwapByteOrder.h"
2828
#include <cstdint>
29+
#include <functional>
2930
#include <limits>
31+
#include <optional>
3032
#include <type_traits>
3133
#if SWIFT_OBJC_INTEROP
3234
#include "swift/Runtime/ObjCBridge.h"
@@ -744,25 +746,48 @@ swift_multiPayloadEnumGeneric_getEnumTag(swift::OpaqueValue *address,
744746
}
745747
}
746748

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) {
754755
auto tagBytesAndOffset = reader.readBytes<uint64_t>();
755756
auto extraTagBytesPattern = (uint8_t)(tagBytesAndOffset >> 62);
756757
auto xiTagBytesOffset =
757758
tagBytesAndOffset & std::numeric_limits<uint32_t>::max();
758759
const Metadata *xiType = nullptr;
759760

760761
if (extraTagBytesPattern) {
761-
auto extraTagBytes = 1 << (extraTagBytesPattern - 1);
762+
auto numExtraTagBytes = 1 << (extraTagBytesPattern - 1);
762763
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);
764790
if (tagBytes) {
765-
xiType = reader.readBytes<const Metadata *>();
766791
unsigned payloadNumExtraInhabitants =
767792
xiType ? xiType->vw_getNumExtraInhabitants() : 0;
768793
unsigned caseIndexFromExtraTagBits =
@@ -773,20 +798,22 @@ swift_singlePayloadEnumGeneric_getEnumTag(swift::OpaqueValue *address,
773798
payloadNumExtraInhabitants;
774799
return noPayloadIndex + 1;
775800
}
776-
} else {
777-
reader.skip(sizeof(size_t));
778-
}
779801

780-
xiType = reader.readBytes<const Metadata *>();
802+
return std::nullopt;
803+
};
781804

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+
}
784811

785-
return xiType->vw_getEnumTagSinglePayload(
786-
(const OpaqueValue *)(addr + xiTagBytesOffset), numEmptyCases);
787-
}
812+
return 0;
813+
};
788814

789-
return 0;
815+
return handleSinglePayloadEnumGenericTag<unsigned>(
816+
reader, addr, extraTagBytesHandler, xihandler);
790817
}
791818

792819
extern "C" swift::OpaqueValue *

0 commit comments

Comments
 (0)