Skip to content

Commit 6abe93e

Browse files
committed
[Macros] PluginRegistry vends 'LoadedLibraryPlugin' instead of 'void *'
`LoadedLibraryPlugin` is currently just a wrapper of `void` pointer from `dlopen`. This will be convenient for abstracting platform specific dynamic linrary handling.
1 parent 25f26e2 commit 6abe93e

File tree

6 files changed

+55
-32
lines changed

6 files changed

+55
-32
lines changed

include/swift/AST/ASTContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ namespace swift {
8080
class ExtensionDecl;
8181
struct ExternalSourceLocs;
8282
class LoadedExecutablePlugin;
83+
class LoadedLibraryPlugin;
8384
class ForeignRepresentationInfo;
8485
class FuncDecl;
8586
class GenericContext;
@@ -1474,7 +1475,7 @@ class ASTContext final {
14741475
/// returns a nullptr.
14751476
/// NOTE: This method is idempotent. If the plugin is already loaded, the same
14761477
/// instance is simply returned.
1477-
void *loadLibraryPlugin(StringRef path);
1478+
LoadedLibraryPlugin *loadLibraryPlugin(StringRef path);
14781479

14791480
/// Lookup an executable plugin that is declared to handle \p moduleName
14801481
/// module by '-load-plugin-executable'.

include/swift/AST/PluginRegistry.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@
2222

2323
namespace swift {
2424

25+
/// Represent a 'dlopen'ed plugin library.
26+
class LoadedLibraryPlugin {
27+
// Opaque handle used to interface with OS-specific dynamic library.
28+
void *handle;
29+
30+
/// Cache of loaded symbols.
31+
llvm::StringMap<void *> resolvedSymbols;
32+
33+
public:
34+
LoadedLibraryPlugin(void *handle) : handle(handle) {}
35+
36+
/// Finds the address of the given symbol within the library.
37+
void *getAddressOfSymbol(const char *symbolName);
38+
};
39+
2540
/// Represent a "resolved" exectuable plugin.
2641
///
2742
/// Plugin clients usually deal with this object to communicate with the actual
@@ -130,7 +145,7 @@ class LoadedExecutablePlugin {
130145

131146
class PluginRegistry {
132147
/// Record of loaded plugin library modules.
133-
llvm::StringMap<void *> LoadedPluginLibraries;
148+
llvm::StringMap<std::unique_ptr<LoadedLibraryPlugin>> LoadedPluginLibraries;
134149

135150
/// Record of loaded plugin executables.
136151
llvm::StringMap<std::unique_ptr<LoadedExecutablePlugin>>
@@ -146,7 +161,7 @@ class PluginRegistry {
146161

147162
/// Load a dynamic link library specified by \p path.
148163
/// If \p path plugin is already loaded, this returns the cached object.
149-
llvm::Expected<void *> loadLibraryPlugin(llvm::StringRef path);
164+
llvm::Expected<LoadedLibraryPlugin *> loadLibraryPlugin(llvm::StringRef path);
150165

151166
/// Load an executable plugin specified by \p path .
152167
/// If \p path plugin is already loaded, this returns the cached object.

include/swift/AST/TypeCheckRequests.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class ClosureExpr;
5050
class GenericParamList;
5151
class LabeledStmt;
5252
class LoadedExecutablePlugin;
53+
class LoadedLibraryPlugin;
5354
class MacroDefinition;
5455
class PrecedenceGroupDecl;
5556
class PropertyWrapperInitializerInfo;
@@ -4017,15 +4018,17 @@ class LoadedCompilerPlugin {
40174018
public:
40184019
LoadedCompilerPlugin(std::nullptr_t) : kind(PluginKind::None), ptr(nullptr) {}
40194020

4020-
static LoadedCompilerPlugin inProcess(void *ptr) {
4021+
static LoadedCompilerPlugin inProcess(LoadedLibraryPlugin *ptr) {
40214022
return {PluginKind::InProcess, ptr};
40224023
}
40234024
static LoadedCompilerPlugin executable(LoadedExecutablePlugin *ptr) {
40244025
return {PluginKind::Executable, ptr};
40254026
}
40264027

4027-
void *getAsInProcessPlugin() const {
4028-
return kind == PluginKind::InProcess ? ptr : nullptr;
4028+
LoadedLibraryPlugin *getAsInProcessPlugin() const {
4029+
return kind == PluginKind::InProcess
4030+
? static_cast<LoadedLibraryPlugin *>(ptr)
4031+
: nullptr;
40294032
}
40304033
LoadedExecutablePlugin *getAsExecutablePlugin() const {
40314034
return kind == PluginKind::Executable

lib/AST/ASTContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6396,7 +6396,7 @@ LoadedExecutablePlugin *ASTContext::loadExecutablePlugin(StringRef path) {
63966396
return plugin.get();
63976397
}
63986398

6399-
void *ASTContext::loadLibraryPlugin(StringRef path) {
6399+
LoadedLibraryPlugin *ASTContext::loadLibraryPlugin(StringRef path) {
64006400
// Remember the path (even if it fails to load.)
64016401
getImpl().LoadedPluginLibraryPaths.insert(path);
64026402

lib/AST/PluginRegistry.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ PluginRegistry::PluginRegistry() {
4444
dumpMessaging = ::getenv("SWIFT_DUMP_PLUGIN_MESSAGING") != nullptr;
4545
}
4646

47-
llvm::Expected<void *> PluginRegistry::loadLibraryPlugin(StringRef path) {
47+
llvm::Expected<LoadedLibraryPlugin *>
48+
PluginRegistry::loadLibraryPlugin(StringRef path) {
4849
std::lock_guard<std::mutex> lock(mtx);
49-
auto found = LoadedPluginLibraries.find(path);
50-
if (found != LoadedPluginLibraries.end()) {
50+
auto &storage = LoadedPluginLibraries[path];
51+
if (storage) {
5152
// Already loaded.
52-
return found->second;
53+
return storage.get();
5354
}
55+
5456
void *lib = nullptr;
5557
#if defined(_WIN32)
5658
lib = LoadLibraryA(path.str().c_str());
@@ -64,8 +66,19 @@ llvm::Expected<void *> PluginRegistry::loadLibraryPlugin(StringRef path) {
6466
return llvm::createStringError(llvm::inconvertibleErrorCode(), dlerror());
6567
}
6668
#endif
67-
LoadedPluginLibraries.insert({path, lib});
68-
return lib;
69+
70+
storage = std::unique_ptr<LoadedLibraryPlugin>(new LoadedLibraryPlugin(lib));
71+
return storage.get();
72+
}
73+
74+
void *LoadedLibraryPlugin::getAddressOfSymbol(const char *symbolName) {
75+
auto &cached = resolvedSymbols[symbolName];
76+
if (cached)
77+
return cached;
78+
#if !defined(_WIN32)
79+
cached = dlsym(handle, symbolName);
80+
#endif
81+
return cached;
6982
}
7083

7184
llvm::Expected<LoadedExecutablePlugin *>

lib/Sema/TypeCheckMacros.cpp

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ extern "C" bool swift_ASTGen_pluginServerLoadLibraryPlugin(
9090

9191
#if SWIFT_SWIFT_PARSER
9292
/// Look for macro's type metadata given its external module and type name.
93-
static void const *lookupMacroTypeMetadataByExternalName(
94-
ASTContext &ctx, StringRef moduleName, StringRef typeName,
95-
void *libraryHint = nullptr
96-
) {
93+
static void const *
94+
lookupMacroTypeMetadataByExternalName(ASTContext &ctx, StringRef moduleName,
95+
StringRef typeName,
96+
LoadedLibraryPlugin *plugin) {
9797
// Look up the type metadata accessor as a struct, enum, or class.
9898
const Demangle::Node::Kind typeKinds[] = {
9999
Demangle::Node::Kind::Structure,
@@ -105,11 +105,7 @@ static void const *lookupMacroTypeMetadataByExternalName(
105105
for (auto typeKind : typeKinds) {
106106
auto symbolName = Demangle::mangledNameForTypeMetadataAccessor(
107107
moduleName, typeName, typeKind);
108-
#if !defined(_WIN32)
109-
/// FIXME: 'PluginRegistry' should vend a wrapper object of the library
110-
/// handle (like llvm::sys::DynamicLibrary) and dlsym should be abstracted.
111-
accessorAddr = dlsym(libraryHint, symbolName.c_str());
112-
#endif
108+
accessorAddr = plugin->getAddressOfSymbol(symbolName.c_str());
113109
if (accessorAddr)
114110
break;
115111
}
@@ -276,7 +272,8 @@ MacroDefinition MacroDefinitionRequest::evaluate(
276272
}
277273

278274
/// Load a plugin library based on a module name.
279-
static void *loadLibraryPluginByName(ASTContext &ctx, Identifier moduleName) {
275+
static LoadedLibraryPlugin *loadLibraryPluginByName(ASTContext &ctx,
276+
Identifier moduleName) {
280277
std::string libraryPath;
281278
if (auto found = ctx.lookupLibraryPluginByModuleName(moduleName)) {
282279
libraryPath = *found;
@@ -367,10 +364,6 @@ loadExecutablePluginByName(ASTContext &ctx, Identifier moduleName) {
367364
LoadedCompilerPlugin
368365
CompilerPluginLoadRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
369366
Identifier moduleName) const {
370-
auto fs = ctx->SourceMgr.getFileSystem();
371-
auto &searchPathOpts = ctx->SearchPathOpts;
372-
auto *registry = ctx->getPluginRegistry();
373-
374367
// Check dynamic link library plugins.
375368
// i.e. '-plugin-path', and '-load-plugin-library'.
376369
if (auto found = loadLibraryPluginByName(*ctx, moduleName))
@@ -386,14 +379,12 @@ CompilerPluginLoadRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
386379
}
387380

388381
static Optional<ExternalMacroDefinition>
389-
resolveInProcessMacro(
390-
ASTContext &ctx, Identifier moduleName, Identifier typeName,
391-
void *libraryHint = nullptr
392-
) {
382+
resolveInProcessMacro(ASTContext &ctx, Identifier moduleName,
383+
Identifier typeName, LoadedLibraryPlugin *plugin) {
393384
#if SWIFT_SWIFT_PARSER
394385
/// Look for the type metadata given the external module and type names.
395386
auto macroMetatype = lookupMacroTypeMetadataByExternalName(
396-
ctx, moduleName.str(), typeName.str(), libraryHint);
387+
ctx, moduleName.str(), typeName.str(), plugin);
397388
if (macroMetatype) {
398389
// Check whether the macro metatype is in-process.
399390
if (auto inProcess = swift_ASTGen_resolveMacroType(macroMetatype)) {

0 commit comments

Comments
 (0)