Skip to content

Commit fbb694b

Browse files
committed
Swift SIL: add bridging for witness and default witness tables
1 parent 7816513 commit fbb694b

File tree

10 files changed

+312
-3
lines changed

10 files changed

+312
-3
lines changed

SwiftCompilerSources/Sources/Optimizer/PassManager/ModulePassContext.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,34 @@ struct ModulePassContext {
4747
}
4848
}
4949

50+
struct WitnessTableList : CollectionLikeSequence, IteratorProtocol {
51+
private var currentTable: WitnessTable?
52+
53+
fileprivate init(first: WitnessTable?) { currentTable = first }
54+
55+
mutating func next() -> WitnessTable? {
56+
if let t = currentTable {
57+
currentTable = PassContext_nextWitnessTableInModule(t.bridged).table
58+
return t
59+
}
60+
return nil
61+
}
62+
}
63+
64+
struct DefaultWitnessTableList : CollectionLikeSequence, IteratorProtocol {
65+
private var currentTable: DefaultWitnessTable?
66+
67+
fileprivate init(first: DefaultWitnessTable?) { currentTable = first }
68+
69+
mutating func next() -> DefaultWitnessTable? {
70+
if let t = currentTable {
71+
currentTable = PassContext_nextDefaultWitnessTableInModule(t.bridged).table
72+
return t
73+
}
74+
return nil
75+
}
76+
}
77+
5078
var functions: FunctionList {
5179
FunctionList(first: PassContext_firstFunctionInModule(_bridged).function)
5280
}
@@ -55,6 +83,14 @@ struct ModulePassContext {
5583
VTableArray(bridged: PassContext_getVTables(_bridged))
5684
}
5785

86+
var witnessTables: WitnessTableList {
87+
WitnessTableList(first: PassContext_firstWitnessTableInModule(_bridged).table)
88+
}
89+
90+
var defaultWitnessTables: DefaultWitnessTableList {
91+
DefaultWitnessTableList(first: PassContext_firstDefaultWitnessTableInModule(_bridged).table)
92+
}
93+
5894
/// Run a closure with a `PassContext` for a function, which allows to modify that function.
5995
///
6096
/// Only a single `transform` can be alive at the same time, i.e. it's not allowed to nest

