Skip to content

Commit 6fd0247

Browse files
committed
Handle 3-byte payloads when reusing payload area for single-payload enums
According to the compiler code, the payload area is reused by treating the first min(4, payload size) bytes as an n-byte integer. The previous code didn't handle 3-byte integers. Mostly, this just means simplifying the `readInteger` function to handle arbitrary byte lengths (requiring only that it's less than the length of the destination integer variable). I've also made a tentative stab at handling big-endian architectures here.
1 parent 1845524 commit 6fd0247

File tree

2 files changed

+11
-35
lines changed

2 files changed

+11
-35
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ class ReflectionContext
788788
return false;
789789
} else {
790790
// No payload: Payload area is reused for more cases
791-
unsigned PayloadTag = 0;
791+
uint32_t PayloadTag = 0;
792792
auto PayloadTagSize = std::min(PayloadSize, decltype(PayloadSize)(sizeof(PayloadTag)));
793793
if (!getReader().readInteger(EnumAddress, PayloadTagSize, &PayloadTag)) {
794794
return false;

include/swift/Remote/MemoryReader.h

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -64,44 +64,20 @@ class MemoryReader {
6464
/// Attempts to read an integer of the specified size from the given
6565
/// address in the remote process.
6666
///
67-
/// Returns false if the operation failed, the request size is not
68-
/// 1, 2, 4, or 8, or the request size is larger than the provided destination.
67+
/// Returns false if the operation failed, or the request size is
68+
/// larger than the provided destination.
6969
template <typename IntegerType>
7070
bool readInteger(RemoteAddress address, size_t bytes, IntegerType *dest) {
71-
if (bytes > sizeof(IntegerType))
72-
return false;
73-
switch (bytes) {
74-
case 1: {
75-
uint8_t n;
76-
if (!readInteger(address, &n))
77-
return false;
78-
*dest = n;
79-
break;
80-
}
81-
case 2: {
82-
uint16_t n;
83-
if (!readInteger(address, &n))
84-
return false;
85-
*dest = n;
86-
break;
87-
}
88-
case 4: {
89-
uint32_t n;
90-
if (!readInteger(address, &n))
91-
return false;
92-
*dest = n;
93-
break;
94-
}
95-
case 8: {
96-
uint64_t n;
97-
if (!readInteger(address, &n))
98-
return false;
99-
*dest = n;
100-
break;
101-
}
102-
default:
71+
*dest = 0;
72+
if ((bytes > sizeof(IntegerType))
73+
|| !readBytes(address, (uint8_t *)dest, bytes)) {
10374
return false;
10475
}
76+
// FIXME: Assumes host and target have the same endianness.
77+
// TODO: Query DLQ for endianness of target, compare to endianness of host.
78+
#if defined(__BIG_ENDIAN__)
79+
*dest >>= (sizeof(IntegerType) - bytes);
80+
#endif
10581
return true;
10682
}
10783

0 commit comments

Comments
 (0)