Skip to content

Commit 7148e84

Browse files
committed
[Runtime] Stub out the implementation of _typeByMangledName().
Introduce a standard library/runtime entry point that produces type metadata given a mangled name, based on the TypeDecoder logic lifted from the remote mirrors library. Implement support for tuple types as a proof-of-concept.
1 parent 132075f commit 7148e84

File tree

3 files changed

+166
-0
lines changed

3 files changed

+166
-0
lines changed

stdlib/public/core/Misc.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,25 @@ func _typeByName(_ name: String) -> Any.Type? {
111111
}
112112
}
113113

114+
@_silgen_name("swift_getTypeByMangledName")
115+
internal func _getTypeByMangledName(
116+
_ name: UnsafePointer<UInt8>,
117+
_ nameLength: UInt)
118+
-> Any.Type?
119+
120+
/// Lookup a class given a mangled name. This is a placeholder while we bring
121+
/// up this functionality.
122+
public // TEMPORARY
123+
func _typeByMangledName(_ name: String) -> Any.Type? {
124+
let nameUTF8 = Array(name.utf8)
125+
return nameUTF8.withUnsafeBufferPointer { (nameUTF8) in
126+
let type = _getTypeByMangledName(nameUTF8.baseAddress!,
127+
UInt(nameUTF8.endIndex))
128+
129+
return type
130+
}
131+
}
132+
114133
/// Returns `floor(log(x))`. This equals to the position of the most
115134
/// significant non-zero bit, or 63 - number-of-zeros before it.
116135
///

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/Basic/LLVM.h"
1818
#include "swift/Basic/Lazy.h"
1919
#include "swift/Demangling/Demangler.h"
20+
#include "swift/Demangling/TypeDecoder.h"
2021
#include "swift/Runtime/Concurrent.h"
2122
#include "swift/Runtime/HeapObject.h"
2223
#include "swift/Runtime/Metadata.h"
@@ -244,3 +245,127 @@ _getTypeByName(const char *typeName, size_t typeNameLength) {
244245
llvm::StringRef name(typeName, typeNameLength);
245246
return _classByName(name);
246247
}
248+
249+
#pragma mark Metadata lookup via mangled name
250+
251+
namespace {
252+
/// Constructs metadata by decoding a mangled type name, for use with
253+
/// \c TypeDecoder.
254+
class DecodedMetadataBuilder {
255+
public:
256+
using BuiltType = const Metadata *;
257+
using BuiltNominalTypeDecl = const NominalTypeDescriptor *;
258+
259+
BuiltNominalTypeDecl createNominalTypeDecl(
260+
const Demangle::NodePointer &node) const {
261+
// FIXME: Implement.
262+
return BuiltNominalTypeDecl();
263+
}
264+
265+
BuiltType createNominalType(BuiltNominalTypeDecl typeDecl,
266+
BuiltType parent) const {
267+
// FIXME: Implement.
268+
return BuiltType();
269+
}
270+
271+
BuiltType createBoundGenericType(BuiltNominalTypeDecl typeDecl,
272+
ArrayRef<BuiltType> genericArgs,
273+
BuiltType parent) const {
274+
// FIXME: Implement.
275+
return BuiltType();
276+
}
277+
278+
BuiltType createBuiltinType(StringRef mangledName) const {
279+
// FIXME: Implement.
280+
return BuiltType();
281+
}
282+
283+
BuiltType createMetatypeType(BuiltType instance, bool wasAbstract) const {
284+
// FIXME: Implement.
285+
return BuiltType();
286+
}
287+
288+
BuiltType createExistentialMetatypeType(BuiltType instance) const {
289+
// FIXME: Implement.
290+
return BuiltType();
291+
}
292+
293+
BuiltType createProtocolCompositionType(ArrayRef<BuiltType> protocols,
294+
bool hasExplicitAnyObject) const {
295+
// FIXME: Implement.
296+
// NOTE: protocols.back() could be a class type. Clean up this API.
297+
return BuiltType();
298+
}
299+
300+
BuiltType createProtocolType(StringRef mangledName, StringRef moduleName,
301+
StringRef privateDiscriminator,
302+
StringRef name) const {
303+
// FIXME: Implement.
304+
return BuiltType();
305+
}
306+
307+
BuiltType createGenericTypeParameterType(unsigned depth,
308+
unsigned index) const {
309+
// FIXME: Implement.
310+
return BuiltType();
311+
}
312+
313+
BuiltType createFunctionType(
314+
ArrayRef<Demangle::FunctionParam<BuiltType>> params,
315+
BuiltType result, FunctionTypeFlags flags) const {
316+
// FIXME: Implement.
317+
return BuiltType();
318+
}
319+
320+
BuiltType createTupleType(ArrayRef<BuiltType> elements,
321+
std::string labels,
322+
bool variadic) const {
323+
// TODO: 'variadic' should no longer exist
324+
return swift_getTupleTypeMetadata(elements.size(), elements.data(),
325+
labels.empty() ? nullptr : labels.c_str(),
326+
/*proposedWitnesses=*/nullptr);
327+
}
328+
329+
BuiltType createDependentMemberType(StringRef name, BuiltType base,
330+
BuiltType protocol) const {
331+
// FIXME: Implement.
332+
return BuiltType();
333+
}
334+
335+
BuiltType createUnownedStorageType(BuiltType base) const {
336+
// FIXME: Implement.
337+
return BuiltType();
338+
}
339+
340+
BuiltType createUnmanagedStorageType(BuiltType base) const {
341+
// FIXME: Implement.
342+
return BuiltType();
343+
}
344+
345+
BuiltType createWeakStorageType(BuiltType base) const {
346+
// FIXME: Implement.
347+
return BuiltType();
348+
}
349+
350+
BuiltType createSILBoxType(BuiltType base) const {
351+
// FIXME: Implement.
352+
return BuiltType();
353+
}
354+
};
355+
356+
}
357+
358+
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
359+
const Metadata * _Nullable
360+
swift_getTypeByMangledName(const char *typeNameStart, size_t typeNameLength) {
361+
// Demangle the type name.
362+
llvm::StringRef typeName(typeNameStart, typeNameLength);
363+
Demangler demangler;
364+
NodePointer node = demangler.demangleType(typeName);
365+
if (!node) {
366+
return nullptr;
367+
}
368+
369+
DecodedMetadataBuilder builder;
370+
return Demangle::decodeMangledType(builder, node);
371+
}

test/Runtime/demangleToMetadata.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-run-simple-swift
2+
// REQUIRES: executable_test
3+
4+
import StdlibUnittest
5+
6+
let DemangleToMetadataTests = TestSuite("DemangleToMetadata")
7+
8+
9+
DemangleToMetadataTests.test("malformed mangled names") {
10+
expectNil(_typeByMangledName("blah"))
11+
}
12+
13+
DemangleToMetadataTests.test("tuple types") {
14+
expectEqual(type(of: ()), _typeByMangledName("yt")!)
15+
expectEqual(type(of: ((), ())), _typeByMangledName("yt_ytt")!)
16+
expectEqual(type(of: ((), b: ())), _typeByMangledName("yt_yt1bt")!)
17+
expectEqual(type(of: (a: (), ())), _typeByMangledName("yt1a_ytt")!)
18+
expectEqual(type(of: (a: (), b: ())), _typeByMangledName("yt1a_yt1bt")!)
19+
}
20+
21+
runAllTests()
22+

0 commit comments

Comments
 (0)