Skip to content

Commit 9a37e46

Browse files
committed
macros: work towards supporting macros on Windows
Start fleshing out some of the executor path for supporting Windows with macros.
1 parent 5422f9a commit 9a37e46

File tree

5 files changed

+105
-22
lines changed

5 files changed

+105
-22
lines changed

include/swift/AST/PluginRegistry.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,11 @@ class LoadedExecutablePlugin {
5353
/// Represents the current process of the executable plugin.
5454
struct PluginProcess {
5555
const llvm::sys::procid_t pid;
56-
const int inputFileDescriptor;
57-
const int outputFileDescriptor;
56+
const void *input;
57+
const void *output;
5858
bool isStale = false;
5959

60-
PluginProcess(llvm::sys::procid_t pid, int inputFileDescriptor,
61-
int outputFileDescriptor);
62-
60+
PluginProcess(llvm::sys::procid_t pid, void *input, void *output);
6361
~PluginProcess();
6462

6563
ssize_t write(const void *buf, size_t nbyte) const;

include/swift/Basic/Program.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,12 @@ int ExecuteInPlace(const char *Program, const char **args,
4040
const char **env = nullptr);
4141

4242
struct ChildProcessInfo {
43-
llvm::sys::procid_t Pid;
44-
int WriteFileDescriptor;
45-
int ReadFileDescriptor;
43+
llvm::sys::ProcessInfo ProcessInfo;
44+
void *Write;
45+
void *Read;
4646

47-
ChildProcessInfo(llvm::sys::procid_t Pid, int WriteFileDescriptor,
48-
int ReadFileDescriptor)
49-
: Pid(Pid), WriteFileDescriptor(WriteFileDescriptor),
50-
ReadFileDescriptor(ReadFileDescriptor) {}
47+
ChildProcessInfo(llvm::sys::ProcessInfo ProcessInfo, void *Write, void *Read)
48+
: ProcessInfo(ProcessInfo), Write(Write), Read(Read) {}
5149
};
5250

5351
/// This function executes the program using the argument provided.

lib/AST/PluginLoader.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,13 @@ PluginRegistry *PluginLoader::getRegistry() {
4141
static StringRef pluginModuleNameStringFromPath(StringRef path) {
4242
// Plugin library must be named 'lib${module name}(.dylib|.so|.dll)'.
4343
// FIXME: Shared library prefix might be different between platforms.
44+
#if defined(_WIN32)
45+
constexpr StringRef libPrefix{};
46+
constexpr StringRef libSuffix = ".dll";
47+
#else
4448
constexpr StringRef libPrefix = "lib";
4549
constexpr StringRef libSuffix = LTDL_SHLIB_EXT;
50+
#endif
4651

4752
StringRef filename = llvm::sys::path::filename(path);
4853
if (filename.starts_with(libPrefix) && filename.ends_with(libSuffix)) {

lib/AST/PluginRegistry.cpp

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ void *LoadedLibraryPlugin::getAddressOfSymbol(const char *symbolName) {
7575
auto &cached = resolvedSymbols[symbolName];
7676
if (cached)
7777
return cached;
78-
#if !defined(_WIN32)
78+
#if defined(_WIN32)
79+
cached = GetProcAddress(static_cast<HMODULE>(handle), symbolName);
80+
#else
7981
cached = dlsym(handle, symbolName);
8082
#endif
8183
return cached;
@@ -153,9 +155,8 @@ llvm::Error LoadedExecutablePlugin::spawnIfNeeded() {
153155
return llvm::errorCodeToError(childInfo.getError());
154156
}
155157

156-
Process = std::make_unique<PluginProcess>(childInfo->Pid,
157-
childInfo->ReadFileDescriptor,
158-
childInfo->WriteFileDescriptor);
158+
Process = std::make_unique<PluginProcess>(childInfo->ProcessInfo.Pid,
159+
childInfo->Read, childInfo->Write);
159160

160161
// Call "on reconnect" callbacks.
161162
for (auto *callback : onReconnect) {
@@ -166,14 +167,14 @@ llvm::Error LoadedExecutablePlugin::spawnIfNeeded() {
166167
}
167168

168169
LoadedExecutablePlugin::PluginProcess::PluginProcess(llvm::sys::procid_t pid,
169-
int inputFileDescriptor,
170-
int outputFileDescriptor)
171-
: pid(pid), inputFileDescriptor(inputFileDescriptor),
172-
outputFileDescriptor(outputFileDescriptor) {}
170+
HANDLE input,
171+
HANDLE output)
172+
: pid(pid), input(input),
173+
output(output) {}
173174

174175
LoadedExecutablePlugin::PluginProcess::~PluginProcess() {
175-
close(inputFileDescriptor);
176-
close(outputFileDescriptor);
176+
CloseHandle((HANDLE)input);
177+
CloseHandle((HANDLE)output);
177178
}
178179

179180
LoadedExecutablePlugin::~LoadedExecutablePlugin() {
@@ -184,6 +185,18 @@ LoadedExecutablePlugin::~LoadedExecutablePlugin() {
184185

185186
ssize_t LoadedExecutablePlugin::PluginProcess::read(void *buf,
186187
size_t nbyte) const {
188+
size_t read = 0;
189+
while (read < nbyte) {
190+
DWORD NumberOfBytesRead = 0;
191+
BOOL bSuccess = ReadFile((HANDLE)input,
192+
(char *)buf + read, nbyte - read,
193+
&NumberOfBytesRead, NULL);
194+
if (bSuccess == FALSE && NumberOfBytesRead == 0)
195+
return read;
196+
read += NumberOfBytesRead;
197+
}
198+
return read;
199+
#if 0
187200
ssize_t bytesToRead = nbyte;
188201
void *ptr = buf;
189202

@@ -206,10 +219,24 @@ ssize_t LoadedExecutablePlugin::PluginProcess::read(void *buf,
206219
}
207220

208221
return nbyte - bytesToRead;
222+
#endif
223+
return 0;
209224
}
210225

211226
ssize_t LoadedExecutablePlugin::PluginProcess::write(const void *buf,
212227
size_t nbyte) const {
228+
size_t written = 0;
229+
while (written < nbyte) {
230+
DWORD NumberOfBytesWritten = 0;
231+
BOOL bSuccess = WriteFile((HANDLE)output,
232+
(const char *)buf + written, nbyte - written,
233+
&NumberOfBytesWritten, NULL);
234+
if (bSuccess == FALSE && NumberOfBytesWritten == 0)
235+
return written;
236+
written += NumberOfBytesWritten;
237+
}
238+
return written;
239+
#if 0
213240
ssize_t bytesToWrite = nbyte;
214241
const void *ptr = buf;
215242

@@ -231,6 +258,7 @@ ssize_t LoadedExecutablePlugin::PluginProcess::write(const void *buf,
231258
bytesToWrite -= writtenSize;
232259
}
233260
return nbyte - bytesToWrite;
261+
#endif
234262
}
235263

236264
llvm::Error LoadedExecutablePlugin::sendMessage(llvm::StringRef message) const {

lib/Basic/Program.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/ADT/StringExtras.h"
1818
#include "llvm/Config/config.h"
1919
#include "llvm/Support/Allocator.h"
20+
#include "llvm/Support/ConvertUTF.h"
2021
#include "llvm/Support/Program.h"
2122

2223
#include <system_error>
@@ -29,6 +30,11 @@
2930
#include <unistd.h>
3031
#endif
3132

33+
#if defined(_WIN32)
34+
#define WIN32_LEAN_AND_MEAN
35+
#include <Windows.h>
36+
#endif
37+
3238
using namespace swift;
3339

3440
int swift::ExecuteInPlace(const char *Program, const char **args,
@@ -178,6 +184,54 @@ swift::ExecuteWithPipe(llvm::StringRef program,
178184
return ChildProcessInfo(pid, p1.write, p2.read);
179185
}
180186

187+
#elif defined(_WIN32)
188+
189+
llvm::ErrorOr<swift::ChildProcessInfo>
190+
swift::ExecuteWithPipe(llvm::StringRef program,
191+
llvm::ArrayRef<llvm::StringRef> args,
192+
llvm::Optional<llvm::ArrayRef<llvm::StringRef>> env) {
193+
enum { PI_READ, PI_WRITE };
194+
195+
HANDLE input[2] = {INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE};
196+
HANDLE output[2] = {INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE};
197+
SECURITY_ATTRIBUTES saAttrs{sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
198+
199+
if (!CreatePipe(&output[PI_READ], &output[PI_WRITE], &saAttrs, 0))
200+
return std::error_code(GetLastError(), std::system_category());
201+
202+
if (!SetHandleInformation(output[PI_READ], HANDLE_FLAG_INHERIT, FALSE))
203+
return std::error_code(GetLastError(), std::system_category());
204+
205+
if (!CreatePipe(&input[PI_READ], &input[PI_WRITE], &saAttrs, 0))
206+
return std::error_code(GetLastError(), std::system_category());
207+
208+
if (!SetHandleInformation(input[PI_WRITE], HANDLE_FLAG_INHERIT, FALSE))
209+
return std::error_code(GetLastError(), std::system_category());
210+
211+
STARTUPINFO si = {0};
212+
si.cb = sizeof(si);
213+
si.hStdInput = input[PI_READ];
214+
si.hStdOutput = output[PI_WRITE];
215+
si.hStdError = output[PI_WRITE];
216+
si.dwFlags = STARTF_USESTDHANDLES;
217+
218+
llvm::SmallVector<llvm::UTF16, 261> converted;
219+
llvm::convertUTF8ToUTF16String(program, converted);
220+
converted.push_back(L'\0');
221+
PROCESS_INFORMATION pi = {0};
222+
if (!CreateProcess((LPWSTR)converted.data(), NULL, NULL, NULL, TRUE, 0, NULL, NULL,
223+
&si, &pi))
224+
return std::error_code(GetLastError(), std::system_category());
225+
226+
CloseHandle(input[PI_READ]);
227+
CloseHandle(output[PI_WRITE]);
228+
CloseHandle(pi.hThread);
229+
230+
llvm::sys::ProcessInfo proc;
231+
proc.Process = pi.hProcess;
232+
return ChildProcessInfo(proc, input[PI_WRITE], output[PI_READ]);
233+
}
234+
181235
#else // HAVE_UNISTD_H
182236

183237
llvm::ErrorOr<swift::ChildProcessInfo>

0 commit comments

Comments
 (0)