SwiftCompilerSources/Sources/SIL/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ add_swift_compiler_module(SIL
2626
Type.swift
2727
Utils.swift
2828
Value.swift
29-
VTable.swift)
30-
29+
VTable.swift
30+
WitnessTable.swift)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//===--- WitnessTable.swift -----------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SILBridging
14+
15+
public struct WitnessTable : CustomStringConvertible, CustomReflectable {
16+
public let bridged: BridgedWitnessTable
17+
18+
public init(bridged: BridgedWitnessTable) { self.bridged = bridged }
19+
20+
public struct Entry : CustomStringConvertible, CustomReflectable {
21+
fileprivate let bridged: BridgedWitnessTableEntry
22+
23+
public enum Kind {
24+
case method
25+
case associatedType
26+
case associatedTypeProtocol
27+
case baseProtocol
28+
}
29+
30+
public var kind: Kind {
31+
switch SILWitnessTableEntry_getKind(bridged) {
32+
case SILWitnessTableEntry_Method: return .method
33+
case SILWitnessTableEntry_AssociatedType: return .associatedType
34+
case SILWitnessTableEntry_AssociatedTypeProtocol: return .associatedTypeProtocol
35+
case SILWitnessTableEntry_BaseProtocol: return .baseProtocol
36+
default:
37+
fatalError("unknown witness table kind")
38+
}
39+
}
40+
41+
public var methodFunction: Function? {
42+
assert(kind == .method)
43+
return SILWitnessTableEntry_getMethodFunction(bridged).function
44+
}
45+
46+
public var description: String {
47+
let stdString = SILWitnessTableEntry_debugDescription(bridged)
48+
return String(_cxxString: stdString)
49+
}
50+
51+
public var customMirror: Mirror { Mirror(self, children: []) }
52+
}
53+
54+
public struct EntryArray : BridgedRandomAccessCollection {
55+
fileprivate let bridged: BridgedArrayRef
56+
57+
public var startIndex: Int { return 0 }
58+
public var endIndex: Int { return Int(bridged.numElements) }
59+
60+
public subscript(_ index: Int) -> Entry {
61+
precondition(index >= 0 && index < endIndex)
62+
return Entry(bridged: BridgedWitnessTableEntry(ptr: bridged.data! + index &* BridgedWitnessTableEntrySize))
63+
}
64+
}
65+
66+
public var entries: EntryArray {
67+
EntryArray(bridged: SILWitnessTable_getEntries(bridged))
68+
}
69+
70+
public var description: String {
71+
let stdString = SILWitnessTable_debugDescription(bridged)
72+
return String(_cxxString: stdString)
73+
}
74+
75+
public var customMirror: Mirror { Mirror(self, children: []) }
76+
}
77+
78+
public struct DefaultWitnessTable : CustomStringConvertible, CustomReflectable {
79+
public let bridged: BridgedDefaultWitnessTable
80+
81+
public init(bridged: BridgedDefaultWitnessTable) { self.bridged = bridged }
82+
83+
public typealias Entry = WitnessTable.Entry
84+
public typealias EntryArray = WitnessTable.EntryArray
85+
86+
public var entries: EntryArray {
87+
EntryArray(bridged: SILDefaultWitnessTable_getEntries(bridged))
88+
}
89+
90+
public var description: String {
91+
let stdString = SILDefaultWitnessTable_debugDescription(bridged)
92+
return String(_cxxString: stdString)
93+
}
94+
95+
public var customMirror: Mirror { Mirror(self, children: []) }
96+
}
97+
98+
extension OptionalBridgedWitnessTable {
99+
public var table: WitnessTable? {
100+
if let p = ptr {
101+
return WitnessTable(bridged: BridgedWitnessTable(ptr: p))
102+
}
103+
return nil
104+
}
105+
}
106+
107+
extension OptionalBridgedDefaultWitnessTable {
108+
public var table: DefaultWitnessTable? {
109+
if let p = ptr {
110+
return DefaultWitnessTable(bridged: BridgedDefaultWitnessTable(ptr: p))
111+
}
112+
return nil
113+
}
114+
}

include/swift/SIL/SILBridging.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
2424
enum {
2525
BridgedOperandSize = 4 * sizeof(uintptr_t),
2626
BridgedSuccessorSize = 4 * sizeof(uintptr_t) + sizeof(uint64_t),
27-
BridgedVTableEntrySize = 5 * sizeof(uintptr_t)
27+
BridgedVTableEntrySize = 5 * sizeof(uintptr_t),
28+
BridgedWitnessTableEntrySize = 5 * sizeof(uintptr_t)
2829
};
2930

