Skip to content

Commit ed2e6b6

Browse files
committed
The number of cases stored in the payload area depends on the payload area size
1 parent 9bfe1b1 commit ed2e6b6

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,30 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
544544
}
545545
}
546546

547+
// Think of a single-payload enum as being encoded in "pages".
548+
// The discriminator (tag) tells us which page we're on:
549+
// * Page 0 is the payload page which can either store
550+
// the single payload case (any valid value
551+
// for the payload) or any of N non-payload cases
552+
// (encoded as XIs for the payload)
553+
// * Other pages use the payload area to encode non-payload
554+
// cases. The number of cases that can be encoded
555+
// on each such page depends only on the size of the
556+
// payload area.
557+
//
558+
// The above logic generalizes the following important cases:
559+
// * A payload with XIs will generally have enough to
560+
// encode all payloadcases. It will have no discriminator
561+
// case, so everything is effectively on "page zero."
562+
// * If the payload has no XIs but is not zero-sized, then
563+
// we'll need a page one. That page will usually be
564+
// large enough to encode all non-payload cases.
565+
// * If the payload is zero-sized, then we only have a
566+
// discriminator. In effect, the single-payload enum
567+
// degenerates in this case to a non-payload enum
568+
// (except for the subtle distinction that the
569+
// single-payload enum doesn't export XIs).
570+
547571
bool projectEnumValue(remote::MemoryReader &reader,
548572
remote::RemoteAddress address,
549573
int *CaseIndex) const override {
@@ -552,7 +576,7 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
552576
auto DiscriminatorAddress = address + PayloadSize;
553577
auto DiscriminatorSize = getSize() - PayloadSize;
554578
unsigned discriminator = 0;
555-
if (getSize() > PayloadSize) {
579+
if (DiscriminatorSize > 0) {
556580
if (!reader.readInteger(DiscriminatorAddress,
557581
DiscriminatorSize,
558582
&discriminator)) {
@@ -574,9 +598,9 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
574598
return false;
575599
}
576600
auto casesPerNonPayloadPage =
577-
DiscriminatorSize >= 4
601+
PayloadSize >= 4
578602
? ValueWitnessFlags::MaxNumExtraInhabitants
579-
: (1UL << (DiscriminatorSize * 8UL));
603+
: (1UL << (PayloadSize * 8UL));
580604
ComputedCase =
581605
1
582606
+ nonPayloadCasesUsingXIs
@@ -618,7 +642,7 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
618642
// case c(Int)
619643
// }
620644
//
621-
// // Enums with one payload with no XIs
645+
// // Enums with one non-empty payload but that has no XIs
622646
// // (This is almost but not quite the same as the single-payload
623647
// // case. Different in that this MPE exposes extra tag values
624648
// // as XIs to an enclosing enum; SPEs don't do that.)

0 commit comments

Comments
 (0)