Skip to content

Commit 2fc5008

Browse files
committed
Add a BitfieldRef mini-utility.
Allows migration of existing data-structures to bitfields by separating the state that contains the bitfield into a separate stack-allocated container.
1 parent 40a85f7 commit 2fc5008

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

include/swift/SIL/SILBitfield.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,55 @@ class KnownSizeSet {
149149
size_t size() const { return numElements; }
150150
};
151151

152+
/// Embed a reference to a Bitfield container inside a longer-lived object so
153+
/// the bitfield container can be stack allocated with a properly nested minimal
154+
/// lifetime. Accessing the container outside the scope of it's stack allocation
155+
/// results in a nullptr dereference.
156+
///
157+
/// struct Parent {
158+
/// BitfieldRef<Container> container;
159+
///
160+
/// void performWithContainer(SILFunction *function) {
161+
/// BitfieldRef<Container>::StackState state(container, functon);
162+
///
163+
/// assert(container->isValid());
164+
/// }
165+
/// };
166+
///
167+
/// TODO: give this variadic template parameters to support a BitfieldContainer
168+
/// whose constructor takes more than a single SILFunction argument.
169+
template <typename BitfieldContainer> struct BitfieldRef {
170+
BitfieldContainer *ref = nullptr;
171+
172+
BitfieldRef() {}
173+
174+
BitfieldContainer &operator*() const {
175+
assert(ref);
176+
return *ref;
177+
}
178+
179+
BitfieldContainer *operator->() const {
180+
assert(ref);
181+
return ref;
182+
}
183+
184+
// Stack-allocated state must be nested relative to other node bitfields.
185+
struct StackState {
186+
BitfieldRef &ref;
187+
BitfieldContainer container;
188+
189+
StackState(BitfieldRef &ref, SILFunction *function)
190+
: ref(ref), container(function) {
191+
ref.ref = &container;
192+
}
193+
194+
~StackState() { ref.ref = nullptr; }
195+
};
196+
197+
private:
198+
BitfieldRef(const BitfieldRef &) = delete;
199+
};
200+
152201
} // namespace swift
153202

154203
#endif

0 commit comments

Comments
 (0)