Skip to content

Commit 44f5ee0

Browse files
committed
This gets through a larger set of tests, but still has a few hacks
1 parent afd00a4 commit 44f5ee0

File tree

1 file changed

+36
-29
lines changed

1 file changed

+36
-29
lines changed

stdlib/tools/swift-reflection-test/swift-reflection-test.c

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ int reflectEnumValue(SwiftReflectionContextRef RC,
615615

616616
printf("Value: ");
617617
int parens = 0;
618+
// Walk into successively nested enum types...
618619
while (EnumTypeRef != 0) {
619620
swift_typeinfo_t EnumTypeInfo = swift_reflection_infoForTypeRef(RC, EnumTypeRef);
620621
switch (EnumTypeInfo.Kind) {
@@ -633,42 +634,48 @@ int reflectEnumValue(SwiftReflectionContextRef RC,
633634
PipeMemoryReader_sendDoneMessage(&Pipe);
634635
return 0;
635636
}
636-
637637
swift_childinfo_t CaseInfo
638638
= swift_reflection_childOfTypeRef(RC, EnumTypeRef, CaseIndex);
639639
printf(".%s", CaseInfo.Name);
640-
EnumTypeRef = CaseInfo.TR;
641-
if (EnumTypeRef != 0) {
640+
641+
if (EnumTypeInfo.Kind == SWIFT_NO_PAYLOAD_ENUM || CaseInfo.TR == 0) {
642+
// No payload here, so end the walk
643+
EnumTypeRef = 0;
644+
} else {
645+
// There's a payload!
642646
printf("(");
643647
parens += 1;
644-
}
645-
break;
646-
}
647-
case SWIFT_STRONG_REFERENCE: // Might be an indirect enum...
648-
{
649-
// Get the pointer value from the target
650-
void *outFreeContext = NULL;
651-
const void *rawPtr
652-
= PipeMemoryReader_readBytes((void *)&Pipe, EnumInstance, 8, &outFreeContext);
653-
uintptr_t instance = *(uintptr_t *)rawPtr;
654-
PipeMemoryReader_freeBytes((void *)&Pipe, rawPtr, outFreeContext);
655-
656-
// Indirect enum is stored as the first field of a closure context...
657-
swift_typeinfo_t TI = swift_reflection_infoForInstance(RC, instance);
658-
if (TI.Kind == SWIFT_CLOSURE_CONTEXT) {
659-
swift_childinfo_t CaseInfo
660-
= swift_reflection_childOfInstance(RC, instance, 0);
661-
if (CaseInfo.Kind == SWIFT_NO_PAYLOAD_ENUM
662-
|| CaseInfo.Kind == SWIFT_SINGLE_PAYLOAD_ENUM
663-
|| CaseInfo.Kind == SWIFT_MULTI_PAYLOAD_ENUM) {
664-
// Found the indirect enum storage, loop to print it out.
665-
EnumTypeRef = CaseInfo.TR;
666-
EnumInstance = instance + CaseInfo.Offset;
667-
break;
648+
EnumTypeRef = CaseInfo.TR; // Walk into payload to see if it's an enum
649+
650+
if (CaseInfo.Kind == SWIFT_STRONG_REFERENCE) { // Maybe an indirect enum?
651+
// Get the pointer value from the target
652+
void *outFreeContext = NULL;
653+
// !!! FIXME !!! obtain the pointer by properly projecting the enum value
654+
// Next lines are a hack to prove the concept.
655+
const void *rawPtr
656+
= PipeMemoryReader_readBytes((void *)&Pipe, EnumInstance, 8, &outFreeContext);
657+
uintptr_t instance = *(uintptr_t *)rawPtr & 0xffffffffffffff8ULL;
658+
PipeMemoryReader_freeBytes((void *)&Pipe, rawPtr, outFreeContext);
659+
660+
// Indirect enum stores the payload as the first field of a closure context
661+
swift_typeinfo_t TI = swift_reflection_infoForInstance(RC, instance);
662+
if (TI.Kind == SWIFT_CLOSURE_CONTEXT) {
663+
// Yep, it's an indirect enum. Let's follow the pointer...
664+
// TODO: Could we get here if we have an enum whose payload is a closure?
665+
swift_childinfo_t CaseInfo
666+
= swift_reflection_childOfInstance(RC, instance, 0);
667+
if (CaseInfo.Kind == SWIFT_NO_PAYLOAD_ENUM
668+
|| CaseInfo.Kind == SWIFT_SINGLE_PAYLOAD_ENUM
669+
|| CaseInfo.Kind == SWIFT_MULTI_PAYLOAD_ENUM) {
670+
// Found the indirect enum storage, loop to print it out.
671+
EnumTypeRef = CaseInfo.TR;
672+
EnumInstance = instance + CaseInfo.Offset;
673+
break;
674+
}
675+
}
668676
}
669677
}
670-
// Not an indirect enum, fall through...
671-
__attribute__((fallthrough));
678+
break;
672679
}
673680
default:
674681
{

0 commit comments

Comments
 (0)