3031
enum ChangeNotificationKind {
@@ -77,6 +78,33 @@ typedef struct {
7778
const void * _Nonnull ptr;
7879
} BridgedVTableEntry;
7980

81+
typedef struct {
82+
const void * _Nonnull ptr;
83+
} BridgedWitnessTable;
84+
85+
typedef struct {
86+
const void * _Nullable ptr;
87+
} OptionalBridgedWitnessTable;
88+
89+
typedef struct {
90+
const void * _Nonnull ptr;
91+
} BridgedDefaultWitnessTable;
92+
93+
typedef struct {
94+
const void * _Nullable ptr;
95+
} OptionalBridgedDefaultWitnessTable;
96+
97+
typedef struct {
98+
const void * _Nonnull ptr;
99+
} BridgedWitnessTableEntry;
100+
101+
typedef enum {
102+
SILWitnessTableEntry_Method,
103+
SILWitnessTableEntry_AssociatedType,
104+
SILWitnessTableEntry_AssociatedTypeProtocol,
105+
SILWitnessTableEntry_BaseProtocol
106+
} SILWitnessTableEntryKind;
107+
80108
typedef struct {
81109
SwiftObject obj;
82110
} BridgedFunction;
@@ -247,6 +275,14 @@ BridgedArrayRef SILVTable_getEntries(BridgedVTable vTable);
247275
std::string SILVTableEntry_debugDescription(BridgedVTableEntry entry);
248276
BridgedFunction SILVTableEntry_getFunction(BridgedVTableEntry entry);
249277

278+
std::string SILWitnessTable_debugDescription(BridgedWitnessTable table);
279+
BridgedArrayRef SILWitnessTable_getEntries(BridgedWitnessTable table);
280+
std::string SILDefaultWitnessTable_debugDescription(BridgedDefaultWitnessTable table);
281+
BridgedArrayRef SILDefaultWitnessTable_getEntries(BridgedDefaultWitnessTable table);
282+
std::string SILWitnessTableEntry_debugDescription(BridgedWitnessTableEntry entry);
283+
SILWitnessTableEntryKind SILWitnessTableEntry_getKind(BridgedWitnessTableEntry entry);
284+
OptionalBridgedFunction SILWitnessTableEntry_getMethodFunction(BridgedWitnessTableEntry entry);
285+
250286
OptionalBridgedBasicBlock SILBasicBlock_next(BridgedBasicBlock block);
251287
OptionalBridgedBasicBlock SILBasicBlock_previous(BridgedBasicBlock block);
252288
BridgedFunction SILBasicBlock_getFunction(BridgedBasicBlock block);

include/swift/SIL/SILBridgingUtils.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "swift/SIL/SILFunction.h"
1818
#include "swift/SIL/SILGlobalVariable.h"
1919
#include "swift/SIL/SILVTable.h"
20+
#include "swift/SIL/SILWitnessTable.h"
21+
#include "swift/SIL/SILDefaultWitnessTable.h"
2022
#include "llvm/ADT/StringRef.h"
2123

2224
#include <string>
@@ -93,6 +95,20 @@ inline const SILVTableEntry *castToVTableEntry(BridgedVTableEntry entry) {
9395
return static_cast<const SILVTableEntry *>(entry.ptr);
9496
}
9597

98+
inline const SILWitnessTable *castToWitnessTable(BridgedWitnessTable table) {
99+
return static_cast<const SILWitnessTable *>(table.ptr);
100+
}
101+
102+
inline const SILDefaultWitnessTable *
103+
castToDefaultWitnessTable(BridgedDefaultWitnessTable table) {
104+
return static_cast<const SILDefaultWitnessTable *>(table.ptr);
105+
}
106+
107+
inline const SILWitnessTable::Entry *
108+
castToWitnessTableEntry(BridgedWitnessTableEntry entry) {
109+
return static_cast<const SILWitnessTable::Entry *>(entry.ptr);
110+
}
111+
96112
inline ValueOwnershipKind castToOwnership(BridgedOwnership ownership) {
97113
switch (ownership) {
98114
case Ownership_Unowned: return OwnershipKind::Unowned;

include/swift/SIL/SILDefaultWitnessTable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ class SILDefaultWitnessTable : public llvm::ilist_node<SILDefaultWitnessTable>,
105105

106106
~SILDefaultWitnessTable();
107107

108+
SILModule &getModule() const { return Mod; }
109+
108110
/// Return true if this is a declaration with no body.
109111
bool isDeclaration() const { return IsDeclaration; }
110112

include/swift/SIL/SILWitnessTable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ class SILWitnessTable : public llvm::ilist_node<SILWitnessTable>,
223223
RootProtocolConformance *conformance);
224224

225225
~SILWitnessTable();
226+
227+
SILModule &getModule() const { return Mod; }
226228

227229
/// Return the AST ProtocolConformance this witness table represents.
228230
RootProtocolConformance *getConformance() const {

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ PassContext_firstFunctionInModule(BridgedPassContext context);
172172
OptionalBridgedFunction
173173
PassContext_nextFunctionInModule(BridgedFunction function);
174174
BridgedVTableArray PassContext_getVTables(BridgedPassContext context);
175+
OptionalBridgedWitnessTable
176+
PassContext_firstWitnessTableInModule(BridgedPassContext context);
177+
OptionalBridgedWitnessTable
178+
PassContext_nextWitnessTableInModule(BridgedWitnessTable table);
179+
OptionalBridgedDefaultWitnessTable
180+
PassContext_firstDefaultWitnessTableInModule(BridgedPassContext context);
181+
OptionalBridgedDefaultWitnessTable
182+
PassContext_nextDefaultWitnessTableInModule(BridgedDefaultWitnessTable table);
175183

176184
OptionalBridgedFunction
177185
PassContext_loadFunction(BridgedPassContext context, llvm::StringRef name);

lib/SIL/Utils/SILBridging.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,67 @@ BridgedFunction SILVTableEntry_getFunction(BridgedVTableEntry entry) {
581581
return {castToVTableEntry(entry)->getImplementation()};
582582
}
583583

584+
//===----------------------------------------------------------------------===//
585+
// SILVWitnessTable, SILDefaultWitnessTable
586+
//===----------------------------------------------------------------------===//
587+
588+
static_assert(BridgedWitnessTableEntrySize == sizeof(SILWitnessTable::Entry),
589+
"wrong bridged WitnessTable entry size");
590+
591+
std::string SILWitnessTable_debugDescription(BridgedWitnessTable table) {
592+
std::string str;
593+
llvm::raw_string_ostream os(str);
594+
castToWitnessTable(table)->print(os);
595+
str.pop_back(); // Remove trailing newline.
596+
return str;
597+
}
598+
599+
BridgedArrayRef SILWitnessTable_getEntries(BridgedWitnessTable table) {
600+
auto entries = castToWitnessTable(table)->getEntries();
601+
return {(const unsigned char *)entries.data(), entries.size()};
602+
}
603+
604+
std::string SILDefaultWitnessTable_debugDescription(BridgedDefaultWitnessTable table) {
605+
std::string str;
606+
llvm::raw_string_ostream os(str);
607+
castToDefaultWitnessTable(table)->print(os);
608+
str.pop_back(); // Remove trailing newline.
609+
return str;
610+
}
611+
612+
BridgedArrayRef SILDefaultWitnessTable_getEntries(BridgedDefaultWitnessTable table) {
613+
auto entries = castToDefaultWitnessTable(table)->getEntries();
614+
return {(const unsigned char *)entries.data(), entries.size()};
615+
}
616+
617+
std::string SILWitnessTableEntry_debugDescription(BridgedWitnessTableEntry entry) {
618+
std::string str;
619+
llvm::raw_string_ostream os(str);
620+
castToWitnessTableEntry(entry)->print(os, /*verbose=*/ false,
621+
PrintOptions::printSIL());
622+
str.pop_back(); // Remove trailing newline.
623+
return str;
624+
}
625+
626+
SILWitnessTableEntryKind SILWitnessTableEntry_getKind(BridgedWitnessTableEntry entry) {
627+
switch (castToWitnessTableEntry(entry)->getKind()) {
628+
case SILWitnessTable::Method:
629+
return SILWitnessTableEntry_Method;
630+
case SILWitnessTable::AssociatedType:
631+
return SILWitnessTableEntry_AssociatedType;
632+
case SILWitnessTable::AssociatedTypeProtocol:
633+
return SILWitnessTableEntry_AssociatedTypeProtocol;
634+
case SILWitnessTable::BaseProtocol:
635+
return SILWitnessTableEntry_BaseProtocol;
636+
default:
637+
llvm_unreachable("wrong witness table entry kind");
638+
}
639+
}
640+
641+
OptionalBridgedFunction SILWitnessTableEntry_getMethodFunction(BridgedWitnessTableEntry entry) {
642+
return {castToWitnessTableEntry(entry)->getMethodWitness().Witness};
643+
}
644+
584645
//===----------------------------------------------------------------------===//
585646
// SILInstruction
586647
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)