Skip to content

Commit 8d736a1

Browse files
committed
MetadataSource Improvements: Builder; Parent, Impossible kinds
Create a builder divorced from the ReflectionContext so that MetadataSources can be created in other contexts, such as emitting private heap metadata during IRGen, where we'll have to record the layout of captures and how to get metadata for generic arguments in order to construct typerefs of the captures, etc. Add Parent, Metadata capture, and Impossible metadata sources.
1 parent 5a735b5 commit 8d736a1

File tree

8 files changed

+531
-4
lines changed

8 files changed

+531
-4
lines changed

include/swift/Reflection/MetadataSource.h

Lines changed: 247 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#ifndef SWIFT_REFLECTION_METADATASOURCE_H
2323
#define SWIFT_REFLECTION_METADATASOURCE_H
2424

25+
#include "llvm/ADT/Optional.h"
2526
#include "llvm/Support/Casting.h"
2627

2728
using llvm::cast;
@@ -39,6 +40,168 @@ enum class MetadataSourceKind {
3940

4041
class MetadataSource {
4142
MetadataSourceKind Kind;
43+
44+
static bool decodeNatural(std::string::const_iterator &it,
45+
const std::string::const_iterator &end,
46+
unsigned &result) {
47+
auto begin = it;
48+
while (it != end) {
49+
if (*it >= '0' && *it <= '9')
50+
++it;
51+
else
52+
break;
53+
}
54+
55+
std::string natural(begin, it);
56+
if (natural.empty())
57+
return false;
58+
59+
result = std::stoi(natural);
60+
return true;
61+
}
62+
63+
template <typename Allocator>
64+
static const MetadataSource *
65+
decodeClosureBinding(Allocator &A,
66+
std::string::const_iterator &it,
67+
const std::string::const_iterator &end) {
68+
if (it == end)
69+
return nullptr;
70+
71+
if (*it == 'B')
72+
++it;
73+
else
74+
return nullptr;
75+
76+
unsigned Index;
77+
if (!decodeNatural(it, end, Index))
78+
return nullptr;
79+
return A.template createClosureBinding(Index);
80+
}
81+
82+
template <typename Allocator>
83+
static const MetadataSource *
84+
decodeReferenceCapture(Allocator &A,
85+
std::string::const_iterator &it,
86+
const std::string::const_iterator &end) {
87+
if (it == end)
88+
return nullptr;
89+
90+
if (*it == 'R')
91+
++it;
92+
else
93+
return nullptr;
94+
95+
unsigned Index;
96+
if (!decodeNatural(it, end, Index))
97+
return nullptr;
98+
return A.template createReferenceCapture(Index);
99+
}
100+
101+
template <typename Allocator>
102+
static const MetadataSource *
103+
decodeMetadataCapture(Allocator &A,
104+
std::string::const_iterator &it,
105+
const std::string::const_iterator &end) {
106+
if (it == end)
107+
return nullptr;
108+
109+
if (*it == 'M')
110+
++it;
111+
else
112+
return nullptr;
113+
114+
unsigned Index;
115+
if (!decodeNatural(it, end, Index))
116+
return nullptr;
117+
return A.template createMetadataCapture(Index);
118+
}
119+
120+
template <typename Allocator>
121+
static const MetadataSource *
122+
decodeGenericArgument(Allocator &A,
123+
std::string::const_iterator &it,
124+
const std::string::const_iterator &end) {
125+
if (it == end)
126+
return nullptr;
127+
128+
if (*it == 'G')
129+
++it;
130+
else
131+
return nullptr;
132+
133+
unsigned Index;
134+
if (!decodeNatural(it, end, Index))
135+
return nullptr;
136+
137+
auto Source = decode(A, it, end);
138+
if (!Source)
139+
return nullptr;
140+
141+
if (it == end || *it != '_')
142+
return nullptr;
143+
144+
++it;
145+
146+
return A.template createGenericArgument(Index, Source);
147+
}
148+
149+
template <typename Allocator>
150+
static const MetadataSource*
151+
decodeParent(Allocator &A,
152+
std::string::const_iterator &it,
153+
const std::string::const_iterator &end) {
154+
if (it == end || *it != 'P')
155+
return nullptr;
156+
157+
++it;
158+
auto Child = decode(A, it, end);
159+
if (!Child)
160+
return nullptr;
161+
162+
if (it == end || *it != '_')
163+
return nullptr;
164+
165+
return A.template createParent(Child);
166+
}
167+
168+
template <typename Allocator>
169+
static const MetadataSource*
170+
decodeImpossible(Allocator &A,
171+
std::string::const_iterator &it,
172+
const std::string::const_iterator &end) {
173+
// Decode the impossible. Create the impossible.
174+
if (it == end || *it != 'I')
175+
return nullptr;
176+
177+
++it;
178+
return A.template createImpossible();
179+
}
180+
181+
template <typename Allocator>
182+
static const MetadataSource *decode(Allocator &A,
183+
std::string::const_iterator &it,
184+
const std::string::const_iterator &end) {
185+
if (it == end) return nullptr;
186+
187+
switch (*it) {
188+
case 'B':
189+
return decodeClosureBinding(A, it, end);
190+
case 'R':
191+
return decodeReferenceCapture(A, it, end);
192+
case 'M':
193+
return decodeMetadataCapture(A, it, end);
194+
case 'G':
195+
return decodeGenericArgument(A, it, end);
196+
case 'P':
197+
return decodeParent(A, it, end);
198+
case 'I':
199+
return decodeImpossible(A, it, end);
200+
default:
201+
return nullptr;
202+
}
203+
}
204+
42205
public:
43206
MetadataSource(MetadataSourceKind Kind) : Kind(Kind) {}
44207

@@ -48,6 +211,12 @@ class MetadataSource {
48211

49212
void dump() const;
50213
void dump(std::ostream &OS, unsigned Indent = 0) const;
214+
std::string encode() const;
215+
template <typename Allocator>
216+
static const MetadataSource *decode(Allocator &A, const std::string &str) {
217+
auto begin = str.begin();
218+
return MetadataSource::decode<Allocator>(A, begin, str.end());
219+
}
51220

52221
virtual ~MetadataSource() = default;
53222
};
@@ -59,8 +228,15 @@ class ClosureBindingMetadataSource final : public MetadataSource {
59228
unsigned Index;
60229

61230
public:
62-
ClosureBindingMetadataSource(unsigned Index) :
63-
MetadataSource(MetadataSourceKind::ClosureBinding) {}
231+
232+
ClosureBindingMetadataSource(unsigned Index)
233+
: MetadataSource(MetadataSourceKind::ClosureBinding), Index(Index) {}
234+
235+
template <typename Allocator>
236+
static const ClosureBindingMetadataSource *
237+
create(Allocator &A, unsigned Index) {
238+
return A.template make_source<ClosureBindingMetadataSource>(Index);
239+
}
64240

65241
unsigned getIndex() const {
66242
return Index;
@@ -75,9 +251,16 @@ class ClosureBindingMetadataSource final : public MetadataSource {
75251
/// be followed to the heap instance's data, then its metadata pointer.
76252
class ReferenceCaptureMetadataSource final : public MetadataSource {
77253
unsigned Index;
254+
78255
public:
79-
ReferenceCaptureMetadataSource(unsigned Index):
80-
MetadataSource(MetadataSourceKind::ReferenceCapture) {}
256+
ReferenceCaptureMetadataSource(unsigned Index)
257+
: MetadataSource(MetadataSourceKind::ReferenceCapture), Index(Index) {}
258+
259+
template <typename Allocator>
260+
static const ReferenceCaptureMetadataSource *
261+
create(Allocator &A, unsigned Index) {
262+
return A.template make_source<ReferenceCaptureMetadataSource>(Index);
263+
}
81264

82265
unsigned getIndex() const {
83266
return Index;
@@ -88,6 +271,29 @@ class ReferenceCaptureMetadataSource final : public MetadataSource {
88271
}
89272
};
90273

274+
/// Represents a capture of a metadata pointer as an argument to a polymorphic function. These are direct sources of metadata.
275+
class MetadataCaptureMetadataSource final : public MetadataSource {
276+
unsigned Index;
277+
278+
public:
279+
MetadataCaptureMetadataSource(unsigned Index)
280+
: MetadataSource(MetadataSourceKind::MetadataCapture), Index(Index) {}
281+
282+
template <typename Allocator>
283+
static const MetadataCaptureMetadataSource *
284+
create(Allocator &A, unsigned Index) {
285+
return A.template make_source<MetadataCaptureMetadataSource>(Index);
286+
}
287+
288+
unsigned getIndex() const {
289+
return Index;
290+
}
291+
292+
static bool classof(const MetadataSource *MS) {
293+
return MS->getKind() == MetadataSourceKind::MetadataCapture;
294+
}
295+
};
296+
91297
/// Represents the nth generic argument in some other source of instantiated
92298
/// metadata.
93299
///
@@ -106,6 +312,12 @@ class GenericArgumentMetadataSource final : public MetadataSource {
106312
Index(Index),
107313
Source(Source) {}
108314

315+
template <typename Allocator>
316+
static const GenericArgumentMetadataSource *
317+
create(Allocator &A, unsigned Index, const MetadataSource *Source) {
318+
return A.template make_source<GenericArgumentMetadataSource>(Index, Source);
319+
}
320+
109321
unsigned getIndex() const {
110322
return Index;
111323
}
@@ -119,6 +331,37 @@ class GenericArgumentMetadataSource final : public MetadataSource {
119331
}
120332
};
121333

334+
class ParentMetadataSource final : public MetadataSource {
335+
const MetadataSource *Child;
336+
public:
337+
ParentMetadataSource(const MetadataSource *Child)
338+
: MetadataSource(MetadataSourceKind::Parent),
339+
Child(Child) {}
340+
341+
template <typename Allocator>
342+
static const ParentMetadataSource*
343+
create(Allocator &A, const MetadataSource *Child) {
344+
return A.template make_source<ParentMetadataSource>(Child);
345+
}
346+
347+
const MetadataSource *getChild() const {
348+
return Child;
349+
}
350+
};
351+
352+
class ImpossibleMetadataSource final : public MetadataSource {
353+
static const ImpossibleMetadataSource *Singleton;
354+
public:
355+
ImpossibleMetadataSource()
356+
: MetadataSource(MetadataSourceKind::Impossible) {}
357+
358+
static const ImpossibleMetadataSource *get();
359+
360+
static bool classof(const MetadataSource *MS) {
361+
return MS->getKind() == MetadataSourceKind::Impossible;
362+
}
363+
};
364+
122365
template <typename ImplClass, typename RetTy = void, typename... Args>
123366
class MetadataSourceVisitor {
124367
public:
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//===--- MetadataSourceBuilder.h - Swift Metadata Source Builder --------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Implements utilities for constructing MetadataSources.
14+
//===----------------------------------------------------------------------===//
15+
16+
#ifndef SWIFT_REFLECTION_METADATASOURCEBUILDER_H
17+
#define SWIFT_REFLECTION_METADATASOURCEBUILDER_H
18+
19+
#include "swift/Reflection/MetadataSource.h"
20+
21+
namespace swift {
22+
namespace reflection {
23+
24+
class MetadataSourceBuilder {
25+
std::vector<std::unique_ptr<const MetadataSource>> MetadataSourcePool;
26+
public:
27+
using Source = const MetadataSource *;
28+
29+
MetadataSourceBuilder() {}
30+
31+
MetadataSourceBuilder(const MetadataSourceBuilder &Other) = delete;
32+
MetadataSourceBuilder &operator=(const MetadataSourceBuilder &Other) = delete;
33+
34+
template <typename MetadataSourceTy, typename... Args>
35+
MetadataSourceTy *make_source(Args... args) {
36+
auto MS = new MetadataSourceTy(::std::forward<Args>(args)...);
37+
MetadataSourcePool.push_back(std::unique_ptr<const MetadataSource>(MS));
38+
return MS;
39+
}
40+
41+
const GenericArgumentMetadataSource *
42+
createGenericArgument(unsigned Index, const MetadataSource *Source) {
43+
return GenericArgumentMetadataSource::create(*this, Index, Source);
44+
}
45+
46+
const MetadataCaptureMetadataSource *
47+
createMetadataCapture(unsigned Index) {
48+
return MetadataCaptureMetadataSource::create(*this, Index);
49+
}
50+
51+
const ReferenceCaptureMetadataSource *
52+
createReferenceCapture(unsigned Index) {
53+
return ReferenceCaptureMetadataSource::create(*this, Index);
54+
}
55+
56+
const ClosureBindingMetadataSource *
57+
createClosureBinding(unsigned Index) {
58+
return ClosureBindingMetadataSource::create(*this, Index);
59+
}
60+
61+
const ParentMetadataSource *
62+
createParent(const MetadataSource *Child) {
63+
return ParentMetadataSource::create(*this, Child);
64+
}
65+
66+
const ImpossibleMetadataSource *
67+
createImpossible() {
68+
return ImpossibleMetadataSource::get();
69+
}
70+
};
71+
72+
} // end namespace reflection
73+
} // end namespace swift
74+
75+
#endif // SWIFT_REFLECTION_METADATASOURCEBUILDER_H

include/swift/Reflection/MetadataSources.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@
1818

1919
METADATA_SOURCE(ClosureBinding, MetadataSource)
2020
METADATA_SOURCE(ReferenceCapture, MetadataSource)
21+
METADATA_SOURCE(MetadataCapture, MetadataSource)
2122
METADATA_SOURCE(GenericArgument, MetadataSource)
23+
METADATA_SOURCE(Parent, MetadataSource)
24+
METADATA_SOURCE(Impossible, MetadataSource)

0 commit comments

Comments
 (0)