Skip to content

Commit 363b5e4

Browse files
committed
Implement reading extra inhabitants of integers
Bools may have extra inhabitants. Implement reading the extra inhabitants of bools in BuiltinTypeInfo::readExtraInhabitantIndex.
1 parent 2ae0644 commit 363b5e4

File tree

1 file changed

+57
-17
lines changed

1 file changed

+57
-17
lines changed

stdlib/public/Reflection/TypeLowering.cpp

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -241,25 +241,65 @@ BuiltinTypeInfo::BuiltinTypeInfo(TypeRefBuilder &builder,
241241
builder.readTypeRef(descriptor, descriptor->TypeName)))
242242
{}
243243

244-
bool
245-
BuiltinTypeInfo::readExtraInhabitantIndex(remote::MemoryReader &reader,
246-
remote::RemoteAddress address,
247-
int *extraInhabitantIndex) const {
248-
if (getNumExtraInhabitants() == 0) {
249-
*extraInhabitantIndex = -1;
250-
return true;
251-
}
252-
// If it has extra inhabitants, it must be a pointer. (The only non-pointer
253-
// data with extra inhabitants is a non-payload enum, which doesn't get here.)
254-
if (Name == "yyXf") {
255-
// But there are two different conventions, one for function pointers:
256-
return reader.readFunctionPointerExtraInhabitantIndex(address, extraInhabitantIndex);
257-
} else {
258-
// And one for pointers to heap-allocated blocks of memory
259-
return reader.readHeapObjectExtraInhabitantIndex(address, extraInhabitantIndex);
260-
}
244+
bool BuiltinTypeInfo::readExtraInhabitantIndex(
245+
remote::MemoryReader &reader, remote::RemoteAddress address,
246+
int *extraInhabitantIndex) const {
247+
if (getNumExtraInhabitants() == 0) {
248+
*extraInhabitantIndex = -1;
249+
return true;
261250
}
251+
// If it has extra inhabitants, it could be an integer type with extra
252+
// inhabitants (a bool) or a pointer.
253+
// Check if it's an integer first. The mangling of an integer type is
254+
// type ::= 'Bi' NATURAL '_'
255+
llvm::StringRef nameRef(Name);
256+
if (nameRef.startswith("Bi") && nameRef.endswith("_")) {
257+
// Drop the front "Bi" and "_" end, check that what we're left with is a
258+
// bool.
259+
llvm::StringRef naturalRef = nameRef.drop_front(2).drop_back();
260+
uint8_t natural;
261+
if (naturalRef.getAsInteger(10, natural))
262+
return false;
263+
264+
assert(natural == 1 &&
265+
"Reading extra inhabitants of integer with more than 1 byte!");
266+
if (natural != 1)
267+
return false;
268+
269+
assert(getSize() == 1 && "Reading extra inhabitants of integer but size of "
270+
"type info is different than 1!");
271+
if (getSize() != 1)
272+
return false;
273+
274+
assert(getNumExtraInhabitants() == 254 &&
275+
"Boolean type info should have 254 extra inhabitants!");
276+
if (getNumExtraInhabitants() != 254)
277+
return false;
278+
279+
uint8_t rawValue;
280+
if (!reader.readInteger(address, &rawValue))
281+
return false;
262282

283+
// The max valid value, for a bool valid values are 0 or 1, so this would
284+
// be 1.
285+
auto maxValidValue = 1;
286+
// If the raw value falls outside the range of valid values, this is an
287+
// extra inhabitant.
288+
if (maxValidValue < rawValue)
289+
*extraInhabitantIndex = rawValue - maxValidValue - 1;
290+
else
291+
*extraInhabitantIndex = -1;
292+
return true;
293+
} else if (Name == "yyXf") {
294+
// But there are two different conventions, one for function pointers:
295+
return reader.readFunctionPointerExtraInhabitantIndex(address,
296+
extraInhabitantIndex);
297+
} else {
298+
// And one for pointers to heap-allocated blocks of memory
299+
return reader.readHeapObjectExtraInhabitantIndex(address,
300+
extraInhabitantIndex);
301+
}
302+
}
263303

264304
bool RecordTypeInfo::readExtraInhabitantIndex(remote::MemoryReader &reader,
265305
remote::RemoteAddress address,

0 commit comments

Comments
 (0)