commit 63a970a548c1973a216d9cf5109138451a0d214a (tree)
parent 0f1d92e2cfda7ac633cc66fdf2b0e5e27cdf0f98
Author: Andrew Kelley <andrew@ziglang.org>
Date: Sun, 14 Apr 2019 10:45:30 -0400
Merge pull request #2268 from shritesh/wasi
wasm: preliminary WASI OS support
Diffstat:
8 files changed, 152 insertions(+), 4 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -607,6 +607,8 @@ set(ZIG_STD_FILES
"os/path.zig"
"os/time.zig"
"os/uefi.zig"
+ "os/wasi.zig"
+ "os/wasi/core.zig"
"os/windows.zig"
"os/windows/advapi32.zig"
"os/windows/error.zig"
diff --git a/src/ir.cpp b/src/ir.cpp
@@ -15828,6 +15828,13 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
ira->codegen->reported_bad_link_libc_error = true;
}
+ bool is_wasi = buf_eql_str(lib_name, "wasi");
+ if (is_wasi && ira->codegen->zig_target->os != OsWASI) {
+ ir_add_error_node(ira, source_node,
+ buf_sprintf("linking against wasi library"));
+ ira->codegen->reported_bad_link_libc_error = true;
+ }
+
LinkLib *link_lib = add_link_lib(ira->codegen, lib_name);
for (size_t i = 0; i < link_lib->symbols.length; i += 1) {
Buf *existing_symbol_name = link_lib->symbols.at(i);
@@ -15836,7 +15843,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
}
}
- if (!is_libc && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {
+ if (!is_libc && !is_wasi && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {
ErrorMsg *msg = ir_add_error_node(ira, source_node,
buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code",
buf_ptr(lib_name)));
diff --git a/src/link.cpp b/src/link.cpp
@@ -1091,7 +1091,9 @@ static void construct_linker_job_wasm(LinkJob *lj) {
CodeGen *g = lj->codegen;
lj->args.append("-error-limit=0");
- lj->args.append("--no-entry"); // So lld doesn't look for _start.
+ if (g->zig_target->os != OsWASI) {
+ lj->args.append("--no-entry"); // So lld doesn't look for _start.
+ }
lj->args.append("--allow-undefined");
lj->args.append("--export-all");
lj->args.append("-o");
diff --git a/std/os.zig b/std/os.zig
@@ -23,6 +23,7 @@ test "std.os" {
_ = @import("os/time.zig");
_ = @import("os/windows.zig");
_ = @import("os/uefi.zig");
+ _ = @import("os/wasi.zig");
_ = @import("os/get_app_data_dir.zig");
}
@@ -33,6 +34,7 @@ pub const freebsd = @import("os/freebsd.zig");
pub const netbsd = @import("os/netbsd.zig");
pub const zen = @import("os/zen.zig");
pub const uefi = @import("os/uefi.zig");
+pub const wasi = @import("os/wasi.zig");
pub const posix = switch (builtin.os) {
Os.linux => linux,
@@ -40,6 +42,7 @@ pub const posix = switch (builtin.os) {
Os.freebsd => freebsd,
Os.netbsd => netbsd,
Os.zen => zen,
+ Os.wasi => wasi,
else => @compileError("Unsupported OS"),
};
@@ -187,7 +190,7 @@ pub fn abort() noreturn {
c.abort();
}
switch (builtin.os) {
- Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => {
+ Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd, Os.wasi => {
_ = posix.raise(posix.SIGABRT);
_ = posix.raise(posix.SIGKILL);
while (true) {}
diff --git a/std/os/wasi.zig b/std/os/wasi.zig
@@ -0,0 +1,108 @@
+pub use @import("wasi/core.zig");
+
+// Based on https://github.com/CraneStation/wasi-sysroot/blob/wasi/libc-bottom-half/headers/public/wasi/core.h
+// and https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md
+
+pub const STDIN_FILENO = 0;
+pub const STDOUT_FILENO = 1;
+pub const STDERR_FILENO = 2;
+
+pub const ESUCCESS = 0;
+pub const E2BIG = 1;
+pub const EACCES = 2;
+pub const EADDRINUSE = 3;
+pub const EADDRNOTAVAIL = 4;
+pub const EAFNOSUPPORT = 5;
+pub const EAGAIN = 6;
+pub const EALREADY = 7;
+pub const EBADF = 8;
+pub const EBADMSG = 9;
+pub const EBUSY = 10;
+pub const ECANCELED = 11;
+pub const ECHILD = 12;
+pub const ECONNABORTED = 13;
+pub const ECONNREFUSED = 14;
+pub const ECONNRESET = 15;
+pub const EDEADLK = 16;
+pub const EDESTADDRREQ = 17;
+pub const EDOM = 18;
+pub const EDQUOT = 19;
+pub const EEXIST = 20;
+pub const EFAULT = 21;
+pub const EFBIG = 22;
+pub const EHOSTUNREACH = 23;
+pub const EIDRM = 24;
+pub const EILSEQ = 25;
+pub const EINPROGRESS = 26;
+pub const EINTR = 27;
+pub const EINVAL = 28;
+pub const EIO = 29;
+pub const EISCONN = 30;
+pub const EISDIR = 31;
+pub const ELOOP = 32;
+pub const EMFILE = 33;
+pub const EMLINK = 34;
+pub const EMSGSIZE = 35;
+pub const EMULTIHOP = 36;
+pub const ENAMETOOLONG = 37;
+pub const ENETDOWN = 38;
+pub const ENETRESET = 39;
+pub const ENETUNREACH = 40;
+pub const ENFILE = 41;
+pub const ENOBUFS = 42;
+pub const ENODEV = 43;
+pub const ENOENT = 44;
+pub const ENOEXEC = 45;
+pub const ENOLCK = 46;
+pub const ENOLINK = 47;
+pub const ENOMEM = 48;
+pub const ENOMSG = 49;
+pub const ENOPROTOOPT = 50;
+pub const ENOSPC = 51;
+pub const ENOSYS = 52;
+pub const ENOTCONN = 53;
+pub const ENOTDIR = 54;
+pub const ENOTEMPTY = 55;
+pub const ENOTRECOVERABLE = 56;
+pub const ENOTSOCK = 57;
+pub const ENOTSUP = 58;
+pub const ENOTTY = 59;
+pub const ENXIO = 60;
+pub const EOVERFLOW = 61;
+pub const EOWNERDEAD = 62;
+pub const EPERM = 63;
+pub const EPIPE = 64;
+pub const EPROTO = 65;
+pub const EPROTONOSUPPORT = 66;
+pub const EPROTOTYPE = 67;
+pub const ERANGE = 68;
+pub const EROFS = 69;
+pub const ESPIPE = 70;
+pub const ESRCH = 71;
+pub const ESTALE = 72;
+pub const ETIMEDOUT = 73;
+pub const ETXTBSY = 74;
+pub const EXDEV = 75;
+pub const ENOTCAPABLE = 76;
+
+// TODO: implement this like darwin does
+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 exit(status: i32) noreturn {
+ __wasi_proc_exit(@bitCast(__wasi_exitcode_t, isize(status)));
+}
+
+pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
+ var nwritten: usize = undefined;
+
+ const iovs = []__wasi_ciovec_t{__wasi_ciovec_t{
+ .buf = buf,
+ .buf_len = count,
+ }};
+
+ _ = __wasi_fd_write(@bitCast(__wasi_fd_t, isize(fd)), &iovs[0], iovs.len, &nwritten);
+ return nwritten;
+}
diff --git a/std/os/wasi/core.zig b/std/os/wasi/core.zig
@@ -0,0 +1,17 @@
+pub const __wasi_errno_t = u16;
+pub const __wasi_exitcode_t = u32;
+pub const __wasi_fd_t = u32;
+pub const __wasi_signal_t = u8;
+
+pub const __wasi_ciovec_t = extern struct {
+ buf: [*]const u8,
+ buf_len: usize,
+};
+
+pub const __WASI_SIGABRT: __wasi_signal_t = 6;
+
+pub extern "wasi" fn __wasi_proc_raise(sig: __wasi_signal_t) __wasi_errno_t;
+
+pub extern "wasi" fn __wasi_proc_exit(rval: __wasi_exitcode_t) noreturn;
+
+pub extern "wasi" fn __wasi_fd_write(fd: __wasi_fd_t, iovs: *const __wasi_ciovec_t, iovs_len: usize, nwritten: *usize) __wasi_errno_t;
diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig
@@ -20,6 +20,10 @@ comptime {
}
nakedcc fn _start() noreturn {
+ if (builtin.os == builtin.Os.wasi) {
+ std.os.wasi.__wasi_proc_exit(callMain());
+ }
+
switch (builtin.arch) {
builtin.Arch.x86_64 => {
argc_ptr = asm ("lea (%%rsp), %[argc]"
diff --git a/std/special/panic.zig b/std/special/panic.zig
@@ -9,10 +9,15 @@ const std = @import("std");
pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
@setCold(true);
switch (builtin.os) {
- // TODO: fix panic in zen.
+ // TODO: fix panic in zen
builtin.Os.freestanding, builtin.Os.zen => {
while (true) {}
},
+ builtin.Os.wasi => {
+ std.debug.warn("{}", msg);
+ _ = std.os.wasi.__wasi_proc_raise(std.os.wasi.__WASI_SIGABRT);
+ unreachable;
+ },
builtin.Os.uefi => {
// TODO look into using the debug info and logging helpful messages
std.os.abort();