Skip to content

Commit 7e76ead

Browse files
committed
[Macros] Use 'LibraryPluginProvider' in swift-plugin-server
Move 'PluginProvider' logic to 'SwiftCompilerPluginMessageHandling' module so the compiler can reuse that logic for the actual in-process plugins.
1 parent 23701bb commit 7e76ead

File tree

5 files changed

+4
-145
lines changed

5 files changed

+4
-145
lines changed

test/Macros/macro_plugin_server.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func testStringify(a: Int, b: Int) {
8787
let s3: String = #stringify(b + a).1
8888
print(s3)
8989

90-
// expected-error @+1 {{macro implementation type 'MacroDefinition.TypeDoesNotExist' could not be found in library plugin '}}
90+
// expected-error @+1 {{type 'MacroDefinition.TypeDoesNotExist' could not be found in library plugin '}}
9191
_ = #missing()
9292

9393
// expected-error @+1 {{type 'MacroDefinition.NotMacroStruct' is not a valid macro implementation type in library plugin '}}

tools/swift-plugin-server/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,13 @@ if (SWIFT_BUILD_SWIFT_SYNTAX)
44
add_swift_host_library(_swiftCSwiftPluginServer OBJECT
55
Sources/CSwiftPluginServer/PluginServer.cpp
66
)
7-
target_link_libraries(_swiftCSwiftPluginServer PRIVATE
8-
swiftDemangling
9-
)
107
target_include_directories(_swiftCSwiftPluginServer PUBLIC
118
Sources/CSwiftPluginServer/include
129
)
1310

1411
add_pure_swift_host_tool(swift-plugin-server
1512
Sources/swift-plugin-server/swift-plugin-server.swift
1613
DEPENDENCIES
17-
swiftDemangling
1814
$<TARGET_OBJECTS:_swiftCSwiftPluginServer>
1915
SWIFT_COMPONENT
2016
compiler

tools/swift-plugin-server/Sources/CSwiftPluginServer/PluginServer.cpp

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "PluginServer.h"
14-
#include "swift/ABI/MetadataValues.h"
15-
#include "swift/Demangling/Demangle.h"
16-
#include "llvm/Support/DynamicLibrary.h"
1714

1815
#if defined(_WIN32)
16+
#include <stdio.h>
1917
#include <io.h>
2018
#elif defined(__unix__) || defined(__APPLE__)
2119
#include <dlfcn.h>
@@ -25,8 +23,6 @@
2523
#include <errno.h>
2624
#include <string.h>
2725

28-
using namespace swift;
29-
3026
namespace {
3127
struct ConnectionHandle {
3228
int inputFD;
@@ -136,51 +132,3 @@ ptrdiff_t PluginServer_write(const void *server, const void *data,
136132
return ::write(connection->outputFD, data, nbyte);
137133
#endif
138134
}
139-
140-
void *PluginServer_load(const char *plugin, const char **errorMessage) {
141-
// Use a static allocation for the error as the client will not release the
142-
// string. POSIX 2008 (IEEE-1003.1-2008) specifies that it is implementation
143-
// defined if `dlerror` is re-entrant. Take advantage of that and make it
144-
// thread-unsafe. This ensures that the string outlives the call permitting
145-
// the client to duplicate it.
146-
static std::string error;
147-
auto library = llvm::sys::DynamicLibrary::getLibrary(plugin, &error);
148-
if (library.isValid())
149-
return library.getOSSpecificHandle();
150-
*errorMessage = error.c_str();
151-
return nullptr;
152-
}
153-
154-
const void *PluginServer_lookupMacroTypeMetadataByExternalName(
155-
const char *moduleName, const char *typeName, void *libraryHint,
156-
const char **errorMessage) {
157-
// Look up the type metadata accessor as a struct, enum, or class.
158-
const Demangle::Node::Kind typeKinds[] = {
159-
Demangle::Node::Kind::Structure,
160-
Demangle::Node::Kind::Enum,
161-
Demangle::Node::Kind::Class,
162-
};
163-
164-
void *accessorAddr = nullptr;
165-
for (auto typeKind : typeKinds) {
166-
auto symbolName =
167-
mangledNameForTypeMetadataAccessor(moduleName, typeName, typeKind);
168-
169-
#if !defined(_WIN32)
170-
if (libraryHint == nullptr)
171-
libraryHint = RTLD_DEFAULT;
172-
#endif
173-
accessorAddr = llvm::sys::DynamicLibrary{libraryHint}
174-
.getAddressOfSymbol(symbolName.c_str());
175-
if (accessorAddr)
176-
break;
177-
}
178-
179-
if (!accessorAddr)
180-
return nullptr;
181-
182-
// Call the accessor to form type metadata.
183-
using MetadataAccessFunc = const void *(MetadataRequest);
184-
auto accessor = reinterpret_cast<MetadataAccessFunc*>(accessorAddr);
185-
return accessor(MetadataRequest(MetadataState::Complete));
186-
}

tools/swift-plugin-server/Sources/CSwiftPluginServer/include/PluginServer.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,6 @@ ptrdiff_t PluginServer_read(const void *connHandle, void *data, size_t nbyte);
3737
ptrdiff_t PluginServer_write(const void *connHandle, const void *data,
3838
size_t nbyte);
3939

40-
//===----------------------------------------------------------------------===//
41-
// Dynamic link
42-
//===----------------------------------------------------------------------===//
43-
44-
/// Load a dynamic link library, and return the handle.
45-
void *PluginServer_load(const char *filename, const char **errorMessage);
46-
47-
/// Resolve a type metadata by a pair of the module name and the type name.
48-
/// 'libraryHint' is a
49-
const void *PluginServer_lookupMacroTypeMetadataByExternalName(
50-
const char *moduleName, const char *typeName, void *libraryHint,
51-
const char **errorMessage);
52-
5340
#ifdef __cplusplus
5441
}
5542
#endif

tools/swift-plugin-server/Sources/swift-plugin-server/swift-plugin-server.swift

Lines changed: 2 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -10,95 +10,23 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import SwiftCompilerPluginMessageHandling
14-
import SwiftSyntaxMacros
13+
@_spi(Compiler) import SwiftCompilerPluginMessageHandling
1514
import swiftLLVMJSON
1615
import CSwiftPluginServer
1716

1817
@main
1918
final class SwiftPluginServer {
20-
struct MacroRef: Hashable {
21-
var moduleName: String
22-
var typeName: String
23-
init(_ moduleName: String, _ typeName: String) {
24-
self.moduleName = moduleName
25-
self.typeName = typeName
26-
}
27-
}
28-
29-
struct LoadedLibraryPlugin {
30-
var libraryPath: String
31-
var handle: UnsafeMutableRawPointer
32-
}
33-
34-
/// Loaded dylib handles associated with the module name.
35-
var loadedLibraryPlugins: [String: LoadedLibraryPlugin] = [:]
36-
37-
/// Resolved cached macros.
38-
var resolvedMacros: [MacroRef: Macro.Type] = [:]
39-
4019
/// @main entry point.
4120
static func main() throws {
4221
let connection = try PluginHostConnection()
4322
let messageHandler = CompilerPluginMessageHandler(
4423
connection: connection,
45-
provider: self.init()
24+
provider: LibraryPluginProvider.shared
4625
)
4726
try messageHandler.main()
4827
}
4928
}
5029

51-
extension SwiftPluginServer: PluginProvider {
52-
/// Load a macro implementation from the dynamic link library.
53-
func loadPluginLibrary(libraryPath: String, moduleName: String) throws {
54-
var errorMessage: UnsafePointer<CChar>?
55-
guard let dlHandle = PluginServer_load(libraryPath, &errorMessage) else {
56-
throw PluginServerError(message: "loader error: " + String(cString: errorMessage!))
57-
}
58-
loadedLibraryPlugins[moduleName] = LoadedLibraryPlugin(
59-
libraryPath: libraryPath,
60-
handle: dlHandle
61-
)
62-
}
63-
64-
/// Lookup a loaded macro by a pair of module name and type name.
65-
func resolveMacro(moduleName: String, typeName: String) throws -> Macro.Type {
66-
if let resolved = resolvedMacros[.init(moduleName, typeName)] {
67-
return resolved
68-
}
69-
70-
// Find 'dlopen'ed library for the module name.
71-
guard let plugin = loadedLibraryPlugins[moduleName] else {
72-
// NOTE: This should be unreachable. Compiler should not use this server
73-
// unless the plugin loading succeeded.
74-
throw PluginServerError(message: "(plugin-server) plugin not loaded for module '\(moduleName)'")
75-
}
76-
77-
// Lookup the type metadata.
78-
var errorMessage: UnsafePointer<CChar>?
79-
guard let macroTypePtr = PluginServer_lookupMacroTypeMetadataByExternalName(
80-
moduleName, typeName, plugin.handle, &errorMessage
81-
) else {
82-
throw PluginServerError(message: "macro implementation type '\(moduleName).\(typeName)' could not be found in library plugin '\(plugin.libraryPath)'")
83-
}
84-
85-
// THe type must be a 'Macro' type.
86-
let macroType = unsafeBitCast(macroTypePtr, to: Any.Type.self)
87-
guard let macro = macroType as? Macro.Type else {
88-
throw PluginServerError(message: "type '\(moduleName).\(typeName)' is not a valid macro implementation type in library plugin '\(plugin.libraryPath)'")
89-
}
90-
91-
// Cache the resolved type.
92-
resolvedMacros[.init(moduleName, typeName)] = macro
93-
return macro
94-
}
95-
96-
/// This 'PluginProvider' implements 'loadLibraryMacro()'.
97-
var features: [SwiftCompilerPluginMessageHandling.PluginFeature] {
98-
[.loadPluginLibrary]
99-
}
100-
}
101-
10230
final class PluginHostConnection: MessageConnection {
10331
let handle: UnsafeRawPointer
10432
init() throws {

0 commit comments

Comments
 (0)