diff --git a/Cargo.lock b/Cargo.lock index 19dadaa14005a..b2619f633e9b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,7 +83,7 @@ name = "atty" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -95,7 +95,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -107,7 +107,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "rustc-std-workspace-core 1.0.0", ] @@ -162,7 +162,7 @@ dependencies = [ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -259,7 +259,7 @@ dependencies = [ "jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -458,7 +458,7 @@ name = "commoncrypto-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -479,7 +479,7 @@ dependencies = [ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -499,7 +499,7 @@ dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -530,7 +530,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -657,7 +657,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -671,7 +671,7 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -729,7 +729,7 @@ name = "directories" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -738,7 +738,7 @@ name = "dirs" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -749,7 +749,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "rustc-std-workspace-core 1.0.0", ] @@ -858,7 +858,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -873,7 +873,7 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -915,7 +915,7 @@ name = "fs2" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -988,7 +988,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1163,7 +1163,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1200,7 +1200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -1208,7 +1208,7 @@ name = "jobserver" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1256,8 +1256,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.46" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.2.50" +source = "git+https://github.com/alexcrichton/libc?branch=wasi#38b2e6164cfe06608c71b88e3dd5b8a9b655e4b1" dependencies = [ "rustc-std-workspace-core 1.0.0", ] @@ -1269,7 +1269,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1282,7 +1282,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -1291,7 +1291,7 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1304,7 +1304,7 @@ version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1370,7 +1370,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1471,7 +1471,7 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1480,7 +1480,7 @@ name = "memmap" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1503,7 +1503,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -1521,7 +1521,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1535,7 +1535,7 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1560,7 +1560,7 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1607,7 +1607,7 @@ version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1653,7 +1653,7 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -1680,7 +1680,7 @@ dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1703,7 +1703,7 @@ version = "0.9.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1741,7 +1741,7 @@ version = "0.0.0" dependencies = [ "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -1751,7 +1751,7 @@ dependencies = [ "alloc 0.0.0", "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "unwind 0.0.0", ] @@ -1778,7 +1778,7 @@ name = "parking_lot_core" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1789,7 +1789,7 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2038,7 +2038,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2049,7 +2049,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2061,7 +2061,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2143,7 +2143,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2524,7 +2524,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2621,7 +2621,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3208,7 +3208,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -3235,7 +3235,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3256,7 +3256,7 @@ dependencies = [ "core 0.0.0", "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "panic_abort 0.0.0", "panic_unwind 0.0.0", "profiler_builtins 0.0.0", @@ -3407,7 +3407,7 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3418,7 +3418,7 @@ version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3470,7 +3470,7 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3490,7 +3490,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3524,7 +3524,7 @@ name = "time" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3605,7 +3605,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3637,7 +3637,7 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3708,7 +3708,7 @@ dependencies = [ "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3824,7 +3824,7 @@ version = "0.0.0" dependencies = [ "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -3891,7 +3891,7 @@ name = "wait-timeout" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -3964,7 +3964,7 @@ name = "xattr" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)", ] [[package]] @@ -4099,7 +4099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)" = "023a4cd09b2ff695f9734c1934145a315594b7986398496841c7031a5a1bbdbd" +"checksum libc 0.2.50 (git+https://github.com/alexcrichton/libc?branch=wasi)" = "" "checksum libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "48441cb35dc255da8ae72825689a95368bf510659ae1ad55dc4aa88cb1789bf1" "checksum libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d75d7966bda4730b722d1eab8e668df445368a24394bae9fc1e8dc0ab3dbe4f4" "checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d" diff --git a/Cargo.toml b/Cargo.toml index cb3c0ee194fe2..d3f99937ef8bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,5 +68,8 @@ rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' } # here rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' } +libc = { git = 'https://github.com/alexcrichton/libc', branch = 'wasi' } +#libc = { path = "../libc" } + [patch."https://github.com/rust-lang/rust-clippy"] clippy_lints = { path = "src/tools/clippy/clippy_lints" } diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 1f4c5543fa9aa..ca66d1523aae7 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -160,7 +160,8 @@ impl<'a> GccLinker<'a> { } fn takes_hints(&self) -> bool { - !self.sess.target.target.options.is_like_osx + !self.sess.target.target.options.is_like_osx && + self.sess.target.target.arch != "wasm32" } // Some platforms take hints about whether a library is static or dynamic. @@ -375,6 +376,12 @@ impl<'a> Linker for GccLinker<'a> { return } + // Symbol visibility takes care of this. Additionally LLD doesn't + // support the script arguments just yet + if self.sess.target.target.arch == "wasm32" { + return; + } + let mut arg = OsString::new(); let path = tmpdir.join("list"); @@ -443,13 +450,13 @@ impl<'a> Linker for GccLinker<'a> { } fn group_start(&mut self) { - if !self.sess.target.target.options.is_like_osx { + if self.takes_hints() { self.linker_arg("--start-group"); } } fn group_end(&mut self) { - if !self.sess.target.target.options.is_like_osx { + if self.takes_hints() { self.linker_arg("--end-group"); } } @@ -877,59 +884,7 @@ pub struct WasmLd<'a> { } impl<'a> WasmLd<'a> { - fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> { - // There have been reports in the wild (rustwasm/wasm-bindgen#119) of - // using threads causing weird hangs and bugs. Disable it entirely as - // this isn't yet the bottleneck of compilation at all anyway. - cmd.arg("--no-threads"); - - // By default LLD only gives us one page of stack (64k) which is a - // little small. Default to a larger stack closer to other PC platforms - // (1MB) and users can always inject their own link-args to override this. - cmd.arg("-z").arg("stack-size=1048576"); - - // By default LLD's memory layout is: - // - // 1. First, a blank page - // 2. Next, all static data - // 3. Finally, the main stack (which grows down) - // - // This has the unfortunate consequence that on stack overflows you - // corrupt static data and can cause some exceedingly weird bugs. To - // help detect this a little sooner we instead request that the stack is - // placed before static data. - // - // This means that we'll generate slightly larger binaries as references - // to static data will take more bytes in the ULEB128 encoding, but - // stack overflow will be guaranteed to trap as it underflows instead of - // corrupting static data. - cmd.arg("--stack-first"); - - // FIXME we probably shouldn't pass this but instead pass an explicit - // whitelist of symbols we'll allow to be undefined. Unfortunately - // though we can't handle symbols like `log10` that LLVM injects at a - // super late date without actually parsing object files. For now let's - // stick to this and hopefully fix it before stabilization happens. - cmd.arg("--allow-undefined"); - - // For now we just never have an entry symbol - cmd.arg("--no-entry"); - - // Rust code should never have warnings, and warnings are often - // indicative of bugs, let's prevent them. - cmd.arg("--fatal-warnings"); - - // The symbol visibility story is a bit in flux right now with LLD. - // It's... not entirely clear to me what's going on, but this looks to - // make everything work when `export_symbols` isn't otherwise called for - // things like executables. - cmd.arg("--export-dynamic"); - - // LLD only implements C++-like demangling, which doesn't match our own - // mangling scheme. Tell LLD to not demangle anything and leave it up to - // us to demangle these symbols later. - cmd.arg("--no-demangle"); - + fn new(cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> { WasmLd { cmd, sess, info } } } diff --git a/src/librustc_target/abi/call/wasm32.rs b/src/librustc_target/abi/call/wasm32.rs index 1fdcbb8e39bdf..9fe3965219cab 100644 --- a/src/librustc_target/abi/call/wasm32.rs +++ b/src/librustc_target/abi/call/wasm32.rs @@ -5,7 +5,11 @@ fn classify_ret_ty(ret: &mut ArgType<'_, Ty>) { } fn classify_arg_ty(arg: &mut ArgType<'_, Ty>) { - arg.extend_integer_width_to(32); + if arg.layout.is_aggregate() { + arg.make_indirect(); + } else { + arg.extend_integer_width_to(32); + } } pub fn compute_abi_info(fty: &mut FnType<'_, Ty>) { diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index bef2afc7b6292..c4a7b0a5607bb 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -66,6 +66,7 @@ mod l4re_base; mod fuchsia_base; mod redox_base; mod riscv_base; +mod wasm32_base; #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, RustcEncodable, RustcDecodable)] @@ -437,6 +438,7 @@ supported_targets! { ("asmjs-unknown-emscripten", asmjs_unknown_emscripten), ("wasm32-unknown-emscripten", wasm32_unknown_emscripten), ("wasm32-unknown-unknown", wasm32_unknown_unknown), + ("wasm32-unknown-wasi", wasm32_unknown_wasi), ("wasm32-experimental-emscripten", wasm32_experimental_emscripten), ("thumbv6m-none-eabi", thumbv6m_none_eabi), diff --git a/src/librustc_target/spec/wasm32_base.rs b/src/librustc_target/spec/wasm32_base.rs new file mode 100644 index 0000000000000..51885ca5718d4 --- /dev/null +++ b/src/librustc_target/spec/wasm32_base.rs @@ -0,0 +1,113 @@ +use std::collections::BTreeMap; +use super::{LldFlavor, TargetOptions, PanicStrategy, LinkerFlavor}; + +pub fn options() -> TargetOptions { + let mut lld_args = Vec::new(); + let mut clang_args = Vec::new(); + let mut arg = |arg: &str| { + lld_args.push(arg.to_string()); + clang_args.push(format!("-Wl,{}", arg)); + }; + + // There have been reports in the wild (rustwasm/wasm-bindgen#119) of + // using threads causing weird hangs and bugs. Disable it entirely as + // this isn't yet the bottleneck of compilation at all anyway. + arg("--no-threads"); + + // By default LLD only gives us one page of stack (64k) which is a + // little small. Default to a larger stack closer to other PC platforms + // (1MB) and users can always inject their own link-args to override this. + arg("-z"); + arg("stack-size=1048576"); + + // By default LLD's memory layout is: + // + // 1. First, a blank page + // 2. Next, all static data + // 3. Finally, the main stack (which grows down) + // + // This has the unfortunate consequence that on stack overflows you + // corrupt static data and can cause some exceedingly weird bugs. To + // help detect this a little sooner we instead request that the stack is + // placed before static data. + // + // This means that we'll generate slightly larger binaries as references + // to static data will take more bytes in the ULEB128 encoding, but + // stack overflow will be guaranteed to trap as it underflows instead of + // corrupting static data. + arg("--stack-first"); + + // FIXME we probably shouldn't pass this but instead pass an explicit + // whitelist of symbols we'll allow to be undefined. Unfortunately + // though we can't handle symbols like `log10` that LLVM injects at a + // super late date without actually parsing object files. For now let's + // stick to this and hopefully fix it before stabilization happens. + arg("--allow-undefined"); + + // Rust code should never have warnings, and warnings are often + // indicative of bugs, let's prevent them. + arg("--fatal-warnings"); + + // LLD only implements C++-like demangling, which doesn't match our own + // mangling scheme. Tell LLD to not demangle anything and leave it up to + // us to demangle these symbols later. + arg("--no-demangle"); + + // The symbol visibility story is a bit in flux right now with LLD. + // It's... not entirely clear to me what's going on, but this looks to + // make everything work when `export_symbols` isn't otherwise called for + // things like executables. + arg("--export-dynamic"); + + // For now we just never have an entry symbol + lld_args.push("--no-entry".to_string()); + + let mut pre_link_args = BTreeMap::new(); + pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Wasm), lld_args); + pre_link_args.insert(LinkerFlavor::Gcc, clang_args); + + TargetOptions { + // we allow dynamic linking, but only cdylibs. Basically we allow a + // final library artifact that exports some symbols (a wasm module) but + // we don't allow intermediate `dylib` crate types + dynamic_linking: true, + only_cdylib: true, + + // This means we'll just embed a `start` function in the wasm module + executables: true, + + // relatively self-explanatory! + exe_suffix: ".wasm".to_string(), + dll_prefix: String::new(), + dll_suffix: ".wasm".to_string(), + linker_is_gnu: false, + + max_atomic_width: Some(64), + + // Unwinding doesn't work right now, so the whole target unconditionally + // defaults to panic=abort. Note that this is guaranteed to change in + // the future once unwinding is implemented. Don't rely on this. + panic_strategy: PanicStrategy::Abort, + + // Wasm doesn't have atomics yet, so tell LLVM that we're in a single + // threaded model which will legalize atomics to normal operations. + singlethread: true, + + // no dynamic linking, no need for default visibility! + default_hidden_visibility: true, + + // we use the LLD shipped with the Rust toolchain by default + linker: Some("rust-lld".to_owned()), + lld_flavor: LldFlavor::Wasm, + + // No need for indirection here, simd types can always be passed by + // value as the whole module either has simd or not, which is different + // from x86 (for example) where programs can have functions that don't + // enable simd features. + simd_types_indirect: false, + + pre_link_args, + + .. Default::default() + } +} diff --git a/src/librustc_target/spec/wasm32_unknown_unknown.rs b/src/librustc_target/spec/wasm32_unknown_unknown.rs index ee2160c472080..ae9bca0f4fc45 100644 --- a/src/librustc_target/spec/wasm32_unknown_unknown.rs +++ b/src/librustc_target/spec/wasm32_unknown_unknown.rs @@ -7,51 +7,10 @@ // (aka panic=abort by default), but otherwise this is in general a relatively // standard target. -use super::{LldFlavor, LinkerFlavor, Target, TargetOptions, PanicStrategy}; +use super::{LldFlavor, LinkerFlavor, Target}; +use super::wasm32_base; pub fn target() -> Result { - let opts = TargetOptions { - // we allow dynamic linking, but only cdylibs. Basically we allow a - // final library artifact that exports some symbols (a wasm module) but - // we don't allow intermediate `dylib` crate types - dynamic_linking: true, - only_cdylib: true, - - // This means we'll just embed a `start` function in the wasm module - executables: true, - - // relatively self-explanatory! - exe_suffix: ".wasm".to_string(), - dll_prefix: String::new(), - dll_suffix: ".wasm".to_string(), - linker_is_gnu: false, - - max_atomic_width: Some(64), - - // Unwinding doesn't work right now, so the whole target unconditionally - // defaults to panic=abort. Note that this is guaranteed to change in - // the future once unwinding is implemented. Don't rely on this. - panic_strategy: PanicStrategy::Abort, - - // Wasm doesn't have atomics yet, so tell LLVM that we're in a single - // threaded model which will legalize atomics to normal operations. - singlethread: true, - - // no dynamic linking, no need for default visibility! - default_hidden_visibility: true, - - // we use the LLD shipped with the Rust toolchain by default - linker: Some("rust-lld".to_owned()), - lld_flavor: LldFlavor::Wasm, - - // No need for indirection here, simd types can always be passed by - // value as the whole module either has simd or not, which is different - // from x86 (for example) where programs can have functions that don't - // enable simd features. - simd_types_indirect: false, - - .. Default::default() - }; Ok(Target { llvm_target: "wasm32-unknown-unknown".to_string(), target_endian: "little".to_string(), @@ -65,6 +24,6 @@ pub fn target() -> Result { data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(), arch: "wasm32".to_string(), linker_flavor: LinkerFlavor::Lld(LldFlavor::Wasm), - options: opts, + options: wasm32_base::options(), }) } diff --git a/src/librustc_target/spec/wasm32_unknown_wasi.rs b/src/librustc_target/spec/wasm32_unknown_wasi.rs new file mode 100644 index 0000000000000..a8612e7ba5659 --- /dev/null +++ b/src/librustc_target/spec/wasm32_unknown_wasi.rs @@ -0,0 +1,25 @@ +use super::{LinkerFlavor, Target}; +use super::wasm32_base; + +pub fn target() -> Result { + let mut options = wasm32_base::options(); + options.linker = Some("clang".to_string()); + options + .pre_link_args + .entry(LinkerFlavor::Gcc) + .or_insert(Vec::new()) + .push("--target=wasm32-unknown-wasi".to_string()); + Ok(Target { + llvm_target: "wasm32-unknown-wasi".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + target_os: "unknown".to_string(), + target_env: "wasi".to_string(), + target_vendor: "unknown".to_string(), + data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(), + arch: "wasm32".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options, + }) +} diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index 5cce3df71d6a9..d48b5acffc074 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -51,6 +51,7 @@ cfg_if! { #[cfg(target_os = "emscripten")] pub mod emscripten; #[cfg(target_os = "fuchsia")] pub mod fuchsia; #[cfg(target_os = "hermit")] pub mod hermit; +#[cfg(target_env = "wasi")] pub mod wasi; #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] pub mod fortanix_sgx; pub mod raw; diff --git a/src/libstd/os/wasi.rs b/src/libstd/os/wasi.rs new file mode 100644 index 0000000000000..d25b8d39ed680 --- /dev/null +++ b/src/libstd/os/wasi.rs @@ -0,0 +1,6 @@ +//! WASI-specific definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +#[stable(feature = "rust1", since = "1.0.0")] +pub use crate::sys::ext::*; diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index 5ba9304c09b99..d7ce6a08e01c9 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -35,6 +35,9 @@ cfg_if! { } else if #[cfg(target_os = "redox")] { mod redox; pub use self::redox::*; + } else if #[cfg(target_env = "wasi")] { + mod wasi; + pub use self::wasi::*; } else if #[cfg(target_arch = "wasm32")] { mod wasm; pub use self::wasm::*; diff --git a/src/libstd/sys/wasi/alloc.rs b/src/libstd/sys/wasi/alloc.rs new file mode 100644 index 0000000000000..c8529937bbde0 --- /dev/null +++ b/src/libstd/sys/wasi/alloc.rs @@ -0,0 +1,43 @@ +use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::ptr; +use crate::sys_common::alloc::{MIN_ALIGN, realloc_fallback}; +use libc; + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + #[inline] + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + libc::malloc(layout.size()) as *mut u8 + } else { + libc::aligned_alloc(layout.size(), layout.align()) as *mut u8 + } + } + + #[inline] + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + libc::calloc(layout.size(), 1) as *mut u8 + } else { + let ptr = self.alloc(layout.clone()); + if !ptr.is_null() { + ptr::write_bytes(ptr, 0, layout.size()); + } + ptr + } + } + + #[inline] + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { + libc::free(ptr as *mut libc::c_void) + } + + #[inline] + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + if layout.align() <= MIN_ALIGN && layout.align() <= new_size { + libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 + } else { + realloc_fallback(self, ptr, layout, new_size) + } + } +} diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs new file mode 100644 index 0000000000000..f7ebc82d9c5aa --- /dev/null +++ b/src/libstd/sys/wasi/args.rs @@ -0,0 +1,49 @@ +use crate::ffi::OsString; +use crate::marker::PhantomData; + +pub unsafe fn init(_argc: isize, _argv: *const *const u8) { + // On wasm these should always be null, so there's nothing for us to do here +} + +pub unsafe fn cleanup() { +} + +pub fn args() -> Args { + Args { + _dont_send_or_sync_me: PhantomData, + } +} + +pub struct Args { + _dont_send_or_sync_me: PhantomData<*mut ()>, +} + +impl Args { + pub fn inner_debug(&self) -> &[OsString] { + &[] + } +} + +impl Iterator for Args { + type Item = OsString; + + fn next(&mut self) -> Option { + None + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(0)) + } +} + +impl ExactSizeIterator for Args { + fn len(&self) -> usize { + 0 + } +} + +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { + None + } +} diff --git a/src/libstd/sys/wasi/backtrace.rs b/src/libstd/sys/wasi/backtrace.rs new file mode 100644 index 0000000000000..7d56b298997aa --- /dev/null +++ b/src/libstd/sys/wasi/backtrace.rs @@ -0,0 +1,27 @@ +use crate::io; +use crate::sys::unsupported; +use crate::sys_common::backtrace::Frame; + +pub struct BacktraceContext; + +pub fn unwind_backtrace(_frames: &mut [Frame]) + -> io::Result<(usize, BacktraceContext)> +{ + unsupported() +} + +pub fn resolve_symname(_frame: Frame, + _callback: F, + _: &BacktraceContext) -> io::Result<()> + where F: FnOnce(Option<&str>) -> io::Result<()> +{ + unsupported() +} + +pub fn foreach_symbol_fileline(_: Frame, + _: F, + _: &BacktraceContext) -> io::Result + where F: FnMut(&[u8], u32) -> io::Result<()> +{ + unsupported() +} diff --git a/src/libstd/sys/wasi/env.rs b/src/libstd/sys/wasi/env.rs new file mode 100644 index 0000000000000..730e356d7fe95 --- /dev/null +++ b/src/libstd/sys/wasi/env.rs @@ -0,0 +1,9 @@ +pub mod os { + pub const FAMILY: &str = ""; + pub const OS: &str = ""; + pub const DLL_PREFIX: &str = ""; + pub const DLL_SUFFIX: &str = ".wasm"; + pub const DLL_EXTENSION: &str = "wasm"; + pub const EXE_SUFFIX: &str = ".wasm"; + pub const EXE_EXTENSION: &str = "wasm"; +} diff --git a/src/libstd/sys/wasi/ext/ffi.rs b/src/libstd/sys/wasi/ext/ffi.rs new file mode 100644 index 0000000000000..07b93dd143f8f --- /dev/null +++ b/src/libstd/sys/wasi/ext/ffi.rs @@ -0,0 +1,61 @@ +//! WASI-specific extension to the primitives in the `std::ffi` module + +#![stable(feature = "rust1", since = "1.0.0")] + +use crate::ffi::{OsStr, OsString}; +use crate::mem; +use crate::sys::os_str::Buf; +use crate::sys_common::{FromInner, IntoInner, AsInner}; + +/// WASI-specific extensions to [`OsString`]. +/// +/// [`OsString`]: ../../../../std/ffi/struct.OsString.html +#[stable(feature = "rust1", since = "1.0.0")] +pub trait OsStringExt { + /// Creates an `OsString` from a byte vector. + #[stable(feature = "rust1", since = "1.0.0")] + fn from_vec(vec: Vec) -> Self; + + /// Yields the underlying byte vector of this `OsString`. + #[stable(feature = "rust1", since = "1.0.0")] + fn into_vec(self) -> Vec; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl OsStringExt for OsString { + fn from_vec(vec: Vec) -> OsString { + FromInner::from_inner(Buf { inner: vec }) + } + fn into_vec(self) -> Vec { + self.into_inner().inner + } +} + +/// WASI-specific extensions to [`OsStr`]. +/// +/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html +#[stable(feature = "rust1", since = "1.0.0")] +pub trait OsStrExt { + #[stable(feature = "rust1", since = "1.0.0")] + /// Creates an [`OsStr`] from a byte slice. + /// + /// [`OsStr`]: ../../../ffi/struct.OsStr.html + fn from_bytes(slice: &[u8]) -> &Self; + + /// Gets the underlying byte view of the [`OsStr`] slice. + /// + /// [`OsStr`]: ../../../ffi/struct.OsStr.html + #[stable(feature = "rust1", since = "1.0.0")] + fn as_bytes(&self) -> &[u8]; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl OsStrExt for OsStr { + fn from_bytes(slice: &[u8]) -> &OsStr { + unsafe { mem::transmute(slice) } + } + fn as_bytes(&self) -> &[u8] { + &self.as_inner().inner + } +} + diff --git a/src/libstd/sys/wasi/ext/mod.rs b/src/libstd/sys/wasi/ext/mod.rs new file mode 100644 index 0000000000000..877b9ed89d81e --- /dev/null +++ b/src/libstd/sys/wasi/ext/mod.rs @@ -0,0 +1,10 @@ +pub mod ffi; + +/// A prelude for conveniently writing platform-specific code. +/// +/// Includes all extension traits, and some important type definitions. +#[stable(feature = "rust1", since = "1.0.0")] +pub mod prelude { + #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::sys::ext::ffi::{OsStringExt, OsStrExt}; +} diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs new file mode 100644 index 0000000000000..1e05e7017594a --- /dev/null +++ b/src/libstd/sys/wasi/fd.rs @@ -0,0 +1,322 @@ +#![allow(dead_code)] + +use crate::io::{self, IoVec, IoVecMut, SeekFrom}; +use crate::mem; +use crate::net::Shutdown; +use crate::sys::cvt_wasi; +use libc::{self, c_char, c_void}; + +pub struct WasiFd { + fd: libc::__wasi_fd_t, +} + +// FIXME: these should probably all be fancier structs, builders, enums, etc +pub type LookupFlags = u32; +pub type FdFlags = u16; +pub type Advice = u8; +pub type Rights = u64; +pub type Oflags = u16; +pub type DirCookie = u64; +pub type Timestamp = u64; +pub type FstFlags = u16; +pub type RiFlags = u16; +pub type RoFlags = u16; +pub type SiFlags = u16; + +fn iovec(a: &mut [IoVecMut]) -> (*const libc::__wasi_iovec_t, usize) { + assert_eq!( + mem::size_of::(), + mem::size_of::() + ); + assert_eq!( + mem::align_of::(), + mem::align_of::() + ); + (a.as_ptr() as *const libc::__wasi_iovec_t, a.len()) +} + +fn ciovec(a: &[IoVec]) -> (*const libc::__wasi_ciovec_t, usize) { + assert_eq!( + mem::size_of::(), + mem::size_of::() + ); + assert_eq!( + mem::align_of::(), + mem::align_of::() + ); + (a.as_ptr() as *const libc::__wasi_ciovec_t, a.len()) +} + +impl WasiFd { + pub unsafe fn from_raw(fd: libc::__wasi_fd_t) -> WasiFd { + WasiFd { fd } + } + + pub fn datasync(&self) -> io::Result<()> { + cvt_wasi(unsafe { libc::__wasi_fd_datasync(self.fd) }) + } + + pub fn pread(&self, bufs: &mut [IoVecMut], offset: u64) -> io::Result { + let mut read = 0; + let (ptr, len) = iovec(bufs); + cvt_wasi(unsafe { libc::__wasi_fd_pread(self.fd, ptr, len, offset, &mut read) })?; + Ok(read) + } + + pub fn pwrite(&self, bufs: &[IoVec], offset: u64) -> io::Result { + let mut read = 0; + let (ptr, len) = ciovec(bufs); + cvt_wasi(unsafe { libc::__wasi_fd_pwrite(self.fd, ptr, len, offset, &mut read) })?; + Ok(read) + } + + pub fn read(&self, bufs: &mut [IoVecMut]) -> io::Result { + let mut read = 0; + let (ptr, len) = iovec(bufs); + cvt_wasi(unsafe { libc::__wasi_fd_read(self.fd, ptr, len, &mut read) })?; + Ok(read) + } + + pub fn write(&self, bufs: &[IoVec]) -> io::Result { + let mut read = 0; + let (ptr, len) = ciovec(bufs); + cvt_wasi(unsafe { libc::__wasi_fd_write(self.fd, ptr, len, &mut read) })?; + Ok(read) + } + + pub fn seek(&self, pos: SeekFrom) -> io::Result { + let (whence, offset) = match pos { + SeekFrom::Start(pos) => (libc::__WASI_WHENCE_SET, pos as i64), + SeekFrom::End(pos) => (libc::__WASI_WHENCE_END, pos), + SeekFrom::Current(pos) => (libc::__WASI_WHENCE_CUR, pos), + }; + let mut pos = 0; + cvt_wasi(unsafe { libc::__wasi_fd_seek(self.fd, offset, whence, &mut pos) })?; + Ok(pos) + } + + pub fn tell(&self) -> io::Result { + let mut pos = 0; + cvt_wasi(unsafe { libc::__wasi_fd_tell(self.fd, &mut pos) })?; + Ok(pos) + } + + // FIXME: __wasi_fd_fdstat_get + + pub fn set_flags(&self, flags: FdFlags) -> io::Result<()> { + cvt_wasi(unsafe { libc::__wasi_fd_fdstat_set_flags(self.fd, flags) }) + } + + pub fn set_rights(&self, base: Rights, inheriting: Rights) -> io::Result<()> { + cvt_wasi(unsafe { libc::__wasi_fd_fdstat_set_rights(self.fd, base, inheriting) }) + } + + pub fn sync(&self) -> io::Result<()> { + cvt_wasi(unsafe { libc::__wasi_fd_sync(self.fd) }) + } + + pub fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> { + cvt_wasi(unsafe { libc::__wasi_fd_advise(self.fd, offset, len, advice as u8) }) + } + + pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { + cvt_wasi(unsafe { libc::__wasi_fd_allocate(self.fd, offset, len) }) + } + + pub fn crate_directory(&self, path: &[u8]) -> io::Result<()> { + cvt_wasi(unsafe { + libc::__wasi_path_create_directory(self.fd, path.as_ptr() as *const c_char, path.len()) + }) + } + + pub fn link( + &self, + old_flags: LookupFlags, + old_path: &[u8], + new_fd: &WasiFd, + new_path: &[u8], + ) -> io::Result<()> { + cvt_wasi(unsafe { + libc::__wasi_path_link( + self.fd, + old_flags, + old_path.as_ptr() as *const c_char, + old_path.len(), + new_fd.fd, + new_path.as_ptr() as *const c_char, + new_path.len(), + ) + }) + } + + pub fn open( + &self, + dirflags: LookupFlags, + path: &[u8], + oflags: Oflags, + fs_rights_base: Rights, + fs_rights_inheriting: Rights, + fs_flags: FdFlags, + ) -> io::Result { + unsafe { + let mut fd = 0; + cvt_wasi(libc::__wasi_path_open( + self.fd, + dirflags, + path.as_ptr() as *const c_char, + path.len(), + oflags, + fs_rights_base, + fs_rights_inheriting, + fs_flags, + &mut fd, + ))?; + Ok(WasiFd::from_raw(fd)) + } + } + + pub fn readdir(&self, buf: &mut [u8], cookie: DirCookie) -> io::Result { + let mut used = 0; + cvt_wasi(unsafe { + libc::__wasi_fd_readdir( + self.fd, + buf.as_mut_ptr() as *mut c_void, + buf.len(), + cookie, + &mut used, + ) + })?; + Ok(used) + } + + pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result { + let mut used = 0; + cvt_wasi(unsafe { + libc::__wasi_path_readlink( + self.fd, + path.as_ptr() as *const c_char, + path.len(), + buf.as_mut_ptr() as *mut c_char, + buf.len(), + &mut used, + ) + })?; + Ok(used) + } + + pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> { + cvt_wasi(unsafe { + libc::__wasi_path_rename( + self.fd, + old_path.as_ptr() as *const c_char, + old_path.len(), + new_fd.fd, + new_path.as_ptr() as *const c_char, + new_path.len(), + ) + }) + } + + // FIXME: __wasi_fd_filestat_get + + pub fn filestat_set_times( + &self, + atim: Timestamp, + mtim: Timestamp, + fstflags: FstFlags, + ) -> io::Result<()> { + cvt_wasi(unsafe { libc::__wasi_fd_filestat_set_times(self.fd, atim, mtim, fstflags) }) + } + + pub fn filestat_set_size(&self, size: u64) -> io::Result<()> { + cvt_wasi(unsafe { libc::__wasi_fd_filestat_set_size(self.fd, size) }) + } + + // FIXME: __wasi_path_filestat_get + + pub fn path_filestat_set_times( + &self, + flags: LookupFlags, + path: &[u8], + atim: Timestamp, + mtim: Timestamp, + fstflags: FstFlags, + ) -> io::Result<()> { + cvt_wasi(unsafe { + libc::__wasi_path_filestat_set_times( + self.fd, + flags, + path.as_ptr() as *const c_char, + path.len(), + atim, + mtim, + fstflags, + ) + }) + } + + pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> { + cvt_wasi(unsafe { + libc::__wasi_path_symlink( + old_path.as_ptr() as *const c_char, + old_path.len(), + self.fd, + new_path.as_ptr() as *const c_char, + new_path.len(), + ) + }) + } + + pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> { + cvt_wasi(unsafe { + libc::__wasi_path_unlink_file(self.fd, path.as_ptr() as *const c_char, path.len()) + }) + } + + pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> { + cvt_wasi(unsafe { + libc::__wasi_path_remove_directory(self.fd, path.as_ptr() as *const c_char, path.len()) + }) + } + + pub fn sock_recv( + &self, + ri_data: &mut [IoVecMut], + ri_flags: RiFlags, + ) -> io::Result<(usize, RoFlags)> { + let mut ro_datalen = 0; + let mut ro_flags = 0; + let (ptr, len) = iovec(ri_data); + cvt_wasi(unsafe { + libc::__wasi_sock_recv(self.fd, ptr, len, ri_flags, &mut ro_datalen, &mut ro_flags) + })?; + Ok((ro_datalen, ro_flags)) + } + + pub fn sock_send(&self, si_data: &[IoVec], si_flags: SiFlags) -> io::Result { + let mut so_datalen = 0; + let (ptr, len) = ciovec(si_data); + cvt_wasi(unsafe { libc::__wasi_sock_send(self.fd, ptr, len, si_flags, &mut so_datalen) })?; + Ok(so_datalen) + } + + pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> { + let how = match how { + Shutdown::Read => libc::__WASI_SHUT_RD, + Shutdown::Write => libc::__WASI_SHUT_WR, + Shutdown::Both => libc::__WASI_SHUT_WR | libc::__WASI_SHUT_RD, + }; + cvt_wasi(unsafe { libc::__wasi_sock_shutdown(self.fd, how) })?; + Ok(()) + } +} + +impl Drop for WasiFd { + fn drop(&mut self) { + unsafe { + // FIXME: can we handle the return code here even though we can't on + // unix? + libc::__wasi_fd_close(self.fd); + } + } +} diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs new file mode 100644 index 0000000000000..485d2c87fbd2d --- /dev/null +++ b/src/libstd/sys/wasi/fs.rs @@ -0,0 +1,294 @@ +use crate::ffi::OsString; +use crate::fmt; +use crate::hash::{Hash, Hasher}; +use crate::io::{self, SeekFrom}; +use crate::path::{Path, PathBuf}; +use crate::sys::time::SystemTime; +use crate::sys::{unsupported, Void}; + +pub struct File(Void); + +pub struct FileAttr(Void); + +pub struct ReadDir(Void); + +pub struct DirEntry(Void); + +#[derive(Clone, Debug)] +pub struct OpenOptions { } + +pub struct FilePermissions(Void); + +pub struct FileType(Void); + +#[derive(Debug)] +pub struct DirBuilder { } + +impl FileAttr { + pub fn size(&self) -> u64 { + match self.0 {} + } + + pub fn perm(&self) -> FilePermissions { + match self.0 {} + } + + pub fn file_type(&self) -> FileType { + match self.0 {} + } + + pub fn modified(&self) -> io::Result { + match self.0 {} + } + + pub fn accessed(&self) -> io::Result { + match self.0 {} + } + + pub fn created(&self) -> io::Result { + match self.0 {} + } +} + +impl Clone for FileAttr { + fn clone(&self) -> FileAttr { + match self.0 {} + } +} + +impl FilePermissions { + pub fn readonly(&self) -> bool { + match self.0 {} + } + + pub fn set_readonly(&mut self, _readonly: bool) { + match self.0 {} + } +} + +impl Clone for FilePermissions { + fn clone(&self) -> FilePermissions { + match self.0 {} + } +} + +impl PartialEq for FilePermissions { + fn eq(&self, _other: &FilePermissions) -> bool { + match self.0 {} + } +} + +impl Eq for FilePermissions { +} + +impl fmt::Debug for FilePermissions { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match self.0 {} + } +} + +impl FileType { + pub fn is_dir(&self) -> bool { + match self.0 {} + } + + pub fn is_file(&self) -> bool { + match self.0 {} + } + + pub fn is_symlink(&self) -> bool { + match self.0 {} + } +} + +impl Clone for FileType { + fn clone(&self) -> FileType { + match self.0 {} + } +} + +impl Copy for FileType {} + +impl PartialEq for FileType { + fn eq(&self, _other: &FileType) -> bool { + match self.0 {} + } +} + +impl Eq for FileType { +} + +impl Hash for FileType { + fn hash(&self, _h: &mut H) { + match self.0 {} + } +} + +impl fmt::Debug for FileType { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match self.0 {} + } +} + +impl fmt::Debug for ReadDir { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match self.0 {} + } +} + +impl Iterator for ReadDir { + type Item = io::Result; + + fn next(&mut self) -> Option> { + match self.0 {} + } +} + +impl DirEntry { + pub fn path(&self) -> PathBuf { + match self.0 {} + } + + pub fn file_name(&self) -> OsString { + match self.0 {} + } + + pub fn metadata(&self) -> io::Result { + match self.0 {} + } + + pub fn file_type(&self) -> io::Result { + match self.0 {} + } +} + +impl OpenOptions { + pub fn new() -> OpenOptions { + OpenOptions { } + } + + pub fn read(&mut self, _read: bool) { } + pub fn write(&mut self, _write: bool) { } + pub fn append(&mut self, _append: bool) { } + pub fn truncate(&mut self, _truncate: bool) { } + pub fn create(&mut self, _create: bool) { } + pub fn create_new(&mut self, _create_new: bool) { } +} + +impl File { + pub fn open(_path: &Path, _opts: &OpenOptions) -> io::Result { + unsupported() + } + + pub fn file_attr(&self) -> io::Result { + match self.0 {} + } + + pub fn fsync(&self) -> io::Result<()> { + match self.0 {} + } + + pub fn datasync(&self) -> io::Result<()> { + match self.0 {} + } + + pub fn truncate(&self, _size: u64) -> io::Result<()> { + match self.0 {} + } + + pub fn read(&self, _buf: &mut [u8]) -> io::Result { + match self.0 {} + } + + pub fn write(&self, _buf: &[u8]) -> io::Result { + match self.0 {} + } + + pub fn flush(&self) -> io::Result<()> { + match self.0 {} + } + + pub fn seek(&self, _pos: SeekFrom) -> io::Result { + match self.0 {} + } + + pub fn duplicate(&self) -> io::Result { + match self.0 {} + } + + pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { + match self.0 {} + } + + pub fn diverge(&self) -> ! { + match self.0 {} + } +} + +impl DirBuilder { + pub fn new() -> DirBuilder { + DirBuilder { } + } + + pub fn mkdir(&self, _p: &Path) -> io::Result<()> { + unsupported() + } +} + +impl fmt::Debug for File { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match self.0 {} + } +} + +pub fn readdir(_p: &Path) -> io::Result { + unsupported() +} + +pub fn unlink(_p: &Path) -> io::Result<()> { + unsupported() +} + +pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> { + unsupported() +} + +pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> { + match perm.0 {} +} + +pub fn rmdir(_p: &Path) -> io::Result<()> { + unsupported() +} + +pub fn remove_dir_all(_path: &Path) -> io::Result<()> { + unsupported() +} + +pub fn readlink(_p: &Path) -> io::Result { + unsupported() +} + +pub fn symlink(_src: &Path, _dst: &Path) -> io::Result<()> { + unsupported() +} + +pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { + unsupported() +} + +pub fn stat(_p: &Path) -> io::Result { + unsupported() +} + +pub fn lstat(_p: &Path) -> io::Result { + unsupported() +} + +pub fn canonicalize(_p: &Path) -> io::Result { + unsupported() +} + +pub fn copy(_from: &Path, _to: &Path) -> io::Result { + unsupported() +} diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs new file mode 100644 index 0000000000000..5f0315d279e8e --- /dev/null +++ b/src/libstd/sys/wasi/io.rs @@ -0,0 +1,62 @@ +use crate::marker::PhantomData; +use crate::slice; + +use libc::{__wasi_ciovec_t, __wasi_iovec_t, c_void}; + +#[repr(transparent)] +pub struct IoVec<'a> { + vec: __wasi_ciovec_t, + _p: PhantomData<&'a [u8]>, +} + +impl<'a> IoVec<'a> { + #[inline] + pub fn new(buf: &'a [u8]) -> IoVec<'a> { + IoVec { + vec: __wasi_ciovec_t { + buf: buf.as_ptr() as *const c_void, + buf_len: buf.len(), + }, + _p: PhantomData, + } + } + + #[inline] + pub fn as_slice(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len) + } + } +} + +pub struct IoVecMut<'a> { + vec: __wasi_iovec_t, + _p: PhantomData<&'a mut [u8]>, +} + +impl<'a> IoVecMut<'a> { + #[inline] + pub fn new(buf: &'a mut [u8]) -> IoVecMut<'a> { + IoVecMut { + vec: __wasi_iovec_t { + buf: buf.as_mut_ptr() as *mut c_void, + buf_len: buf.len() + }, + _p: PhantomData, + } + } + + #[inline] + pub fn as_slice(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len) + } + } + + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [u8] { + unsafe { + slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) + } + } +} diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs new file mode 100644 index 0000000000000..319d69d7ead0f --- /dev/null +++ b/src/libstd/sys/wasi/mod.rs @@ -0,0 +1,128 @@ +//! System bindings for the wasm/web platform +//! +//! This module contains the facade (aka platform-specific) implementations of +//! OS level functionality for wasm. Note that this wasm is *not* the emscripten +//! wasm, so we have no runtime here. +//! +//! This is all super highly experimental and not actually intended for +//! wide/production use yet, it's still all in the experimental category. This +//! will likely change over time. +//! +//! Currently all functions here are basically stubs that immediately return +//! errors. The hope is that with a portability lint we can turn actually just +//! remove all this and just omit parts of the standard library if we're +//! compiling for wasm. That way it's a compile time error for something that's +//! guaranteed to be a runtime error! + +use libc; +use crate::io::{Error, ErrorKind}; +use crate::mem; +use crate::os::raw::c_char; + +pub mod alloc; +pub mod args; +#[cfg(feature = "backtrace")] +pub mod backtrace; +#[path = "../wasm/cmath.rs"] +pub mod cmath; +#[path = "../wasm/condvar.rs"] +pub mod condvar; +pub mod env; +pub mod fd; +pub mod fs; +#[path = "../wasm/memchr.rs"] +pub mod memchr; +#[path = "../wasm/mutex.rs"] +pub mod mutex; +pub mod net; +pub mod io; +pub mod os; +pub mod os_str; +pub mod path; +pub mod pipe; +pub mod process; +#[path = "../wasm/rwlock.rs"] +pub mod rwlock; +#[path = "../wasm/stack_overflow.rs"] +pub mod stack_overflow; +pub mod stdio; +pub mod thread; +#[path = "../wasm/thread_local.rs"] +pub mod thread_local; +pub mod time; +pub mod ext; + +#[cfg(not(test))] +pub fn init() { +} + +pub fn unsupported() -> crate::io::Result { + Err(unsupported_err()) +} + +pub fn unsupported_err() -> Error { + Error::new(ErrorKind::Other, "operation not supported on wasm yet") +} + +pub fn decode_error_kind(_code: i32) -> ErrorKind { + ErrorKind::Other +} + +// This enum is used as the storage for a bunch of types which can't actually +// exist. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub enum Void {} + +pub unsafe fn strlen(mut s: *const c_char) -> usize { + let mut n = 0; + while *s != 0 { + n += 1; + s = s.offset(1); + } + return n +} + +pub unsafe fn abort_internal() -> ! { + libc::abort() +} + +pub fn hashmap_random_keys() -> (u64, u64) { + let mut ret = (0u64, 0u64); + unsafe { + let base = &mut ret as *mut (u64, u64) as *mut libc::c_void; + let len = mem::size_of_val(&ret); + cvt_wasi(libc::__wasi_random_get(base, len)).unwrap(); + } + return ret +} + +#[doc(hidden)] +pub trait IsMinusOne { + fn is_minus_one(&self) -> bool; +} + +macro_rules! impl_is_minus_one { + ($($t:ident)*) => ($(impl IsMinusOne for $t { + fn is_minus_one(&self) -> bool { + *self == -1 + } + })*) +} + +impl_is_minus_one! { i8 i16 i32 i64 isize } + +pub fn cvt(t: T) -> crate::io::Result { + if t.is_minus_one() { + Err(Error::last_os_error()) + } else { + Ok(t) + } +} + +pub fn cvt_wasi(r: u16) -> crate::io::Result<()> { + if r != libc::__WASI_ESUCCESS { + Err(Error::from_raw_os_error(r as i32)) + } else { + Ok(()) + } +} diff --git a/src/libstd/sys/wasi/net.rs b/src/libstd/sys/wasi/net.rs new file mode 100644 index 0000000000000..1249832fb09d2 --- /dev/null +++ b/src/libstd/sys/wasi/net.rs @@ -0,0 +1,354 @@ +use crate::fmt; +use crate::io::{self, IoVec, IoVecMut}; +use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr}; +use crate::time::Duration; +use crate::sys::{unsupported, Void}; +use crate::convert::TryFrom; + +pub struct TcpStream(Void); + +impl TcpStream { + pub fn connect(_: io::Result<&SocketAddr>) -> io::Result { + unsupported() + } + + pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result { + unsupported() + } + + pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { + match self.0 {} + } + + pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { + match self.0 {} + } + + pub fn read_timeout(&self) -> io::Result> { + match self.0 {} + } + + pub fn write_timeout(&self) -> io::Result> { + match self.0 {} + } + + pub fn peek(&self, _: &mut [u8]) -> io::Result { + match self.0 {} + } + + pub fn read(&self, _: &mut [u8]) -> io::Result { + match self.0 {} + } + + pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result { + match self.0 {} + } + + pub fn write(&self, _: &[u8]) -> io::Result { + match self.0 {} + } + + pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result { + match self.0 {} + } + + pub fn peer_addr(&self) -> io::Result { + match self.0 {} + } + + pub fn socket_addr(&self) -> io::Result { + match self.0 {} + } + + pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { + match self.0 {} + } + + pub fn duplicate(&self) -> io::Result { + match self.0 {} + } + + pub fn set_nodelay(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn nodelay(&self) -> io::Result { + match self.0 {} + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + match self.0 {} + } + + pub fn ttl(&self) -> io::Result { + match self.0 {} + } + + pub fn take_error(&self) -> io::Result> { + match self.0 {} + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + match self.0 {} + } +} + +impl fmt::Debug for TcpStream { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match self.0 {} + } +} + +pub struct TcpListener(Void); + +impl TcpListener { + pub fn bind(_: io::Result<&SocketAddr>) -> io::Result { + unsupported() + } + + pub fn socket_addr(&self) -> io::Result { + match self.0 {} + } + + pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { + match self.0 {} + } + + pub fn duplicate(&self) -> io::Result { + match self.0 {} + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + match self.0 {} + } + + pub fn ttl(&self) -> io::Result { + match self.0 {} + } + + pub fn set_only_v6(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn only_v6(&self) -> io::Result { + match self.0 {} + } + + pub fn take_error(&self) -> io::Result> { + match self.0 {} + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + match self.0 {} + } +} + +impl fmt::Debug for TcpListener { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match self.0 {} + } +} + +pub struct UdpSocket(Void); + +impl UdpSocket { + pub fn bind(_: io::Result<&SocketAddr>) -> io::Result { + unsupported() + } + + pub fn socket_addr(&self) -> io::Result { + match self.0 {} + } + + pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + match self.0 {} + } + + pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + match self.0 {} + } + + pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result { + match self.0 {} + } + + pub fn duplicate(&self) -> io::Result { + match self.0 {} + } + + pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { + match self.0 {} + } + + pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { + match self.0 {} + } + + pub fn read_timeout(&self) -> io::Result> { + match self.0 {} + } + + pub fn write_timeout(&self) -> io::Result> { + match self.0 {} + } + + pub fn set_broadcast(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn broadcast(&self) -> io::Result { + match self.0 {} + } + + pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn multicast_loop_v4(&self) -> io::Result { + match self.0 {} + } + + pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { + match self.0 {} + } + + pub fn multicast_ttl_v4(&self) -> io::Result { + match self.0 {} + } + + pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn multicast_loop_v6(&self) -> io::Result { + match self.0 {} + } + + pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) + -> io::Result<()> { + match self.0 {} + } + + pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) + -> io::Result<()> { + match self.0 {} + } + + pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) + -> io::Result<()> { + match self.0 {} + } + + pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) + -> io::Result<()> { + match self.0 {} + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + match self.0 {} + } + + pub fn ttl(&self) -> io::Result { + match self.0 {} + } + + pub fn take_error(&self) -> io::Result> { + match self.0 {} + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn recv(&self, _: &mut [u8]) -> io::Result { + match self.0 {} + } + + pub fn peek(&self, _: &mut [u8]) -> io::Result { + match self.0 {} + } + + pub fn send(&self, _: &[u8]) -> io::Result { + match self.0 {} + } + + pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { + match self.0 {} + } +} + +impl fmt::Debug for UdpSocket { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match self.0 {} + } +} + +pub struct LookupHost(Void); + +impl LookupHost { + pub fn port(&self) -> u16 { + match self.0 {} + } +} + +impl Iterator for LookupHost { + type Item = SocketAddr; + fn next(&mut self) -> Option { + match self.0 {} + } +} + +impl<'a> TryFrom<&'a str> for LookupHost { + type Error = io::Error; + + fn try_from(_v: &'a str) -> io::Result { + unsupported() + } +} + +impl<'a> TryFrom<(&'a str, u16)> for LookupHost { + type Error = io::Error; + + fn try_from(_v: (&'a str, u16)) -> io::Result { + unsupported() + } +} + +#[allow(nonstandard_style)] +pub mod netc { + pub const AF_INET: u8 = 0; + pub const AF_INET6: u8 = 1; + pub type sa_family_t = u8; + + #[derive(Copy, Clone)] + pub struct in_addr { + pub s_addr: u32, + } + + #[derive(Copy, Clone)] + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: u16, + pub sin_addr: in_addr, + } + + #[derive(Copy, Clone)] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } + + #[derive(Copy, Clone)] + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: u16, + pub sin6_addr: in6_addr, + pub sin6_flowinfo: u32, + pub sin6_scope_id: u32, + } + + #[derive(Copy, Clone)] + pub struct sockaddr { + } + + pub type socklen_t = usize; +} diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs new file mode 100644 index 0000000000000..01fe8a46f95c1 --- /dev/null +++ b/src/libstd/sys/wasi/os.rs @@ -0,0 +1,174 @@ +use crate::any::Any; +use crate::error::Error as StdError; +use crate::ffi::{OsString, OsStr, CString, CStr}; +use crate::fmt; +use crate::io; +use crate::marker::PhantomData; +use crate::os::wasi::prelude::*; +use crate::path::{self, PathBuf}; +use crate::ptr; +use crate::str; +use crate::sys::memchr; +use crate::sys::{cvt, unsupported, Void}; +use crate::vec; + +#[cfg(not(target_feature = "atomics"))] +pub unsafe fn env_lock() -> impl Any { + // No need for a lock if we're single-threaded, but this function will need + // to get implemented for multi-threaded scenarios +} + +pub fn errno() -> i32 { + extern { + #[thread_local] + static errno: libc::c_int; + } + + unsafe { errno as i32 } +} + +pub fn error_string(_errno: i32) -> String { + "operation failed".to_string() +} + +pub fn getcwd() -> io::Result { + unsupported() +} + +pub fn chdir(_: &path::Path) -> io::Result<()> { + unsupported() +} + +pub struct SplitPaths<'a>(&'a Void); + +pub fn split_paths(_unparsed: &OsStr) -> SplitPaths { + panic!("unsupported") +} + +impl<'a> Iterator for SplitPaths<'a> { + type Item = PathBuf; + fn next(&mut self) -> Option { + match *self.0 {} + } +} + +#[derive(Debug)] +pub struct JoinPathsError; + +pub fn join_paths(_paths: I) -> Result + where I: Iterator, T: AsRef +{ + Err(JoinPathsError) +} + +impl fmt::Display for JoinPathsError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + "not supported on wasm yet".fmt(f) + } +} + +impl StdError for JoinPathsError { + fn description(&self) -> &str { + "not supported on wasm yet" + } +} + +pub fn current_exe() -> io::Result { + unsupported() +} + +pub struct Env { + iter: vec::IntoIter<(OsString, OsString)>, + _dont_send_or_sync_me: PhantomData<*mut ()>, +} + +impl Iterator for Env { + type Item = (OsString, OsString); + fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} + + +pub fn env() -> Env { + unsafe { + let _guard = env_lock(); + let mut environ = libc::environ; + let mut result = Vec::new(); + while environ != ptr::null_mut() && *environ != ptr::null_mut() { + if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { + result.push(key_value); + } + environ = environ.offset(1); + } + return Env { + iter: result.into_iter(), + _dont_send_or_sync_me: PhantomData, + } + } + + fn parse(input: &[u8]) -> Option<(OsString, OsString)> { + // Strategy (copied from glibc): Variable name and value are separated + // by an ASCII equals sign '='. Since a variable name must not be + // empty, allow variable names starting with an equals sign. Skip all + // malformed lines. + if input.is_empty() { + return None; + } + let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1); + pos.map(|p| ( + OsStringExt::from_vec(input[..p].to_vec()), + OsStringExt::from_vec(input[p+1..].to_vec()), + )) + } +} + +pub fn getenv(k: &OsStr) -> io::Result> { + let k = CString::new(k.as_bytes())?; + unsafe { + let _guard = env_lock(); + let s = libc::getenv(k.as_ptr()) as *const libc::c_char; + let ret = if s.is_null() { + None + } else { + Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec())) + }; + Ok(ret) + } +} + +pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { + let k = CString::new(k.as_bytes())?; + let v = CString::new(v.as_bytes())?; + + unsafe { + let _guard = env_lock(); + cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ()) + } +} + +pub fn unsetenv(n: &OsStr) -> io::Result<()> { + let nbuf = CString::new(n.as_bytes())?; + + unsafe { + let _guard = env_lock(); + cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ()) + } +} + +pub fn temp_dir() -> PathBuf { + panic!("no filesystem on wasm") +} + +pub fn home_dir() -> Option { + None +} + +pub fn exit(code: i32) -> ! { + unsafe { + libc::exit(code) + } +} + +pub fn getpid() -> u32 { + panic!("unsupported"); +} diff --git a/src/libstd/sys/wasi/os_str.rs b/src/libstd/sys/wasi/os_str.rs new file mode 100644 index 0000000000000..7e4112b2d3221 --- /dev/null +++ b/src/libstd/sys/wasi/os_str.rs @@ -0,0 +1,179 @@ +/// The underlying OsString/OsStr implementation on Unix systems: just +/// a `Vec`/`[u8]`. + +use crate::borrow::Cow; +use crate::fmt; +use crate::str; +use crate::mem; +use crate::rc::Rc; +use crate::sync::Arc; +use crate::sys_common::{AsInner, IntoInner}; +use crate::sys_common::bytestring::debug_fmt_bytestring; +use core::str::lossy::Utf8Lossy; + +#[derive(Clone, Hash)] +pub struct Buf { + pub inner: Vec +} + +pub struct Slice { + pub inner: [u8] +} + +impl fmt::Debug for Slice { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + debug_fmt_bytestring(&self.inner, formatter) + } +} + +impl fmt::Display for Slice { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter) + } +} + +impl fmt::Debug for Buf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self.as_slice(), formatter) + } +} + +impl fmt::Display for Buf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self.as_slice(), formatter) + } +} + +impl IntoInner> for Buf { + fn into_inner(self) -> Vec { + self.inner + } +} + +impl AsInner<[u8]> for Buf { + fn as_inner(&self) -> &[u8] { + &self.inner + } +} + + +impl Buf { + pub fn from_string(s: String) -> Buf { + Buf { inner: s.into_bytes() } + } + + #[inline] + pub fn with_capacity(capacity: usize) -> Buf { + Buf { + inner: Vec::with_capacity(capacity) + } + } + + #[inline] + pub fn clear(&mut self) { + self.inner.clear() + } + + #[inline] + pub fn capacity(&self) -> usize { + self.inner.capacity() + } + + #[inline] + pub fn reserve(&mut self, additional: usize) { + self.inner.reserve(additional) + } + + #[inline] + pub fn reserve_exact(&mut self, additional: usize) { + self.inner.reserve_exact(additional) + } + + #[inline] + pub fn shrink_to_fit(&mut self) { + self.inner.shrink_to_fit() + } + + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + + pub fn as_slice(&self) -> &Slice { + unsafe { mem::transmute(&*self.inner) } + } + + pub fn into_string(self) -> Result { + String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } ) + } + + pub fn push_slice(&mut self, s: &Slice) { + self.inner.extend_from_slice(&s.inner) + } + + #[inline] + pub fn into_box(self) -> Box { + unsafe { mem::transmute(self.inner.into_boxed_slice()) } + } + + #[inline] + pub fn from_box(boxed: Box) -> Buf { + let inner: Box<[u8]> = unsafe { mem::transmute(boxed) }; + Buf { inner: inner.into_vec() } + } + + #[inline] + pub fn into_arc(&self) -> Arc { + self.as_slice().into_arc() + } + + #[inline] + pub fn into_rc(&self) -> Rc { + self.as_slice().into_rc() + } +} + +impl Slice { + fn from_u8_slice(s: &[u8]) -> &Slice { + unsafe { mem::transmute(s) } + } + + pub fn from_str(s: &str) -> &Slice { + Slice::from_u8_slice(s.as_bytes()) + } + + pub fn to_str(&self) -> Option<&str> { + str::from_utf8(&self.inner).ok() + } + + pub fn to_string_lossy(&self) -> Cow { + String::from_utf8_lossy(&self.inner) + } + + pub fn to_owned(&self) -> Buf { + Buf { inner: self.inner.to_vec() } + } + + #[inline] + pub fn into_box(&self) -> Box { + let boxed: Box<[u8]> = self.inner.into(); + unsafe { mem::transmute(boxed) } + } + + pub fn empty_box() -> Box { + let boxed: Box<[u8]> = Default::default(); + unsafe { mem::transmute(boxed) } + } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc: Arc<[u8]> = Arc::from(&self.inner); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc: Rc<[u8]> = Rc::from(&self.inner); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } + } +} diff --git a/src/libstd/sys/wasi/path.rs b/src/libstd/sys/wasi/path.rs new file mode 100644 index 0000000000000..5c062e7c97cd3 --- /dev/null +++ b/src/libstd/sys/wasi/path.rs @@ -0,0 +1,19 @@ +use crate::path::Prefix; +use crate::ffi::OsStr; + +#[inline] +pub fn is_sep_byte(b: u8) -> bool { + b == b'/' +} + +#[inline] +pub fn is_verbatim_sep(b: u8) -> bool { + b == b'/' +} + +pub fn parse_prefix(_: &OsStr) -> Option { + None +} + +pub const MAIN_SEP_STR: &str = "/"; +pub const MAIN_SEP: char = '/'; diff --git a/src/libstd/sys/wasi/pipe.rs b/src/libstd/sys/wasi/pipe.rs new file mode 100644 index 0000000000000..2582b993b608e --- /dev/null +++ b/src/libstd/sys/wasi/pipe.rs @@ -0,0 +1,25 @@ +use crate::io; +use crate::sys::Void; + +pub struct AnonPipe(Void); + +impl AnonPipe { + pub fn read(&self, _buf: &mut [u8]) -> io::Result { + match self.0 {} + } + + pub fn write(&self, _buf: &[u8]) -> io::Result { + match self.0 {} + } + + pub fn diverge(&self) -> ! { + match self.0 {} + } +} + +pub fn read2(p1: AnonPipe, + _v1: &mut Vec, + _p2: AnonPipe, + _v2: &mut Vec) -> io::Result<()> { + match p1.0 {} +} diff --git a/src/libstd/sys/wasi/process.rs b/src/libstd/sys/wasi/process.rs new file mode 100644 index 0000000000000..c49daaa16320e --- /dev/null +++ b/src/libstd/sys/wasi/process.rs @@ -0,0 +1,152 @@ +use crate::ffi::OsStr; +use crate::fmt; +use crate::io; +use crate::sys::fs::File; +use crate::sys::pipe::AnonPipe; +use crate::sys::{unsupported, Void}; +use crate::sys_common::process::{CommandEnv, DefaultEnvKey}; + +//////////////////////////////////////////////////////////////////////////////// +// Command +//////////////////////////////////////////////////////////////////////////////// + +pub struct Command { + env: CommandEnv +} + +// passed back to std::process with the pipes connected to the child, if any +// were requested +pub struct StdioPipes { + pub stdin: Option, + pub stdout: Option, + pub stderr: Option, +} + +pub enum Stdio { + Inherit, + Null, + MakePipe, +} + +impl Command { + pub fn new(_program: &OsStr) -> Command { + Command { + env: Default::default() + } + } + + pub fn arg(&mut self, _arg: &OsStr) { + } + + pub fn env_mut(&mut self) -> &mut CommandEnv { + &mut self.env + } + + pub fn cwd(&mut self, _dir: &OsStr) { + } + + pub fn stdin(&mut self, _stdin: Stdio) { + } + + pub fn stdout(&mut self, _stdout: Stdio) { + } + + pub fn stderr(&mut self, _stderr: Stdio) { + } + + pub fn spawn(&mut self, _default: Stdio, _needs_stdin: bool) + -> io::Result<(Process, StdioPipes)> { + unsupported() + } +} + +impl From for Stdio { + fn from(pipe: AnonPipe) -> Stdio { + pipe.diverge() + } +} + +impl From for Stdio { + fn from(file: File) -> Stdio { + file.diverge() + } +} + +impl fmt::Debug for Command { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } +} + +pub struct ExitStatus(Void); + +impl ExitStatus { + pub fn success(&self) -> bool { + match self.0 {} + } + + pub fn code(&self) -> Option { + match self.0 {} + } +} + +impl Clone for ExitStatus { + fn clone(&self) -> ExitStatus { + match self.0 {} + } +} + +impl Copy for ExitStatus {} + +impl PartialEq for ExitStatus { + fn eq(&self, _other: &ExitStatus) -> bool { + match self.0 {} + } +} + +impl Eq for ExitStatus { +} + +impl fmt::Debug for ExitStatus { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match self.0 {} + } +} + +impl fmt::Display for ExitStatus { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match self.0 {} + } +} + +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitCode(bool); + +impl ExitCode { + pub const SUCCESS: ExitCode = ExitCode(false); + pub const FAILURE: ExitCode = ExitCode(true); + + pub fn as_i32(&self) -> i32 { + self.0 as i32 + } +} + +pub struct Process(Void); + +impl Process { + pub fn id(&self) -> u32 { + match self.0 {} + } + + pub fn kill(&mut self) -> io::Result<()> { + match self.0 {} + } + + pub fn wait(&mut self) -> io::Result { + match self.0 {} + } + + pub fn try_wait(&mut self) -> io::Result> { + match self.0 {} + } +} diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs new file mode 100644 index 0000000000000..f6a4958897d9b --- /dev/null +++ b/src/libstd/sys/wasi/stdio.rs @@ -0,0 +1,74 @@ +use crate::io; +use crate::libc; +use crate::sys::cvt; + +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; + +impl Stdin { + pub fn new() -> io::Result { + Ok(Stdin) + } + + pub fn read(&self, data: &mut [u8]) -> io::Result { + let amt = cvt(unsafe { + libc::read(libc::STDIN_FILENO, data.as_mut_ptr() as *mut _, data.len()) + })?; + Ok(amt as usize) + } +} + +impl Stdout { + pub fn new() -> io::Result { + Ok(Stdout) + } + + pub fn write(&self, data: &[u8]) -> io::Result { + let amt = cvt(unsafe { + libc::write(libc::STDOUT_FILENO, data.as_ptr() as *const _, data.len()) + })?; + Ok(amt as usize) + } + + pub fn flush(&self) -> io::Result<()> { + Ok(()) + } +} + +impl Stderr { + pub fn new() -> io::Result { + Ok(Stderr) + } + + pub fn write(&self, data: &[u8]) -> io::Result { + let amt = cvt(unsafe { + libc::write(libc::STDERR_FILENO, data.as_ptr() as *const _, data.len()) + })?; + Ok(amt as usize) + } + + pub fn flush(&self) -> io::Result<()> { + Ok(()) + } +} + +impl io::Write for Stderr { + fn write(&mut self, data: &[u8]) -> io::Result { + (&*self).write(data) + } + + fn flush(&mut self) -> io::Result<()> { + (&*self).flush() + } +} + +pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE; + +pub fn is_ebadf(err: &io::Error) -> bool { + err.raw_os_error() == Some(libc::__WASI_EBADF as i32) +} + +pub fn panic_output() -> Option { + Stderr::new().ok() +} diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs new file mode 100644 index 0000000000000..9d3c6ac59d186 --- /dev/null +++ b/src/libstd/sys/wasi/thread.rs @@ -0,0 +1,57 @@ +use crate::boxed::FnBox; +use crate::cmp; +use crate::ffi::CStr; +use crate::io; +use crate::sys::cvt; +use crate::sys::{unsupported, Void}; +use crate::time::Duration; +use libc; + +pub struct Thread(Void); + +pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; + +impl Thread { + // unsafe: see thread::Builder::spawn_unchecked for safety requirements + pub unsafe fn new(_stack: usize, _p: Box) + -> io::Result + { + unsupported() + } + + pub fn yield_now() { + let ret = unsafe { libc::__wasi_sched_yield() }; + debug_assert_eq!(ret, 0); + } + + pub fn set_name(_name: &CStr) { + // nope + } + + pub fn sleep(dur: Duration) { + let mut secs = dur.as_secs(); + let mut nsecs = dur.subsec_nanos() as i32; + + unsafe { + while secs > 0 || nsecs > 0 { + let mut ts = libc::timespec { + tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t, + tv_nsec: nsecs, + }; + secs -= ts.tv_sec as u64; + cvt(libc::nanosleep(&ts, &mut ts)).unwrap(); + nsecs = 0; + } + } + } + + pub fn join(self) { + match self.0 {} + } +} + +pub mod guard { + pub type Guard = !; + pub unsafe fn current() -> Option { None } + pub unsafe fn init() -> Option { None } +} diff --git a/src/libstd/sys/wasi/time.rs b/src/libstd/sys/wasi/time.rs new file mode 100644 index 0000000000000..c126ae09507ae --- /dev/null +++ b/src/libstd/sys/wasi/time.rs @@ -0,0 +1,72 @@ +use crate::time::Duration; +use crate::mem; +use crate::sys::cvt_wasi; +use libc; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct Instant(Duration); + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct SystemTime(Duration); + +pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0)); + +fn current_time(clock: u32) -> Duration { + unsafe { + let mut ts = mem::zeroed(); + cvt_wasi(libc::__wasi_clock_time_get( + clock, + 1, // precision... seems ignored though? + &mut ts, + )).unwrap(); + Duration::new( + (ts / 1_000_000_000) as u64, + (ts % 1_000_000_000) as u32, + ) + } +} + +impl Instant { + pub fn now() -> Instant { + Instant(current_time(libc::__WASI_CLOCK_MONOTONIC)) + } + + pub const fn zero() -> Instant { + Instant(Duration::from_secs(0)) + } + + pub fn actually_monotonic() -> bool { + true + } + + pub fn sub_instant(&self, other: &Instant) -> Duration { + self.0 - other.0 + } + + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(Instant(self.0.checked_add(*other)?)) + } + + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(Instant(self.0.checked_sub(*other)?)) + } +} + +impl SystemTime { + pub fn now() -> SystemTime { + SystemTime(current_time(libc::__WASI_CLOCK_REALTIME)) + } + + pub fn sub_time(&self, other: &SystemTime) + -> Result { + self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) + } + + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(SystemTime(self.0.checked_add(*other)?)) + } + + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(SystemTime(self.0.checked_sub(*other)?)) + } +}