From 747529e96bf61f1a2017224f956d4029e55fce42 Mon Sep 17 00:00:00 2001 From: Benjamin Feng Date: Tue, 19 Nov 2019 00:31:26 -0600 Subject: [PATCH 1/7] Use wasm_allocator --- lib/std/heap.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/heap.zig b/lib/std/heap.zig index 24ab395734..f251c83989 100644 --- a/lib/std/heap.zig +++ b/lib/std/heap.zig @@ -33,7 +33,7 @@ fn cShrink(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new /// This allocator makes a syscall directly for every allocation and free. /// Thread-safe and lock-free. -pub const direct_allocator = &direct_allocator_state; +pub const direct_allocator = if (builtin.arch == .wasm32) wasm_allocator else &direct_allocator_state; var direct_allocator_state = Allocator{ .reallocFn = DirectAllocator.realloc, .shrinkFn = DirectAllocator.shrink, From c3d93cd9f2a6ebc4e7104435a8bf24213eb4ba34 Mon Sep 17 00:00:00 2001 From: Benjamin Feng Date: Tue, 19 Nov 2019 16:12:26 -0600 Subject: [PATCH 2/7] WASI time_t / timespec --- lib/std/os/bits/wasi.zig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/std/os/bits/wasi.zig b/lib/std/os/bits/wasi.zig index 93d2a82fde..36944e5639 100644 --- a/lib/std/os/bits/wasi.zig +++ b/lib/std/os/bits/wasi.zig @@ -298,6 +298,7 @@ pub const subscription_t = extern struct { }; pub const timestamp_t = u64; +pub const time_t = i64; // match https://github.com/CraneStation/wasi-libc pub const userdata_t = u64; @@ -305,3 +306,8 @@ pub const whence_t = u8; pub const WHENCE_CUR: whence_t = 0; pub const WHENCE_END: whence_t = 1; pub const WHENCE_SET: whence_t = 2; + +pub const timespec = extern struct { + tv_sec: time_t, + tv_nsec: isize, +}; From 14e9c7d1f2f9a1b583237626e6b834c8e86d6cf7 Mon Sep 17 00:00:00 2001 From: Benjamin Feng Date: Tue, 19 Nov 2019 19:44:19 -0600 Subject: [PATCH 3/7] WASI clock functions --- lib/std/os/wasi.zig | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/lib/std/os/wasi.zig b/lib/std/os/wasi.zig index fce29ef0b3..7f030510ed 100644 --- a/lib/std/os/wasi.zig +++ b/lib/std/os/wasi.zig @@ -76,3 +76,35 @@ pub extern "wasi_unstable" fn sched_yield() errno_t; pub extern "wasi_unstable" fn sock_recv(sock: fd_t, ri_data: *const iovec_t, ri_data_len: usize, ri_flags: riflags_t, ro_datalen: *usize, ro_flags: *roflags_t) errno_t; pub extern "wasi_unstable" fn sock_send(sock: fd_t, si_data: *const ciovec_t, si_data_len: usize, si_flags: siflags_t, so_datalen: *usize) errno_t; pub extern "wasi_unstable" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t; + +/// Get the errno from a syscall return value, or 0 for no error. +pub fn getErrno(r: usize) usize { + const signed_r = @bitCast(isize, r); + return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0; +} + +pub fn clock_getres(clock_id: i32, res: *timespec) errno_t { + var ts: timestamp_t = undefined; + const err = clock_res_get(@bitCast(u32, clock_id), &ts); + if (err != 0) { + return err; + } + res.* = .{ + .tv_sec = @intCast(i64, ts / 1000000000), + .tv_nsec = @intCast(isize, ts % 1000000000), + }; + return 0; +} + +pub fn clock_gettime(clock_id: i32, tp: *timespec) errno_t { + var ts: timestamp_t = undefined; + const err = clock_time_get(@bitCast(u32, clock_id), 1, &ts); + if (err != 0) { + return err; + } + tp.* = .{ + .tv_sec = @intCast(i64, ts / 1000000000), + .tv_nsec = @intCast(isize, ts % 1000000000), + }; + return 0; +} From b88bb93af3cf22f5a994100e037dbb4091144f0c Mon Sep 17 00:00:00 2001 From: Benjamin Feng Date: Tue, 19 Nov 2019 20:17:00 -0600 Subject: [PATCH 4/7] WASI isatty --- lib/std/os.zig | 2 +- lib/std/os/bits/wasi.zig | 2 +- lib/std/os/wasi.zig | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index 68a3a6e9f6..36c1c8dbff 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1522,7 +1522,7 @@ pub fn isatty(handle: fd_t) bool { return system.isatty(handle) != 0; } if (builtin.os == .wasi) { - @compileError("TODO implement std.os.isatty for WASI"); + return system.isatty(handle); } if (builtin.os == .linux) { var wsz: linux.winsize = undefined; diff --git a/lib/std/os/bits/wasi.zig b/lib/std/os/bits/wasi.zig index 36944e5639..139418ded2 100644 --- a/lib/std/os/bits/wasi.zig +++ b/lib/std/os/bits/wasi.zig @@ -138,7 +138,7 @@ pub const FDFLAG_NONBLOCK: fdflags_t = 0x0004; pub const FDFLAG_RSYNC: fdflags_t = 0x0008; pub const FDFLAG_SYNC: fdflags_t = 0x0010; -const fdstat_t = extern struct { +pub const fdstat_t = extern struct { fs_filetype: filetype_t, fs_flags: fdflags_t, fs_rights_base: rights_t, diff --git a/lib/std/os/wasi.zig b/lib/std/os/wasi.zig index 7f030510ed..e8f4d052ea 100644 --- a/lib/std/os/wasi.zig +++ b/lib/std/os/wasi.zig @@ -108,3 +108,22 @@ pub fn clock_gettime(clock_id: i32, tp: *timespec) errno_t { }; return 0; } + +pub fn isatty(fd: fd_t) bool { + var statbuf: fdstat_t = undefined; + const err = fd_fdstat_get(fd, &statbuf); + if (err != 0) { + // errno = err; + return false; + } + + // A tty is a character device that we can't seek or tell on. + if (statbuf.fs_filetype != FILETYPE_CHARACTER_DEVICE or + (statbuf.fs_rights_base & (RIGHT_FD_SEEK | RIGHT_FD_TELL)) != 0) + { + // errno = ENOTTY; + return false; + } + + return true; +} From 218f9ff34e94511489d42f41831bc249464ed853 Mon Sep 17 00:00:00 2001 From: Benjamin Feng Date: Tue, 19 Nov 2019 20:55:55 -0600 Subject: [PATCH 5/7] Work around WASI's nonexistent @returnAddress() --- lib/std/debug.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 3cf4306ea5..86d6522247 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -213,7 +213,8 @@ pub fn assert(ok: bool) void { pub fn panic(comptime format: []const u8, args: ...) noreturn { @setCold(true); - const first_trace_addr = @returnAddress(); + // TODO: remove conditional once wasi / LLVM defines __builtin_return_address + const first_trace_addr = if (builtin.os == .wasi) null else @returnAddress(); panicExtra(null, first_trace_addr, format, args); } From d27721f58cfeff5fcd805125875e9c55b54b65bd Mon Sep 17 00:00:00 2001 From: Benjamin Feng Date: Wed, 20 Nov 2019 00:56:34 -0600 Subject: [PATCH 6/7] Add .enable_wasmtime build flag --- lib/std/build.zig | 8 ++++++++ lib/std/target.zig | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/std/build.zig b/lib/std/build.zig index b124b12fef..c4095a7fd1 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1064,6 +1064,9 @@ pub const LibExeObjStep = struct { /// Uses system QEMU installation to run cross compiled foreign architecture build artifacts. enable_qemu: bool = false, + /// Uses system Wasmtime installation to run cross compiled wasm/wasi build artifacts. + enable_wasmtime: bool = false, + /// After following the steps in https://github.com/ziglang/zig/wiki/Updating-libc#glibc, /// this will be the directory $glibc-build-dir/install/glibcs /// Given the example of the aarch64 target, this is the directory @@ -1863,6 +1866,11 @@ pub const LibExeObjStep = struct { try zig_args.append(bin_name); try zig_args.append("--test-cmd-bin"); }, + .wasmtime => |bin_name| if (self.enable_wasmtime) { + try zig_args.append("--test-cmd"); + try zig_args.append(bin_name); + try zig_args.append("--test-cmd-bin"); + }, } for (self.packages.toSliceConst()) |pkg| { zig_args.append("--pkg-begin") catch unreachable; diff --git a/lib/std/target.zig b/lib/std/target.zig index 5c0ac3d905..9652d5b6e5 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -611,6 +611,7 @@ pub const Target = union(enum) { native, qemu: []const u8, wine: []const u8, + wasmtime: []const u8, unavailable, }; @@ -649,6 +650,13 @@ pub const Target = union(enum) { } } + if (self.isWasm()) { + switch (self.getArchPtrBitWidth()) { + 32 => return Executor{ .wasmtime = "wasmtime" }, + else => return .unavailable, + } + } + return .unavailable; } }; From 0f0d01a0374dd62d55a0fe3eed72b9ec009af410 Mon Sep 17 00:00:00 2001 From: Benjamin Feng Date: Thu, 21 Nov 2019 18:41:02 -0600 Subject: [PATCH 7/7] Replace magic numbers with named constants --- lib/std/os/wasi.zig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/std/os/wasi.zig b/lib/std/os/wasi.zig index e8f4d052ea..7ba2339e06 100644 --- a/lib/std/os/wasi.zig +++ b/lib/std/os/wasi.zig @@ -90,8 +90,8 @@ pub fn clock_getres(clock_id: i32, res: *timespec) errno_t { return err; } res.* = .{ - .tv_sec = @intCast(i64, ts / 1000000000), - .tv_nsec = @intCast(isize, ts % 1000000000), + .tv_sec = @intCast(i64, ts / std.time.ns_per_s), + .tv_nsec = @intCast(isize, ts % std.time.ns_per_s), }; return 0; } @@ -103,8 +103,8 @@ pub fn clock_gettime(clock_id: i32, tp: *timespec) errno_t { return err; } tp.* = .{ - .tv_sec = @intCast(i64, ts / 1000000000), - .tv_nsec = @intCast(isize, ts % 1000000000), + .tv_sec = @intCast(i64, ts / std.time.ns_per_s), + .tv_nsec = @intCast(isize, ts % std.time.ns_per_s), }; return 0; }