diff --git a/.github/actions/5a-wasi/action.yml b/.github/actions/5a-wasi/action.yml index efd57eac032..ef3968508d7 100644 --- a/.github/actions/5a-wasi/action.yml +++ b/.github/actions/5a-wasi/action.yml @@ -47,3 +47,28 @@ runs: export WASMTIME_BACKTRACE_DETAILS=1 ../wasmtime/wasmtime -W exceptions ./druntime-test-runner-debug ../wasmtime/wasmtime -W exceptions ./druntime-test-runner + + - name: Run `importc_compare` + shell: bash + run: | + set -eux + cd .. + + os='${{ inputs.os }}' + arch='${{ inputs.arch }}' + triple="$arch-unknown-$os" + + # wasm-enable-sjlj only used so `setjmp.h` doesn't error out + bootstrap-ldc/bin/ldc2 \ + -defaultlib=druntime-ldc -L-Linstall/lib-$os-$arch \ + -gcc=wasi-sdk/bin/$arch-$os-clang \ + --mtriple=$triple \ + -P=-mllvm -P=-wasm-enable-sjlj \ + -P=-D_WASI_EMULATED_SIGNAL --d-version=WASI_EMULATED_SIGNAL \ + -P=-D_WASI_EMULATED_PROCESS_CLOCKS --d-version=WASI_EMULATED_PROCESS_CLOCKS \ + -P=-D_WASI_EMULATED_MMAN --d-version=WASI_EMULATED_MMAN \ + -I$PWD/ldc/runtime/druntime/test/importc_compare/src \ + $PWD/ldc/runtime/druntime/test/importc_compare/src/importc_compare.d + + export WASMTIME_BACKTRACE_DETAILS=1 + wasmtime/wasmtime -W exceptions ./importc_compare.wasm diff --git a/driver/main.cpp b/driver/main.cpp index a01260fc1ce..8e2b48268dc 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -935,22 +935,26 @@ void registerPredefinedTargetVersions() { case llvm::Triple::WASI: VersionCondition::addPredefinedGlobalIdent("WASI"); VersionCondition::addPredefinedGlobalIdent("WASIp1"); + VersionCondition::addPredefinedGlobalIdent("Posix"); VersionCondition::addPredefinedGlobalIdent("CRuntime_WASI"); break; #if LLVM_VERSION_MAJOR >= 22 case llvm::Triple::WASIp1: VersionCondition::addPredefinedGlobalIdent("WASI"); VersionCondition::addPredefinedGlobalIdent("WASIp1"); + VersionCondition::addPredefinedGlobalIdent("Posix"); VersionCondition::addPredefinedGlobalIdent("CRuntime_WASI"); break; case llvm::Triple::WASIp2: VersionCondition::addPredefinedGlobalIdent("WASI"); VersionCondition::addPredefinedGlobalIdent("WASIp2"); + VersionCondition::addPredefinedGlobalIdent("Posix"); VersionCondition::addPredefinedGlobalIdent("CRuntime_WASI"); break; case llvm::Triple::WASIp3: VersionCondition::addPredefinedGlobalIdent("WASI"); VersionCondition::addPredefinedGlobalIdent("WASIp3"); + VersionCondition::addPredefinedGlobalIdent("Posix"); VersionCondition::addPredefinedGlobalIdent("CRuntime_WASI"); break; #endif diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 94af0fbb306..7a392ce1b5f 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -208,12 +208,11 @@ file(GLOB_RECURSE DRUNTIME_D_OPENBSD ${RUNTIME_DIR}/src/core/sys/openbsd/*.d) file(GLOB_RECURSE DRUNTIME_D_POSIX ${RUNTIME_DIR}/src/core/sys/posix/*.d) file(GLOB_RECURSE DRUNTIME_D_SOLARIS ${RUNTIME_DIR}/src/core/sys/solaris/*.d) file(GLOB_RECURSE DRUNTIME_D_WINDOWS ${RUNTIME_DIR}/src/core/sys/windows/*.d) -file(GLOB_RECURSE DRUNTIME_D_WASI ${RUNTIME_DIR}/src/core/sys/wasi/*.d) list(REMOVE_ITEM DRUNTIME_D ${DRUNTIME_D_BIONIC} ${DRUNTIME_D_DARWIN} ${DRUNTIME_D_DRAGONFLYBSD} ${DRUNTIME_D_FREEBSD} ${DRUNTIME_D_LINUX} ${DRUNTIME_D_NETBSD} ${DRUNTIME_D_OPENBSD} ${DRUNTIME_D_POSIX} ${DRUNTIME_D_SOLARIS} - ${DRUNTIME_D_WINDOWS} ${DRUNTIME_D_WASI} + ${DRUNTIME_D_WINDOWS} ) if("${TARGET_SYSTEM}" MATCHES "Windows") list(APPEND DRUNTIME_D ${DRUNTIME_D_WINDOWS}) @@ -235,8 +234,6 @@ elseif("${TARGET_SYSTEM}" MATCHES "UNIX") elseif("${TARGET_SYSTEM}" MATCHES "SunOS") list(APPEND DRUNTIME_D ${DRUNTIME_D_SOLARIS}) endif() -elseif("${TARGET_SYSTEM}" MATCHES "WASI") - list(APPEND DRUNTIME_D ${DRUNTIME_D_WASI}) endif() # druntime C parts diff --git a/runtime/druntime/src/core/demangle.d b/runtime/druntime/src/core/demangle.d index 6d28f1ed2be..bcd7620cd77 100644 --- a/runtime/druntime/src/core/demangle.d +++ b/runtime/druntime/src/core/demangle.d @@ -3003,6 +3003,7 @@ CXX_DEMANGLER getCXXDemangler() nothrow @trusted version (OpenBSD) import core.sys.openbsd.dlfcn : RTLD_DEFAULT; version (Darwin) import core.sys.darwin.dlfcn : RTLD_DEFAULT; version (Solaris) import core.sys.solaris.dlfcn : RTLD_DEFAULT; + version (CRuntime_WASI) import core.sys.posix.dlfcn : RTLD_DEFAULT; if (auto found = cast(CXX_DEMANGLER) dlsym(RTLD_DEFAULT, "__cxa_demangle")) atomicStore(__cxa_demangle, found); diff --git a/runtime/druntime/src/core/internal/abort.d b/runtime/druntime/src/core/internal/abort.d index 2e64e1e13dc..c0adde99dd2 100644 --- a/runtime/druntime/src/core/internal/abort.d +++ b/runtime/druntime/src/core/internal/abort.d @@ -41,94 +41,6 @@ void abort(scope string msg, scope string filename = __FILE__, size_t line = __L } } } - else version (WASIp1) { - // currently depends on wasi-libc being linked in to provide these "syscalls" - // TODO: detach this from wasi-libc - alias ushort __wasi_errno_t; - alias int __wasi_fd_t; - alias size_t __wasi_size_t; - - extern(C) struct __wasi_ciovec_t { - const(ubyte)* buf; - __wasi_size_t buf_len; - } - - pragma(mangle, "__wasi_fd_write") - extern(C) static __wasi_errno_t - __wasi_fd_write(__wasi_fd_t fd, - const __wasi_ciovec_t *iovs, - size_t iovs_len, __wasi_size_t *retptr0) @nogc nothrow; - - static void writeStr(scope const(char)[][] m...) @nogc nothrow @trusted - { - foreach (s; m) { - __wasi_ciovec_t iovec; - __wasi_size_t ret; - iovec.buf = cast(const(ubyte)*)s.ptr; - iovec.buf_len = s.length; - cast(void)__wasi_fd_write(2, &iovec, 1, &ret); - } - } - } else version (WASIp2) { - // currently depends on wasi-libc being linked in to provide these "syscalls" - // TODO: detach this from wasi-libc - extern(C) struct wasip2_list_u8_t { - ubyte* ptr; - size_t len; - } - extern(C) struct streams_own_output_stream_t { - int __handle; - } - extern(C) struct streams_borrow_output_stream_t { - int __handle; - } - alias streams_own_output_stream_t stderr_own_output_stream_t; - extern(C) struct io_error_own_error_t { - int __handle; - } - alias io_error_own_error_t streams_own_error_t; - - extern(C) struct streams_stream_error_t { - ubyte tag; - - union Val { - streams_own_error_t last_operation_failed; - } - Val val; - } - - pragma(mangle, "streams_output_stream_drop_own") - extern(C) static void streams_output_stream_drop_own(streams_own_output_stream_t handle) @nogc nothrow; - pragma(mangle, "streams_borrow_output_stream") - extern(C) static streams_borrow_output_stream_t streams_borrow_output_stream(streams_own_output_stream_t handle) @nogc nothrow; - pragma(mangle, "stderr_get_stderr") - extern(C) static stderr_own_output_stream_t stderr_get_stderr() @nogc nothrow; - pragma(mangle, "io_error_error_drop_own") - extern(C) static void io_error_error_drop_own(io_error_own_error_t handle) @nogc nothrow; - pragma(mangle, "streams_stream_error_free") - extern(C) static void streams_stream_error_free(streams_stream_error_t *ptr) @nogc nothrow; - pragma(mangle, "streams_method_output_stream_blocking_write_and_flush") - extern(C) static bool streams_method_output_stream_blocking_write_and_flush(streams_borrow_output_stream_t self, wasip2_list_u8_t *contents, streams_stream_error_t *err) @nogc nothrow; - - static void writeStr(scope const(char)[][] m...) @nogc nothrow @trusted - { - auto stderr_own = stderr_get_stderr(); - scope(exit) streams_output_stream_drop_own(stderr_own); - - auto stderr = streams_borrow_output_stream(stderr_own); - - foreach (s; m) { - wasip2_list_u8_t contents; - contents.ptr = cast(ubyte*)s.ptr; - contents.len = s.length; - streams_stream_error_t err; - bool success = streams_method_output_stream_blocking_write_and_flush(stderr, &contents, &err); - if (!success) { - streams_stream_error_free(&err); - } - } - } - } else static assert(0, "Unsupported OS"); diff --git a/runtime/druntime/src/core/internal/backtrace/dwarf.d b/runtime/druntime/src/core/internal/backtrace/dwarf.d index 1f2662241ff..0109c604c3f 100644 --- a/runtime/druntime/src/core/internal/backtrace/dwarf.d +++ b/runtime/druntime/src/core/internal/backtrace/dwarf.d @@ -49,6 +49,9 @@ module core.internal.backtrace.dwarf; +version (WASI) {} +else: + version (Posix): import core.internal.string; diff --git a/runtime/druntime/src/core/internal/elf/io.d b/runtime/druntime/src/core/internal/elf/io.d index 80c9415e149..67cefe69815 100644 --- a/runtime/druntime/src/core/internal/elf/io.d +++ b/runtime/druntime/src/core/internal/elf/io.d @@ -13,6 +13,9 @@ module core.internal.elf.io; version (Posix): +version (WASI) {} +else: + import core.lifetime : move; import core.memory : pageSize; import core.stdc.stdlib : free, malloc; diff --git a/runtime/druntime/src/core/internal/gc/impl/conservative/gc.d b/runtime/druntime/src/core/internal/gc/impl/conservative/gc.d index 2fc13760fc5..ffa0bdcbfbf 100644 --- a/runtime/druntime/src/core/internal/gc/impl/conservative/gc.d +++ b/runtime/druntime/src/core/internal/gc/impl/conservative/gc.d @@ -30,10 +30,13 @@ module core.internal.gc.impl.conservative.gc; /***************************************************/ version (WASI) {} // WASI is single-threaded -else version = COLLECT_PARALLEL; // parallel scanning +else +{ + version = COLLECT_PARALLEL; // parallel scanning -version (Posix) - version = COLLECT_FORK; + version (Posix) + version = COLLECT_FORK; +} import core.internal.gc.bits; import core.internal.gc.os; @@ -1787,7 +1790,8 @@ struct Gcx usedSmallPages = usedLargePages = 0; mappedPages = 0; //printf("gcx = %p, self = %x\n", &this, self); - version (Posix) + version(WASI) {} + else version (Posix) { import core.sys.posix.pthread : pthread_atfork; instance = &this; diff --git a/runtime/druntime/src/core/internal/gc/os.d b/runtime/druntime/src/core/internal/gc/os.d index 914b7b903c7..6322890c8bc 100644 --- a/runtime/druntime/src/core/internal/gc/os.d +++ b/runtime/druntime/src/core/internal/gc/os.d @@ -22,6 +22,10 @@ version (Windows) //version = GC_Use_Alloc_Win32; } +else version (WASI) +{ + import core.stdc.stdlib : free, malloc; +} else version (Posix) { version (OSX) diff --git a/runtime/druntime/src/core/runtime.d b/runtime/druntime/src/core/runtime.d index f307a382ed5..88adf9e8ead 100644 --- a/runtime/druntime/src/core/runtime.d +++ b/runtime/druntime/src/core/runtime.d @@ -817,7 +817,8 @@ void defaultTraceDeallocator(Throwable.TraceInfo info) nothrow } /// Default implementation for most POSIX systems -version (Posix) private class DefaultTraceInfo : Throwable.TraceInfo +version (WASI) {} +else version (Posix) private class DefaultTraceInfo : Throwable.TraceInfo { import core.demangle; import core.stdc.stdlib : free; diff --git a/runtime/druntime/src/core/stdc/config.d b/runtime/druntime/src/core/stdc/config.d index 7c5b53df1ff..712cbc2255c 100644 --- a/runtime/druntime/src/core/stdc/config.d +++ b/runtime/druntime/src/core/stdc/config.d @@ -182,37 +182,6 @@ else version (Posix) alias cpp_ulonglong = ulong; } } -else version (WASI) -{ - static if ( (void*).sizeof > int.sizeof ) - { - enum __c_longlong : long; - enum __c_ulonglong : ulong; - - alias c_long = long; - alias c_ulong = ulong; - - alias cpp_long = long; - alias cpp_ulong = ulong; - - alias cpp_longlong = __c_longlong; - alias cpp_ulonglong = __c_ulonglong; - } - else - { - enum __c_long : int; - enum __c_ulong : uint; - - alias c_long = int; - alias c_ulong = uint; - - alias cpp_long = __c_long; - alias cpp_ulong = __c_ulong; - - alias cpp_longlong = long; - alias cpp_ulonglong = ulong; - } -} version (GNU) alias c_long_double = real; diff --git a/runtime/druntime/src/core/stdc/limits.d b/runtime/druntime/src/core/stdc/limits.d index c5df0cd65b4..20f1c0c0f6b 100644 --- a/runtime/druntime/src/core/stdc/limits.d +++ b/runtime/druntime/src/core/stdc/limits.d @@ -192,7 +192,7 @@ else version (CRuntime_WASI) /// enum PATH_MAX = 256; /// - enum PIPE_BUF = 512; + enum PIPE_BUF = 4096; } else static assert(0, "unsupported OS"); diff --git a/runtime/druntime/src/core/stdc/signal.d b/runtime/druntime/src/core/stdc/signal.d index 7bc59a5be44..6abfea47c6c 100644 --- a/runtime/druntime/src/core/stdc/signal.d +++ b/runtime/druntime/src/core/stdc/signal.d @@ -20,7 +20,8 @@ nothrow: // this should be volatile /// -version (CRuntime_WASI) { +version (CRuntime_WASI) +{ import core.stdc.config : c_long; alias c_long sig_atomic_t; } else { @@ -29,14 +30,18 @@ version (CRuntime_WASI) { private alias sigfn_t = void function(int); -version (Posix) + +version (CRuntime_WASI) { + extern(C) void __SIG_ERR(int); + extern(C) void __SIG_IGN(int); + /// - enum SIG_ERR = cast(sigfn_t) -1; + enum SIG_ERR = cast(sigfn_t)&__SIG_ERR; /// - enum SIG_DFL = cast(sigfn_t) 0; + enum SIG_DFL = cast(sigfn_t)0; /// - enum SIG_IGN = cast(sigfn_t) 1; + enum SIG_IGN = cast(sigfn_t)&__SIG_IGN; // standard C signals /// @@ -52,7 +57,7 @@ version (Posix) /// enum SIGTERM = 15; // Termination } -else version (Windows) +else version (Posix) { /// enum SIG_ERR = cast(sigfn_t) -1; @@ -63,7 +68,7 @@ else version (Windows) // standard C signals /// - enum SIGABRT = 22; // Abnormal termination + enum SIGABRT = 6; // Abnormal termination /// enum SIGFPE = 8; // Floating-point error /// @@ -75,21 +80,18 @@ else version (Windows) /// enum SIGTERM = 15; // Termination } -else version (CRuntime_WASI) +else version (Windows) { - extern(C) void __SIG_ERR(int); - extern(C) void __SIG_IGN(int); - /// - enum SIG_ERR = cast(sigfn_t)&__SIG_ERR; + enum SIG_ERR = cast(sigfn_t) -1; /// - enum SIG_DFL = cast(sigfn_t)0; + enum SIG_DFL = cast(sigfn_t) 0; /// - enum SIG_IGN = cast(sigfn_t)&__SIG_IGN; + enum SIG_IGN = cast(sigfn_t) 1; // standard C signals /// - enum SIGABRT = 6; // Abnormal termination + enum SIGABRT = 22; // Abnormal termination /// enum SIGFPE = 8; // Floating-point error /// diff --git a/runtime/druntime/src/core/stdc/stddef.d b/runtime/druntime/src/core/stdc/stddef.d index 828ccb42a85..a147248e48d 100644 --- a/runtime/druntime/src/core/stdc/stddef.d +++ b/runtime/druntime/src/core/stdc/stddef.d @@ -34,8 +34,3 @@ else version (Posix) /// alias wchar_t = dchar; } -else version (WASI) -{ - /// - alias wchar_t = dchar; -} diff --git a/runtime/druntime/src/core/stdc/stdint.d b/runtime/druntime/src/core/stdc/stdint.d index 385f4ca5dde..33db7a9cec6 100644 --- a/runtime/druntime/src/core/stdc/stdint.d +++ b/runtime/druntime/src/core/stdc/stdint.d @@ -398,15 +398,15 @@ else version (WASI) alias int_least64_t = long; /// alias uint_least64_t = ulong; /// - alias int_fast8_t = byte; /// - alias uint_fast8_t = ubyte; /// - alias int_fast16_t = ptrdiff_t; /// - alias uint_fast16_t = size_t; /// - alias int_fast32_t = ptrdiff_t; /// - alias uint_fast32_t = size_t; /// + alias int_fast8_t = byte; /// + alias uint_fast8_t = ubyte; /// + alias int_fast16_t = short; /// + alias uint_fast16_t = ushort; /// + alias int_fast32_t = int; /// + alias uint_fast32_t = uint; /// - alias int_fast64_t = long; /// - alias uint_fast64_t = ulong; /// + alias int_fast64_t = long; /// + alias uint_fast64_t = ulong; /// alias intptr_t = ptrdiff_t; /// alias uintptr_t = size_t; /// diff --git a/runtime/druntime/src/core/stdc/time.d b/runtime/druntime/src/core/stdc/time.d index 6e2caa5e496..ead533718b7 100644 --- a/runtime/druntime/src/core/stdc/time.d +++ b/runtime/druntime/src/core/stdc/time.d @@ -19,9 +19,7 @@ version (Posix) public import core.sys.posix.stdc.time; else version (Windows) public import core.sys.windows.stdc.time; -else version (WASI) { - public import core.sys.wasi.posix.stdc.time; -} else +else static assert(0, "unsupported system"); import core.stdc.config; diff --git a/runtime/druntime/src/core/stdc/wchar_.d b/runtime/druntime/src/core/stdc/wchar_.d index 43c72ec1905..81af1304152 100644 --- a/runtime/druntime/src/core/stdc/wchar_.d +++ b/runtime/druntime/src/core/stdc/wchar_.d @@ -146,6 +146,18 @@ else version (Windows) /// alias mbstate_t = __mbstate_t; } +else version (CRuntime_WASI) +{ + /// + struct __mbstate_t + { + uint __opaque1; + uint __opaque2; + } + + /// + alias mbstate_t = __mbstate_t; +} else { /// diff --git a/runtime/druntime/src/core/sync/condition.d b/runtime/druntime/src/core/sync/condition.d index 13fc9541e3f..ca5518c4765 100644 --- a/runtime/druntime/src/core/sync/condition.d +++ b/runtime/druntime/src/core/sync/condition.d @@ -41,10 +41,6 @@ else version (Posix) pthread_cond_signal, pthread_cond_t, pthread_cond_timedwait, pthread_cond_wait; import core.sys.posix.time : timespec; } -else version (WASI) -{ - // Dummy no-ops -} else { static assert(false, "Platform not supported"); @@ -254,10 +250,6 @@ class Condition if ( rc ) throw staticError!AssertError("Unable to wait for condition", __FILE__, __LINE__); } - else version (WASI) - { - throw staticError!AssertError("Unable to wait for condition", __FILE__, __LINE__); - } } /** @@ -323,10 +315,6 @@ class Condition return false; throw staticError!AssertError("Unable to wait for condition", __FILE__, __LINE__); } - else version (WASI) - { - throw staticError!AssertError("Unable to wait for condition", __FILE__, __LINE__); - } } /** @@ -375,10 +363,6 @@ class Condition if ( rc ) throw staticError!AssertError("Unable to notify condition", __FILE__, __LINE__); } - else version (WASI) - { - throw staticError!AssertError("Unable to notify condition", __FILE__, __LINE__); - } } /** @@ -427,10 +411,6 @@ class Condition if ( rc ) throw staticError!AssertError("Unable to notify condition", __FILE__, __LINE__); } - else version (WASI) - { - throw staticError!AssertError("Unable to notify condition", __FILE__, __LINE__); - } } private: @@ -636,10 +616,6 @@ private: Mutex m_assocMutex; pthread_cond_t m_hndl; } - else version (WASI) - { - Mutex m_assocMutex; - } } diff --git a/runtime/druntime/src/core/sync/event.d b/runtime/druntime/src/core/sync/event.d index c28c4e7b49f..9c8cb1b0250 100644 --- a/runtime/druntime/src/core/sync/event.d +++ b/runtime/druntime/src/core/sync/event.d @@ -26,10 +26,6 @@ else version (Posix) import core.sys.posix.sys.types : pthread_cond_t, pthread_mutex_t; import core.sys.posix.time : timespec; } -else version (WASI) -{ - // Dummy no-op -} else { static assert(false, "Platform not supported"); @@ -137,10 +133,6 @@ nothrow @nogc: m_manualReset = manualReset; m_initalized = true; } - else version (WASI) - { - abort("Error: Cannot initialize Event on WASI."); - } } // copying not allowed, can produce resource leaks @@ -200,10 +192,6 @@ nothrow @nogc: pthread_mutex_unlock(&m_mutex); } } - else version (WASI) - { - abort("Error: Cannot deinitialize Event on WASI."); - } } /// Reset the event manually @@ -241,11 +229,6 @@ nothrow @nogc: { return wait(Duration.max); } - else version (WASI) - { - abort("Error: Cannot wait for Event on WASI."); - return false; - } } /** @@ -307,11 +290,6 @@ nothrow @nogc: return result == 0; } - else version (WASI) - { - abort("Error: Cannot wait for Event on WASI."); - return false; - } } private: @@ -330,8 +308,6 @@ private: } // Test single-thread (non-shared) use. -version (WASI) {} // WASI is single-threaded (and has no Event support) -else @nogc nothrow unittest { // auto-reset, initial state false @@ -349,7 +325,7 @@ else assert(!ev2.wait(1.dur!"msecs")); } -version (WASI) {} // WASI is single-threaded (and has no Event support) +version (WASI) {} // WASI is single-threaded else unittest { diff --git a/runtime/druntime/src/core/sync/mutex.d b/runtime/druntime/src/core/sync/mutex.d index bd87004f192..3c43c8c3696 100644 --- a/runtime/druntime/src/core/sync/mutex.d +++ b/runtime/druntime/src/core/sync/mutex.d @@ -31,10 +31,6 @@ else version (Posix) pthread_mutexattr_init, pthread_mutexattr_settype; import core.sys.posix.sys.types : pthread_mutex_t, pthread_mutexattr_t; } -else version (WASI) -{ - // Dummy no-op -} else { static assert(false, "Platform not supported"); @@ -279,10 +275,6 @@ class Mutex : { return pthread_mutex_trylock(&self.m_hndl) == 0; } - else version (WASI) - { - return true; - } } @@ -388,13 +380,13 @@ unittest // Verify that the underlying implementation has been destroyed by checking // that locking is not possible. This assumes that the underlying // implementation is well behaved and makes the object non-lockable upon - // destruction. The Bionic, DragonFly, Musl, and Solaris C runtimes don't - // appear to do so, so skip this test. + // destruction. The Bionic, DragonFly, Musl, Solaris, and WASI C runtimes + // don't appear to do so, so skip this test. version (CRuntime_Bionic) {} else version (CRuntime_Musl) {} else version (DragonFlyBSD) {} else version (Solaris) {} else - version (WASI) {} else + version (CRuntime_WASI) {} else assert(!mtx.tryLock_nothrow()); free(cast(void*) mtx); diff --git a/runtime/druntime/src/core/sync/semaphore.d b/runtime/druntime/src/core/sync/semaphore.d index af399886e8f..696533aaafe 100644 --- a/runtime/druntime/src/core/sync/semaphore.d +++ b/runtime/druntime/src/core/sync/semaphore.d @@ -43,6 +43,10 @@ else version (Darwin) import core.sys.darwin.mach.semaphore : mach_task_self, mach_timespec_t, semaphore_create, semaphore_destroy, semaphore_signal, semaphore_t, semaphore_timedwait, semaphore_wait, SYNC_POLICY_FIFO; } +else version (WASI) +{ + // Dummy no-op +} else version (Posix) { import core.stdc.errno : EAGAIN, EINTR, errno, ETIMEDOUT; @@ -50,10 +54,6 @@ else version (Posix) import core.sys.posix.semaphore : sem_destroy, sem_init, sem_post, sem_t, sem_timedwait, sem_trywait, sem_wait; import core.sys.posix.time : clock_gettime, CLOCK_REALTIME, timespec; } -else version (WASI) -{ - // Dummy no-op -} else { static assert(false, "Platform not supported"); @@ -105,16 +105,16 @@ class Semaphore if ( rc ) throw new SyncError( "Unable to create semaphore" ); } + else version (WASI) + { + m_hndl = count; + } else version (Posix) { int rc = sem_init( &m_hndl, 0, count ); if ( rc ) throw new SyncError( "Unable to create semaphore" ); } - else version (WASI) - { - m_hndl = count; - } } @@ -129,6 +129,10 @@ class Semaphore { auto rc = semaphore_destroy( mach_task_self(), m_hndl ); assert( !rc, "Unable to destroy semaphore" ); + } + else version (WASI) + { + } else version (Posix) { @@ -170,6 +174,12 @@ class Semaphore throw new SyncError( "Unable to wait for semaphore" ); } } + else version (WASI) + { + if (m_hndl == 0) throw new SyncError( "Unable to wait for semaphore" ); + + m_hndl -= 1; + } else version (Posix) { while ( true ) @@ -180,12 +190,6 @@ class Semaphore throw new SyncError( "Unable to wait for semaphore" ); } } - else version (WASI) - { - if (m_hndl == 0) throw new SyncError( "Unable to wait for semaphore" ); - - m_hndl -= 1; - } } @@ -266,6 +270,11 @@ class Semaphore throw new SyncError( "Unable to wait for semaphore" ); } } + else version (WASI) + { + wait(); + return true; + } else version (Posix) { timespec t = void; @@ -282,11 +291,6 @@ class Semaphore throw new SyncError( "Unable to wait for semaphore" ); } } - else version (WASI) - { - wait(); - return true; - } } @@ -310,12 +314,6 @@ class Semaphore if ( rc ) throw new SyncError( "Unable to notify semaphore" ); } - else version (Posix) - { - int rc = sem_post( &m_hndl ); - if ( rc ) - throw new SyncError( "Unable to notify semaphore" ); - } else version (WASI) { if (m_hndl < typeof(m_hndl).max) @@ -323,6 +321,12 @@ class Semaphore else throw new SyncError( "Unable to notify semaphore" ); } + else version (Posix) + { + int rc = sem_post( &m_hndl ); + if ( rc ) + throw new SyncError( "Unable to notify semaphore" ); + } } @@ -354,6 +358,11 @@ class Semaphore { return wait( dur!"hnsecs"(0) ); } + else version (WASI) + { + wait(); + return true; + } else version (Posix) { while ( true ) @@ -366,11 +375,6 @@ class Semaphore throw new SyncError( "Unable to wait for semaphore" ); } } - else version (WASI) - { - wait(); - return true; - } } @@ -381,8 +385,9 @@ protected: /// ditto else version (Darwin) alias Handle = semaphore_t; /// ditto - else version (Posix) alias Handle = sem_t; else version (WASI) alias Handle = uint; + /// ditto + else version (Posix) alias Handle = sem_t; /// Handle to the system-specific semaphore. Handle m_hndl; diff --git a/runtime/druntime/src/core/sys/posix/aio.d b/runtime/druntime/src/core/sys/posix/aio.d index 674fab9fc99..5a9be3c26f2 100644 --- a/runtime/druntime/src/core/sys/posix/aio.d +++ b/runtime/druntime/src/core/sys/posix/aio.d @@ -8,6 +8,9 @@ */ module core.sys.posix.aio; +version (CRuntime_WASI) {} +else: + import core.stdc.config; import core.sys.posix.signal; import core.sys.posix.sys.types; diff --git a/runtime/druntime/src/core/sys/posix/arpa/inet.d b/runtime/druntime/src/core/sys/posix/arpa/inet.d index 33f31094e33..515c4378e45 100644 --- a/runtime/druntime/src/core/sys/posix/arpa/inet.d +++ b/runtime/druntime/src/core/sys/posix/arpa/inet.d @@ -284,6 +284,29 @@ else version (CRuntime_Musl) const(char)* inet_ntop(int, const scope void*, char*, socklen_t); int inet_pton(int, const scope char*, void*); } +else version (CRuntime_WASI) +{ + alias in_port_t = ushort; + alias in_addr_t = uint; + + struct in_addr + { + in_addr_t s_addr; + } + + @trusted pure + { + uint32_t htonl(uint32_t); + uint16_t htons(uint16_t); + uint32_t ntohl(uint32_t); + uint16_t ntohs(uint16_t); + } + + in_addr_t inet_addr(const scope char*); + char* inet_ntoa(in_addr); + const(char)* inet_ntop(int, const scope void*, char*, socklen_t); + int inet_pton(int, const scope char*, void*); +} else version (CRuntime_UClibc) { alias in_port_t = uint16_t; diff --git a/runtime/druntime/src/core/sys/posix/config.d b/runtime/druntime/src/core/sys/posix/config.d index 9463471d32f..1cbe2b00993 100644 --- a/runtime/druntime/src/core/sys/posix/config.d +++ b/runtime/druntime/src/core/sys/posix/config.d @@ -97,6 +97,28 @@ else version (CRuntime_Musl) else enum __WORDSIZE = 32; } +else version (CRuntime_WASI) +{ + enum _GNU_SOURCE = false; + enum _DEFAULT_SOURCE = false; + enum _ATFILE_SOURCE = false; + + // off_t is always 64 bits on WASI + enum _FILE_OFFSET_BITS = 64; + + // Not present in WASI sources + enum __REDIRECT = false; + + // Always use code paths that are compatible with 64 bits off_t + enum __USE_FILE_OFFSET64 = true; + enum __USE_LARGEFILE = __USE_FILE_OFFSET64 && !__REDIRECT; + enum __USE_LARGEFILE64 = __USE_FILE_OFFSET64 && !__REDIRECT; + + version (D_LP64) + enum __WORDSIZE = 64; + else + enum __WORDSIZE = 32; +} else version (CRuntime_UClibc) { enum _GNU_SOURCE = false; diff --git a/runtime/druntime/src/core/sys/posix/dirent.d b/runtime/druntime/src/core/sys/posix/dirent.d index c77d6da22b2..868e8fba246 100644 --- a/runtime/druntime/src/core/sys/posix/dirent.d +++ b/runtime/druntime/src/core/sys/posix/dirent.d @@ -158,6 +158,15 @@ else version (Solaris) char[1] d_name = 0; } } +else version (CRuntime_WASI) +{ + struct dirent + { + ino_t d_ino; + ubyte d_type; + char[0] d_name; + } +} else { static assert(false, "Unsupported platform"); @@ -404,6 +413,28 @@ else version (CRuntime_Musl) alias readdir64 = readdir; } } +else version (CRuntime_WASI) +{ + enum + { + DT_UNKNOWN = 0, + DT_BLK = 1, + DT_CHR = 2, + DT_DIR = 3, + DT_REG = 4, + DT_FIFO = 6, + DT_LNK = 7, + DT_SOCK = 20 + } + + struct DIR + { + // Managed by OS + } + + dirent* readdir(DIR*); + alias readdir64 = readdir; +} else version (CRuntime_UClibc) { // NOTE: The following constants are non-standard Linux definitions @@ -575,6 +606,9 @@ else version (CRuntime_Musl) { int readdir_r(DIR*, dirent*, dirent**); } +else version (CRuntime_WASI) +{ +} else version (CRuntime_UClibc) { static if ( __USE_LARGEFILE64 ) @@ -669,6 +703,11 @@ else version (CRuntime_Musl) void seekdir(DIR*, c_long); c_long telldir(DIR*); } +else version (CRuntime_WASI) +{ + void seekdir(DIR*, c_long); + c_long telldir(DIR*); +} else version (CRuntime_UClibc) { void seekdir(DIR*, c_long); diff --git a/runtime/druntime/src/core/sys/posix/dlfcn.d b/runtime/druntime/src/core/sys/posix/dlfcn.d index ff590b30f7a..85a3a63726e 100644 --- a/runtime/druntime/src/core/sys/posix/dlfcn.d +++ b/runtime/druntime/src/core/sys/posix/dlfcn.d @@ -220,6 +220,23 @@ else version (CRuntime_Musl) int dladdr(const(void) *, Dl_info *); int dlinfo(void *, int, void *); } +else version (CRuntime_WASI) +{ + enum RTLD_LAZY = 1; + enum RTLD_NOW = 2; + enum RTLD_NOLOAD = 4; + enum RTLD_NODELETE = 4096; + enum RTLD_GLOBAL = 256; + enum RTLD_LOCAL = 8; + + enum RTLD_NEXT = cast(void *)-1; + enum RTLD_DEFAULT = cast(void *)0; + + int dlclose(void *); + char *dlerror(); + void *dlopen(const(char) *, int); + void *dlsym(void *__restrict, const(char) *__restrict); +} else version (Darwin) { enum RTLD_LAZY = 0x00001; diff --git a/runtime/druntime/src/core/sys/posix/fcntl.d b/runtime/druntime/src/core/sys/posix/fcntl.d index f64e234cedf..e110c86b3e3 100644 --- a/runtime/druntime/src/core/sys/posix/fcntl.d +++ b/runtime/druntime/src/core/sys/posix/fcntl.d @@ -870,6 +870,65 @@ else version (Solaris) enum AT_REMOVEDIR = 0x1; enum AT_EACCESS = 0x4; } +else version (CRuntime_WASI) +{ + enum F_GETFD = 1; + enum F_SETFD = 2; + enum F_GETFL = 3; + enum F_SETFL = 4; + enum F_DUPFD = 5; + enum F_DUPFD_CLOEXEC = 6; + enum F_GETLK = 7; + enum F_SETLK = 8; + enum F_SETLKW = 9; + + enum F_RDLCK = 0; + enum F_WRLCK = 1; + enum F_UNLCK = 2; + + enum FD_CLOEXEC = 1; + + enum O_APPEND = 0x0001; + enum O_DSYNC = 0x0002; + enum O_NONBLOCK = 0x0004; + enum O_RSYNC = 0x0008; + enum O_SYNC = 0x0010; + enum O_CREAT = 0x0001 << 12; + enum O_DIRECTORY = 0x0002 << 12; + enum O_EXCL = 0x0004 << 12; + enum O_TRUNC = 0x0008 << 12; + + enum O_NOFOLLOW = 0x01000000; + enum O_EXEC = 0x02000000; + enum O_RDONLY = 0x04000000; + enum O_SEARCH = 0x08000000; + enum O_WRONLY = 0x10000000; + + enum O_CLOEXEC = 0; + + enum O_TTY_INIT = 0; + + enum O_NOCTTY = 0; + + enum O_RDWR = O_RDONLY | O_WRONLY; + enum O_ACCMODE = O_EXEC | O_RDWR | O_SEARCH; + + struct flock + { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; + } + + enum AT_EACCESS = 0x0; + enum AT_SYMLINK_NOFOLLOW = 0x1; + enum AT_SYMLINK_FOLLOW = 0x2; + enum AT_REMOVEDIR = 0x4; + + enum AT_FDCWD = -2; +} else { static assert(false, "Unsupported platform"); @@ -979,6 +1038,12 @@ else version (CRuntime_Musl) int open(const scope char*, int, ...); int openat(int, const scope char*, int, ...); } +else version (CRuntime_WASI) +{ + int creat(const scope char*, mode_t); + int open(const scope char*, int, ...); + int openat(int, const scope char*, int, ...); +} else version (CRuntime_UClibc) { static if ( __USE_FILE_OFFSET64 ) diff --git a/runtime/druntime/src/core/sys/posix/grp.d b/runtime/druntime/src/core/sys/posix/grp.d index 3a9b993c0ed..72c3b3a8a65 100644 --- a/runtime/druntime/src/core/sys/posix/grp.d +++ b/runtime/druntime/src/core/sys/posix/grp.d @@ -14,6 +14,9 @@ */ module core.sys.posix.grp; +version (CRuntime_WASI) {} +else: + import core.sys.posix.config; public import core.sys.posix.sys.types; // for gid_t, uid_t diff --git a/runtime/druntime/src/core/sys/posix/locale.d b/runtime/druntime/src/core/sys/posix/locale.d index 821487afd29..3fd95be48da 100644 --- a/runtime/druntime/src/core/sys/posix/locale.d +++ b/runtime/druntime/src/core/sys/posix/locale.d @@ -305,6 +305,82 @@ else version (CRuntime_Musl) /// Set the per-thread locale locale_t uselocale (locale_t locale); } +else version (CRuntime_WASI) +{ + /// + struct lconv + { + char* decimal_point; + char* thousands_sep; + char* grouping; + char* int_curr_symbol; + char* currency_symbol; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char int_p_cs_precedes; + char int_p_sep_by_space; + char int_n_cs_precedes; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; + } + + /// + enum + { + LC_CTYPE = 0, + LC_NUMERIC = 1, + LC_TIME = 2, + LC_COLLATE = 3, + LC_MONETARY = 4, + LC_MESSAGES = 5, + LC_ALL = 6, + } + + /// + enum + { + LC_CTYPE_MASK = (1 << LC_CTYPE), + LC_NUMERIC_MASK = (1 << LC_NUMERIC), + LC_TIME_MASK = (1 << LC_TIME), + LC_COLLATE_MASK = (1 << LC_COLLATE), + LC_MONETARY_MASK = (1 << LC_MONETARY), + LC_MESSAGES_MASK = (1 << LC_MESSAGES), + LC_ALL_MASK = 0x7fffffff, + } + + private struct __locale_struct; + + /// + alias locale_t = __locale_struct*; + + /// + enum LC_GLOBAL_LOCALE = (cast(locale_t)-1); + + /// Duplicate existing locale + locale_t duplocale(locale_t locale); + /// Free an allocated locale + void freelocale(locale_t locale); + /// Natural language formatting for C + lconv* localeconv(); + /// Create a new locale + locale_t newlocale(int mask, const char* locale, locale_t base); + /// Set the C library's notion of natural language formatting style + char* setlocale(int category, const char* locale); + /// Set the per-thread locale + locale_t uselocale (locale_t locale); +} else version (OpenBSD) { /// diff --git a/runtime/druntime/src/core/sys/posix/net/if_.d b/runtime/druntime/src/core/sys/posix/net/if_.d index 7fadcd884c4..f20d1ffc61e 100644 --- a/runtime/druntime/src/core/sys/posix/net/if_.d +++ b/runtime/druntime/src/core/sys/posix/net/if_.d @@ -14,6 +14,9 @@ */ module core.sys.posix.net.if_; +version (CRuntime_WASI) {} +else: + import core.sys.posix.config; version (OSX) diff --git a/runtime/druntime/src/core/sys/posix/netdb.d b/runtime/druntime/src/core/sys/posix/netdb.d index 4713f4b4955..0edcd592f2b 100644 --- a/runtime/druntime/src/core/sys/posix/netdb.d +++ b/runtime/druntime/src/core/sys/posix/netdb.d @@ -943,6 +943,84 @@ else version (CRuntime_Musl) EAI_OVERFLOW = -12, } } +else version (CRuntime_WASI) +{ + struct hostent + { + char* h_name; + char** h_aliases; + int h_addrtype; + int h_length; + char** h_addr_list; + char* h_addr()() @property { return h_addr_list[0]; } // non-standard + } + + struct netent + { + char* n_name; + char** n_aliases; + int n_addrtype; + uint32_t n_net; + } + + struct protoent + { + char* p_name; + char** p_aliases; + int p_proto; + } + + struct servent + { + char* s_name; + char** s_aliases; + int s_port; + char* s_proto; + } + + struct addrinfo + { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + socklen_t ai_addrlen; + sockaddr* ai_addr; + char* ai_canonname; + addrinfo* ai_next; + } + + enum { + AI_PASSIVE = 0x1, + AI_CANONNAME = 0x2, + AI_NUMERICHOST = 0x4, + AI_NUMERICSERV = 0x400, + AI_V4MAPPED = 0x8, + AI_ALL = 0x10, + AI_ADDRCONFIG = 0x20, + } + enum { + NI_NUMERICHOST = 1, + NI_NUMERICSERV = 2, + NI_NOFQDN = 4, + NI_NAMEREQD = 8, + NI_DGRAM = 16, + NI_MAXSERV = 32, + NI_MAXHOST = 255, + } + enum { + EAI_BADFLAGS = -1, + EAI_NONAME = -2, + EAI_AGAIN = -3, + EAI_FAIL = -4, + EAI_FAMILY = -6, + EAI_SOCKTYPE = -7, + EAI_SERVICE = -8, + EAI_MEMORY = -10, + EAI_SYSTEM = -11, + EAI_OVERFLOW = -12, + } +} else version (CRuntime_UClibc) { struct hostent diff --git a/runtime/druntime/src/core/sys/posix/netinet/in_.d b/runtime/druntime/src/core/sys/posix/netinet/in_.d index 75359ea213a..276bddd8181 100644 --- a/runtime/druntime/src/core/sys/posix/netinet/in_.d +++ b/runtime/druntime/src/core/sys/posix/netinet/in_.d @@ -442,7 +442,33 @@ else version (linux) INADDR_NONE = 0xFFFFFFFF } } +else version (CRuntime_WASI) +{ + struct sockaddr_in + { + align(16) // __BIGGEST_ALIGNMENT__ on Wasm + sa_family_t sin_family; + + in_port_t sin_port; + in_addr sin_addr; + } + + enum + { + IPPROTO_IP = 0, + IPPROTO_ICMP = 1, + IPPROTO_TCP = 6, + IPPROTO_UDP = 17, + } + enum : c_ulong + { + INADDR_ANY = 0x00000000, + INADDR_BROADCAST = 0xffffffff, + INADDR_LOOPBACK = 0x7f000001, + INADDR_NONE = 0xFFFFFFFF + } +} // // IPV6 (IP6) @@ -1597,6 +1623,44 @@ else version (CRuntime_Musl) extern __gshared immutable in6_addr in6addr_any; extern __gshared immutable in6_addr in6addr_loopback; } +else version (CRuntime_WASI) +{ + + struct in6_addr { + align(int32_t.alignof) + ubyte[16] s6_addr; + } + struct sockaddr_in6 { + align(16) // __BIGGEST_ALIGNMENT__ on Wasm + sa_family_t sin6_family; + + in_port_t sin6_port; + uint sin6_flowinfo; + in6_addr sin6_addr; + uint sin6_scope_id; + } + + struct ipv6_mreq + { + in6_addr ipv6mr_multiaddr; + uint ipv6mr_interface; + } + + enum : uint + { + IPPROTO_IPV6 = 41, + + IPV6_UNICAST_HOPS = 16, + IPV6_MULTICAST_IF = 17, + IPV6_MULTICAST_HOPS = 18, + IPV6_MULTICAST_LOOP = 19, + IPV6_JOIN_GROUP = 20, + IPV6_LEAVE_GROUP = 21, + IPV6_V6ONLY = 26 + } + extern __gshared immutable in6_addr in6addr_any; + extern __gshared immutable in6_addr in6addr_loopback; +} else version (CRuntime_UClibc) { struct in6_addr @@ -1769,3 +1833,7 @@ else version (CRuntime_UClibc) { enum uint IPPROTO_RAW = 255; } +else version (CRuntime_WASI) +{ + enum uint IPPROTO_RAW = 255; +} diff --git a/runtime/druntime/src/core/sys/posix/netinet/tcp.d b/runtime/druntime/src/core/sys/posix/netinet/tcp.d index d400d2d9a86..0a532ee455c 100644 --- a/runtime/druntime/src/core/sys/posix/netinet/tcp.d +++ b/runtime/druntime/src/core/sys/posix/netinet/tcp.d @@ -67,3 +67,7 @@ else version (linux) { enum TCP_NODELAY = 1; } +else version (CRuntime_WASI) +{ + enum TCP_NODELAY = 1; +} diff --git a/runtime/druntime/src/core/sys/posix/poll.d b/runtime/druntime/src/core/sys/posix/poll.d index 4a320d158d1..bf7594ab548 100644 --- a/runtime/druntime/src/core/sys/posix/poll.d +++ b/runtime/druntime/src/core/sys/posix/poll.d @@ -163,6 +163,19 @@ else version (CRuntime_Musl) int poll(pollfd*, nfds_t, c_long); } +else version (CRuntime_WASI) +{ + struct pollfd + { + int fd; + short events; + short revents; + } + + alias nfds_t = c_ulong; + + int poll(pollfd*, nfds_t, c_long); +} else version (CRuntime_UClibc) { struct pollfd @@ -338,6 +351,23 @@ else version (Solaris) POLLNVAL = 0x0020, } } +else version (CRuntime_WASI) +{ + enum + { + POLLRDNORM = 0x1, + POLLWRNORM = 0x2, + + POLLIN = POLLRDNORM, + POLLOUT = POLLWRNORM, + + POLLPRI = 0x0200, + + POLLERR = 0x1000, + POLLHUP = 0x2000, + POLLNVAL = 0x4000, + } +} else { static assert(false, "Unsupported platform"); diff --git a/runtime/druntime/src/core/sys/posix/pthread.d b/runtime/druntime/src/core/sys/posix/pthread.d index 33c442df08f..1e01da472f7 100644 --- a/runtime/druntime/src/core/sys/posix/pthread.d +++ b/runtime/druntime/src/core/sys/posix/pthread.d @@ -30,6 +30,13 @@ else version (TVOS) else version (WatchOS) version = Darwin; +// TODO: figure out when to set WASICooperativeThreads for WASIp3 + +version (CRuntime_WASI) +{ + version (WASICooperativeThreads) version = FullySupported; +} else version = FullySupported; + version (Posix): extern (C) nothrow: @@ -419,6 +426,39 @@ else version (CRuntime_Musl) PTHREAD_PROCESS_SHARED = 1 } } +else version (CRuntime_WASI) +{ + enum + { + PTHREAD_CANCEL_ENABLE = 0, + PTHREAD_CANCEL_DISABLE = 1, + PTHREAD_CANCEL_DEFERRED = 0, + PTHREAD_CANCEL_ASYNCHRONOUS = 1, + } + + enum PTHREAD_CANCELED = cast(void*) -1; + + enum + { + PTHREAD_CREATE_JOINABLE = 0, + PTHREAD_CREATE_DETACHED = 1 + } + + enum + { + PTHREAD_INHERIT_SCHED = 0, + PTHREAD_EXPLICIT_SCHED = 1, + } + + enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init; + enum PTHREAD_ONCE_INIT = pthread_once_t.init; + + enum + { + PTHREAD_PROCESS_PRIVATE = 0, + PTHREAD_PROCESS_SHARED = 1 + } +} else version (CRuntime_UClibc) { enum @@ -466,11 +506,14 @@ int pthread_atfork(void function(), void function(), void function()); int pthread_atfork(void function() @nogc, void function() @nogc, void function() @nogc); int pthread_attr_destroy(pthread_attr_t*); int pthread_attr_getdetachstate(const scope pthread_attr_t*, int*); - int pthread_attr_getschedparam(const scope pthread_attr_t*, sched_param*); int pthread_attr_init(pthread_attr_t*); int pthread_attr_setdetachstate(pthread_attr_t*, int); - int pthread_attr_setschedparam(const scope pthread_attr_t*, sched_param*); - int pthread_cancel(pthread_t); + version (FullySupported) + { + int pthread_attr_getschedparam(const scope pthread_attr_t*, sched_param*); + int pthread_attr_setschedparam(const scope pthread_attr_t*, sched_param*); + int pthread_cancel(pthread_t); + } } alias _pthread_cleanup_routine = void function(void*); @@ -699,6 +742,31 @@ else version (CRuntime_Musl) } } } +else version (CRuntime_WASI) +{ + struct __ptcb { + _pthread_cleanup_routine f; + void* __x; + __ptcb* __next; + } + void _pthread_cleanup_push(__ptcb*, _pthread_cleanup_routine, void*); + void _pthread_cleanup_pop(__ptcb*, int); + + struct pthread_cleanup + { + __ptcb __cleanup = void; + + extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg ) + { + _pthread_cleanup_push( &__cleanup, routine, arg ); + } + + extern (D) void pop()( int execute ) + { + _pthread_cleanup_pop( &__cleanup, execute ); + } + } +} else version (CRuntime_UClibc) { struct _pthread_cleanup_buffer @@ -885,6 +953,18 @@ else version (CRuntime_Musl) int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } +else version (CRuntime_WASI) +{ + enum PTHREAD_BARRIER_SERIAL_THREAD = -1; + + int pthread_barrier_destroy(pthread_barrier_t*); + int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint); + int pthread_barrier_wait(pthread_barrier_t*); + int pthread_barrierattr_destroy(pthread_barrierattr_t*); + int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); + int pthread_barrierattr_init(pthread_barrierattr_t*); + int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); +} else version (CRuntime_UClibc) { enum PTHREAD_BARRIER_SERIAL_THREAD = -1; @@ -949,6 +1029,11 @@ else version (CRuntime_Musl) int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); } +else version (CRuntime_WASI) +{ + int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); + int pthread_condattr_setclock(pthread_condattr_t*, clockid_t); +} else version (CRuntime_UClibc) { int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*); @@ -1032,6 +1117,14 @@ else version (CRuntime_Musl) int pthread_spin_trylock(pthread_spinlock_t*); int pthread_spin_unlock(pthread_spinlock_t*); } +else version (CRuntime_WASI) +{ + int pthread_spin_destroy(pthread_spinlock_t*); + int pthread_spin_init(pthread_spinlock_t*, int); + int pthread_spin_lock(pthread_spinlock_t*); + int pthread_spin_trylock(pthread_spinlock_t*); + int pthread_spin_unlock(pthread_spinlock_t*); +} else version (CRuntime_UClibc) { int pthread_spin_destroy(pthread_spinlock_t*); @@ -1204,6 +1297,16 @@ else version (CRuntime_Musl) } int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted; } +else version (CRuntime_WASI) +{ + enum { + PTHREAD_MUTEX_NORMAL = 0, + PTHREAD_MUTEX_RECURSIVE = 1, + PTHREAD_MUTEX_ERRORCHECK = 2, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL, + } + int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted; +} else version (CRuntime_UClibc) { enum @@ -1271,6 +1374,10 @@ else version (CRuntime_Musl) { int pthread_getcpuclockid(pthread_t, clockid_t*); } +else version (CRuntime_WASI) +{ + int pthread_getcpuclockid(pthread_t, clockid_t*); +} else version (CRuntime_UClibc) { int pthread_getcpuclockid(pthread_t, clockid_t*); @@ -1342,6 +1449,12 @@ else version (CRuntime_Musl) int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); } +else version (CRuntime_WASI) +{ + int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*); +} else version (CRuntime_UClibc) { int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*); @@ -1571,6 +1684,18 @@ else version (CRuntime_Musl) int pthread_setschedparam(pthread_t, int, const scope sched_param*); int pthread_setschedprio(pthread_t, int); } +else version (CRuntime_WASI) +{ + enum + { + PTHREAD_SCOPE_SYSTEM, + PTHREAD_SCOPE_PROCESS + } + + int pthread_getschedparam(pthread_t, int*, sched_param*); + int pthread_setschedparam(pthread_t, int, const scope sched_param*); + int pthread_setschedprio(pthread_t, int); +} else version (CRuntime_UClibc) { enum @@ -1683,6 +1808,11 @@ else version (CRuntime_Musl) int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); int pthread_attr_setstacksize(pthread_attr_t*, size_t); } +else version (CRuntime_WASI) +{ + int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); + int pthread_attr_setstacksize(pthread_attr_t*, size_t); +} else version (CRuntime_UClibc) { int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); @@ -1784,6 +1914,15 @@ else version (CRuntime_Musl) int pthread_rwlockattr_getpshared(pthread_rwlockattr_t*, int*); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); } +else version (CRuntime_WASI) +{ + int pthread_condattr_getpshared(pthread_condattr_t*, int*); + int pthread_condattr_setpshared(pthread_condattr_t*, int); + int pthread_mutexattr_getpshared(pthread_mutexattr_t*, int*); + int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); + int pthread_rwlockattr_getpshared(pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); +} else version (CRuntime_UClibc) { int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*); diff --git a/runtime/druntime/src/core/sys/posix/pwd.d b/runtime/druntime/src/core/sys/posix/pwd.d index 3402a9e263a..f3bcc65fff0 100644 --- a/runtime/druntime/src/core/sys/posix/pwd.d +++ b/runtime/druntime/src/core/sys/posix/pwd.d @@ -14,6 +14,9 @@ */ module core.sys.posix.pwd; +version (CRuntime_WASI) {} +else: + import core.sys.posix.config; public import core.sys.posix.sys.types; // for gid_t, uid_t diff --git a/runtime/druntime/src/core/sys/posix/sched.d b/runtime/druntime/src/core/sys/posix/sched.d index 273be5e8191..b5f5a3b496c 100644 --- a/runtime/druntime/src/core/sys/posix/sched.d +++ b/runtime/druntime/src/core/sys/posix/sched.d @@ -169,15 +169,34 @@ else version (Solaris) enum SCHED_FX = 6; enum _SCHED_NEXT = 7; } +else version (CRuntime_WASI) +{ + struct sched_param + { + int sched_priority; + int __reserved1; + struct __timespec32 + { + time_t __reserved_1; + c_long __reserved_2; + } + __timespec32[2] __reserved2; + int __reserved3; + } +} else { static assert(false, "Unsupported platform"); } -int sched_getparam(pid_t, sched_param*); -int sched_getscheduler(pid_t); -int sched_setparam(pid_t, const scope sched_param*); -int sched_setscheduler(pid_t, int, const scope sched_param*); +version (CRuntime_WASI) {} +else +{ + int sched_getparam(pid_t, sched_param*); + int sched_getscheduler(pid_t); + int sched_setparam(pid_t, const scope sched_param*); + int sched_setscheduler(pid_t, int, const scope sched_param*); +} // // Thread (THR) @@ -222,6 +241,10 @@ else version (CRuntime_Musl) { int sched_yield(); } +else version (CRuntime_WASI) +{ + int sched_yield(); +} else version (CRuntime_UClibc) { int sched_yield(); @@ -296,6 +319,9 @@ else version (CRuntime_Musl) pragma(mangle, muslRedirTime64Mangle!("sched_rr_get_interval", "__sched_rr_get_interval_time64")) int sched_rr_get_interval(pid_t, timespec*); } +else version (CRuntime_WASI) +{ +} else version (CRuntime_UClibc) { int sched_get_priority_max(int); diff --git a/runtime/druntime/src/core/sys/posix/semaphore.d b/runtime/druntime/src/core/sys/posix/semaphore.d index dc9c14fd96b..bec9e57f119 100644 --- a/runtime/druntime/src/core/sys/posix/semaphore.d +++ b/runtime/druntime/src/core/sys/posix/semaphore.d @@ -14,6 +14,9 @@ */ module core.sys.posix.semaphore; +version (CRuntime_WASI) {} +else: + import core.sys.posix.config; import core.sys.posix.time; diff --git a/runtime/druntime/src/core/sys/posix/signal.d b/runtime/druntime/src/core/sys/posix/signal.d index ffa88f48f14..76ba404e5c7 100644 --- a/runtime/druntime/src/core/sys/posix/signal.d +++ b/runtime/druntime/src/core/sys/posix/signal.d @@ -41,6 +41,17 @@ version (SystemZ) version = IBMZ_Any; version (X86) version = X86_Any; version (X86_64) version = X86_Any; +version (CRuntime_WASI) +{ + version (WASI_EMULATED_SIGNAL) + version = Supported; + else + pragma(msg, "wasm lacks signal support; to enable minimal signal"~ + " emulation, compile with --d-version=WASI_EMULATED_SIGNAL"~ + " and link with -lwasi-emulated-signal"); +} else version = Supported; + +version (Supported): version (Posix): extern (C): //nothrow: // this causes http://issues.dlang.org/show_bug.cgi?id=12738 (which has been fixed) @@ -109,26 +120,26 @@ int raise(int sig); (defined in core.stdc.signal) //sig_atomic_t (defined in core.stdc.signal) private alias sigfn_t = void function(int); -private alias sigactfn_t = void function(int, siginfo_t*, void*); +private alias sigfn_t2 = void function(int) nothrow @nogc; -// nothrow versions -nothrow @nogc +version (CRuntime_WASI) {} +else { - private alias sigfn_t2 = void function(int); - private alias sigactfn_t2 = void function(int, siginfo_t*, void*); -} + private alias sigactfn_t = void function(int, siginfo_t*, void*); + private alias sigactfn_t2 = void function(int, siginfo_t*, void*) nothrow @nogc; -enum -{ - SIGEV_SIGNAL, - SIGEV_NONE, - SIGEV_THREAD -} + enum + { + SIGEV_SIGNAL, + SIGEV_NONE, + SIGEV_THREAD + } -union sigval -{ - int sival_int; - void* sival_ptr; + union sigval + { + int sival_int; + void* sival_ptr; + } } version (Solaris) @@ -585,6 +596,35 @@ else version (Solaris) enum SIGUSR2 = 17; enum SIGURG = 21; } +else version (CRuntime_WASI) +{ + enum SIGHUP = 1; + //SIGINT (defined in core.stdc.signal) + enum SIGQUIT = 3; + //SIGILL (defined in core.stdc.signal) + //SIGABRT (defined in core.stdc.signal) + enum SIGIOT = SIGABRT; + enum SIGBUS = 7; + //SIGFPE (defined in core.stdc.signal) + enum SIGKILL = 9; + enum SIGUSR1 = 10; + //SIGSEGV (defined in core.stdc.signal) + enum SIGUSR2 = 12; + enum SIGPIPE = 13; + enum SIGALRM = 14; + //SIGTERM (defined in core.stdc.signal) + enum SIGSTKFLT = 16; + enum SIGCHLD = 17; + enum SIGCONT = 18; + enum SIGSTOP = 19; + enum SIGTSTP = 20; + enum SIGTTIN = 21; + enum SIGTTOU = 22; + enum SIGURG = 23; + enum SIGWINCH = 28; + enum SIGIO = 29; + enum SIGPWR = 30; +} else { static assert(false, "Unsupported platform"); @@ -872,6 +912,9 @@ else version (Darwin) int sa_flags; } } +else version (CRuntime_WASI) +{ +} else { static assert(false, "Unsupported platform"); @@ -1441,6 +1484,27 @@ else version (Solaris) enum SI_ASYNCIO = -4; enum SI_MESGQ = -5; } +else version (CRuntime_WASI) +{ + alias sigset_t = ubyte; + + enum SIG_BLOCK = 0; + enum SIG_UNBLOCK = 1; + enum SIG_SETMASK = 2; + + enum + { + SI_ASYNCNL = -60, + SI_TKILL = -6, + SI_SIGIO, + SI_ASYNCIO, + SI_MESGQ, + SI_TIMER, + SI_QUEUE, + SI_USER, + SI_KERNEL = 0x80 + } +} else { static assert(false, "Unsupported platform"); @@ -1634,6 +1698,9 @@ else version (CRuntime_Musl) int sigsuspend(const scope sigset_t*); int sigwait(const scope sigset_t*, int*); } +else version (CRuntime_WASI) +{ +} else version (CRuntime_UClibc) { int kill(pid_t, int); @@ -2409,6 +2476,17 @@ else version (Solaris) POLL_HUP, } } +else version (CRuntime_WASI) +{ + enum SIGPOLL = 29; + enum SIGPROF = 27; + enum SIGSYS = 31; + enum SIGTRAP = 5; + enum SIGVTALRM = 26; + enum SIGXCPU = 24; + enum SIGXFSZ = 25; + enum SIGUNUSED = SIGSYS; +} else { static assert(false, "Unsupported platform"); @@ -2848,6 +2926,14 @@ else version (CRuntime_Musl) int sigpause(int); int sigrelse(int); } +else version (CRuntime_WASI) +{ + sigfn_t bsd_signal(int sig, sigfn_t func); + + nothrow: + @nogc: + sigfn_t2 bsd_signal(int sig, sigfn_t2 func); +} else version (CRuntime_UClibc) { enum SS_ONSTACK = 1; @@ -3029,6 +3115,9 @@ else version (Solaris) int __sigev_pad2; } } +else version (CRuntime_WASI) +{ +} else { static assert(false, "Unsupported platform"); @@ -3090,6 +3179,9 @@ else version (CRuntime_Musl) int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); int sigwaitinfo(const scope sigset_t*, siginfo_t*); } +else version (CRuntime_WASI) +{ +} else version (CRuntime_UClibc) { int sigqueue(pid_t, int, const sigval); @@ -3154,6 +3246,9 @@ else version (CRuntime_Musl) int pthread_kill(pthread_t, int); int pthread_sigmask(int, const scope sigset_t*, sigset_t*); } +else version (CRuntime_WASI) +{ +} else version (CRuntime_UClibc) { int pthread_kill(pthread_t, int); diff --git a/runtime/druntime/src/core/sys/posix/spawn.d b/runtime/druntime/src/core/sys/posix/spawn.d index 081270b42c5..a22957c0f1f 100644 --- a/runtime/druntime/src/core/sys/posix/spawn.d +++ b/runtime/druntime/src/core/sys/posix/spawn.d @@ -9,6 +9,9 @@ */ module core.sys.posix.spawn; +version (CRuntime_WASI) {} +else: + /* Based on the following system headers: diff --git a/runtime/druntime/src/core/sys/posix/stdc/time.d b/runtime/druntime/src/core/sys/posix/stdc/time.d index abeb715ad73..3278751f591 100644 --- a/runtime/druntime/src/core/sys/posix/stdc/time.d +++ b/runtime/druntime/src/core/sys/posix/stdc/time.d @@ -34,19 +34,40 @@ nothrow: @nogc: /// -struct tm -{ - int tm_sec; /// seconds after the minute [0-60] - int tm_min; /// minutes after the hour [0-59] - int tm_hour; /// hours since midnight [0-23] - int tm_mday; /// day of the month [1-31] - int tm_mon; /// months since January [0-11] - int tm_year; /// years since 1900 - int tm_wday; /// days since Sunday [0-6] - int tm_yday; /// days since January 1 [0-365] - int tm_isdst; /// Daylight Savings Time flag - c_long tm_gmtoff; /// offset from CUT in seconds - char* tm_zone; /// timezone abbreviation +version (CRuntime_WASI) +{ + struct tm + { + int tm_sec; /// seconds after the minute [0-60] + int tm_min; /// minutes after the hour [0-59] + int tm_hour; /// hours since midnight [0-23] + int tm_mday; /// day of the month [1-31] + int tm_mon; /// months since January [0-11] + int tm_year; /// years since 1900 + int tm_wday; /// days since Sunday [0-6] + int tm_yday; /// days since January 1 [0-365] + int tm_isdst; /// Daylight Savings Time flag + int tm_gmtoff; /// offset from CUT in seconds + char* tm_zone; /// timezone abbreviation + int tm_nsec; /// never filled? nsec after the second [0-1000000000]? + } +} +else +{ + struct tm + { + int tm_sec; /// seconds after the minute [0-60] + int tm_min; /// minutes after the hour [0-59] + int tm_hour; /// hours since midnight [0-23] + int tm_mday; /// day of the month [1-31] + int tm_mon; /// months since January [0-11] + int tm_year; /// years since 1900 + int tm_wday; /// days since Sunday [0-6] + int tm_yday; /// days since January 1 [0-365] + int tm_isdst; /// Daylight Savings Time flag + c_long tm_gmtoff; /// offset from CUT in seconds + char* tm_zone; /// timezone abbreviation + } } public import core.sys.posix.sys.types : time_t, clock_t; @@ -69,6 +90,22 @@ else version (CRuntime_Musl) enum clock_t CLOCKS_PER_SEC = 1_000_000; clock_t clock(); } +else version (CRuntime_WASI) +{ + enum clock_t CLOCKS_PER_SEC = 1_000_000_000; + + version (WASI_EMULATED_PROCESS_CLOCKS) + clock_t clock(); + else + deprecated( + "WASI lacks process-associated clocks; to enable emulation of the"~ + " `clock` function using the wall clock, which isn't sensitive to"~ + " whether the program is running or suspended, compile with"~ + " --d-version=WASI_EMULATED_PROCESS_CLOCKS and link with"~ + " -lwasi-emulated-process-clocks" + ) + clock_t clock(); +} else version (CRuntime_Bionic) { enum clock_t CLOCKS_PER_SEC = 1_000_000; @@ -186,6 +223,9 @@ else version (CRuntime_Musl) /// extern __gshared const(char)*[2] tzname; // non-standard } +else version (CRuntime_WASI) +{ +} else version (CRuntime_UClibc) { /// diff --git a/runtime/druntime/src/core/sys/posix/stdio.d b/runtime/druntime/src/core/sys/posix/stdio.d index eceef7f5d44..485d6cefc12 100644 --- a/runtime/druntime/src/core/sys/posix/stdio.d +++ b/runtime/druntime/src/core/sys/posix/stdio.d @@ -198,6 +198,23 @@ else version (CRuntime_Musl) alias tmpfile64 = tmpfile; } } +else version (CRuntime_WASI) +{ + int fgetpos(FILE*, fpos_t *); + FILE* fopen(const scope char*, const scope char*); + FILE* freopen(const scope char*, const scope char*, FILE*); + int fseek(FILE*, c_long, int); + int fsetpos(FILE*, const scope fpos_t*); + + deprecated("tmpfile is not defined on WASI") + FILE* tmpfile(); + + alias fgetpos64 = fgetpos; + alias fopen64 = fopen; + alias freopen64 = freopen; + alias fsetpos64 = fsetpos; + alias tmpfile64 = tmpfile; +} else version (Solaris) { static if (__USE_FILE_OFFSET64 && __WORDSIZE != 64) @@ -323,6 +340,20 @@ else version (CRuntime_Musl) ssize_t getline(char**, size_t*, FILE*); int renameat(int, const scope char*, int, const scope char*); } +else version (CRuntime_WASI) +{ + enum L_ctermid = 20; + + int fseeko(FILE*, off_t, int); + off_t ftello(FILE*); + + alias fseeko64 = fseeko; + alias ftello64 = ftello; + + ssize_t getdelim(char**, size_t*, int, FILE*); + ssize_t getline(char**, size_t*, FILE*); + int renameat(int, const scope char*, int, const scope char*); +} else version (CRuntime_Bionic) { enum L_ctermid = 1024; @@ -449,8 +480,13 @@ char* ctermid(char*); FILE* fdopen(int, const scope char*); int fileno(FILE*); char* gets(char*); -int pclose(FILE*); -FILE* popen(const scope char*, const scope char*); + +version (CRuntime_WASI) {} +else +{ + int pclose(FILE*); + FILE* popen(const scope char*, const scope char*); +} // memstream functions are conforming to POSIX.1-2008. These functions are @@ -469,6 +505,8 @@ else version (CRuntime_UClibc) // http://git.musl-libc.org/cgit/musl/commit/src/stdio/open_memstream.c?id=b158b32a44d56ef20407d4285b58180447ffff1f else version (CRuntime_Musl) version = HaveMemstream; +else version (CRuntime_WASI) + version = HaveMemstream; version (HaveMemstream) { @@ -511,6 +549,20 @@ else version (CRuntime_Musl) int putc_unlocked(int, FILE*); int putchar_unlocked(int); } +else version (CRuntime_WASI) +{ + // TODO: once WebAssembly/wasi-libc#851 makes its way to wasi-sdk release + version (none) + { + void flockfile(FILE*); + int ftrylockfile(FILE*); + void funlockfile(FILE*); + } + int getc_unlocked(FILE*); + int getchar_unlocked(); + int putc_unlocked(int, FILE*); + int putchar_unlocked(int); +} else version (CRuntime_Bionic) { void flockfile(FILE*); @@ -602,7 +654,11 @@ va_list (defined in core.stdc.stdarg) char* tempnam(const scope char*, const scope char*); */ -char* tempnam(const scope char*, const scope char*); +version (CRuntime_WASI) {} +else +{ + char* tempnam(const scope char*, const scope char*); +} version (CRuntime_Glibc) { diff --git a/runtime/druntime/src/core/sys/posix/stdlib.d b/runtime/druntime/src/core/sys/posix/stdlib.d index 3a6a5d2407d..ec2cd6aa7bc 100644 --- a/runtime/druntime/src/core/sys/posix/stdlib.d +++ b/runtime/druntime/src/core/sys/posix/stdlib.d @@ -129,6 +129,10 @@ else version (CRuntime_Musl) { int posix_memalign(scope void**, size_t, size_t) pure; } +else version (CRuntime_WASI) +{ + int posix_memalign(scope void**, size_t, size_t) pure; +} else version (CRuntime_UClibc) { int posix_memalign(scope void**, size_t, size_t) pure; @@ -203,6 +207,11 @@ else version (CRuntime_Musl) int setenv(const scope char*, const scope char*, int); int unsetenv(const scope char*); } +else version (CRuntime_WASI) +{ + int setenv(const scope char*, const scope char*, int); + int unsetenv(const scope char*); +} else version (CRuntime_UClibc) { int setenv(const scope char*, const scope char*, int); @@ -249,6 +258,10 @@ else version (CRuntime_UClibc) { int rand_r(uint*); } +else version (CRuntime_WASI) +{ + int rand_r(uint*); +} // // XOpen (XSI) @@ -610,6 +623,35 @@ else version (CRuntime_Musl) alias mkstemp64 = mkstemp; } } +else version (CRuntime_WASI) +{ + c_long a64l(const scope char*); + double drand48(); + char* ecvt(double, int, int *, int *); // LEGACY + double erand48(ref ushort[3]); + char* fcvt(double, int, int *, int *); // LEGACY + char* gcvt(double, int, char*); // LEGACY + int getsubopt(char**, const scope char**, char**); + c_long jrand48(ref ushort[3]); + char* l64a(c_long); + void lcong48(ref ushort[7]); + c_long lrand48(); + c_long mrand48(); + c_long nrand48(ref ushort[3]); + int putenv(char*); + c_long random(); + char* realpath(const scope char*, char*); + ushort *seed48(ref ushort[3]); + void setkey(const scope char*); + char* setstate(const scope char*); + void srand48(c_long); + void srandom(uint); + + import core.stdc.stdint; + uint32_t arc4random(); + void arc4random_buf(void*, size_t); + uint32_t arc4random_uniform(uint32_t); +} else version (Solaris) { //WNOHANG (defined in core.sys.posix.sys.wait) diff --git a/runtime/druntime/src/core/sys/posix/sys/ioctl.d b/runtime/druntime/src/core/sys/posix/sys/ioctl.d index 27584d357c4..a6b458390c7 100644 --- a/runtime/druntime/src/core/sys/posix/sys/ioctl.d +++ b/runtime/druntime/src/core/sys/posix/sys/ioctl.d @@ -400,6 +400,11 @@ else version (DragonFlyBSD) else version (Solaris) { } +else version (CRuntime_WASI) +{ + enum FIONREAD = 1; + enum FIONBIO = 2; +} else { static assert(false, "Unsupported platform"); @@ -442,6 +447,10 @@ else version (CRuntime_Musl) { int ioctl(int, int, ...); } +else version (CRuntime_WASI) +{ + int ioctl(int, int, ...); +} else version (CRuntime_UClibc) { int ioctl(int __fd, c_ulong __request, ...); diff --git a/runtime/druntime/src/core/sys/posix/sys/ipc.d b/runtime/druntime/src/core/sys/posix/sys/ipc.d index 32caba95a10..7d1472cd40d 100644 --- a/runtime/druntime/src/core/sys/posix/sys/ipc.d +++ b/runtime/druntime/src/core/sys/posix/sys/ipc.d @@ -14,6 +14,9 @@ */ module core.sys.posix.sys.ipc; +version (CRuntime_WASI) {} +else: + import core.sys.posix.config; public import core.sys.posix.sys.types; // for uid_t, gid_t, mode_t, key_t diff --git a/runtime/druntime/src/core/sys/posix/sys/mman.d b/runtime/druntime/src/core/sys/posix/sys/mman.d index 42da553c404..aafef576670 100644 --- a/runtime/druntime/src/core/sys/posix/sys/mman.d +++ b/runtime/druntime/src/core/sys/posix/sys/mman.d @@ -43,6 +43,17 @@ version (SystemZ) version = IBMZ_Any; version (X86) version = X86_Any; version (X86_64) version = X86_Any; +version (CRuntime_WASI) +{ + version (WASI_EMULATED_MMAN) + version = Supported; + else + pragma(msg, "WASI lacks a true mmap; to enable minimal mmap"~ + " emulation, compile with --d-version=WASI_EMULATED_MMAN"~ + " and link with -lwasi-emulated-mman"); +} else version = Supported; + +version (Supported): version (Posix): extern (C) nothrow @nogc: @@ -90,6 +101,10 @@ else version (CRuntime_Musl) { int posix_madvise(void *, size_t, int); } +else version (CRuntime_WASI) +{ + int posix_madvise(void *, size_t, int); +} else version (CRuntime_UClibc) { int posix_madvise(void *__addr, size_t __len, int __advice); @@ -170,6 +185,14 @@ else version (DragonFlyBSD) else version (Solaris) { } +else version (CRuntime_WASI) +{ + enum POSIX_MADV_NORMAL = 0; + enum POSIX_MADV_RANDOM = 1; + enum POSIX_MADV_SEQUENTIAL = 2; + enum POSIX_MADV_WILLNEED = 3; + enum POSIX_MADV_DONTNEED = 4; +} else { static assert(false, "Unsupported platform"); @@ -234,6 +257,13 @@ else version (Solaris) enum PROT_WRITE = 0x02; enum PROT_EXEC = 0x04; } +else version (CRuntime_WASI) +{ + enum PROT_NONE = 0x00; + enum PROT_READ = 0x01; + enum PROT_WRITE = 0x02; + enum PROT_EXEC = 0x04; +} else { static assert(false, "Unsupported platform"); @@ -310,6 +340,13 @@ else version (CRuntime_UClibc) void* mmap(void*, size_t, int, int, int, off_t); int munmap(void*, size_t); } +else version (CRuntime_WASI) +{ + void* mmap(void*, size_t, int, int, int, off_t); + int munmap(void*, size_t); + + alias mmap64 = mmap; +} else { static assert(false, "Unsupported platform"); @@ -475,6 +512,19 @@ else version (Solaris) enum MS_ASYNC = 0x0001; enum MS_INVALIDATE = 0x0002; } +else version (CRuntime_WASI) +{ + enum MAP_SHARED = 0x0001; + enum MAP_PRIVATE = 0x0002; + enum MAP_FIXED = 0x0010; + enum MAP_ANON = 0x0020; + + enum MAP_FAILED = cast(void*)-1; + + enum MS_ASYNC = 0x0001; + enum MS_INVALIDATE = 0x0002; + enum MS_SYNC = 0x0004; +} else { static assert(false, "Unsupported platform"); @@ -521,6 +571,10 @@ else version (CRuntime_Musl) { int msync(void*, size_t, int); } +else version (CRuntime_WASI) +{ + int msync(void*, size_t, int); +} else version (CRuntime_UClibc) { int msync(void*, size_t, int); @@ -591,6 +645,11 @@ else version (Solaris) enum MCL_CURRENT = 0x0001; enum MCL_FUTURE = 0x0002; } +else version (CRuntime_WASI) +{ + enum MCL_CURRENT = 0x0001; + enum MCL_FUTURE = 0x0002; +} else { static assert(false, "Unsupported platform"); @@ -646,6 +705,11 @@ else version (CRuntime_Musl) int mlockall(int); int munlockall(); } +else version (CRuntime_WASI) +{ + int mlockall(int); + int munlockall(); +} else version (CRuntime_UClibc) { int mlockall(int); @@ -709,6 +773,11 @@ else version (CRuntime_Musl) int mlock(const scope void*, size_t); int munlock(const scope void*, size_t); } +else version (CRuntime_WASI) +{ + int mlock(const scope void*, size_t); + int munlock(const scope void*, size_t); +} else version (CRuntime_UClibc) { int mlock(const scope void*, size_t); @@ -762,6 +831,10 @@ else version (CRuntime_Musl) { int mprotect(void*, size_t, int); } +else version (CRuntime_WASI) +{ + int mprotect(void*, size_t, int); +} else version (CRuntime_UClibc) { int mprotect(void*, size_t, int); @@ -822,6 +895,11 @@ else version (CRuntime_Musl) int shm_open(const scope char*, int, mode_t); int shm_unlink(const scope char*); } +else version (CRuntime_WASI) +{ + int shm_open(const scope char*, int, mode_t); + int shm_unlink(const scope char*); +} else version (CRuntime_UClibc) { int shm_open(const scope char*, int, mode_t); diff --git a/runtime/druntime/src/core/sys/posix/sys/resource.d b/runtime/druntime/src/core/sys/posix/sys/resource.d index eb62e4950fd..62d3e05d9f9 100644 --- a/runtime/druntime/src/core/sys/posix/sys/resource.d +++ b/runtime/druntime/src/core/sys/posix/sys/resource.d @@ -7,6 +7,25 @@ * Standards: The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008 */ module core.sys.posix.sys.resource; + +version (CRuntime_WASI) +{ + version (WASI_EMULATED_PROCESS_CLOCKS) + { + version = Supported; + } + else + { + pragma(msg, "WASI lacks process-associated clocks; to enable"~ + " emulation of the `getrusage` function using the wall"~ + " clock, which isn't sensitive to whether the program is"~ + " running or suspended, compile with"~ + " --d-version=WASI_EMULATED_PROCESS_CLOCKS and link with"~ + " -lwasi-emulated-process-clocks"); + } +} else version = Supported; + +version (Supported): version (Posix): public import core.sys.posix.sys.time; @@ -477,6 +496,20 @@ else version (Solaris) RLIMIT_AS = 6, } } +else version (CRuntime_WASI) +{ + struct rusage + { + timeval ru_utime; + timeval ru_stime; + } + + enum + { + RUSAGE_SELF = 1, + RUSAGE_CHILDREN = 2, + } +} else static assert (false, "Unsupported platform"); @@ -494,10 +527,14 @@ int setpriority(int, id_t, int); int setrlimit(int, const rlimit*); */ -struct rlimit +version (CRuntime_WASI) {} +else { - rlim_t rlim_cur; - rlim_t rlim_max; + struct rlimit + { + rlim_t rlim_cur; + rlim_t rlim_max; + } } version (CRuntime_Glibc) @@ -569,6 +606,10 @@ else version (CRuntime_Musl) pragma(mangle, muslRedirTime64Mangle!("getrusage", "__getrusage_time64")) int getrusage(int, rusage*); } +else version (CRuntime_WASI) +{ + int getrusage(int, rusage*); +} else version (Solaris) { int getpriority(int, int); diff --git a/runtime/druntime/src/core/sys/posix/sys/select.d b/runtime/druntime/src/core/sys/posix/sys/select.d index 5152d0fe17d..b3c1395829a 100644 --- a/runtime/druntime/src/core/sys/posix/sys/select.d +++ b/runtime/druntime/src/core/sys/posix/sys/select.d @@ -12,7 +12,14 @@ import core.sys.posix.config; public import core.stdc.time; // for timespec public import core.sys.posix.sys.time; // for timeval public import core.sys.posix.sys.types; // for time_t -public import core.sys.posix.signal; // for sigset_t + +version (CRuntime_WASI) + version (WASI_EMULATED_SIGNAL) + public import core.sys.posix.signal; // for sigset_t + else + alias sigset_t = ubyte; +else + public import core.sys.posix.signal; // for sigset_t //debug=select; // uncomment to turn on debugging printf's @@ -512,6 +519,54 @@ else version (CRuntime_Musl) pragma(mangle, muslRedirTime64Mangle!("select", "__select_time64")) int select(int, fd_set*, fd_set*, fd_set*, timeval*); } +else version (CRuntime_WASI) +{ + enum FD_SETSIZE = 1024; + + struct fd_set { + size_t __nfds; + int[FD_SETSIZE] __fds; + } + + extern (D) void FD_CLR()( int fd, fd_set* fdset ) pure + { + auto slice = fdset.__fds[0..fdset.__nfds]; + foreach (ref elem; slice) { + if (elem == fd) { + elem = slice[$-1]; + fdset.__nfds -= 1; + return; + } + } + } + + extern (D) bool FD_ISSET()( int fd, const(fd_set)* fdset ) pure + { + auto slice = fdset.__fds[0..fdset.__nfds]; + foreach (elem; slice) { + if (elem == fd) return true; + } + return false; + } + + extern (D) void FD_SET()( int fd, fd_set* fdset ) pure + { + auto slice = fdset.__fds[0..fdset.__nfds]; + foreach (elem; slice) { + if (elem == fd) return; + } + + fdset.__fds[fdset.__nfds++] = fd; + } + + extern (D) void FD_ZERO()( fd_set* fdset ) pure + { + fdset.__nfds = 0; + } + + int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); + int select(int, fd_set*, fd_set*, fd_set*, timeval*); +} else version (CRuntime_UClibc) { private diff --git a/runtime/druntime/src/core/sys/posix/sys/shm.d b/runtime/druntime/src/core/sys/posix/sys/shm.d index 358fcf9e322..4a3aca91a23 100644 --- a/runtime/druntime/src/core/sys/posix/sys/shm.d +++ b/runtime/druntime/src/core/sys/posix/sys/shm.d @@ -14,6 +14,9 @@ */ module core.sys.posix.sys.shm; +version (CRuntime_WASI) {} +else: + import core.sys.posix.config; public import core.sys.posix.sys.types; // for pid_t, time_t, key_t public import core.sys.posix.sys.ipc; diff --git a/runtime/druntime/src/core/sys/posix/sys/socket.d b/runtime/druntime/src/core/sys/posix/sys/socket.d index 0ae101db098..0d9dd24a7d5 100644 --- a/runtime/druntime/src/core/sys/posix/sys/socket.d +++ b/runtime/druntime/src/core/sys/posix/sys/socket.d @@ -1598,6 +1598,128 @@ else version (Solaris) SHUT_RDWR } } +else version (CRuntime_WASI) +{ + alias socklen_t = uint; + alias sa_family_t = ushort; + + struct sockaddr + { + align(16) // __BIGGEST_ALIGNMENT__ on Wasm + sa_family_t sa_family; + + byte[0] sa_data; + } + + struct sockaddr_storage + { + align(16) // __BIGGEST_ALIGNMENT__ on Wasm + sa_family_t ss_family; + byte[32] __ss_data; + } + + struct msghdr + { + void* msg_name; + socklen_t msg_namelen; + iovec* msg_iov; + int msg_iovlen; + void* msg_control; + socklen_t msg_controllen; + int msg_flags; + } + + struct linger + { + int l_onoff; + int l_linger; + } + + enum + { + SOCK_DGRAM = 5, + SOCK_STREAM = 6, + } + + enum + { + SOL_SOCKET = 0x7fffffff + } + + version (WASIp1) + { + enum : ushort + { + MSG_PEEK = (1 << 0), // __WASI_RIFLAGS_RECV_PEEK + MSG_WAITALL = (1 << 1), // __WASI_RIFLAGS_RECV_WAITALL + MSG_TRUNC = (1 << 0), // __WASI_ROFLAGS_RECV_DATA_TRUNCATED + } + } + else + { + enum + { + SO_REUSEADDR = 2, + SO_ERROR = 4, + SO_SNDBUF = 7, + SO_RCVBUF = 8, + SO_KEEPALIVE = 9, + SO_ACCEPTCONN = 30, + SO_PROTOCOL = 38, + SO_DOMAIN = 39, + + SO_TYPE = 3 + } + + version (D_LP64) + { + enum + { + SO_RCVTIMEO = 66, + SO_SNDTIMEO = 67, + } + } + else + { + enum + { + SO_RCVTIMEO = 20, + SO_SNDTIMEO = 21, + } + } + + enum + { + SOMAXCONN = 128 + } + + enum : uint + { + MSG_DONTWAIT = 0x0040, + MSG_NOSIGNAL = 0x4000, + MSG_PEEK = 0x0002, + MSG_WAITALL = 0x0100, + MSG_TRUNC = 0x0020 + } + } + + enum + { + PF_UNSPEC = 0, + PF_INET = 1, + + AF_UNSPEC = PF_UNSPEC, + AF_INET = PF_INET, + AF_UNIX = 3 + } + + enum + { + SHUT_RD, + SHUT_WR, + SHUT_RDWR + } +} else { static assert(false, "Unsupported platform"); @@ -1817,6 +1939,27 @@ else version (CRuntime_Musl) int sockatmark(int); int socketpair(int, int, int, ref int[2]); } +else version (CRuntime_WASI) +{ + int accept(int, sockaddr*, socklen_t*); + int getsockopt(int, int, int, void*, socklen_t*); + ssize_t recv(int, void*, size_t, int); + ssize_t send(int, const scope void*, size_t, int); + int shutdown(int, int); + version (WASIp1) {} + else + { + int bind(int, const scope sockaddr*, socklen_t); + int connect(int, const scope sockaddr*, socklen_t); + int listen(int, int); + int getpeername(int, sockaddr*, socklen_t*); + int getsockname(int, sockaddr*, socklen_t*); + ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); + ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t); + int socket(int, int, int); + int setsockopt(int, int, int, const scope void*, socklen_t); + } +} else version (CRuntime_UClibc) { int accept(int, sockaddr*, socklen_t*); @@ -1899,6 +2042,14 @@ else version (Solaris) AF_INET6 = 26, } } +else version (CRuntime_WASI) +{ + enum + { + PF_INET6 = 2, + AF_INET6 = PF_INET6, + } +} else { static assert(false, "Unsupported platform"); @@ -1960,6 +2111,9 @@ else version (Solaris) SOCK_RAW = 4, } } +else version (CRuntime_WASI) +{ +} else { static assert(false, "Unsupported platform"); diff --git a/runtime/druntime/src/core/sys/posix/sys/stat.d b/runtime/druntime/src/core/sys/posix/sys/stat.d index 83590b5b996..5586ca90a37 100644 --- a/runtime/druntime/src/core/sys/posix/sys/stat.d +++ b/runtime/druntime/src/core/sys/posix/sys/stat.d @@ -1540,6 +1540,40 @@ else version (Solaris) enum S_ISGID = 0x400; enum S_ISVTX = 0x200; } +else version (CRuntime_WASI) +{ + struct stat_t + { + dev_t st_dev; /* inode's device */ + ino_t st_ino; /* inode's number */ + nlink_t st_nlink; /* number of hard links */ + + mode_t st_mode; /* inode protection mode */ + uid_t st_uid; /* user ID of the file's owner */ + gid_t st_gid; /* group ID of the file's group */ + uint __pad0; + dev_t st_rdev; /* device type */ + off_t st_size; /* file size, in bytes */ + blksize_t st_blksize; /* optimal blocksize for I/O */ + blkcnt_t st_blocks; /* blocks allocated for file */ + + timespec st_atim; /* time of last access */ + timespec st_mtim; /* time of last data modification */ + timespec st_ctim; /* time of last file status change */ + ulong[3] __reserved; + + extern(D) @safe @property inout pure nothrow + { + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } + } + } + + enum S_ISUID = 0x800; // octal 04000 + enum S_ISGID = 0x400; // octal 02000 + enum S_ISVTX = 0x200; // octal 01000 +} else { static assert(false, "Unsupported platform"); @@ -1861,6 +1895,41 @@ else version (CRuntime_Musl) extern (D) bool S_ISLNK()( mode_t mode ) { return S_ISTYPE( mode, S_IFLNK ); } extern (D) bool S_ISSOCK()( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); } } +else version (CRuntime_WASI) +{ + enum { + S_IRUSR = 0x100, + S_IWUSR = 0x080, + S_IXUSR = 0x040, + S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR, + + S_IRGRP = S_IRUSR >> 3, + S_IWGRP = S_IWUSR >> 3, + S_IXGRP = S_IXUSR >> 3, + S_IRWXG = S_IRWXU >> 3, + + S_IROTH = S_IRGRP >> 3, + S_IWOTH = S_IWGRP >> 3, + S_IXOTH = S_IXGRP >> 3, + S_IRWXO = S_IRWXG >> 3, + } + + private + { + extern (D) bool S_ISTYPE()( mode_t mode, uint mask ) + { + return ( mode & S_IFMT ) == mask; + } + } + + extern (D) bool S_ISBLK()( mode_t mode ) { return S_ISTYPE( mode, S_IFBLK ); } + extern (D) bool S_ISCHR()( mode_t mode ) { return S_ISTYPE( mode, S_IFCHR ); } + extern (D) bool S_ISDIR()( mode_t mode ) { return S_ISTYPE( mode, S_IFDIR ); } + extern (D) bool S_ISFIFO()( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO ); } + extern (D) bool S_ISREG()( mode_t mode ) { return S_ISTYPE( mode, S_IFREG ); } + extern (D) bool S_ISLNK()( mode_t mode ) { return S_ISTYPE( mode, S_IFLNK ); } + extern (D) bool S_ISSOCK()( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); } +} else version (CRuntime_UClibc) { enum S_IRUSR = 0x100; // octal 0400 @@ -1921,9 +1990,14 @@ int fchmod(int, mode_t); //int fstat(int, stat_t*); //int lstat(const scope char*, stat_t*); int mkdir(const scope char*, mode_t); -int mkfifo(const scope char*, mode_t); + +version (CRuntime_WASI) {} +else +{ + int mkfifo(const scope char*, mode_t); + mode_t umask(mode_t); +} //int stat(const scope char*, stat_t*); -mode_t umask(mode_t); version (CRuntime_Glibc) { @@ -2144,6 +2218,21 @@ else version (CRuntime_Musl) int mkfifoat(int, const scope char*, mode_t); int utimensat(int, const scope char*, ref const(timespec)[2], int); } +else version (CRuntime_WASI) +{ + int stat(const scope char*, stat_t*); + int fstat(int, stat_t*); + int lstat(const scope char*, stat_t*); + int fstatat(int, const scope char*, stat_t*, int); + + alias fstat64 = fstat; + alias lstat64 = lstat; + alias stat64 = stat; + int fchmodat(int, const scope char*, mode_t, int); + int futimens(int, ref const(timespec)[2]); + int mkdirat(int, const scope char*, mode_t); + int utimensat(int, const scope char*, ref const(timespec)[2], int); +} else version (CRuntime_UClibc) { static if ( __USE_LARGEFILE64 ) @@ -2213,6 +2302,11 @@ else version (Solaris) enum UTIME_NOW = -1; enum UTIME_OMIT = -2; } +else version (CRuntime_WASI) +{ + enum UTIME_NOW = -1; + enum UTIME_OMIT = -2; +} else { static assert(false, "Unsupported platform"); @@ -2319,6 +2413,18 @@ else version (Solaris) enum S_IFDOOR = 0xD000; enum S_IFPORT = 0xE000; } +else version (CRuntime_WASI) +{ + enum S_IFMT = S_IFBLK | S_IFCHR | S_IFDIR | S_IFIFO | S_IFLNK | + S_IFREG | S_IFSOCK; + enum S_IFBLK = 0x6000; + enum S_IFCHR = 0x2000; + enum S_IFDIR = 0x4000; + enum S_IFLNK = 0xA000; + enum S_IFREG = 0x8000; + enum S_IFSOCK = 0xC000; + enum S_IFIFO = 0x1000; +} else { static assert(false, "Unsupported platform"); @@ -2384,6 +2490,9 @@ else version (CRuntime_Musl) int mknod(const scope char*, mode_t, dev_t); int mknodat(int, const scope char*, mode_t, dev_t); } +else version (CRuntime_WASI) +{ +} else version (CRuntime_UClibc) { int mknod(const scope char*, mode_t, dev_t); diff --git a/runtime/druntime/src/core/sys/posix/sys/statvfs.d b/runtime/druntime/src/core/sys/posix/sys/statvfs.d index a8f3dd50654..7e4d23eae01 100644 --- a/runtime/druntime/src/core/sys/posix/sys/statvfs.d +++ b/runtime/druntime/src/core/sys/posix/sys/statvfs.d @@ -136,6 +136,57 @@ else version (CRuntime_Musl) alias statvfs64 = statvfs; alias fstatvfs64 = fstatvfs; } +else version (CRuntime_WASI) +{ + struct statvfs_t + { + c_ulong f_bsize; + c_ulong f_frsize; + fsblkcnt_t f_blocks; + fsblkcnt_t f_bfree; + fsblkcnt_t f_bavail; + fsfilcnt_t f_files; + fsfilcnt_t f_ffree; + fsfilcnt_t f_favail; + version (LittleEndian) + { + c_ulong f_fsid; + byte[2*int.sizeof-c_long.sizeof] __padding; + } + else + { + byte[2*int.sizeof-c_long.sizeof] __padding; + c_ulong f_fsid; + } + c_ulong f_flag; + c_ulong f_namemax; + uint f_type; + int[5] __reserved; + } + + enum FFlag + { + ST_RDONLY = 1, /* Mount read-only. */ + ST_NOSUID = 2, + ST_NODEV = 4, /* Disallow access to device special files. */ + ST_NOEXEC = 8, /* Disallow program execution. */ + ST_SYNCHRONOUS = 16, /* Writes are synced at once. */ + ST_MANDLOCK = 64, /* Allow mandatory locks on an FS. */ + ST_WRITE = 128, /* Write on file/directory/symlink. */ + ST_APPEND = 256, /* Append-only file. */ + ST_IMMUTABLE = 512, /* Immutable file. */ + ST_NOATIME = 1024, /* Do not update access times. */ + ST_NODIRATIME = 2048, /* Do not update directory access times. */ + ST_RELATIME = 4096 /* Update atime relative to mtime/ctime. */ + + } + + int statvfs (const char * file, statvfs_t* buf); + int fstatvfs (int fildes, statvfs_t *buf); + + alias statvfs64 = statvfs; + alias fstatvfs64 = fstatvfs; +} else version (NetBSD) { enum _VFS_MNAMELEN = 1024; diff --git a/runtime/druntime/src/core/sys/posix/sys/time.d b/runtime/druntime/src/core/sys/posix/sys/time.d index 6dcd4878d19..a7ebcd980b8 100644 --- a/runtime/druntime/src/core/sys/posix/sys/time.d +++ b/runtime/druntime/src/core/sys/posix/sys/time.d @@ -94,6 +94,16 @@ else version (CRuntime_Musl) pragma(mangle, muslRedirTime64Mangle!("utimes", "__utimes_time64")) int utimes(const scope char*, ref const(timeval)[2]); } +else version (CRuntime_WASI) +{ + struct timeval + { + time_t tv_sec; + suseconds_t tv_usec; + } + int gettimeofday(timeval*, void*); + int utimes(const scope char*, ref const(timeval)[2]); +} else version (Darwin) { struct timeval diff --git a/runtime/druntime/src/core/sys/posix/sys/types.d b/runtime/druntime/src/core/sys/posix/sys/types.d index cad60b4da4d..10defc4f61a 100644 --- a/runtime/druntime/src/core/sys/posix/sys/types.d +++ b/runtime/druntime/src/core/sys/posix/sys/types.d @@ -328,6 +328,27 @@ else version (Solaris) alias time_t = c_long; alias uid_t = uint; } +else version (CRuntime_WASI) +{ + alias blkcnt_t = long; + alias ino_t = ulong; + alias off_t = long; + + alias blksize_t = c_long; + + alias dev_t = ulong; + alias gid_t = uint; + alias mode_t = uint; + + alias nlink_t = ulong; + + alias pid_t = int; + //size_t (defined in core.stdc.stddef) + alias ssize_t = c_long; + alias uid_t = uint; + + alias time_t = long; +} else { static assert(false, "Unsupported platform"); @@ -439,6 +460,17 @@ else version (Solaris) alias zoneid_t = id_t; alias ctid_t = id_t; } +else version (CRuntime_WASI) +{ + alias fsblkcnt_t = ulong; + alias fsfilcnt_t = ulong; + + alias clock_t = long; + alias id_t = uint; + alias key_t = int; + alias suseconds_t = long; + alias useconds_t = uint; +} else { static assert(false, "Unsupported platform"); @@ -820,6 +852,82 @@ else version (CRuntime_Musl) alias pthread_t = c_ulong; } +else version (CRuntime_WASI) +{ + version (D_LP64) + { + union pthread_attr_t + { + int[14] __i; + ulong[7] __s; + } + + union pthread_cond_t + { + int[12] __i; + void*[6] __p; + } + + union pthread_mutex_t + { + int[10] __i; + void*[5] __p; + } + + union pthread_rwlock_t + { + int[14] __i; + void*[7] __p; + } + } + else + { + union pthread_attr_t + { + int[9] __i; + uint[9] __s; + } + + union pthread_cond_t + { + int[12] __i; + void*[12] __p; + } + + union pthread_mutex_t + { + int[6] __i; + void*[6] __p; + } + + union pthread_rwlock_t + { + int[8] __i; + void*[8] __p; + } + } + + struct pthread_rwlockattr_t + { + uint[2] __attr; + } + + alias pthread_key_t = uint; + + struct pthread_condattr_t + { + uint __attr; + } + + struct pthread_mutexattr_t + { + uint __attr; + } + + alias pthread_once_t = int; + + alias pthread_t = c_ulong; +} else version (Darwin) { version (D_LP64) @@ -1429,6 +1537,30 @@ else version (CRuntime_Musl) uint __attr; } } +else version (CRuntime_WASI) +{ + version (D_LP64) + { + union pthread_barrier_t + { + int[8] __i; + void*[4] __p; + } + } + else + { + union pthread_barrier_t + { + int[5] __i; + void*[5] __p; + } + } + + struct pthread_barrierattr_t + { + uint __attr; + } +} else version (CRuntime_UClibc) { struct pthread_barrier_t @@ -1487,6 +1619,10 @@ else version (CRuntime_Musl) { alias pthread_spinlock_t = int; } +else version (CRuntime_WASI) +{ + alias pthread_spinlock_t = int; +} // // Timer (TMR) diff --git a/runtime/druntime/src/core/sys/posix/sys/uio.d b/runtime/druntime/src/core/sys/posix/sys/uio.d index e2839631e3b..b2009a865a2 100644 --- a/runtime/druntime/src/core/sys/posix/sys/uio.d +++ b/runtime/druntime/src/core/sys/posix/sys/uio.d @@ -145,6 +145,17 @@ else version (CRuntime_Musl) ssize_t readv(int, const scope iovec*, int); ssize_t writev(int, const scope iovec*, int); } +else version (CRuntime_WASI) +{ + struct iovec + { + void* iov_base; + size_t iov_len; + } + + ssize_t readv(int, const scope iovec*, int); + ssize_t writev(int, const scope iovec*, int); +} else version (CRuntime_UClibc) { struct iovec diff --git a/runtime/druntime/src/core/sys/posix/sys/un.d b/runtime/druntime/src/core/sys/posix/sys/un.d index 11e98a72ab2..62a124b974e 100644 --- a/runtime/druntime/src/core/sys/posix/sys/un.d +++ b/runtime/druntime/src/core/sys/posix/sys/un.d @@ -104,3 +104,11 @@ else version (Solaris) byte[108] sun_path; } } +else version (CRuntime_WASI) +{ + struct sockaddr_un + { + align(16) // __BIGGEST_ALIGNMENT__ on Wasm + sa_family_t sun_family; + } +} diff --git a/runtime/druntime/src/core/sys/posix/sys/utsname.d b/runtime/druntime/src/core/sys/posix/sys/utsname.d index 5de50aca465..8115ebe105d 100644 --- a/runtime/druntime/src/core/sys/posix/sys/utsname.d +++ b/runtime/druntime/src/core/sys/posix/sys/utsname.d @@ -170,6 +170,22 @@ else version (CRuntime_Musl) int uname(utsname*); } +else version (CRuntime_WASI) +{ + private enum SYS_NMLN = 65; + + struct utsname + { + char[SYS_NMLN] sysname = 0; + char[SYS_NMLN] nodename = 0; + char[SYS_NMLN] release = 0; + char[SYS_NMLN] _version = 0; + char[SYS_NMLN] machine = 0; + char[SYS_NMLN] domainname = 0; + } + + int uname(utsname*); +} else version (CRuntime_UClibc) { private enum utsNameLength = 65; diff --git a/runtime/druntime/src/core/sys/posix/sys/wait.d b/runtime/druntime/src/core/sys/posix/sys/wait.d index 0c4e72e999b..99d300c2ccd 100644 --- a/runtime/druntime/src/core/sys/posix/sys/wait.d +++ b/runtime/druntime/src/core/sys/posix/sys/wait.d @@ -14,6 +14,9 @@ */ module core.sys.posix.sys.wait; +version (CRuntime_WASI) {} +else: + import core.sys.posix.config; public import core.sys.posix.sys.types; // for id_t, pid_t public import core.sys.posix.signal; // for siginfo_t (XSI) diff --git a/runtime/druntime/src/core/sys/posix/syslog.d b/runtime/druntime/src/core/sys/posix/syslog.d index ba2a4ac03ff..1ad0df62950 100644 --- a/runtime/druntime/src/core/sys/posix/syslog.d +++ b/runtime/druntime/src/core/sys/posix/syslog.d @@ -586,3 +586,63 @@ else version (CRuntime_Musl) void syslog (int __pri, const char *__fmt, ...); void closelog(); } +else version (CRuntime_WASI) +{ + //PRIORITY + enum { + LOG_EMERG = 0, /* system is unusable */ + LOG_ALERT = 1, /* action must be taken immediately */ + LOG_CRIT = 2, /* critical conditions */ + LOG_ERR = 3, /* error conditions */ + LOG_WARNING = 4, /* warning conditions */ + LOG_NOTICE = 5, /* normal but significant condition */ + LOG_INFO = 6, /* informational */ + LOG_DEBUG = 7, /* debug-level messages */ + } + + //OPTIONS + enum { + LOG_PID = 0x01, /* log the pid with each message */ + LOG_CONS = 0x02, /* log on the console if errors in sending */ + LOG_ODELAY = 0x04, /* delay open until first syslog() (default) */ + LOG_NDELAY = 0x08, /* don't delay open */ + LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */ + LOG_PERROR = 0x20, /* log to stderr as well */ + } + + //FACILITY + enum { + LOG_KERN = (0<<3), /* kernel messages */ + LOG_USER = (1<<3), /* random user-level messages */ + LOG_MAIL = (2<<3), /* mail system */ + LOG_DAEMON = (3<<3), /* system daemons */ + LOG_AUTH = (4<<3), /* security/authorization messages */ + LOG_SYSLOG = (5<<3), /* messages generated internally by syslogd */ + LOG_LPR = (6<<3), /* line printer subsystem */ + LOG_NEWS = (7<<3), /* network news subsystem */ + LOG_UUCP = (8<<3), /* UUCP subsystem */ + LOG_CRON = (9<<3), /* clock daemon */ + LOG_AUTHPRIV = (10<<3), /* security/authorization messages (private), */ + LOG_FTP = (11<<3), /* ftp daemon */ + + /* other codes through 15 reserved for system use */ + LOG_LOCAL0 = (16<<3), /* reserved for local use */ + LOG_LOCAL1 = (17<<3), /* reserved for local use */ + LOG_LOCAL2 = (18<<3), /* reserved for local use */ + LOG_LOCAL3 = (19<<3), /* reserved for local use */ + LOG_LOCAL4 = (20<<3), /* reserved for local use */ + LOG_LOCAL5 = (21<<3), /* reserved for local use */ + LOG_LOCAL6 = (22<<3), /* reserved for local use */ + LOG_LOCAL7 = (23<<3), /* reserved for local use */ + + LOG_NFACILITIES = 24, /* current number of facilities */ + } + + int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */ + int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */ + + void openlog (const char *, int __option, int __facility); + int setlogmask (int __mask); + void syslog (int __pri, const char *__fmt, ...); + void closelog(); +} diff --git a/runtime/druntime/src/core/sys/posix/termios.d b/runtime/druntime/src/core/sys/posix/termios.d index 38181a9d84f..394002bfab0 100644 --- a/runtime/druntime/src/core/sys/posix/termios.d +++ b/runtime/druntime/src/core/sys/posix/termios.d @@ -14,6 +14,9 @@ */ module core.sys.posix.termios; +version (CRuntime_WASI) {} +else: + import core.sys.posix.config; public import core.sys.posix.sys.types; // for pid_t diff --git a/runtime/druntime/src/core/sys/posix/time.d b/runtime/druntime/src/core/sys/posix/time.d index 4fc73aab8c5..c90ac45bcab 100644 --- a/runtime/druntime/src/core/sys/posix/time.d +++ b/runtime/druntime/src/core/sys/posix/time.d @@ -19,7 +19,10 @@ import core.sys.posix.config; import core.sys.posix.endian; public import core.stdc.time; public import core.sys.posix.sys.types; -public import core.sys.posix.signal; // for sigevent + +version (CRuntime_WASI) {} +else + public import core.sys.posix.signal; // for sigevent version (OSX) version = Darwin; @@ -88,6 +91,10 @@ else version (CRuntime_Musl) pragma(mangle, muslRedirTime64Mangle!("timegm", "__timegm_time64")) time_t timegm(tm*); } +else version (CRuntime_WASI) +{ + time_t timegm(tm*); +} else version (CRuntime_UClibc) { time_t timegm(tm*); @@ -157,6 +164,13 @@ else version (Solaris) { enum CLOCK_MONOTONIC = 4; } +else version (CRuntime_WASI) +{ + struct __clockid; + + extern const __clockid _CLOCK_MONOTONIC; + enum CLOCK_MONOTONIC = &_CLOCK_MONOTONIC; +} else { static assert(0); @@ -260,6 +274,14 @@ else version (Solaris) alias timestruc_t = timespec; } +else version (CRuntime_WASI) +{ + struct timespec + { + time_t tv_sec; + c_long tv_nsec; + } +} else { static assert(false, "Unsupported platform"); @@ -517,6 +539,28 @@ else version (CRuntime_Musl) int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); int timer_getoverrun(timer_t); } +else version (CRuntime_WASI) +{ + alias clockid_t = const __clockid*; + alias timer_t = void*; + + struct itimerspec + { + timespec it_interval; + timespec it_value; + } + + enum TIMER_ABSTIME = 1; + + extern const __clockid _CLOCK_REALTIME; + enum CLOCK_REALTIME = &_CLOCK_REALTIME; + + int nanosleep(const scope timespec*, timespec*); + + int clock_getres(clockid_t, timespec*); + int clock_gettime(clockid_t, timespec*); + int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*); +} else version (CRuntime_UClibc) { enum CLOCK_REALTIME = 0; @@ -628,6 +672,13 @@ else version (CRuntime_Musl) pragma(mangle, muslRedirTime64Mangle!("localtime_r", "__localtime64_r")) tm* localtime_r(const scope time_t*, tm*); } +else version (CRuntime_WASI) +{ + char* asctime_r(const scope tm*, char*); + char* ctime_r(const scope time_t*, char*); + tm* gmtime_r(const scope time_t*, tm*); + tm* localtime_r(const scope time_t*, tm*); +} else version (CRuntime_UClibc) { char* asctime_r(const scope tm*, char*); @@ -713,6 +764,11 @@ else version (CRuntime_Musl) tm* getdate(const scope char*); char* strptime(const scope char*, const scope char*, tm*); } +else version (CRuntime_WASI) +{ + tm* getdate(const scope char*); + char* strptime(const scope char*, const scope char*, tm*); +} else version (CRuntime_UClibc) { extern __gshared int daylight; diff --git a/runtime/druntime/src/core/sys/posix/unistd.d b/runtime/druntime/src/core/sys/posix/unistd.d index ea6d866999c..01b51d55795 100644 --- a/runtime/druntime/src/core/sys/posix/unistd.d +++ b/runtime/druntime/src/core/sys/posix/unistd.d @@ -43,74 +43,147 @@ extern __gshared int opterr; extern __gshared int optopt; int access(const scope char*, int); -uint alarm(uint) @trusted; + +version (CRuntime_WASI) {} +else + uint alarm(uint) @trusted; + int chdir(const scope char*); -int chown(const scope char*, uid_t, gid_t); + +version (CRuntime_WASI) {} +else + int chown(const scope char*, uid_t, gid_t); + int close(int) @trusted; size_t confstr(int, char*, size_t); int dup(int) @trusted; int dup2(int, int) @trusted; //int dup3(int, int, int) @trusted; -int execl(const scope char*, const scope char*, ...); -int execle(const scope char*, const scope char*, ...); -int execlp(const scope char*, const scope char*, ...); -int execv(const scope char*, const scope char**); -int execve(const scope char*, const scope char**, const scope char**); -int execvp(const scope char*, const scope char**); + +version (CRuntime_WASI) {} +else +{ + int execl(const scope char*, const scope char*, ...); + int execle(const scope char*, const scope char*, ...); + int execlp(const scope char*, const scope char*, ...); + int execv(const scope char*, const scope char**); + int execve(const scope char*, const scope char**, const scope char**); + int execvp(const scope char*, const scope char**); +} + noreturn _exit(int) @trusted; //int faccessat(int, const scope char*, int, int); -int fchown(int, uid_t, gid_t) @trusted; + +version (CRuntime_WASI) {} +else + int fchown(int, uid_t, gid_t) @trusted; + //int fchownat(int, const scope char*, uid_t, gid_t, int); //int fexecve(int, const scope char**, const scope char**); -pid_t fork() @trusted; + +version (CRuntime_WASI) {} +else + pid_t fork() @trusted; + //pid_t _Fork() @trusted; c_long fpathconf(int, int) @trusted; //int ftruncate(int, off_t); char* getcwd(char*, size_t); //int getentropy(void*, size_t); -gid_t getegid() @trusted; -uid_t geteuid() @trusted; -gid_t getgid() @trusted; -int getgroups(int, gid_t *); + +version (CRuntime_WASI) {} +else +{ + gid_t getegid() @trusted; + uid_t geteuid() @trusted; + gid_t getgid() @trusted; + int getgroups(int, gid_t *); +} + int gethostname(char*, size_t); char* getlogin() @trusted; int getlogin_r(char*, size_t); int getopt(int, const scope char**, const scope char*); -pid_t getpgrp() @trusted; -pid_t getpid() @trusted; -pid_t getppid() @trusted; + +version (CRuntime_WASI) {} +else +{ + pid_t getpgrp() @trusted; + pid_t getppid() @trusted; +} + +version (CRuntime_WASI) +{ + version (WASI_EMULATED_GETPID) + pid_t getpid() @trusted; + else + deprecated("WASI lacks process identifiers; to enable emulation of"~ + " the `getpid` function using a placeholder value, which"~ + " doesn't reflect the host PID of the program, compile"~ + " with --d-version=WASI_EMULATED_GETPID and link with"~ + " -lwasi-emulated-getpid") + pid_t getpid() @trusted; +} else + pid_t getpid() @trusted; + //int getresgid(gid_t*, gid_t*, gid_t*); //int getresuid(uid_t*, uid_t*, uid_t*); -uid_t getuid() @trusted; + +version (CRuntime_WASI) {} +else + uid_t getuid() @trusted; + int isatty(int) @trusted; int link(const scope char*, const scope char*); //int linkat(int, const scope char*, int, const scope char*, int); //off_t lseek(int, off_t, int); c_long pathconf(const scope char*, int); -int pause() @trusted; + +version (CRuntime_WASI) {} +else + int pause() @trusted; + int pipe(ref int[2]) @trusted; //int pipe2(ref int[2], int) @trusted; ssize_t read(int, void*, size_t); ssize_t readlink(const scope char*, char*, size_t); //ssize_t readlinkat(int, const scope char*, char*, size_t); int rmdir(const scope char*); -int setegid(gid_t) @trusted; -int seteuid(uid_t) @trusted; -int setgid(gid_t) @trusted; -int setgroups(size_t, const scope gid_t*) @trusted; -int setpgid(pid_t, pid_t) @trusted; + +version (CRuntime_WASI) {} +else +{ + int setpgid(pid_t, pid_t) @trusted; + int setegid(gid_t) @trusted; + int seteuid(uid_t) @trusted; + int setgid(gid_t) @trusted; + int setgroups(size_t, const scope gid_t*) @trusted; +} + //int setresgid(gid_t, gid_t, gid_t) @trusted; //int setresuid(uid_t, uid_t, uid_t) @trusted; -pid_t setsid() @trusted; -int setuid(uid_t) @trusted; + +version (CRuntime_WASI) {} +else +{ + pid_t setsid() @trusted; + int setuid(uid_t) @trusted; +} + uint sleep(uint) @trusted; int symlink(const scope char*, const scope char*); //int symlinkat(const scope char*, int, const scope char*); c_long sysconf(int) @trusted; -pid_t tcgetpgrp(int) @trusted; -int tcsetpgrp(int, pid_t) @trusted; -char* ttyname(int) @trusted; -int ttyname_r(int, char*, size_t); + +version (CRuntime_WASI) {} +else +{ + pid_t tcgetpgrp(int) @trusted; + int tcsetpgrp(int, pid_t) @trusted; + char* ttyname(int) @trusted; + int ttyname_r(int, char*, size_t); +} + int unlink(const scope char*); //int unlinkat(int, const scope char*, int); ssize_t write(int, const scope void*, size_t); @@ -327,6 +400,19 @@ else version (CRuntime_Musl) int symlinkat(const scope char*, int, const scope char*); int unlinkat(int, const scope char*, int); } +else version (CRuntime_WASI) +{ + off_t lseek(int, off_t, int) @trusted; + alias lseek64 = lseek; + int dup3(int, int, int) @trusted; + int faccessat(int, const scope char*, int, int); + int getentropy(void*, size_t); + int linkat(int, const scope char*, int, const scope char*, int); + int pipe2(ref int[2], int) @trusted; + ssize_t readlinkat(int, const scope char*, char*, size_t); + int symlinkat(const scope char*, int, const scope char*); + int unlinkat(int, const scope char*, int); +} else version (CRuntime_UClibc) { static if ( __USE_FILE_OFFSET64 ) @@ -2176,6 +2262,248 @@ else version (CRuntime_Musl) _SC_THREAD_ROBUST_PRIO_PROTECT } } +else version (CRuntime_WASI) +{ + enum F_OK = 0; + enum W_OK = 2; + enum X_OK = 1; + enum R_OK = 4; + + enum F_ULOCK = 0; + enum F_LOCK = 1; + enum F_TLOCK = 2; + enum F_TEST = 3; + + enum + { + _CS_PATH, + _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS, + _CS_GNU_LIBC_VERSION, + _CS_GNU_LIBPTHREAD_VERSION, + _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS, + _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS, + + _CS_POSIX_V6_ILP32_OFF32_CFLAGS = 1116, + _CS_POSIX_V6_ILP32_OFF32_LDFLAGS, + _CS_POSIX_V6_ILP32_OFF32_LIBS, + _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS, + _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS, + _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS, + _CS_POSIX_V6_ILP32_OFFBIG_LIBS, + _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS, + _CS_POSIX_V6_LP64_OFF64_CFLAGS, + _CS_POSIX_V6_LP64_OFF64_LDFLAGS, + _CS_POSIX_V6_LP64_OFF64_LIBS, + _CS_POSIX_V6_LP64_OFF64_LINTFLAGS, + _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS, + _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS, + _CS_POSIX_V6_LPBIG_OFFBIG_LIBS, + _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS, + _CS_POSIX_V7_ILP32_OFF32_CFLAGS, + _CS_POSIX_V7_ILP32_OFF32_LDFLAGS, + _CS_POSIX_V7_ILP32_OFF32_LIBS, + _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS, + _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS, + _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS, + _CS_POSIX_V7_ILP32_OFFBIG_LIBS, + _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS, + _CS_POSIX_V7_LP64_OFF64_CFLAGS, + _CS_POSIX_V7_LP64_OFF64_LDFLAGS, + _CS_POSIX_V7_LP64_OFF64_LIBS, + _CS_POSIX_V7_LP64_OFF64_LINTFLAGS, + _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS, + _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS, + _CS_POSIX_V7_LPBIG_OFFBIG_LIBS, + _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS, + _CS_V6_ENV, + _CS_V7_ENV + } + + enum + { + _PC_LINK_MAX, + _PC_MAX_CANON, + _PC_MAX_INPUT, + _PC_NAME_MAX, + _PC_PATH_MAX, + _PC_PIPE_BUF, + _PC_CHOWN_RESTRICTED, + _PC_NO_TRUNC, + _PC_VDISABLE, + _PC_SYNC_IO, + _PC_ASYNC_IO, + _PC_PRIO_IO, + _PC_SOCK_MAXBUF, + _PC_FILESIZEBITS, + _PC_REC_INCR_XFER_SIZE, + _PC_REC_MAX_XFER_SIZE, + _PC_REC_MIN_XFER_SIZE, + _PC_REC_XFER_ALIGN, + _PC_ALLOC_SIZE_MIN, + _PC_SYMLINK_MAX, + _PC_2_SYMLINKS + } + + enum + { + _SC_ARG_MAX, + _SC_CHILD_MAX, + _SC_CLK_TCK, + _SC_NGROUPS_MAX, + _SC_OPEN_MAX, + _SC_STREAM_MAX, + _SC_TZNAME_MAX, + _SC_JOB_CONTROL, + _SC_SAVED_IDS, + _SC_REALTIME_SIGNALS, + _SC_PRIORITY_SCHEDULING, + _SC_TIMERS, + _SC_ASYNCHRONOUS_IO, + _SC_PRIORITIZED_IO, + _SC_SYNCHRONIZED_IO, + _SC_FSYNC, + _SC_MAPPED_FILES, + _SC_MEMLOCK, + _SC_MEMLOCK_RANGE, + _SC_MEMORY_PROTECTION, + _SC_MESSAGE_PASSING, + _SC_SEMAPHORES, + _SC_SHARED_MEMORY_OBJECTS, + _SC_AIO_LISTIO_MAX, + _SC_AIO_MAX, + _SC_AIO_PRIO_DELTA_MAX, + _SC_DELAYTIMER_MAX, + _SC_MQ_OPEN_MAX, + _SC_MQ_PRIO_MAX, + _SC_VERSION, + _SC_PAGE_SIZE, + _SC_PAGESIZE = _SC_PAGE_SIZE, + _SC_RTSIG_MAX, + _SC_SEM_NSEMS_MAX, + _SC_SEM_VALUE_MAX, + _SC_SIGQUEUE_MAX, + _SC_TIMER_MAX, + _SC_BC_BASE_MAX, + _SC_BC_DIM_MAX, + _SC_BC_SCALE_MAX, + _SC_BC_STRING_MAX, + _SC_COLL_WEIGHTS_MAX, + + _SC_EXPR_NEST_MAX = 42, + _SC_LINE_MAX, + _SC_RE_DUP_MAX, + + _SC_2_VERSION = 46, + _SC_2_C_BIND, + _SC_2_C_DEV, + _SC_2_FORT_DEV, + _SC_2_FORT_RUN, + _SC_2_SW_DEV, + _SC_2_LOCALEDEF, + + _SC_UIO_MAXIOV = 60, + _SC_IOV_MAX = _SC_UIO_MAXIOV, + + _SC_THREADS = 67, + _SC_THREAD_SAFE_FUNCTIONS, + _SC_GETGR_R_SIZE_MAX, + _SC_GETPW_R_SIZE_MAX, + _SC_LOGIN_NAME_MAX, + _SC_TTY_NAME_MAX, + _SC_THREAD_DESTRUCTOR_ITERATIONS, + _SC_THREAD_KEYS_MAX, + _SC_THREAD_STACK_MIN, + _SC_THREAD_THREADS_MAX, + _SC_THREAD_ATTR_STACKADDR, + _SC_THREAD_ATTR_STACKSIZE, + _SC_THREAD_PRIORITY_SCHEDULING, + _SC_THREAD_PRIO_INHERIT, + _SC_THREAD_PRIO_PROTECT, + _SC_THREAD_PROCESS_SHARED, + + _SC_NPROCESSORS_CONF, + _SC_NPROCESSORS_ONLN, + _SC_PHYS_PAGES, + _SC_AVPHYS_PAGES, + _SC_ATEXIT_MAX, + _SC_PASS_MAX, + + _SC_XOPEN_VERSION, + _SC_XOPEN_XCU_VERSION, + _SC_XOPEN_UNIX, + _SC_XOPEN_CRYPT, + _SC_XOPEN_ENH_I18N, + _SC_XOPEN_SHM, + + _SC_2_CHAR_TERM, + _SC_2_UPE = 97, + + _SC_XOPEN_XPG2, + _SC_XOPEN_XPG3, + _SC_XOPEN_XPG4, + + _SC_NZERO = 109, + + _SC_XBS5_ILP32_OFF32 = 125, + _SC_XBS5_ILP32_OFFBIG, + _SC_XBS5_LP64_OFF64, + _SC_XBS5_LPBIG_OFFBIG, + + _SC_XOPEN_LEGACY, + _SC_XOPEN_REALTIME, + _SC_XOPEN_REALTIME_THREADS, + + _SC_ADVISORY_INFO, + _SC_BARRIERS, + _SC_CLOCK_SELECTION = 137, + _SC_CPUTIME, + _SC_THREAD_CPUTIME, + _SC_MONOTONIC_CLOCK = 149, + _SC_READER_WRITER_LOCKS = 153, + _SC_SPIN_LOCKS, + _SC_REGEXP, + _SC_SHELL = 157, + _SC_SPAWN = 159, + _SC_SPORADIC_SERVER, + _SC_THREAD_SPORADIC_SERVER, + _SC_TIMEOUTS = 164, + _SC_TYPED_MEMORY_OBJECTS, + _SC_2_PBS = 168, + _SC_2_PBS_ACCOUNTING, + _SC_2_PBS_LOCATE, + _SC_2_PBS_MESSAGE, + _SC_2_PBS_TRACK, + _SC_SYMLOOP_MAX, + _SC_STREAMS, + _SC_2_PBS_CHECKPOINT, + + _SC_V6_ILP32_OFF32, + _SC_V6_ILP32_OFFBIG, + _SC_V6_LP64_OFF64, + _SC_V6_LPBIG_OFFBIG, + + _SC_HOST_NAME_MAX, + _SC_TRACE, + _SC_TRACE_EVENT_FILTER, + _SC_TRACE_INHERIT, + _SC_TRACE_LOG, + + _SC_IPV6 = 235, + _SC_RAW_SOCKETS, + _SC_V7_ILP32_OFF32, + _SC_V7_ILP32_OFFBIG, + _SC_V7_LP64_OFF64, + _SC_V7_LPBIG_OFFBIG, + _SC_SS_REPL_MAX, + _SC_TRACE_EVENT_NAME_MAX, + _SC_TRACE_NAME_MAX, + _SC_TRACE_SYS_MAX, + _SC_TRACE_USER_EVENT_MAX, + _SC_XOPEN_STREAMS, + _SC_THREAD_ROBUST_PRIO_INHERIT, + _SC_THREAD_ROBUST_PRIO_PROTECT + } +} else version (CRuntime_UClibc) { enum F_OK = 0; @@ -2531,6 +2859,10 @@ else version (CRuntime_Musl) { int fsync(int) @trusted; } +else version (CRuntime_WASI) +{ + int fsync(int) @trusted; +} else version (Solaris) { int fsync(int) @trusted; @@ -2563,6 +2895,10 @@ else version (CRuntime_UClibc) { int fdatasync(int) @trusted; } +else version (CRuntime_WASI) +{ + int fdatasync(int) @trusted; +} // // XOpen (XSI) @@ -2645,6 +2981,9 @@ else version (CRuntime_Musl) int lockf(int, int, off_t); alias lockf64 = lockf; } +else version (CRuntime_WASI) +{ +} else version (Darwin) { char* crypt(const scope char*, const scope char*); @@ -2928,6 +3267,10 @@ else version (CRuntime_Musl) { extern __gshared const char** environ; } +else version (CRuntime_WASI) +{ + extern __gshared const char** environ; +} else version (Solaris) { extern __gshared const char** environ; diff --git a/runtime/druntime/src/core/sys/posix/utime.d b/runtime/druntime/src/core/sys/posix/utime.d index 16a26b23d95..bd7b68ef082 100644 --- a/runtime/druntime/src/core/sys/posix/utime.d +++ b/runtime/druntime/src/core/sys/posix/utime.d @@ -65,6 +65,16 @@ else version (CRuntime_Musl) pragma(mangle, muslRedirTime64Mangle!("utime", "__utime64")) int utime(const scope char*, const scope utimbuf*); } +else version (CRuntime_WASI) +{ + struct utimbuf + { + time_t actime; + time_t modtime; + } + + int utime(const scope char*, const scope utimbuf*); +} else version (Darwin) { struct utimbuf diff --git a/runtime/druntime/src/core/sys/wasi/posix/stdc/time.d b/runtime/druntime/src/core/sys/wasi/posix/stdc/time.d deleted file mode 100644 index 13439651f5d..00000000000 --- a/runtime/druntime/src/core/sys/wasi/posix/stdc/time.d +++ /dev/null @@ -1,29 +0,0 @@ -module core.sys.wasi.posix.stdc.time; - -extern (C): -@trusted: -nothrow: -@nogc: - -alias clock_t = long; // signed 64-bit -alias time_t = long; // signed 64-bit - -/// -struct tm -{ - int tm_sec; /// seconds after the minute [0-60] - int tm_min; /// minutes after the hour [0-59] - int tm_hour; /// hours since midnight [0-23] - int tm_mday; /// day of the month [1-31] - int tm_mon; /// months since January [0-11] - int tm_year; /// years since 1900 - int tm_wday; /// days since Sunday [0-6] - int tm_yday; /// days since January 1 [0-365] - int tm_isdst; /// Daylight Savings Time flag - int __tm_gmtoff; /// offset from CUT in seconds - const(char)* __tm_zone; /// timezone abbreviation - int __tm_nsec; -} - -enum clock_t CLOCKS_PER_SEC = 1_000_000_000; -clock_t clock(); diff --git a/runtime/druntime/src/core/sys/wasi/posix/time.d b/runtime/druntime/src/core/sys/wasi/posix/time.d deleted file mode 100644 index e41e9b1bad6..00000000000 --- a/runtime/druntime/src/core/sys/wasi/posix/time.d +++ /dev/null @@ -1,37 +0,0 @@ -module core.sys.wasi.posix.time; - -import core.stdc.config : muslRedirTime64Mangle; -import core.sys.wasi.posix.stdc.time : time_t; - -extern(C): -@nogc: -nothrow: -@trusted: - -struct __clockid; -alias clockid_t = __clockid*; - -private extern __gshared __clockid _CLOCK_MONOTONIC; -enum CLOCK_MONOTONIC = &_CLOCK_MONOTONIC; -private extern __gshared __clockid _CLOCK_REALTIME; -enum CLOCK_REALTIME = &_CLOCK_REALTIME; - -struct timespec { - time_t tv_sec; - long tv_nsec; -} - -alias long suseconds_t; - -struct timeval -{ - time_t tv_sec; - suseconds_t tv_usec; -} - -// No need for muslRedirTime64Mangle (even though WASI-libc is a musl fork) -// since _REDIR_TIME64 will never be set for Wasm (even wasm32) -int clock_getres(clockid_t, timespec*); -int clock_gettime(clockid_t, timespec*); - -int nanosleep(const scope timespec*, timespec*); diff --git a/runtime/druntime/src/core/thread/osthread.d b/runtime/druntime/src/core/thread/osthread.d index 0dd06a3dfb6..a124dcbea9e 100644 --- a/runtime/druntime/src/core/thread/osthread.d +++ b/runtime/druntime/src/core/thread/osthread.d @@ -98,14 +98,27 @@ version (Windows) else version (Posix) { static import core.sys.posix.pthread; - static import core.sys.posix.signal; import core.stdc.errno : EINTR, errno; - import core.sys.posix.pthread : pthread_atfork, pthread_attr_destroy, pthread_attr_getstack, pthread_attr_init, - pthread_attr_setstacksize, pthread_create, pthread_detach, pthread_getschedparam, pthread_join, pthread_self, - pthread_setschedparam, sched_get_priority_max, sched_get_priority_min, sched_param, sched_yield; - import core.sys.posix.semaphore : sem_init, sem_post, sem_t, sem_wait; - import core.sys.posix.signal : pthread_kill, sigaction, sigaction_t, sigdelset, sigfillset, sigset_t, sigsuspend, - SIGUSR1, stack_t; + + version (CRuntime_WASI) + import core.sys.posix.pthread : pthread_attr_destroy, pthread_attr_getstack, + pthread_attr_init, pthread_attr_setstacksize, pthread_create, pthread_detach, + pthread_join, pthread_self, sched_yield; + else + { + static import core.sys.posix.signal; + + import core.sys.posix.pthread : pthread_atfork, pthread_attr_destroy, pthread_attr_getstack, + pthread_attr_init, pthread_attr_setstacksize, pthread_create, pthread_detach, pthread_getschedparam, + pthread_join, pthread_self, pthread_setschedparam, sched_get_priority_max, sched_get_priority_min, + sched_param, sched_yield; + + import core.sys.posix.semaphore : sem_init, sem_post, sem_t, sem_wait; + + import core.sys.posix.signal : pthread_kill, sigaction, sigaction_t, sigdelset, sigfillset, sigset_t, sigsuspend, + SIGUSR1, stack_t; + } + import core.sys.posix.stdlib : free, malloc, realloc; import core.sys.posix.sys.types : pthread_attr_t, pthread_key_t, pthread_t; import core.sys.posix.time : nanosleep, timespec; @@ -158,14 +171,6 @@ else version (Posix) // Use POSIX threads for suspend/resume } } -else version (WASI) -{ - // No real threading support - // Just manipulations of the main "thread" - import core.stdc.stdlib : free, malloc, realloc; - import core.stdc.errno : EINTR, errno; - import core.sys.wasi.posix.time : nanosleep, timespec; -} version (GNU) { @@ -526,8 +531,6 @@ class Thread : ThreadBase multiThreadedFlag = false; } - version (WASI) onThreadError("cannot start new threads on WASI"); - version (Windows) {} else version (Posix) { @@ -681,10 +684,6 @@ class Thread : ThreadBase // on object destruction. m_addr = m_addr.init; } - else version (WASI) - { - throw new ThreadException( "Unable to join thread" ); - } if ( m_unhandled ) { @@ -905,6 +904,10 @@ class Thread : ThreadBase { return fakePriority==int.max? PRIORITY_DEFAULT : fakePriority; } + else version (WASI) + { + return PRIORITY_DEFAULT; + } else version (Posix) { int policy; @@ -918,10 +921,6 @@ class Thread : ThreadBase } return param.sched_priority; } - else version (WASI) - { - return 0; - } } @@ -977,6 +976,10 @@ class Thread : ThreadBase { fakePriority = val; } + else version (WASI) + { + // do nothing + } else version (Posix) { static if (__traits(compiles, core.sys.posix.pthread.pthread_setschedprio)) @@ -1064,11 +1067,6 @@ class Thread : ThreadBase { return atomicLoad(m_isRunning); } - else version (WASI) - { - // the "main thread" is the only that will pass super.isRunning(), and is always running - return true; - } } @@ -1131,23 +1129,6 @@ class Thread : ThreadBase timespec tin = void; timespec tout = void; - val.split!("seconds", "nsecs")(tin.tv_sec, tin.tv_nsec); - if ( val.total!"seconds" > tin.tv_sec.max ) - tin.tv_sec = tin.tv_sec.max; - while ( true ) - { - if ( !nanosleep( &tin, &tout ) ) - return; - if ( errno != EINTR ) - assert(0, "Unable to sleep for the specified duration"); - tin = tout; - } - } - else version (WASI) - { - timespec tin = void; - timespec tout = void; - val.split!("seconds", "nsecs")(tin.tv_sec, tin.tv_nsec); if ( val.total!"seconds" > tin.tv_sec.max ) tin.tv_sec = tin.tv_sec.max; @@ -1342,6 +1323,9 @@ version (CoreDdoc) { } } +else version (WASI) +{ +} else version (Posix) { extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc @@ -1379,7 +1363,8 @@ else version (Posix) } } -version (Posix) +version (WASI) {} +else version (Posix) { private __gshared int suspendSignalNumber; private __gshared int resumeSignalNumber; @@ -1414,12 +1399,6 @@ private extern (D) ThreadBase attachThread(ThreadBase _thisThread) @nogc nothrow atomicStore!(MemoryOrder.raw)(thisThread.toThread.m_isRunning, true); } - else version (WASI) - { - thisThread.m_addr = 1; // assumes this is done only once - thisContext.bstack = getStackBottom(); - thisContext.tstack = thisContext.bstack; - } thisThread.m_isDaemon = true; thisThread.tlsRTdataInit(); @@ -1895,10 +1874,6 @@ else version (Windows) { alias getpid = imported!"core.sys.windows.winbase".GetCurrentProcessId; } -else version (WASI) -{ - int getpid() @nogc nothrow @safe => 1; -} extern (C) @nogc nothrow { @@ -2457,6 +2432,22 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc t.m_curr.tstack = getStackTop(); } } + else version (WASI) + { + if ( t.m_addr != pthread_self() ) // dummy main thread + { + if ( !t.isRunning ) + { + Thread.remove( t ); + return false; + } + onThreadError( "Unable to suspend thread" ); + } + else if ( !t.m_lock ) + { + t.m_curr.tstack = getStackTop(); + } + } else version (Posix) { if ( t.m_addr != pthread_self() ) @@ -2476,17 +2467,6 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc t.m_curr.tstack = getStackTop(); } } - else version (WASI) - { - if ( t.m_addr != 1 ) // dummy main thread - { - onThreadError( "Unable to suspend thread" ); - } - else if ( !t.m_lock ) - { - t.m_curr.tstack = getStackTop(); - } - } return true; } @@ -2553,6 +2533,8 @@ extern (C) void thread_suspendAll() nothrow {} else version (Solaris) {} + else version (WASI) + {} else version (Posix) { // Subtract own thread if we called suspend() on ourselves. @@ -2641,6 +2623,22 @@ private extern (D) void resume(ThreadBase _t) nothrow @nogc t.m_curr.tstack = t.m_curr.bstack; t.m_reg[0 .. $] = 0; } + else version (WASI) + { + if ( t.m_addr != pthread_self() ) // dummy main thread + { + if ( !t.isRunning ) + { + Thread.remove( t ); + return; + } + onThreadError( "Unable to resume thread" ); + } + else if ( !t.m_lock ) + { + t.m_curr.tstack = t.m_curr.bstack; + } + } else version (Posix) { if ( t.m_addr != pthread_self() ) @@ -2660,17 +2658,6 @@ private extern (D) void resume(ThreadBase _t) nothrow @nogc t.m_curr.tstack = t.m_curr.bstack; } } - else version (WASI) - { - if ( t.m_addr != 1 ) // dummy main thread - { - onThreadError( "Unable to resume thread" ); - } - else if ( !t.m_lock ) - { - t.m_curr.tstack = t.m_curr.bstack; - } - } else static assert(false, "Platform not supported."); } @@ -2715,6 +2702,9 @@ extern (C) void thread_init() @nogc nothrow else version (Solaris) { } + else version (WASI) + { + } else version (Posix) { version (OpenBSD) @@ -3083,107 +3073,98 @@ else version (Posix) return null; } + version (WASI) {} + else + { + // + // Used to track the number of suspended threads + // + __gshared sem_t suspendCount; + + extern (C) bool thread_preSuspend( void* sp ) nothrow { + // NOTE: Since registers are being pushed and popped from the + // stack, any other stack data used by this function should + // be gone before the stack cleanup code is called below. + Thread obj = Thread.getThis(); + if (obj is null) + { + return false; + } - // - // Used to track the number of suspended threads - // - __gshared sem_t suspendCount; - + if ( !obj.m_lock ) + { + obj.m_curr.tstack = sp; + } - extern (C) bool thread_preSuspend( void* sp ) nothrow { - // NOTE: Since registers are being pushed and popped from the - // stack, any other stack data used by this function should - // be gone before the stack cleanup code is called below. - Thread obj = Thread.getThis(); - if (obj is null) - { - return false; + return true; } - if ( !obj.m_lock ) - { - obj.m_curr.tstack = sp; - } + extern (C) bool thread_postSuspend() nothrow { + Thread obj = Thread.getThis(); + if (obj is null) + { + return false; + } - return true; - } + if ( !obj.m_lock ) + { + obj.m_curr.tstack = obj.m_curr.bstack; + } - extern (C) bool thread_postSuspend() nothrow { - Thread obj = Thread.getThis(); - if (obj is null) - { - return false; + return true; } - if ( !obj.m_lock ) + extern (C) void thread_suspendHandler( int sig ) nothrow + in { - obj.m_curr.tstack = obj.m_curr.bstack; + assert( sig == suspendSignalNumber ); } - - return true; - } - - extern (C) void thread_suspendHandler( int sig ) nothrow - in - { - assert( sig == suspendSignalNumber ); - } - do - { - void op(void* sp) nothrow + do { - int cancel_state = thread_cancelDisable(); - scope(exit) thread_cancelRestore(cancel_state); - - bool supported = thread_preSuspend(getStackTop()); - assert(supported, "Tried to suspend a detached thread!"); - - scope(exit) + void op(void* sp) nothrow { - supported = thread_postSuspend(); + int cancel_state = thread_cancelDisable(); + scope(exit) thread_cancelRestore(cancel_state); + + bool supported = thread_preSuspend(getStackTop()); assert(supported, "Tried to suspend a detached thread!"); - } - sigset_t sigres = void; - int status; + scope(exit) + { + supported = thread_postSuspend(); + assert(supported, "Tried to suspend a detached thread!"); + } - status = sigfillset( &sigres ); - assert( status == 0 ); + sigset_t sigres = void; + int status; - status = sigdelset( &sigres, resumeSignalNumber ); - assert( status == 0 ); + status = sigfillset( &sigres ); + assert( status == 0 ); - status = sem_post( &suspendCount ); - assert( status == 0 ); + status = sigdelset( &sigres, resumeSignalNumber ); + assert( status == 0 ); - sigsuspend( &sigres ); + status = sem_post( &suspendCount ); + assert( status == 0 ); + + sigsuspend( &sigres ); + } + callWithStackShell(&op); } - callWithStackShell(&op); - } - extern (C) void thread_resumeHandler( int sig ) nothrow - in - { - assert( sig == resumeSignalNumber ); - } - do - { + extern (C) void thread_resumeHandler( int sig ) nothrow + in + { + assert( sig == resumeSignalNumber ); + } + do + { + } } } } -else version (WASI) -{ - // - // Entry point for WASI threads - // - extern (C) void* thread_entryPoint( void* arg ) nothrow - { - onThreadError("Cannot enter new WASI threads."); - return null; - } -} else { // NOTE: This is the only place threading versions are checked. If a new @@ -3566,10 +3547,6 @@ void joinLowLevelThread(ThreadID tid) nothrow @nogc if (pthread_join(tid, null) != 0) onThreadError("Unable to join thread"); } - else version (WASI) - { - onThreadError("Unable to join thread"); - } } version (WASI) {} // WASI is single-threaded diff --git a/runtime/druntime/src/core/time.d b/runtime/druntime/src/core/time.d index 5e679716cce..c47d1e11c5a 100644 --- a/runtime/druntime/src/core/time.d +++ b/runtime/druntime/src/core/time.d @@ -92,11 +92,6 @@ else version (Posix) import core.sys.posix.sys.time : gettimeofday, timeval; import core.sys.posix.time : clock_getres, clock_gettime, CLOCK_MONOTONIC, timespec; } -else version (WASI) -{ - import core.sys.wasi.posix.time : clock_getres, clock_gettime, CLOCK_MONOTONIC, timespec; -} - version (unittest) import core.stdc.stdio : printf; @@ -447,6 +442,16 @@ version (Posix) case second: assert(0); } } + else version (WASI) + { + with(ClockType) final switch (clockType) + { + case coarse: return CLOCK_MONOTONIC; + case normal: return CLOCK_MONOTONIC; + case precise: return CLOCK_MONOTONIC; + case second: assert(0); + } + } else // It needs to be decided (and implemented in an appropriate // version branch here) which clock types new platforms are going @@ -456,21 +461,6 @@ version (Posix) assert(0, "What are the monotonic clock types supported by this system?"); } } -else -version (WASI) -{ - private auto _posixClock(ClockType clockType) - { - import core.sys.wasi.posix.time; - with(ClockType) final switch (clockType) - { - case coarse: return CLOCK_MONOTONIC; - case normal: return CLOCK_MONOTONIC; - case precise: return CLOCK_MONOTONIC; - case second: assert(0); - } - } -} unittest { @@ -2158,10 +2148,6 @@ struct MonoTimeImpl(ClockType clockType) { enum clockArg = _posixClock(clockType); } - else version (WASI) - { - enum clockArg = _posixClock(clockType); - } else static assert(0, "Unsupported platform"); @@ -2227,24 +2213,6 @@ struct MonoTimeImpl(ClockType clockType) 1_000_000_000L, ticksPerSecond)); } - else version (WASI) - { - timespec ts = void; - immutable error = clock_gettime(clockArg, &ts); - // clockArg is supported and if tv_sec is long or larger - // overflow won't happen before 292 billion years A.D. - static if (ts.tv_sec.max < long.max) - { - if (error) - { - import core.internal.abort : abort; - abort("Call to clock_gettime failed."); - } - } - return MonoTimeImpl(convClockFreq(ts.tv_sec * 1_000_000_000L + ts.tv_nsec, - 1_000_000_000L, - ticksPerSecond)); - } } @@ -2640,34 +2608,6 @@ extern(C) void _d_initMonoTime() @nogc nothrow } } } - else version (WASI) - { - timespec ts; - foreach (i, typeStr; __traits(allMembers, ClockType)) - { - static if (typeStr != "second") - { - enum clockArg = _posixClock(__traits(getMember, ClockType, typeStr)); - if (clock_getres(clockArg, &ts) == 0) - { - // ensure we are only writing immutable data once - if (tps[i] != 0) - // should only be called once - assert(0); - - // For some reason, on some systems, clock_getres returns - // a resolution which is clearly wrong: - // - it's a millisecond or worse, but the time is updated - // much more frequently than that. - // - it's negative - // - it's zero - // In such cases, we'll just use nanosecond resolution. - tps[i] = ts.tv_sec != 0 || ts.tv_nsec <= 0 || ts.tv_nsec >= 1000 - ? 1_000_000_000L : 1_000_000_000L / ts.tv_nsec; - } - } - } - } else static assert(0, "Unsupported platform"); } @@ -2969,23 +2909,6 @@ deprecated: else ticksPerSec = 1_000_000; } - else version (WASI) - { - timespec ts; - - if (clock_getres(CLOCK_MONOTONIC, &ts) != 0) - ticksPerSec = 0; - else - { - //For some reason, on some systems, clock_getres returns - //a resolution which is clearly wrong (it's a millisecond - //or worse, but the time is updated much more frequently - //than that). In such cases, we'll just use nanosecond - //resolution. - ticksPerSec = ts.tv_nsec >= 1000 ? 1_000_000_000 - : 1_000_000_000 / ts.tv_nsec; - } - } else static assert(0, "Unsupported platform"); @@ -3555,23 +3478,6 @@ deprecated: tv.tv_usec * TickDuration.ticksPerSec / 1000 / 1000); } } - else version (WASI) - { - timespec ts = void; - immutable error = clock_gettime(CLOCK_MONOTONIC, &ts); - // CLOCK_MONOTONIC is supported and if tv_sec is long or larger - // overflow won't happen before 292 billion years A.D. - static if (ts.tv_sec.max < long.max) - { - if (error) - { - import core.internal.abort : abort; - abort("Call to clock_gettime failed."); - } - } - return TickDuration(ts.tv_sec * TickDuration.ticksPerSec + - ts.tv_nsec * TickDuration.ticksPerSec / 1000 / 1000 / 1000); - } } version (CoreUnittest) @safe nothrow unittest diff --git a/runtime/druntime/src/rt/dmain2.d b/runtime/druntime/src/rt/dmain2.d index 2519ae92add..156b0764906 100644 --- a/runtime/druntime/src/rt/dmain2.d +++ b/runtime/druntime/src/rt/dmain2.d @@ -43,10 +43,6 @@ else version (Posix) { import core.stdc.string : strlen; } -else version (WASI) -{ - import core.stdc.string : strlen; -} version (DigitalMars) version (AArch64) version = UseMalloc; // cuz alloca() is not implemented yet @@ -353,18 +349,6 @@ extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc) totalArgsLength += arg.length; } } - else version (WASI) - { - // Allocate args[] on the stack - char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc]; - - size_t totalArgsLength = 0; - foreach (i, ref arg; args) - { - arg = argv[i][0 .. strlen(argv[i])]; - totalArgsLength += arg.length; - } - } else static assert(0); diff --git a/runtime/druntime/test/importc_compare/src/importc_compare.d b/runtime/druntime/test/importc_compare/src/importc_compare.d index bf3fd14172d..62f0feec8e4 100644 --- a/runtime/druntime/test/importc_compare/src/importc_compare.d +++ b/runtime/druntime/test/importc_compare/src/importc_compare.d @@ -64,6 +64,15 @@ immutable ErrorFilter[] knownProblems = [ ErrorFilter("core.sys.posix.time.timer_t", "", "FreeBSD", 0, ""), ErrorFilter("core.sys.posix.ucontext.ucontext_t", "", "Apple", 0, ""), ErrorFilter("core.sys.posix.ucontext.ucontext_t", "", "FreeBSD", 0, ""), + + // Ignore complaint about `union` vs `struct`. Defined in C headers + // As a single union __u wrapped in a struct. In D, we just define it + // as a union directly. + ErrorFilter("core.sys.posix.sys.types.pthread_attr_t", "", "CRuntime_WASI", 0, ""), + ErrorFilter("core.sys.posix.sys.types.pthread_cond_t", "", "CRuntime_WASI", 0, ""), + ErrorFilter("core.sys.posix.sys.types.pthread_mutex_t", "", "CRuntime_WASI", 0, ""), + ErrorFilter("core.sys.posix.sys.types.pthread_rwlock_t", "", "CRuntime_WASI", 0, ""), + ErrorFilter("core.sys.posix.sys.types.pthread_barrier_t", "", "CRuntime_WASI", 0, ""), ]; struct ErrorFilter