Skip to content

Commit 347e565

Browse files
authored
Merge pull request #64845 from rintaro/macros-loadedlibraryplugin
[Macros] PluginRegistry vends 'LoadedLibraryPlugin' instead of 'void *'
2 parents 153c9d2 + 90e1558 commit 347e565

File tree

6 files changed

+72
-74
lines changed

6 files changed

+72
-74
lines changed

include/swift/AST/ASTContext.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ namespace swift {
8282
class ExtensionDecl;
8383
struct ExternalSourceLocs;
8484
class LoadedExecutablePlugin;
85+
class LoadedLibraryPlugin;
8586
class ForeignRepresentationInfo;
8687
class FuncDecl;
8788
class GenericContext;
@@ -1496,7 +1497,7 @@ class ASTContext final {
14961497
/// returns a nullptr.
14971498
/// NOTE: This method is idempotent. If the plugin is already loaded, the same
14981499
/// instance is simply returned.
1499-
void *loadLibraryPlugin(StringRef path);
1500+
LoadedLibraryPlugin *loadLibraryPlugin(StringRef path);
15001501

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

include/swift/AST/PluginRegistry.h

+21-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12+
#ifndef SWIFT_PLUGIN_REGISTRY_H
13+
#define SWIFT_PLUGIN_REGISTRY_H
1214

1315
#include "llvm/ADT/ArrayRef.h"
1416
#include "llvm/ADT/StringMap.h"
@@ -22,6 +24,21 @@
2224

2325
namespace swift {
2426

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

131148
class PluginRegistry {
132149
/// Record of loaded plugin library modules.
133-
llvm::StringMap<void *> LoadedPluginLibraries;
150+
llvm::StringMap<std::unique_ptr<LoadedLibraryPlugin>> LoadedPluginLibraries;
134151

135152
/// Record of loaded plugin executables.
136153
llvm::StringMap<std::unique_ptr<LoadedExecutablePlugin>>
@@ -146,7 +163,7 @@ class PluginRegistry {
146163

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

151168
/// Load an executable plugin specified by \p path .
152169
/// If \p path plugin is already loaded, this returns the cached object.
@@ -155,3 +172,5 @@ class PluginRegistry {
155172
};
156173

157174
} // namespace swift
175+
176+
#endif // SWIFT_PLUGIN_REGISTRY_H

include/swift/AST/TypeCheckRequests.h

+9-28
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/AST/Type.h"
2727
#include "swift/AST/Evaluator.h"
2828
#include "swift/AST/Pattern.h"
29+
#include "swift/AST/PluginRegistry.h"
2930
#include "swift/AST/ProtocolConformance.h"
3031
#include "swift/AST/SimpleRequest.h"
3132
#include "swift/AST/SourceFile.h"
@@ -49,7 +50,6 @@ struct ExternalMacroDefinition;
4950
class ClosureExpr;
5051
class GenericParamList;
5152
class LabeledStmt;
52-
class LoadedExecutablePlugin;
5353
class MacroDefinition;
5454
class PrecedenceGroupDecl;
5555
class PropertyWrapperInitializerInfo;
@@ -3998,39 +3998,20 @@ class ExpandSynthesizedMemberMacroRequest
39983998
bool isCached() const { return true; }
39993999
};
40004000

4001-
/// Load a plugin module with the given name.
4002-
///
4003-
///
4001+
/// Represent a loaded plugin either an in-process library or an executable.
40044002
class LoadedCompilerPlugin {
4005-
enum class PluginKind : uint8_t {
4006-
None,
4007-
InProcess,
4008-
Executable,
4009-
};
4010-
PluginKind kind;
4011-
void *ptr;
4012-
4013-
LoadedCompilerPlugin(PluginKind kind, void *ptr) : kind(kind), ptr(ptr) {
4014-
assert(ptr != nullptr || kind == PluginKind::None);
4015-
}
4003+
llvm::PointerUnion<LoadedLibraryPlugin *, LoadedExecutablePlugin *> ptr;
40164004

40174005
public:
4018-
LoadedCompilerPlugin(std::nullptr_t) : kind(PluginKind::None), ptr(nullptr) {}
4019-
4020-
static LoadedCompilerPlugin inProcess(void *ptr) {
4021-
return {PluginKind::InProcess, ptr};
4022-
}
4023-
static LoadedCompilerPlugin executable(LoadedExecutablePlugin *ptr) {
4024-
return {PluginKind::Executable, ptr};
4025-
}
4006+
LoadedCompilerPlugin(std::nullptr_t) : ptr(nullptr) {}
4007+
LoadedCompilerPlugin(LoadedLibraryPlugin *ptr) : ptr(ptr){};
4008+
LoadedCompilerPlugin(LoadedExecutablePlugin *ptr) : ptr(ptr){};
40264009

4027-
void *getAsInProcessPlugin() const {
4028-
return kind == PluginKind::InProcess ? ptr : nullptr;
4010+
LoadedLibraryPlugin *getAsLibraryPlugin() const {
4011+
return ptr.dyn_cast<LoadedLibraryPlugin *>();
40294012
}
40304013
LoadedExecutablePlugin *getAsExecutablePlugin() const {
4031-
return kind == PluginKind::Executable
4032-
? static_cast<LoadedExecutablePlugin *>(ptr)
4033-
: nullptr;
4014+
return ptr.dyn_cast<LoadedExecutablePlugin *>();
40344015
}
40354016
};
40364017

lib/AST/ASTContext.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -6412,7 +6412,7 @@ LoadedExecutablePlugin *ASTContext::loadExecutablePlugin(StringRef path) {
64126412
return plugin.get();
64136413
}
64146414

6415-
void *ASTContext::loadLibraryPlugin(StringRef path) {
6415+
LoadedLibraryPlugin *ASTContext::loadLibraryPlugin(StringRef path) {
64166416
// Remember the path (even if it fails to load.)
64176417
getImpl().LoadedPluginLibraryPaths.insert(path);
64186418

lib/AST/PluginRegistry.cpp

+24-11
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::make_unique<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 *>
@@ -98,8 +111,8 @@ PluginRegistry::loadExecutablePlugin(StringRef path) {
98111
"not executable");
99112
}
100113

101-
auto plugin = std::unique_ptr<LoadedExecutablePlugin>(
102-
new LoadedExecutablePlugin(path, stat.getLastModificationTime()));
114+
auto plugin = std::make_unique<LoadedExecutablePlugin>(
115+
path, stat.getLastModificationTime());
103116

104117
plugin->setDumpMessaging(dumpMessaging);
105118

@@ -140,9 +153,9 @@ llvm::Error LoadedExecutablePlugin::spawnIfNeeded() {
140153
return llvm::errorCodeToError(childInfo.getError());
141154
}
142155

143-
Process = std::unique_ptr<PluginProcess>(
144-
new PluginProcess(childInfo->Pid, childInfo->ReadFileDescriptor,
145-
childInfo->WriteFileDescriptor));
156+
Process = std::make_unique<PluginProcess>(childInfo->Pid,
157+
childInfo->ReadFileDescriptor,
158+
childInfo->WriteFileDescriptor);
146159

147160
// Call "on reconnect" callbacks.
148161
for (auto *callback : onReconnect) {

lib/Sema/TypeCheckMacros.cpp

+15-31
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,6 @@
3838
#include "swift/Subsystems.h"
3939
#include "llvm/Config/config.h"
4040

41-
#if defined(_WIN32)
42-
#define WIN32_LEAN_AND_MEAN
43-
#define NOMINMAX
44-
#include <windows.h>
45-
#else
46-
#include <dlfcn.h>
47-
#endif
48-
4941
using namespace swift;
5042

5143
extern "C" void *swift_ASTGen_resolveMacroType(const void *macroType);
@@ -90,10 +82,10 @@ extern "C" bool swift_ASTGen_pluginServerLoadLibraryPlugin(
9082

9183
#if SWIFT_SWIFT_PARSER
9284
/// 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-
) {
85+
static void const *
86+
lookupMacroTypeMetadataByExternalName(ASTContext &ctx, StringRef moduleName,
87+
StringRef typeName,
88+
LoadedLibraryPlugin *plugin) {
9789
// Look up the type metadata accessor as a struct, enum, or class.
9890
const Demangle::Node::Kind typeKinds[] = {
9991
Demangle::Node::Kind::Structure,
@@ -105,11 +97,7 @@ static void const *lookupMacroTypeMetadataByExternalName(
10597
for (auto typeKind : typeKinds) {
10698
auto symbolName = Demangle::mangledNameForTypeMetadataAccessor(
10799
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
100+
accessorAddr = plugin->getAddressOfSymbol(symbolName.c_str());
113101
if (accessorAddr)
114102
break;
115103
}
@@ -276,7 +264,8 @@ MacroDefinition MacroDefinitionRequest::evaluate(
276264
}
277265

278266
/// Load a plugin library based on a module name.
279-
static void *loadLibraryPluginByName(ASTContext &ctx, Identifier moduleName) {
267+
static LoadedLibraryPlugin *loadLibraryPluginByName(ASTContext &ctx,
268+
Identifier moduleName) {
280269
std::string libraryPath;
281270
if (auto found = ctx.lookupLibraryPluginByModuleName(moduleName)) {
282271
libraryPath = *found;
@@ -367,33 +356,28 @@ loadExecutablePluginByName(ASTContext &ctx, Identifier moduleName) {
367356
LoadedCompilerPlugin
368357
CompilerPluginLoadRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
369358
Identifier moduleName) const {
370-
auto fs = ctx->SourceMgr.getFileSystem();
371-
auto &searchPathOpts = ctx->SearchPathOpts;
372-
auto *registry = ctx->getPluginRegistry();
373-
374359
// Check dynamic link library plugins.
375360
// i.e. '-plugin-path', and '-load-plugin-library'.
376-
if (auto found = loadLibraryPluginByName(*ctx, moduleName))
377-
return LoadedCompilerPlugin::inProcess(found);
361+
if (auto found = loadLibraryPluginByName(*ctx, moduleName)) {
362+
return found;
363+
}
378364

379365
// Fall back to executable plugins.
380366
// i.e. '-external-plugin-path', and '-load-plugin-executable'.
381367
if (auto *found = loadExecutablePluginByName(*ctx, moduleName)) {
382-
return LoadedCompilerPlugin::executable(found);
368+
return found;
383369
}
384370

385371
return nullptr;
386372
}
387373

388374
static Optional<ExternalMacroDefinition>
389-
resolveInProcessMacro(
390-
ASTContext &ctx, Identifier moduleName, Identifier typeName,
391-
void *libraryHint = nullptr
392-
) {
375+
resolveInProcessMacro(ASTContext &ctx, Identifier moduleName,
376+
Identifier typeName, LoadedLibraryPlugin *plugin) {
393377
#if SWIFT_SWIFT_PARSER
394378
/// Look for the type metadata given the external module and type names.
395379
auto macroMetatype = lookupMacroTypeMetadataByExternalName(
396-
ctx, moduleName.str(), typeName.str(), libraryHint);
380+
ctx, moduleName.str(), typeName.str(), plugin);
397381
if (macroMetatype) {
398382
// Check whether the macro metatype is in-process.
399383
if (auto inProcess = swift_ASTGen_resolveMacroType(macroMetatype)) {
@@ -438,7 +422,7 @@ ExternalMacroDefinitionRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
438422
LoadedCompilerPlugin loaded =
439423
evaluateOrDefault(evaluator, loadRequest, nullptr);
440424

441-
if (auto loadedLibrary = loaded.getAsInProcessPlugin()) {
425+
if (auto loadedLibrary = loaded.getAsLibraryPlugin()) {
442426
if (auto inProcess = resolveInProcessMacro(
443427
*ctx, moduleName, typeName, loadedLibrary))
444428
return *inProcess;

0 commit comments

Comments
 (0)