Skip to content

Commit dd66fdd

Browse files
committed
[Basic] Improve API of BridgedArrayRef + BridgedData
Remove the default constructor footgun present with the struct implementations, and sprinkle some `SWIFT_NAME` and bridging utilities to make them nicer to work with.
1 parent 57384f4 commit dd66fdd

File tree

12 files changed

+129
-62
lines changed

12 files changed

+129
-62
lines changed

SwiftCompilerSources/Sources/Basic/Utils.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ extension String {
135135
extension Array {
136136
public func withBridgedArrayRef<T>(_ c: (BridgedArrayRef) -> T) -> T {
137137
return withUnsafeBytes { buf in
138-
return c(BridgedArrayRef(data: buf.baseAddress!, numElements: count))
138+
return c(BridgedArrayRef(data: buf.baseAddress!, count: count))
139139
}
140140
}
141141
}
@@ -164,8 +164,8 @@ extension Optional where Wrapped == UnsafeMutablePointer<BridgedSwiftObject> {
164164

165165
extension BridgedArrayRef {
166166
public func withElements<T, R>(ofType ty: T.Type, _ c: (UnsafeBufferPointer<T>) -> R) -> R {
167-
let start = data?.bindMemory(to: ty, capacity: numElements);
168-
let buffer = UnsafeBufferPointer(start: start, count: numElements);
167+
let start = data?.bindMemory(to: ty, capacity: count)
168+
let buffer = UnsafeBufferPointer(start: start, count: count)
169169
return c(buffer)
170170
}
171171
}

include/swift/Basic/BasicBridging.h

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,20 +103,66 @@ typedef uintptr_t SwiftUInt;
103103
// MARK: ArrayRef
104104
//===----------------------------------------------------------------------===//
105105

106-
struct BridgedArrayRef {
107-
const void *_Nullable data;
108-
size_t numElements;
106+
class BridgedArrayRef {
107+
public:
108+
SWIFT_UNAVAILABLE("Use '.data' instead")
109+
const void *_Nullable Data;
110+
111+
SWIFT_UNAVAILABLE("Use '.count' instead")
112+
size_t Length;
113+
114+
BridgedArrayRef() : Data(nullptr), Length(0) {}
115+
116+
SWIFT_NAME("init(data:count:)")
117+
BridgedArrayRef(const void *_Nullable data, size_t length)
118+
: Data(data), Length(length) {}
119+
120+
#ifdef USED_IN_CPP_SOURCE
121+
template <typename T>
122+
BridgedArrayRef(llvm::ArrayRef<T> arr)
123+
: Data(arr.data()), Length(arr.size()) {}
124+
125+
template <typename T>
126+
llvm::ArrayRef<T> get() const {
127+
return {static_cast<const T *>(Data), Length};
128+
}
129+
#endif
109130
};
110131

132+
SWIFT_NAME("getter:BridgedArrayRef.data(self:)")
133+
BRIDGED_INLINE
134+
const void *_Nullable BridgedArrayRef_data(BridgedArrayRef arr);
135+
136+
SWIFT_NAME("getter:BridgedArrayRef.count(self:)")
137+
BRIDGED_INLINE SwiftInt BridgedArrayRef_count(BridgedArrayRef arr);
138+
111139
//===----------------------------------------------------------------------===//
112140
// MARK: Data
113141
//===----------------------------------------------------------------------===//
114142

115-
struct BridgedData {
116-
const char *_Nullable baseAddress;
117-
size_t size;
143+
class BridgedData {
144+
public:
145+
SWIFT_UNAVAILABLE("Use '.baseAddress' instead")
146+
const char *_Nullable BaseAddress;
147+
148+
SWIFT_UNAVAILABLE("Use '.count' instead")
149+
size_t Length;
150+
151+
BridgedData() : BaseAddress(nullptr), Length(0) {}
152+
153+
SWIFT_NAME("init(baseAddress:count:)")
154+
BridgedData(const char *_Nullable baseAddress, size_t length)
155+
: BaseAddress(baseAddress), Length(length) {}
118156
};
119157

158+
SWIFT_NAME("getter:BridgedData.baseAddress(self:)")
159+
BRIDGED_INLINE
160+
const char *_Nullable BridgedData_baseAddress(BridgedData data);
161+
162+
SWIFT_NAME("getter:BridgedData.count(self:)")
163+
BRIDGED_INLINE SwiftInt BridgedData_count(BridgedData data);
164+
165+
SWIFT_NAME("BridgedData.free(self:)")
120166
void BridgedData_free(BridgedData data);
121167

122168
//===----------------------------------------------------------------------===//
@@ -153,6 +199,8 @@ class BridgedStringRef {
153199
llvm::StringRef get() const { return llvm::StringRef(Data, Length); }
154200
#endif
155201

202+
BridgedStringRef() : Data(nullptr), Length(0) {}
203+
156204
SWIFT_NAME("init(data:count:)")
157205
BridgedStringRef(const char *_Nullable data, size_t length)
158206
: Data(data), Length(length) {}

include/swift/Basic/BasicBridgingImpl.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,30 @@
1515

1616
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
1717

18+
//===----------------------------------------------------------------------===//
19+
// MARK: BridgedArrayRef
20+
//===----------------------------------------------------------------------===//
21+
22+
const void *_Nullable BridgedArrayRef_data(BridgedArrayRef arr) {
23+
return arr.Data;
24+
}
25+
26+
SwiftInt BridgedArrayRef_count(BridgedArrayRef arr) {
27+
return static_cast<SwiftInt>(arr.Length);
28+
}
29+
30+
//===----------------------------------------------------------------------===//
31+
// MARK: BridgedData
32+
//===----------------------------------------------------------------------===//
33+
34+
const char *_Nullable BridgedData_baseAddress(BridgedData data) {
35+
return data.BaseAddress;
36+
}
37+
38+
SwiftInt BridgedData_count(BridgedData data) {
39+
return static_cast<SwiftInt>(data.Length);
40+
}
41+
1842
//===----------------------------------------------------------------------===//
1943
// MARK: BridgedStringRef
2044
//===----------------------------------------------------------------------===//

include/swift/Basic/BridgingUtils.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@
2323

2424
namespace swift {
2525

26-
template <typename T>
27-
inline llvm::ArrayRef<T> getArrayRef(BridgedArrayRef bridged) {
28-
return {static_cast<const T *>(bridged.data), bridged.numElements};
29-
}
30-
3126
} // namespace swift
3227

3328
#endif

include/swift/SIL/SILBridging.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,18 @@ struct BridgedSubstitutionMap {
411411
struct BridgedTypeArray {
412412
BridgedArrayRef typeArray;
413413

414+
#ifdef USED_IN_CPP_SOURCE
415+
BridgedTypeArray(llvm::ArrayRef<swift::Type> types) : typeArray(types) {}
416+
417+
llvm::ArrayRef<swift::Type> get() const {
418+
return typeArray.get<swift::Type>();
419+
}
420+
#endif
421+
414422
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
415423
static BridgedTypeArray fromReplacementTypes(BridgedSubstitutionMap substMap);
416424

417-
SwiftInt getCount() const { return SwiftInt(typeArray.numElements); }
425+
SwiftInt getCount() const { return SwiftInt(typeArray.Length); }
418426

419427
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
420428
BridgedType getAt(SwiftInt index) const;
@@ -423,7 +431,16 @@ struct BridgedTypeArray {
423431
struct BridgedSILTypeArray {
424432
BridgedArrayRef typeArray;
425433

426-
SwiftInt getCount() const { return SwiftInt(typeArray.numElements); }
434+
#ifdef USED_IN_CPP_SOURCE
435+
BridgedSILTypeArray(llvm::ArrayRef<swift::SILType> silTypes)
436+
: typeArray(silTypes) {}
437+
438+
llvm::ArrayRef<swift::SILType> get() const {
439+
return typeArray.get<swift::SILType>();
440+
}
441+
#endif
442+
443+
SwiftInt getCount() const { return SwiftInt(typeArray.Length); }
427444

428445
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
429446
BridgedType getAt(SwiftInt index) const;

include/swift/SIL/SILBridgingImpl.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -567,14 +567,13 @@ SwiftInt BridgedMultiValueResult::getIndex() const {
567567
// BridgedTypeArray
568568
//===----------------------------------------------------------------------===//
569569

570-
BridgedTypeArray BridgedTypeArray::fromReplacementTypes(BridgedSubstitutionMap substMap) {
571-
swift::ArrayRef<swift::Type> replTypes = substMap.get().getReplacementTypes();
572-
return {replTypes.data(), replTypes.size()};
570+
BridgedTypeArray
571+
BridgedTypeArray::fromReplacementTypes(BridgedSubstitutionMap substMap) {
572+
return substMap.get().getReplacementTypes();
573573
}
574574

575575
BridgedType BridgedTypeArray::getAt(SwiftInt index) const {
576-
assert((size_t)index < typeArray.numElements);
577-
swift::Type origTy = ((const swift::Type *)typeArray.data)[index];
576+
swift::Type origTy = get()[index];
578577
auto ty = origTy->getCanonicalType();
579578
if (ty->isLegalSILType())
580579
return swift::SILType::getPrimitiveObjectType(ty);
@@ -586,8 +585,7 @@ BridgedType BridgedTypeArray::getAt(SwiftInt index) const {
586585
//===----------------------------------------------------------------------===//
587586

588587
BridgedType BridgedSILTypeArray::getAt(SwiftInt index) const {
589-
assert((size_t)index < typeArray.numElements);
590-
return ((const swift::SILType *)typeArray.data)[index];
588+
return get()[index];
591589
}
592590

593591
//===----------------------------------------------------------------------===//
@@ -865,8 +863,7 @@ SwiftInt BridgedInstruction::AllocRefInstBase_getNumTailTypes() const {
865863
}
866864

867865
BridgedSILTypeArray BridgedInstruction::AllocRefInstBase_getTailAllocatedTypes() const {
868-
llvm::ArrayRef<swift::SILType> types = getAs<const swift::AllocRefInstBase>()->getTailAllocatedTypes();
869-
return {types.data(), types.size()};
866+
return getAs<const swift::AllocRefInstBase>()->getTailAllocatedTypes();
870867
}
871868

872869
bool BridgedInstruction::AllocRefDynamicInst_isDynamicTypeDeinitAndSizeKnownEquivalentToBaseType() const {

lib/AST/ASTBridging.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ using namespace swift;
4040
template <typename T>
4141
static inline llvm::ArrayRef<T>
4242
unbridgedArrayRef(const BridgedArrayRef bridged) {
43-
return {static_cast<const T *>(bridged.data), size_t(bridged.numElements)};
43+
return bridged.get<T>();
4444
}
4545

4646
static inline StringRef unbridged(BridgedStringRef cStr) {
@@ -202,7 +202,7 @@ void BridgedDiagnosticEngine_diagnose(
202202

203203
auto diagID = static_cast<DiagID>(bridgedDiagID);
204204
SmallVector<DiagnosticArgument, 2> arguments;
205-
for (auto arg : getArrayRef<BridgedDiagnosticArgument>(bridgedArguments)) {
205+
for (auto arg : bridgedArguments.get<BridgedDiagnosticArgument>()) {
206206
arguments.push_back(arg.get());
207207
}
208208
auto inflight = D->diagnose(loc.get(), diagID, arguments);
@@ -215,7 +215,7 @@ void BridgedDiagnosticEngine_diagnose(
215215

216216
// Add fix-its.
217217
for (const BridgedDiagnosticFixIt &fixIt :
218-
getArrayRef<BridgedDiagnosticFixIt>(bridgedFixIts)) {
218+
bridgedFixIts.get<BridgedDiagnosticFixIt>()) {
219219
auto range = fixIt.get().getRange();
220220
auto text = fixIt.get().getText();
221221
inflight.fixItReplaceChars(range.getStart(), range.getEnd(), text);
@@ -1460,7 +1460,7 @@ bool Plugin_spawnIfNeeded(PluginHandle handle) {
14601460

14611461
bool Plugin_sendMessage(PluginHandle handle, const BridgedData data) {
14621462
auto *plugin = static_cast<LoadedExecutablePlugin *>(handle);
1463-
StringRef message(data.baseAddress, data.size);
1463+
StringRef message(data.BaseAddress, data.Length);
14641464
auto error = plugin->sendMessage(message);
14651465
if (error) {
14661466
// FIXME: Pass the error message back to the caller.

lib/ASTGen/Sources/ASTGen/ASTGen.swift

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,7 @@ extension ASTGenVisitor {
380380
@inline(__always)
381381
func generate(_ node: InheritedTypeListSyntax?) -> BridgedArrayRef {
382382
guard let node else {
383-
// NOTE: You cannot do '.init()' here as that will produce garbage
384-
// (rdar://116825963).
385-
return .init(data: nil, numElements: 0)
383+
return .init()
386384
}
387385

388386
return self.generate(node)
@@ -391,9 +389,7 @@ extension ASTGenVisitor {
391389
@inline(__always)
392390
func generate(_ node: PrecedenceGroupNameListSyntax?) -> BridgedArrayRef {
393391
guard let node else {
394-
// NOTE: You cannot do '.init()' here as that will produce garbage
395-
// (rdar://116825963).
396-
return .init(data: nil, numElements: 0)
392+
return .init()
397393
}
398394

399395
return self.generate(node)
@@ -407,9 +403,7 @@ extension Collection {
407403
/// on a ``LazyFilterSequence`` due to the `count` access.
408404
func compactMap<T>(in astgen: ASTGenVisitor, _ transform: (Element) -> T?) -> BridgedArrayRef {
409405
if self.isEmpty {
410-
// NOTE: You cannot do '.init()' here as that will produce garbage
411-
// (rdar://116825963).
412-
return .init(data: nil, numElements: 0)
406+
return .init()
413407
}
414408

415409
let baseAddress = astgen.allocator.allocate(T.self, count: self.count).baseAddress!
@@ -427,23 +421,21 @@ extension Collection {
427421
}
428422
}
429423

430-
return .init(data: baseAddress, numElements: self.count)
424+
return .init(data: baseAddress, count: self.count)
431425
}
432426
}
433427

434428
extension LazyCollectionProtocol {
435429
/// Returns a copy of the collection's elements as a `BridgedArrayRef` with a lifetime tied to that of `astgen`.
436430
func bridgedArray(in astgen: ASTGenVisitor) -> BridgedArrayRef {
437431
if self.isEmpty {
438-
// NOTE: You cannot do '.init()' here as that will produce garbage
439-
// (rdar://116825963).
440-
return .init(data: nil, numElements: 0)
432+
return .init()
441433
}
442434

443435
let buffer = astgen.allocator.allocate(Element.self, count: self.count)
444436
_ = buffer.initialize(from: self)
445437

446-
return .init(data: buffer.baseAddress, numElements: self.count)
438+
return .init(data: buffer.baseAddress, count: self.count)
447439
}
448440
}
449441

@@ -463,9 +455,7 @@ extension Optional where Wrapped: LazyCollectionProtocol {
463455
@inline(__always)
464456
func bridgedArray(in astgen: ASTGenVisitor) -> BridgedArrayRef {
465457
guard let self else {
466-
// NOTE: You cannot do '.init()' here as that will produce garbage
467-
// (rdar://116825963).
468-
return .init(data: nil, numElements: 0)
458+
return .init()
469459
}
470460

471461
return self.bridgedArray(in: astgen)

lib/ASTGen/Sources/ASTGen/Macros.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,7 @@ func makeExpansionOutputResult(
401401
outputPointer: UnsafeMutablePointer<BridgedStringRef>
402402
) -> Int {
403403
guard var expandedSource = expandedSource else {
404-
// NOTE: You cannot use 'init()' here as that will produce garbage
405-
// (rdar://116825963).
406-
outputPointer.pointee = BridgedStringRef(data: nil, count: 0)
404+
outputPointer.pointee = BridgedStringRef()
407405
return -1
408406
}
409407
outputPointer.pointee = allocateBridgedString(expandedSource)

lib/ASTGen/Sources/ASTGen/PluginHost.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,23 +119,21 @@ struct CompilerPlugin {
119119

120120
private func sendMessage(_ message: HostToPluginMessage) throws {
121121
let hadError = try LLVMJSON.encoding(message) { (data) -> Bool in
122-
return Plugin_sendMessage(opaqueHandle, BridgedData(baseAddress: data.baseAddress, size: data.count))
122+
return Plugin_sendMessage(opaqueHandle, BridgedData(baseAddress: data.baseAddress, count: data.count))
123123
}
124124
if hadError {
125125
throw PluginError.failedToSendMessage
126126
}
127127
}
128128

129129
private func waitForNextMessage() throws -> PluginToHostMessage {
130-
// NOTE: You cannot use 'init()' here as that will produce garbage
131-
// (rdar://116825963).
132-
var result = BridgedData(baseAddress: nil, size: 0)
130+
var result = BridgedData()
133131
let hadError = Plugin_waitForNextMessage(opaqueHandle, &result)
134-
defer { BridgedData_free(result) }
132+
defer { result.free() }
135133
guard !hadError else {
136134
throw PluginError.failedToReceiveMessage
137135
}
138-
let data = UnsafeBufferPointer(start: result.baseAddress, count: Int(result.size))
136+
let data = UnsafeBufferPointer(start: result.baseAddress, count: result.count)
139137
return try LLVMJSON.decode(PluginToHostMessage.self, from: data)
140138
}
141139

lib/ASTGen/Sources/LLVMJSON/LLVMJSON.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
extension String {
1919
init(_ data: BridgedData) {
20-
let buffer = UnsafeBufferPointer(start: data.baseAddress, count: Int(data.size))
20+
let buffer = UnsafeBufferPointer(start: data.baseAddress, count: data.count)
2121
self = buffer.withMemoryRebound(to: UInt8.self) { buffer in
2222
String(decoding: buffer, as: UTF8.self)
2323
}
@@ -37,14 +37,14 @@ public struct LLVMJSON {
3737
var data: BridgedData = BridgedData()
3838
JSON_value_serialize(valuePtr, &data)
3939
assert(data.baseAddress != nil)
40-
defer { BridgedData_free(data) }
41-
let buffer = UnsafeBufferPointer(start: data.baseAddress, count: data.size)
40+
defer { data.free() }
41+
let buffer = UnsafeBufferPointer(start: data.baseAddress, count: data.count)
4242
return try body(buffer)
4343
}
4444

4545
/// Decode a JSON data to a Swift value.
4646
public static func decode<T: Decodable>(_ type: T.Type, from json: UnsafeBufferPointer<Int8>) throws -> T {
47-
let data = BridgedData(baseAddress: json.baseAddress, size: json.count)
47+
let data = BridgedData(baseAddress: json.baseAddress, count: json.count)
4848
let valuePtr = JSON_deserializedValue(data)
4949
defer { JSON_value_delete(valuePtr) }
5050

0 commit comments

Comments
 (0)