Skip to content

Commit 4746370

Browse files
committed
[Distributed] Metadata: Refactor demangling of function types from method mangled names
- Extract common logic across count, result and parameter type demangling - Add support for demangling of generic functions - Fix handling of single unlabeled parameter types
1 parent 0c2121a commit 4746370

File tree

1 file changed

+81
-59
lines changed

1 file changed

+81
-59
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 81 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,54 +1910,90 @@ cstrToStringRef(const char *typeNameStart, size_t typeNameLength) {
19101910
return typeName;
19111911
}
19121912

1913-
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
1914-
unsigned
1915-
swift_func_getParameterCount(const char *typeNameStart, size_t typeNameLength) {
1913+
/// Given mangling for a method, extract its function type in demangled
1914+
/// representation.
1915+
static NodePointer extractFunctionTypeFromMethod(Demangler &demangler,
1916+
const char *typeNameStart,
1917+
size_t typeNameLength) {
19161918
llvm::Optional<llvm::StringRef> typeName =
19171919
cstrToStringRef(typeNameStart, typeNameLength);
19181920
if (!typeName)
1919-
return -1;
1920-
1921-
StackAllocatedDemangler<1024> demangler;
1921+
return nullptr;
19221922

19231923
auto node = demangler.demangleSymbol(*typeName);
1924-
if (!node) return -2;
1924+
if (!node)
1925+
return nullptr;
19251926

19261927
node = node->findByKind(Node::Kind::Function, /*maxDepth=*/2);
1927-
if (!node) return -3;
1928+
if (!node)
1929+
return nullptr;
19281930

19291931
node = node->findByKind(Node::Kind::Type, /*maxDepth=*/2);
1930-
if (!node) return -4;
1932+
if (!node)
1933+
return nullptr;
19311934

1932-
node = node->findByKind(Node::Kind::ArgumentTuple, /*maxDepth=*/3);
1933-
// Get the "deepest" Tuple from the ArgumentTuple, that's the arguments
1934-
while (node && node->getKind() != Node::Kind::Tuple) {
1935-
node = node->getFirstChild();
1935+
// If this is a generic function, it requires special handling.
1936+
if (auto genericType =
1937+
node->findByKind(Node::Kind::DependentGenericType, /*maxDepth=*/1)) {
1938+
node = genericType->findByKind(Node::Kind::Type, /*maxDepth=*/1);
1939+
return node->findByKind(Node::Kind::FunctionType, /*maxDepth=*/1);
19361940
}
19371941

1938-
if (node) {
1939-
return node->getNumChildren();
1940-
}
1942+
auto funcType = node->getFirstChild();
1943+
assert(funcType->getKind() == Node::Kind::FunctionType);
1944+
return funcType;
1945+
}
1946+
1947+
/// For a single unlabeled parameter this function returns whole
1948+
/// `ArgumentTuple`, for everything else a `Tuple` element inside it.
1949+
static NodePointer getParameterList(NodePointer funcType) {
1950+
assert(funcType->getKind() == Node::Kind::FunctionType);
1951+
1952+
auto parameterContainer =
1953+
funcType->findByKind(Node::Kind::ArgumentTuple, /*maxDepth=*/1);
1954+
assert(parameterContainer->getNumChildren() > 0);
1955+
1956+
// This is a type that convers entire parameter list.
1957+
auto parameterList = parameterContainer->getFirstChild();
1958+
assert(parameterList->getKind() == Node::Kind::Type);
1959+
1960+
auto parameters = parameterList->getFirstChild();
1961+
if (parameters->getKind() == Node::Kind::Tuple)
1962+
return parameters;
1963+
1964+
return parameterContainer;
1965+
}
1966+
1967+
SWIFT_CC(swift)
1968+
SWIFT_RUNTIME_STDLIB_SPI
1969+
unsigned swift_func_getParameterCount(const char *typeNameStart,
1970+
size_t typeNameLength) {
1971+
StackAllocatedDemangler<1024> demangler;
19411972

1942-
return -5;
1973+
auto funcType =
1974+
extractFunctionTypeFromMethod(demangler, typeNameStart, typeNameLength);
1975+
if (!funcType)
1976+
return -1;
1977+
1978+
auto parameterList = getParameterList(funcType);
1979+
return parameterList->getNumChildren();
19431980
}
19441981

19451982
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
19461983
const Metadata *_Nullable
19471984
swift_func_getReturnTypeInfo(const char *typeNameStart, size_t typeNameLength) {
1948-
llvm::Optional<llvm::StringRef> typeName =
1949-
cstrToStringRef(typeNameStart, typeNameLength);
1950-
if (!typeName) return nullptr;
1951-
19521985
StackAllocatedDemangler<1024> demangler;
1953-
auto node = demangler.demangleSymbol(*typeName);
1954-
if (!node) return nullptr;
19551986

1956-
node = node->findByKind(Node::Kind::Function, /*maxDepth=*/2);
1957-
if (!node) return nullptr;
1987+
auto *funcType =
1988+
extractFunctionTypeFromMethod(demangler, typeNameStart, typeNameLength);
1989+
if (!funcType)
1990+
return nullptr;
1991+
1992+
auto resultType = funcType->getLastChild();
1993+
if (!resultType)
1994+
return nullptr;
19581995

1959-
node = node->findByKind(Node::Kind::ReturnType, /*maxDepth=*/4);
1960-
if (!node) return nullptr;
1996+
assert(resultType->getKind() == Node::Kind::ReturnType);
19611997

19621998
DecodedMetadataBuilder builder(
19631999
demangler,
@@ -1967,7 +2003,8 @@ swift_func_getReturnTypeInfo(const char *typeNameStart, size_t typeNameLength) {
19672003
[](const Metadata *, unsigned) { return nullptr; });
19682004

19692005
TypeDecoder<DecodedMetadataBuilder> decoder(builder);
1970-
auto builtTypeOrError = decoder.decodeMangledType(node);
2006+
auto builtTypeOrError =
2007+
decoder.decodeMangledType(resultType->getFirstChild());
19712008
if (builtTypeOrError.isError()) {
19722009
auto err = builtTypeOrError.getError();
19732010
char *errStr = err->copyErrorString();
@@ -1985,31 +2022,19 @@ swift_func_getParameterTypeInfo(
19852022
Metadata const **types, unsigned typesLength) {
19862023
if (typesLength < 0) return -1;
19872024

1988-
llvm::Optional<llvm::StringRef> typeName =
1989-
cstrToStringRef(typeNameStart, typeNameLength);
1990-
if (!typeName) return -1;
1991-
19922025
StackAllocatedDemangler<1024> demangler;
1993-
auto node = demangler.demangleSymbol(*typeName);
1994-
if (!node) return -1;
19952026

1996-
node = node->findByKind(Node::Kind::Function, /*maxDepth=*/2);
1997-
if (!node) return -3;
2027+
auto *funcType =
2028+
extractFunctionTypeFromMethod(demangler, typeNameStart, typeNameLength);
2029+
if (!funcType)
2030+
return -1;
19982031

1999-
node = node->findByKind(Node::Kind::Type, /*maxDepth=*/2);
2000-
if (!node) return -4;
2001-
2002-
node = node->findByKind(Node::Kind::ArgumentTuple, /*maxDepth=*/3);
2003-
// Get the "deepest" Tuple from the ArgumentTuple, that's the arguments
2004-
while (node && node->getKind() != Node::Kind::Tuple) {
2005-
node = node->getFirstChild();
2006-
}
2032+
auto parameterList = getParameterList(funcType);
20072033

20082034
// Only successfully return if the expected parameter count is the same
20092035
// as space prepared for it in the buffer.
2010-
if (!node || (node && node->getNumChildren() != typesLength)) {
2011-
return -5;
2012-
}
2036+
if (!(parameterList && parameterList->getNumChildren() == typesLength))
2037+
return -2;
20132038

20142039
DecodedMetadataBuilder builder(
20152040
demangler,
@@ -2021,14 +2046,15 @@ swift_func_getParameterTypeInfo(
20212046

20222047
auto typeIdx = 0;
20232048
// for each parameter (TupleElement), store it into the provided buffer
2024-
for (auto tupleElement : *node) {
2025-
assert(tupleElement->getKind() == Node::Kind::TupleElement);
2026-
assert(tupleElement->getNumChildren() == 1);
2049+
for (auto *parameter : *parameterList) {
2050+
if (parameter->getKind() == Node::Kind::TupleElement) {
2051+
assert(parameter->getNumChildren() == 1);
2052+
parameter = parameter->getFirstChild();
2053+
}
20272054

2028-
auto typeNode = tupleElement->getFirstChild();
2029-
assert(typeNode->getKind() == Node::Kind::Type);
2055+
assert(parameter->getKind() == Node::Kind::Type);
20302056

2031-
auto builtTypeOrError = decoder.decodeMangledType(tupleElement);
2057+
auto builtTypeOrError = decoder.decodeMangledType(parameter);
20322058
if (builtTypeOrError.isError()) {
20332059
auto err = builtTypeOrError.getError();
20342060
char *errStr = err->copyErrorString();
@@ -2038,14 +2064,10 @@ swift_func_getParameterTypeInfo(
20382064
}
20392065

20402066
types[typeIdx] = builtTypeOrError.getType();
2041-
typeIdx += 1;
2067+
++typeIdx;
20422068
} // end foreach parameter
20432069

2044-
if (node) {
2045-
return node->getNumChildren();
2046-
}
2047-
2048-
return -9;
2070+
return typesLength;
20492071
}
20502072

20512073
// ==== End of Function metadata functions ---------------------------------------

0 commit comments

Comments
 (0)