https://github.com/whitequark updated 
https://github.com/llvm/llvm-project/pull/92677

>From 5f8f347ca1ddcda307a7fc2e3ef7d33c5f2c398d Mon Sep 17 00:00:00 2001
From: Catherine <whitequ...@whitequark.org>
Date: Sun, 19 May 2024 04:41:27 +0000
Subject: [PATCH] Conditionalize use of POSIX features missing on
 WASI/WebAssembly.

This patch makes it possible to build LLVM, Clang, and LLD for
WASI/WebAssembly. This patch introduces conditionals of the form
`defined(__wasi__)` or `defined(__wasm__)` wherever necessary to detect
the use of the WASI platform. In addition, it introduces a `HAVE_SETJMP`
feature test macro because the WASI platform can have or lack support
for this feature depending on compiler options.
---
 clang/lib/Driver/Driver.cpp                   |  2 +-
 lld/Common/Filesystem.cpp                     |  4 ++
 llvm/cmake/config-ix.cmake                    |  1 +
 llvm/cmake/modules/HandleLLVMOptions.cmake    |  4 ++
 llvm/include/llvm/ADT/bit.h                   |  2 +-
 llvm/include/llvm/Config/config.h.cmake       |  4 ++
 .../Interpreter/ExternalFunctions.cpp         |  6 +++
 llvm/lib/Support/CrashRecoveryContext.cpp     | 40 ++++++++++++++--
 llvm/lib/Support/InitLLVM.cpp                 |  2 +
 llvm/lib/Support/LockFileManager.cpp          |  4 +-
 llvm/lib/Support/Signals.cpp                  | 16 +++++--
 llvm/lib/Support/Unix/Memory.inc              |  5 ++
 llvm/lib/Support/Unix/Path.inc                | 47 ++++++++++++++++---
 llvm/lib/Support/Unix/Process.inc             | 16 ++++++-
 llvm/lib/Support/Unix/Program.inc             | 16 ++++++-
 llvm/lib/Support/Unix/Unix.h                  |  3 ++
 llvm/lib/Support/Unix/Watchdog.inc            |  4 +-
 llvm/lib/Support/raw_socket_stream.cpp        |  4 ++
 18 files changed, 159 insertions(+), 21 deletions(-)

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 28c3b52483e51..9bb94bbab6931 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1578,7 +1578,7 @@ bool Driver::getCrashDiagnosticFile(StringRef 
ReproCrashFilename,
     CrashDiagDir = "/";
   path::append(CrashDiagDir, "Library/Logs/DiagnosticReports");
   int PID =
-#if LLVM_ON_UNIX
+#if LLVM_ON_UNIX && !defined(__wasi__)
       getpid();
 #else
       0;
diff --git a/lld/Common/Filesystem.cpp b/lld/Common/Filesystem.cpp
index c2d3644191c9f..3fee1f8efa5e2 100644
--- a/lld/Common/Filesystem.cpp
+++ b/lld/Common/Filesystem.cpp
@@ -75,6 +75,10 @@ void lld::unlinkAsync(StringRef path) {
       sys::fs::remove(tmpName);
   }
   sys::fs::remove(path);
+// WASI does have threads but they complicate deployment and the benefits of
+// async file removal do not outweigh the drawbacks.
+#elif defined(__wasi__)
+  sys::fs::remove(path);
 #else
   if (parallel::strategy.ThreadsRequested == 1)
     return;
diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index 0aae13e30f2ab..cb405d5cf9888 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -300,6 +300,7 @@ check_symbol_exists(getrlimit 
"sys/types.h;sys/time.h;sys/resource.h" HAVE_GETRL
 check_symbol_exists(posix_spawn spawn.h HAVE_POSIX_SPAWN)
 check_symbol_exists(pread unistd.h HAVE_PREAD)
 check_symbol_exists(sbrk unistd.h HAVE_SBRK)
+check_symbol_exists(setjmp setjmp.h HAVE_SETJMP)
 check_symbol_exists(strerror_r string.h HAVE_STRERROR_R)
 check_symbol_exists(strerror_s string.h HAVE_DECL_STRERROR_S)
 check_symbol_exists(setenv stdlib.h HAVE_SETENV)
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake 
b/llvm/cmake/modules/HandleLLVMOptions.cmake
index 5ca580fbb59c5..11cc1af78b9ba 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -217,6 +217,10 @@ elseif(FUCHSIA OR UNIX)
   else()
     set(LLVM_HAVE_LINK_VERSION_SCRIPT 1)
   endif()
+elseif(WASI)
+  set(LLVM_ON_WIN32 0)
+  set(LLVM_ON_UNIX 1)
+  set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
 elseif(CMAKE_SYSTEM_NAME STREQUAL "Generic")
   set(LLVM_ON_WIN32 0)
   set(LLVM_ON_UNIX 0)
diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h
index c42b5e686bdc9..e57d54e04a317 100644
--- a/llvm/include/llvm/ADT/bit.h
+++ b/llvm/include/llvm/ADT/bit.h
@@ -29,7 +29,7 @@
 
 #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) ||            
\
     defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) ||  
\
-    defined(__OpenBSD__) || defined(__DragonFly__)
+    defined(__OpenBSD__) || defined(__DragonFly__) || defined(__wasm__)
 #include <endian.h>
 #elif defined(_AIX)
 #include <sys/machine.h>
diff --git a/llvm/include/llvm/Config/config.h.cmake 
b/llvm/include/llvm/Config/config.h.cmake
index ff30741c8f360..21a8f31e34a93 100644
--- a/llvm/include/llvm/Config/config.h.cmake
+++ b/llvm/include/llvm/Config/config.h.cmake
@@ -164,6 +164,10 @@
 /* Define to 1 if you have the `sbrk' function. */
 #cmakedefine HAVE_SBRK ${HAVE_SBRK}
 
+/* Define to 1 if you have the `setjmp' function. */
+/* This function is expected to be present everywhere except for a subset of 
WebAssembly builds. */
+#cmakedefine HAVE_SETJMP ${HAVE_SETJMP}
+
 /* Define to 1 if you have the `setenv' function. */
 #cmakedefine HAVE_SETENV ${HAVE_SETENV}
 
diff --git a/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp 
b/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
index 4f8f883a75f32..1d933ab710974 100644
--- a/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
+++ b/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
@@ -34,7 +34,9 @@
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
 #include <cmath>
+#if !defined(__wasi__)
 #include <csignal>
+#endif
 #include <cstdint>
 #include <cstdio>
 #include <cstring>
@@ -340,7 +342,11 @@ static GenericValue lle_X_exit(FunctionType *FT, 
ArrayRef<GenericValue> Args) {
 static GenericValue lle_X_abort(FunctionType *FT, ArrayRef<GenericValue> Args) 
{
   //FIXME: should we report or raise here?
   //report_fatal_error("Interpreted program raised SIGABRT");
+#if defined(__wasi__)
+  abort();
+#else
   raise (SIGABRT);
+#endif
   return GenericValue();
 }
 
diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp 
b/llvm/lib/Support/CrashRecoveryContext.cpp
index f53aea177d612..4cb2d2271262f 100644
--- a/llvm/lib/Support/CrashRecoveryContext.cpp
+++ b/llvm/lib/Support/CrashRecoveryContext.cpp
@@ -13,8 +13,17 @@
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/thread.h"
 #include <cassert>
+#if !defined(__wasi__)
+#include <csignal>
+#endif
+#if LLVM_ENABLE_THREADS
 #include <mutex>
+#endif
+#if HAVE_SETJMP
+// We can rely on setjmp to exist everywhere except for a subset of WebAssembly
+// builds.
 #include <setjmp.h>
+#endif
 
 using namespace llvm;
 
@@ -31,7 +40,9 @@ struct CrashRecoveryContextImpl {
   const CrashRecoveryContextImpl *Next;
 
   CrashRecoveryContext *CRC;
+#ifdef HAVE_SETJMP
   ::jmp_buf JumpBuffer;
+#endif
   volatile unsigned Failed : 1;
   unsigned SwitchedThread : 1;
   unsigned ValidJumpBuffer : 1;
@@ -50,7 +61,7 @@ struct CrashRecoveryContextImpl {
   /// Called when the separate crash-recovery thread was finished, to
   /// indicate that we don't need to clear the thread-local CurrentContext.
   void setSwitchedThread() {
-#if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
+#if LLVM_ENABLE_THREADS
     SwitchedThread = true;
 #endif
   }
@@ -72,19 +83,23 @@ struct CrashRecoveryContextImpl {
 
     CRC->RetCode = RetCode;
 
+#if HAVE_SETJMP
     // Jump back to the RunSafely we were called under.
     if (ValidJumpBuffer)
       longjmp(JumpBuffer, 1);
+#endif
 
     // Otherwise let the caller decide of the outcome of the crash. Currently
     // this occurs when using SEH on Windows with MSVC or clang-cl.
   }
 };
 
-std::mutex &getCrashRecoveryContextMutex() {
+#if LLVM_ENABLE_THREADS
+static std::mutex &getCrashRecoveryContextMutex() {
   static std::mutex CrashRecoveryContextMutex;
   return CrashRecoveryContextMutex;
 }
+#endif
 
 static bool gCrashRecoveryEnabled = false;
 
@@ -138,7 +153,9 @@ CrashRecoveryContext *CrashRecoveryContext::GetCurrent() {
 }
 
 void CrashRecoveryContext::Enable() {
+#if LLVM_ENABLE_THREADS
   std::lock_guard<std::mutex> L(getCrashRecoveryContextMutex());
+#endif
   // FIXME: Shouldn't this be a refcount or something?
   if (gCrashRecoveryEnabled)
     return;
@@ -147,7 +164,9 @@ void CrashRecoveryContext::Enable() {
 }
 
 void CrashRecoveryContext::Disable() {
+#if LLVM_ENABLE_THREADS
   std::lock_guard<std::mutex> L(getCrashRecoveryContextMutex());
+#endif
   if (!gCrashRecoveryEnabled)
     return;
   gCrashRecoveryEnabled = false;
@@ -329,7 +348,16 @@ static void uninstallExceptionOrSignalHandlers() {
   }
 }
 
-#else // !_WIN32
+#elif defined(__wasi__)
+
+// WASI implementation.
+//
+// WASI traps are always fatal, and recovery is not possible. Do nothing.
+
+static void installExceptionOrSignalHandlers() {}
+static void uninstallExceptionOrSignalHandlers() {}
+
+#else // !_WIN32 && !__wasi__
 
 // Generic POSIX implementation.
 //
@@ -417,10 +445,12 @@ bool CrashRecoveryContext::RunSafely(function_ref<void()> 
Fn) {
     CrashRecoveryContextImpl *CRCI = new CrashRecoveryContextImpl(this);
     Impl = CRCI;
 
+#if HAVE_SETJMP
     CRCI->ValidJumpBuffer = true;
     if (setjmp(CRCI->JumpBuffer) != 0) {
       return false;
     }
+#endif
   }
 
   Fn();
@@ -467,7 +497,9 @@ bool CrashRecoveryContext::isCrash(int RetCode) {
 bool CrashRecoveryContext::throwIfCrash(int RetCode) {
   if (!isCrash(RetCode))
     return false;
-#if defined(_WIN32)
+#if defined(__wasi__)
+  abort();
+#elif defined(_WIN32)
   ::RaiseException(RetCode, 0, 0, NULL);
 #else
   llvm::sys::unregisterHandlers();
diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp
index b7e463a19122d..e3f8bb13f2f73 100644
--- a/llvm/lib/Support/InitLLVM.cpp
+++ b/llvm/lib/Support/InitLLVM.cpp
@@ -47,6 +47,7 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv,
   // Bring stdin/stdout/stderr into a known state.
   sys::AddSignalHandler(CleanupStdHandles, nullptr);
 #endif
+#if !defined(__wasi__)
   if (InstallPipeSignalExitHandler)
     // The pipe signal handler must be installed before any other handlers are
     // registered. This is because the Unix \ref RegisterHandlers function does
@@ -59,6 +60,7 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv,
   StackPrinter.emplace(Argc, Argv);
   sys::PrintStackTraceOnErrorSignal(Argv[0]);
   install_out_of_memory_new_handler();
+#endif
 
 #ifdef __MVS__
 
diff --git a/llvm/lib/Support/LockFileManager.cpp 
b/llvm/lib/Support/LockFileManager.cpp
index ea040ccf22b99..c754136d7cb09 100644
--- a/llvm/lib/Support/LockFileManager.cpp
+++ b/llvm/lib/Support/LockFileManager.cpp
@@ -94,7 +94,7 @@ static std::error_code getHostID(SmallVectorImpl<char> 
&HostID) {
   StringRef UUIDRef(UUIDStr);
   HostID.append(UUIDRef.begin(), UUIDRef.end());
 
-#elif LLVM_ON_UNIX
+#elif !defined(__wasi__)
   char HostName[256];
   HostName[255] = 0;
   HostName[0] = 0;
@@ -111,7 +111,7 @@ static std::error_code getHostID(SmallVectorImpl<char> 
&HostID) {
 }
 
 bool LockFileManager::processStillExecuting(StringRef HostID, int PID) {
-#if LLVM_ON_UNIX && !defined(__ANDROID__)
+#if LLVM_ON_UNIX && !defined(__ANDROID__) && !defined(__wasi__)
   SmallString<256> StoredHostID;
   if (getHostID(StoredHostID))
     return true; // Conservatively assume it's executing on error.
diff --git a/llvm/lib/Support/Signals.cpp b/llvm/lib/Support/Signals.cpp
index 9f9030e79d104..ec5a183705d6e 100644
--- a/llvm/lib/Support/Signals.cpp
+++ b/llvm/lib/Support/Signals.cpp
@@ -273,9 +273,19 @@ static bool printMarkupStackTrace(StringRef Argv0, void 
**StackTrace, int Depth,
 }
 
 // Include the platform-specific parts of this class.
-#ifdef LLVM_ON_UNIX
+#if defined(__wasi__)
+// WASI does not have signals.
+void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr,
+                                 void *Cookie) {}
+void llvm::sys::RunInterruptHandlers() {}
+void sys::CleanupOnSignal(uintptr_t Context) {}
+bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg) {
+  return false;
+}
+void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) {}
+void llvm::sys::DisableSystemDialogsOnCrash() {}
+#elif defined(LLVM_ON_UNIX)
 #include "Unix/Signals.inc"
-#endif
-#ifdef _WIN32
+#elif defined(_WIN32)
 #include "Windows/Signals.inc"
 #endif
diff --git a/llvm/lib/Support/Unix/Memory.inc b/llvm/lib/Support/Unix/Memory.inc
index bac208a7d543c..2fa9db84c9774 100644
--- a/llvm/lib/Support/Unix/Memory.inc
+++ b/llvm/lib/Support/Unix/Memory.inc
@@ -163,6 +163,11 @@ std::error_code Memory::releaseMappedMemory(MemoryBlock 
&M) {
 
 std::error_code Memory::protectMappedMemory(const MemoryBlock &M,
                                             unsigned Flags) {
+#if defined(__wasi__)
+  // Wasm does not allow making memory read-only or executable.
+  return std::error_code(ENOSYS, std::generic_category());
+#endif
+
   static const Align PageSize = Align(Process::getPageSizeEstimate());
   if (M.Address == nullptr || M.AllocatedSize == 0)
     return std::error_code();
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 6e679f74869f0..e40621ebac551 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -32,7 +32,9 @@
 #endif
 
 #include <dirent.h>
+#if !defined(__wasi__)
 #include <pwd.h>
+#endif
 #include <sys/file.h>
 
 #ifdef __APPLE__
@@ -126,10 +128,12 @@ namespace fs {
 
 const file_t kInvalidFile = -1;
 
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) ||     
 \
-    defined(__FreeBSD_kernel__) || defined(__linux__) || defined(__CYGWIN__) 
|| \
-    defined(__DragonFly__) || defined(_AIX) || defined(__GNU__) ||             
 \
-    (defined(__sun__) && defined(__svr4__) || defined(__HAIKU__))
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) ||     
\
+    defined(__FreeBSD_kernel__) || defined(__linux__) ||                       
\
+    defined(__CYGWIN__) || defined(__DragonFly__) || defined(_AIX) ||          
\
+    defined(__GNU__) ||                                                        
\
+    (defined(__sun__) && defined(__svr4__) || defined(__HAIKU__)) ||           
\
+    defined(__wasi__)
 static int test_dir(char ret[PATH_MAX], const char *dir, const char *bin) {
   struct stat sb;
   char fullpath[PATH_MAX];
@@ -283,7 +287,7 @@ std::string getMainExecutable(const char *argv0, void 
*MainAddr) {
   // Fall back to the classical detection.
   if (getprogpath(exe_path, argv0))
     return exe_path;
-#elif defined(__OpenBSD__) || defined(__HAIKU__)
+#elif defined(__OpenBSD__) || defined(__HAIKU__) || defined(__wasi__)
   char exe_path[PATH_MAX];
   // argv[0] only
   if (getprogpath(exe_path, argv0) != NULL)
@@ -508,6 +512,9 @@ static bool is_local_impl(struct STATVFS &Vfs) {
 #elif defined(__EMSCRIPTEN__)
   // Emscripten doesn't currently support remote filesystem mounts.
   return true;
+#elif defined(__wasi__)
+  // WASI doesn't currently support remote filesystem mounts.
+  return true;
 #elif defined(__HAIKU__)
   // Haiku doesn't expose this information.
   return false;
@@ -673,6 +680,11 @@ static void expandTildeExpr(SmallVectorImpl<char> &Path) {
     return;
   }
 
+#if defined(__wasi__)
+  // No access to password database, return back the original path.
+  (void)Remainder;
+  return;
+#else
   // This is a string of the form ~username/, look up this user's entry in the
   // password database.
   std::unique_ptr<char[]> Buf;
@@ -694,6 +706,7 @@ static void expandTildeExpr(SmallVectorImpl<char> &Path) {
   Path.clear();
   Path.append(Entry->pw_dir, Entry->pw_dir + strlen(Entry->pw_dir));
   llvm::sys::path::append(Path, Storage);
+#endif
 }
 
 void expand_tilde(const Twine &path, SmallVectorImpl<char> &dest) {
@@ -770,11 +783,15 @@ std::error_code status(int FD, file_status &Result) {
 }
 
 unsigned getUmask() {
+#if defined(__wasi__)
+  return 0022;
+#else
   // Chose arbitary new mask and reset the umask to the old mask.
   // umask(2) never fails so ignore the return of the second call.
   unsigned Mask = ::umask(0);
   (void)::umask(Mask);
   return Mask;
+#endif
 }
 
 std::error_code setPermissions(const Twine &Path, perms Permissions) {
@@ -880,7 +897,7 @@ void mapped_file_region::dontNeedImpl() {
   assert(Mode == mapped_file_region::readonly);
   if (!Mapping)
     return;
-#if defined(__MVS__) || defined(_AIX)
+#if defined(__MVS__) || defined(_AIX) || defined(__wasi__)
     // If we don't have madvise, or it isn't beneficial, treat this as a no-op.
 #elif defined(POSIX_MADV_DONTNEED)
   ::posix_madvise(Mapping, Size, POSIX_MADV_DONTNEED);
@@ -1224,6 +1241,9 @@ Expected<size_t> readNativeFileSlice(file_t FD, 
MutableArrayRef<char> Buf,
 }
 
 std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
+#if defined(__wasi__)
+  return std::error_code(ENOSYS, std::generic_category());
+#else
   auto Start = std::chrono::steady_clock::now();
   auto End = Start + Timeout;
   do {
@@ -1241,9 +1261,13 @@ std::error_code tryLockFile(int FD, 
std::chrono::milliseconds Timeout) {
     usleep(1000);
   } while (std::chrono::steady_clock::now() < End);
   return make_error_code(errc::no_lock_available);
+#endif
 }
 
 std::error_code lockFile(int FD) {
+#if defined(__wasi__)
+  return std::error_code(ENOSYS, std::generic_category());
+#else
   struct flock Lock;
   memset(&Lock, 0, sizeof(Lock));
   Lock.l_type = F_WRLCK;
@@ -1253,9 +1277,13 @@ std::error_code lockFile(int FD) {
   if (::fcntl(FD, F_SETLKW, &Lock) != -1)
     return std::error_code();
   return errnoAsErrorCode();
+#endif
 }
 
 std::error_code unlockFile(int FD) {
+#if defined(__wasi__)
+  return std::error_code(ENOSYS, std::generic_category());
+#else
   struct flock Lock;
   Lock.l_type = F_UNLCK;
   Lock.l_whence = SEEK_SET;
@@ -1264,6 +1292,7 @@ std::error_code unlockFile(int FD) {
   if (::fcntl(FD, F_SETLK, &Lock) != -1)
     return std::error_code();
   return errnoAsErrorCode();
+#endif
 }
 
 std::error_code closeFile(file_t &F) {
@@ -1335,11 +1364,15 @@ std::error_code real_path(const Twine &path, 
SmallVectorImpl<char> &dest,
 }
 
 std::error_code changeFileOwnership(int FD, uint32_t Owner, uint32_t Group) {
+#if defined(__wasi__)
+  return std::error_code(ENOTSUP, std::generic_category());
+#else
   auto FChown = [&]() { return ::fchown(FD, Owner, Group); };
   // Retry if fchown call fails due to interruption.
   if ((sys::RetryAfterSignal(-1, FChown)) < 0)
     return errnoAsErrorCode();
   return std::error_code();
+#endif
 }
 
 } // end namespace fs
@@ -1349,6 +1382,7 @@ namespace path {
 bool home_directory(SmallVectorImpl<char> &result) {
   std::unique_ptr<char[]> Buf;
   char *RequestedDir = getenv("HOME");
+#if !defined(__wasi__)
   if (!RequestedDir) {
     long BufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
     if (BufSize <= 0)
@@ -1360,6 +1394,7 @@ bool home_directory(SmallVectorImpl<char> &result) {
     if (pw && pw->pw_dir)
       RequestedDir = pw->pw_dir;
   }
+#endif
   if (!RequestedDir)
     return false;
 
diff --git a/llvm/lib/Support/Unix/Process.inc 
b/llvm/lib/Support/Unix/Process.inc
index 84b10ff5d1d08..543a5a26e59bd 100644
--- a/llvm/lib/Support/Unix/Process.inc
+++ b/llvm/lib/Support/Unix/Process.inc
@@ -62,7 +62,8 @@ getRUsageTimes() {
   ::getrusage(RUSAGE_SELF, &RU);
   return {toDuration(RU.ru_utime), toDuration(RU.ru_stime)};
 #else
-#ifndef __MVS__ // Exclude for MVS in case -pedantic is used
+#if !(defined(__MVS__) ||                                                      
\
+      defined(__wasi__)) // Exclude in case -pedantic is used
 #warning Cannot get usage times on this platform
 #endif
   return {std::chrono::microseconds::zero(), 
std::chrono::microseconds::zero()};
@@ -72,7 +73,11 @@ getRUsageTimes() {
 Process::Pid Process::getProcessId() {
   static_assert(sizeof(Pid) >= sizeof(pid_t),
                 "Process::Pid should be big enough to store pid_t");
+#if defined(__wasi__)
+  return Pid(0);
+#else
   return Pid(::getpid());
+#endif
 }
 
 // On Cygwin, getpagesize() returns 64k(AllocationGranularity) and
@@ -252,13 +257,21 @@ std::error_code Process::FixupStandardFileDescriptors() {
 
     if (NullFD == StandardFD)
       FDC.keepOpen();
+#if defined(__wasi__)
+    else // WASI does not have `dup2` by design. Return EBADF.
+#else
     else if (dup2(NullFD, StandardFD) < 0)
+#endif
       return errnoAsErrorCode();
   }
   return std::error_code();
 }
 
 std::error_code Process::SafelyCloseFileDescriptor(int FD) {
+#if defined(__wasi__)
+  ::close(FD);
+  return errnoAsErrorCode();
+#else
   // Create a signal set filled with *all* signals.
   sigset_t FullSet, SavedSet;
   if (sigfillset(&FullSet) < 0 || sigfillset(&SavedSet) < 0)
@@ -291,6 +304,7 @@ std::error_code Process::SafelyCloseFileDescriptor(int FD) {
   if (ErrnoFromClose)
     return std::error_code(ErrnoFromClose, std::generic_category());
   return std::error_code(EC, std::generic_category());
+#endif
 }
 
 bool Process::StandardInIsUserInput() {
diff --git a/llvm/lib/Support/Unix/Program.inc 
b/llvm/lib/Support/Unix/Program.inc
index 2742734bb11ed..d4becf6ea7742 100644
--- a/llvm/lib/Support/Unix/Program.inc
+++ b/llvm/lib/Support/Unix/Program.inc
@@ -71,6 +71,7 @@ ProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {}
 ErrorOr<std::string> sys::findProgramByName(StringRef Name,
                                             ArrayRef<StringRef> Paths) {
   assert(!Name.empty() && "Must have a name!");
+#if !defined(__wasi__)
   // Use the given path verbatim if it contains any slashes; this matches
   // the behavior of sh(1) and friends.
   if (Name.contains('/'))
@@ -93,12 +94,14 @@ ErrorOr<std::string> sys::findProgramByName(StringRef Name,
     if (sys::fs::can_execute(FilePath.c_str()))
       return std::string(FilePath); // Found the executable!
   }
+#endif
   return errc::no_such_file_or_directory;
 }
 
 static bool RedirectIO(std::optional<StringRef> Path, int FD, std::string 
*ErrMsg) {
   if (!Path) // Noop
     return false;
+#if !defined(__wasi__)
   std::string File;
   if (Path->empty())
     // Redirect empty paths to /dev/null
@@ -121,6 +124,7 @@ static bool RedirectIO(std::optional<StringRef> Path, int 
FD, std::string *ErrMs
     return true;
   }
   close(InFD); // Close the original FD
+#endif
   return false;
 }
 
@@ -178,6 +182,11 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
                     ArrayRef<std::optional<StringRef>> Redirects,
                     unsigned MemoryLimit, std::string *ErrMsg,
                     BitVector *AffinityMask, bool DetachProcess) {
+#if defined(__wasi__)
+  if (ErrMsg)
+    *ErrMsg = std::string("WASI does not support spawning subprocesses");
+  return false;
+#else
   if (!llvm::sys::fs::exists(Program)) {
     if (ErrMsg)
       *ErrMsg = std::string("Executable \"") + Program.str() +
@@ -347,6 +356,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
   PI.Process = child;
 
   return true;
+#endif
 }
 
 namespace llvm {
@@ -354,7 +364,7 @@ namespace sys {
 
 #if defined(_AIX)
 static pid_t(wait4)(pid_t pid, int *status, int options, struct rusage *usage);
-#elif !defined(__Fuchsia__)
+#elif !defined(__Fuchsia__) && !defined(__wasi__)
 using ::wait4;
 #endif
 
@@ -400,6 +410,9 @@ ProcessInfo llvm::sys::Wait(const ProcessInfo &PI,
                             std::string *ErrMsg,
                             std::optional<ProcessStatistics> *ProcStat,
                             bool Polling) {
+#if defined(__wasi__)
+  assert(false && "Unsupported");
+#else
   struct sigaction Act, Old;
   assert(PI.Pid && "invalid pid to wait on, process not started?");
 
@@ -517,6 +530,7 @@ ProcessInfo llvm::sys::Wait(const ProcessInfo &PI,
     WaitResult.ReturnCode = -2;
   }
   return WaitResult;
+#endif
 }
 
 std::error_code llvm::sys::ChangeStdinMode(fs::OpenFlags Flags) {
diff --git a/llvm/lib/Support/Unix/Unix.h b/llvm/lib/Support/Unix/Unix.h
index 1599241a344af..b378c05e9021b 100644
--- a/llvm/lib/Support/Unix/Unix.h
+++ b/llvm/lib/Support/Unix/Unix.h
@@ -30,7 +30,10 @@
 #include <cstring>
 #include <string>
 #include <sys/types.h>
+
+#if !defined(__wasi__)
 #include <sys/wait.h>
+#endif
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
diff --git a/llvm/lib/Support/Unix/Watchdog.inc 
b/llvm/lib/Support/Unix/Watchdog.inc
index b33e52d88500d..415a23ee09777 100644
--- a/llvm/lib/Support/Unix/Watchdog.inc
+++ b/llvm/lib/Support/Unix/Watchdog.inc
@@ -19,13 +19,13 @@
 namespace llvm {
 namespace sys {
 Watchdog::Watchdog(unsigned int seconds) {
-#ifdef HAVE_UNISTD_H
+#if HAVE_UNISTD_H && !defined(__wasi__)
   alarm(seconds);
 #endif
 }
 
 Watchdog::~Watchdog() {
-#ifdef HAVE_UNISTD_H
+#if HAVE_UNISTD_H && !defined(__wasi__)
   alarm(0);
 #endif
 }
diff --git a/llvm/lib/Support/raw_socket_stream.cpp 
b/llvm/lib/Support/raw_socket_stream.cpp
index 4cd3d58b80198..90ee29065bc1b 100644
--- a/llvm/lib/Support/raw_socket_stream.cpp
+++ b/llvm/lib/Support/raw_socket_stream.cpp
@@ -41,6 +41,8 @@
 
 using namespace llvm;
 
+#if defined(_WIN32) || !defined(__wasi__)
+
 #ifdef _WIN32
 WSABalancer::WSABalancer() {
   WSADATA WsaData;
@@ -307,3 +309,5 @@ raw_socket_stream::createConnectedUnix(StringRef 
SocketPath) {
 }
 
 raw_socket_stream::~raw_socket_stream() {}
+
+#endif

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to