13
13
#include " PluginServer.h"
14
14
#include " swift/ABI/MetadataValues.h"
15
15
#include " swift/Demangling/Demangle.h"
16
+ #include " llvm/Support/ConvertUTF.h"
17
+ #include " llvm/Support/DynamicLibrary.h"
16
18
19
+ #if defined(_WIN32)
20
+ #define WIN32_LEAN_AND_MEAN
21
+ #include < Windows.h>
22
+ #elif defined(__unix__) || defined(__APPLE__)
17
23
#include < dlfcn.h>
24
+ #include < unistd.h>
25
+ #endif
26
+
18
27
#include < errno.h>
19
28
#include < string.h>
20
- #include < unistd.h>
21
29
22
30
using namespace swift ;
23
31
24
32
namespace {
33
+ #if defined(_WIN32)
34
+ struct ConnectionHandle {
35
+ HANDLE hInput;
36
+ HANDLE hOutput;
37
+
38
+ ConnectionHandle (HANDLE hInput, HANDLE hOutput)
39
+ : hInput(hInput), hOutput(hOutput) {}
40
+ };
41
+ #else
25
42
struct ConnectionHandle {
26
43
int inputFD;
27
44
int outputFD;
28
45
29
46
ConnectionHandle (int inputFD, int outputFD)
30
47
: inputFD(inputFD), outputFD(outputFD) {}
31
48
};
49
+ #endif
32
50
} // namespace
33
51
34
52
const void *PluginServer_createConnection (const char **errorMessage) {
53
+ #if defined(_WIN32)
54
+ return new ConnectionHandle (GetStdHandle (STD_INPUT_HANDLE),
55
+ GetStdHandle (STD_OUTPUT_HANDLE));
56
+ #else
35
57
// Duplicate the `stdin` file descriptor, which we will then use for
36
58
// receiving messages from the plugin host.
37
59
auto inputFD = dup (STDIN_FILENO);
@@ -65,37 +87,73 @@ const void *PluginServer_createConnection(const char **errorMessage) {
65
87
66
88
// Open a message channel for communicating with the plugin host.
67
89
return new ConnectionHandle (inputFD, outputFD);
90
+ #endif
68
91
}
69
92
70
- void PluginServer_destroyConnection (const void *connHandle) {
71
- const auto *conn = static_cast <const ConnectionHandle *>(connHandle);
72
- delete conn;
93
+ void PluginServer_destroyConnection (const void *server) {
94
+ delete static_cast <const ConnectionHandle *>(server);
73
95
}
74
96
75
- long PluginServer_read (const void *connHandle, void *data,
76
- unsigned long nbyte) {
77
- const auto *conn = static_cast <const ConnectionHandle *>(connHandle);
97
+ size_t PluginServer_read (const void *server, void *data, size_t nbyte) {
98
+ const auto *connection = static_cast <const ConnectionHandle *>(server);
99
+ #if defined(_WIN32)
100
+ DWORD NumberOfBytesRead;
101
+ llvm::SmallVector<wchar_t > buffer (nbyte);
102
+ if (!ReadFile (connection->hInput , buffer.data (),
103
+ buffer.size () * sizeof (wchar_t ), &NumberOfBytesRead, NULL ))
104
+ return 0 ;
105
+
106
+ llvm::SmallVector<char > converted;
107
+ if (llvm::sys::windows::UTF16ToUTF8 (buffer.data (), buffer.size (), converted))
108
+ return 0 ;
109
+ memcpy (data, converted.data (), min (nbyte, converted.size ()));
110
+ return min (nbyte, converted.size ());
111
+ #else
78
112
return ::read (conn->inputFD , data, nbyte);
113
+ #endif
79
114
}
80
115
81
- long PluginServer_write (const void *connHandle, const void *data,
82
- unsigned long nbyte) {
83
- const auto *conn = static_cast <const ConnectionHandle *>(connHandle);
116
+ size_t PluginServer_write (const void *server, const void *data, size_t nbyte) {
117
+ const auto *connection = static_cast <const ConnectionHandle *>(server);
118
+ #if defined(_WIN32)
119
+ using namespace llvm ;
120
+
121
+ SmallVector<wchar_t > buffer;
122
+ if (sys::windows::UTF8ToUTF16 (StringRef{static_cast <const char *>(data),
123
+ static_cast <size_t >(nbyte)}, buffer))
124
+ return 0 ;
125
+
126
+ DWORD NumberOfBytesWritten;
127
+ if (!WriteFile (connection->hOutput , buffer.data (),
128
+ buffer.size () * sizeof (wchar_t ), &NumberOfBytesWritten, NULL ))
129
+ return 0 ;
130
+ return NumberOfBytesWritten;
131
+ #else
84
132
return ::write (conn->outputFD , data, nbyte);
133
+ #endif
85
134
}
86
135
87
- void *PluginServer_dlopen (const char *filename, const char **errorMessage) {
136
+ void *PluginServer_load (const char *filename, const char **errorMessage) {
137
+ #if defined(_WIN32)
138
+ std::string error;
139
+ llvm::sys::DynamicLibrary library =
140
+ llvm::sys::DynamicLibrary::getLibrary (filename, &error);
141
+ if (library.isValid ())
142
+ return library.getOSSpecificHandle ();
143
+ *errorMessage = ::strdup (error.c_str ());
144
+ return nullptr ;
145
+ #else
88
146
auto *handle = ::dlopen (filename, RTLD_LAZY | RTLD_LOCAL);
89
147
if (!handle) {
90
148
*errorMessage = dlerror ();
91
149
}
92
150
return handle;
151
+ #endif
93
152
}
94
153
95
154
const void *PluginServer_lookupMacroTypeMetadataByExternalName (
96
155
const char *moduleName, const char *typeName, void *libraryHint,
97
156
const char **errorMessage) {
98
-
99
157
// Look up the type metadata accessor as a struct, enum, or class.
100
158
const Demangle::Node::Kind typeKinds[] = {
101
159
Demangle::Node::Kind::Structure,
@@ -108,8 +166,13 @@ const void *PluginServer_lookupMacroTypeMetadataByExternalName(
108
166
auto symbolName =
109
167
mangledNameForTypeMetadataAccessor (moduleName, typeName, typeKind);
110
168
169
+ #if defined(_WIN32)
170
+ accessorAddr = llvm::sys::DynamicLibrary{libraryHint}
171
+ .getAddressOfSymbol (symbolName.c_str ());
172
+ #else
111
173
auto *handle = libraryHint ? libraryHint : RTLD_DEFAULT;
112
174
accessorAddr = ::dlsym (handle, symbolName.c_str ());
175
+ #endif
113
176
if (accessorAddr)
114
177
break ;
115
178
}
0 commit comments