authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-14 10:45:30-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-04-14 10:45:30-04:00
log63a970a548c1973a216d9cf5109138451a0d214a
tree284bc38814d5ee31be03df1a15447c5d6fe20d45
parent0f1d92e2cfda7ac633cc66fdf2b0e5e27cdf0f98
parent94e0871603add796e87ac53a3271cf5b9b3d6b0e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #2268 from shritesh/wasi

wasm: preliminary WASI OS support

8 files changed, 152 insertions(+), 4 deletions(-)

CMakeLists.txt+2
...@@ -607,6 +607,8 @@ set(ZIG_STD_FILES...@@ -607,6 +607,8 @@ set(ZIG_STD_FILES
607 "os/path.zig"607 "os/path.zig"
608 "os/time.zig"608 "os/time.zig"
609 "os/uefi.zig"609 "os/uefi.zig"
610 "os/wasi.zig"
611 "os/wasi/core.zig"
610 "os/windows.zig"612 "os/windows.zig"
611 "os/windows/advapi32.zig"613 "os/windows/advapi32.zig"
612 "os/windows/error.zig"614 "os/windows/error.zig"
src/ir.cpp+8-1
...@@ -15828,6 +15828,13 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,...@@ -15828,6 +15828,13 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
15828 ira->codegen->reported_bad_link_libc_error = true;15828 ira->codegen->reported_bad_link_libc_error = true;
15829 }15829 }
1583015830
15831 bool is_wasi = buf_eql_str(lib_name, "wasi");
15832 if (is_wasi && ira->codegen->zig_target->os != OsWASI) {
15833 ir_add_error_node(ira, source_node,
15834 buf_sprintf("linking against wasi library"));
15835 ira->codegen->reported_bad_link_libc_error = true;
15836 }
15837
15831 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name);15838 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name);
15832 for (size_t i = 0; i < link_lib->symbols.length; i += 1) {15839 for (size_t i = 0; i < link_lib->symbols.length; i += 1) {
15833 Buf *existing_symbol_name = link_lib->symbols.at(i);15840 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,...@@ -15836,7 +15843,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
15836 }15843 }
15837 }15844 }
1583815845
15839 if (!is_libc && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {15846 if (!is_libc && !is_wasi && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {
15840 ErrorMsg *msg = ir_add_error_node(ira, source_node,15847 ErrorMsg *msg = ir_add_error_node(ira, source_node,
15841 buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code",15848 buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code",
15842 buf_ptr(lib_name)));15849 buf_ptr(lib_name)));
src/link.cpp+3-1
...@@ -1091,7 +1091,9 @@ static void construct_linker_job_wasm(LinkJob *lj) {...@@ -1091,7 +1091,9 @@ static void construct_linker_job_wasm(LinkJob *lj) {
1091 CodeGen *g = lj->codegen;1091 CodeGen *g = lj->codegen;
10921092
1093 lj->args.append("-error-limit=0");1093 lj->args.append("-error-limit=0");
1094 lj->args.append("--no-entry"); // So lld doesn't look for _start.1094 if (g->zig_target->os != OsWASI) {
1095 lj->args.append("--no-entry"); // So lld doesn't look for _start.
1096 }
1095 lj->args.append("--allow-undefined");1097 lj->args.append("--allow-undefined");
1096 lj->args.append("--export-all");1098 lj->args.append("--export-all");
1097 lj->args.append("-o");1099 lj->args.append("-o");
std/os.zig+4-1
...@@ -23,6 +23,7 @@ test "std.os" {...@@ -23,6 +23,7 @@ test "std.os" {
23 _ = @import("os/time.zig");23 _ = @import("os/time.zig");
24 _ = @import("os/windows.zig");24 _ = @import("os/windows.zig");
25 _ = @import("os/uefi.zig");25 _ = @import("os/uefi.zig");
26 _ = @import("os/wasi.zig");
26 _ = @import("os/get_app_data_dir.zig");27 _ = @import("os/get_app_data_dir.zig");
27}28}
2829
...@@ -33,6 +34,7 @@ pub const freebsd = @import("os/freebsd.zig");...@@ -33,6 +34,7 @@ pub const freebsd = @import("os/freebsd.zig");
33pub const netbsd = @import("os/netbsd.zig");34pub const netbsd = @import("os/netbsd.zig");
34pub const zen = @import("os/zen.zig");35pub const zen = @import("os/zen.zig");
35pub const uefi = @import("os/uefi.zig");36pub const uefi = @import("os/uefi.zig");
37pub const wasi = @import("os/wasi.zig");
3638
37pub const posix = switch (builtin.os) {39pub const posix = switch (builtin.os) {
38 Os.linux => linux,40 Os.linux => linux,
...@@ -40,6 +42,7 @@ pub const posix = switch (builtin.os) {...@@ -40,6 +42,7 @@ pub const posix = switch (builtin.os) {
40 Os.freebsd => freebsd,42 Os.freebsd => freebsd,
41 Os.netbsd => netbsd,43 Os.netbsd => netbsd,
42 Os.zen => zen,44 Os.zen => zen,
45 Os.wasi => wasi,
43 else => @compileError("Unsupported OS"),46 else => @compileError("Unsupported OS"),
44};47};
4548
...@@ -187,7 +190,7 @@ pub fn abort() noreturn {...@@ -187,7 +190,7 @@ pub fn abort() noreturn {
187 c.abort();190 c.abort();
188 }191 }
189 switch (builtin.os) {192 switch (builtin.os) {
190 Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => {193 Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd, Os.wasi => {
191 _ = posix.raise(posix.SIGABRT);194 _ = posix.raise(posix.SIGABRT);
192 _ = posix.raise(posix.SIGKILL);195 _ = posix.raise(posix.SIGKILL);
193 while (true) {}196 while (true) {}
std/os/wasi.zig created+108
...@@ -0,0 +1,108 @@
1pub use @import("wasi/core.zig");
2
3// Based on https://github.com/CraneStation/wasi-sysroot/blob/wasi/libc-bottom-half/headers/public/wasi/core.h
4// and https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md
5
6pub const STDIN_FILENO = 0;
7pub const STDOUT_FILENO = 1;
8pub const STDERR_FILENO = 2;
9
10pub const ESUCCESS = 0;
11pub const E2BIG = 1;
12pub const EACCES = 2;
13pub const EADDRINUSE = 3;
14pub const EADDRNOTAVAIL = 4;
15pub const EAFNOSUPPORT = 5;
16pub const EAGAIN = 6;
17pub const EALREADY = 7;
18pub const EBADF = 8;
19pub const EBADMSG = 9;
20pub const EBUSY = 10;
21pub const ECANCELED = 11;
22pub const ECHILD = 12;
23pub const ECONNABORTED = 13;
24pub const ECONNREFUSED = 14;
25pub const ECONNRESET = 15;
26pub const EDEADLK = 16;
27pub const EDESTADDRREQ = 17;
28pub const EDOM = 18;
29pub const EDQUOT = 19;
30pub const EEXIST = 20;
31pub const EFAULT = 21;
32pub const EFBIG = 22;
33pub const EHOSTUNREACH = 23;
34pub const EIDRM = 24;
35pub const EILSEQ = 25;
36pub const EINPROGRESS = 26;
37pub const EINTR = 27;
38pub const EINVAL = 28;
39pub const EIO = 29;
40pub const EISCONN = 30;
41pub const EISDIR = 31;
42pub const ELOOP = 32;
43pub const EMFILE = 33;
44pub const EMLINK = 34;
45pub const EMSGSIZE = 35;
46pub const EMULTIHOP = 36;
47pub const ENAMETOOLONG = 37;
48pub const ENETDOWN = 38;
49pub const ENETRESET = 39;
50pub const ENETUNREACH = 40;
51pub const ENFILE = 41;
52pub const ENOBUFS = 42;
53pub const ENODEV = 43;
54pub const ENOENT = 44;
55pub const ENOEXEC = 45;
56pub const ENOLCK = 46;
57pub const ENOLINK = 47;
58pub const ENOMEM = 48;
59pub const ENOMSG = 49;
60pub const ENOPROTOOPT = 50;
61pub const ENOSPC = 51;
62pub const ENOSYS = 52;
63pub const ENOTCONN = 53;
64pub const ENOTDIR = 54;
65pub const ENOTEMPTY = 55;
66pub const ENOTRECOVERABLE = 56;
67pub const ENOTSOCK = 57;
68pub const ENOTSUP = 58;
69pub const ENOTTY = 59;
70pub const ENXIO = 60;
71pub const EOVERFLOW = 61;
72pub const EOWNERDEAD = 62;
73pub const EPERM = 63;
74pub const EPIPE = 64;
75pub const EPROTO = 65;
76pub const EPROTONOSUPPORT = 66;
77pub const EPROTOTYPE = 67;
78pub const ERANGE = 68;
79pub const EROFS = 69;
80pub const ESPIPE = 70;
81pub const ESRCH = 71;
82pub const ESTALE = 72;
83pub const ETIMEDOUT = 73;
84pub const ETXTBSY = 74;
85pub const EXDEV = 75;
86pub const ENOTCAPABLE = 76;
87
88// TODO: implement this like darwin does
89pub fn getErrno(r: usize) usize {
90 const signed_r = @bitCast(isize, r);
91 return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0;
92}
93
94pub fn exit(status: i32) noreturn {
95 __wasi_proc_exit(@bitCast(__wasi_exitcode_t, isize(status)));
96}
97
98pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
99 var nwritten: usize = undefined;
100
101 const iovs = []__wasi_ciovec_t{__wasi_ciovec_t{
102 .buf = buf,
103 .buf_len = count,
104 }};
105
106 _ = __wasi_fd_write(@bitCast(__wasi_fd_t, isize(fd)), &iovs[0], iovs.len, &nwritten);
107 return nwritten;
108}
std/os/wasi/core.zig created+17
...@@ -0,0 +1,17 @@
1pub const __wasi_errno_t = u16;
2pub const __wasi_exitcode_t = u32;
3pub const __wasi_fd_t = u32;
4pub const __wasi_signal_t = u8;
5
6pub const __wasi_ciovec_t = extern struct {
7 buf: [*]const u8,
8 buf_len: usize,
9};
10
11pub const __WASI_SIGABRT: __wasi_signal_t = 6;
12
13pub extern "wasi" fn __wasi_proc_raise(sig: __wasi_signal_t) __wasi_errno_t;
14
15pub extern "wasi" fn __wasi_proc_exit(rval: __wasi_exitcode_t) noreturn;
16
17pub extern "wasi" fn __wasi_fd_write(fd: __wasi_fd_t, iovs: *const __wasi_ciovec_t, iovs_len: usize, nwritten: *usize) __wasi_errno_t;
std/special/bootstrap.zig+4
...@@ -20,6 +20,10 @@ comptime {...@@ -20,6 +20,10 @@ comptime {
20}20}
2121
22nakedcc fn _start() noreturn {22nakedcc fn _start() noreturn {
23 if (builtin.os == builtin.Os.wasi) {
24 std.os.wasi.__wasi_proc_exit(callMain());
25 }
26
23 switch (builtin.arch) {27 switch (builtin.arch) {
24 builtin.Arch.x86_64 => {28 builtin.Arch.x86_64 => {
25 argc_ptr = asm ("lea (%%rsp), %[argc]"29 argc_ptr = asm ("lea (%%rsp), %[argc]"
std/special/panic.zig+6-1
...@@ -9,10 +9,15 @@ const std = @import("std");...@@ -9,10 +9,15 @@ const std = @import("std");
9pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {9pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
10 @setCold(true);10 @setCold(true);
11 switch (builtin.os) {11 switch (builtin.os) {
12 // TODO: fix panic in zen.12 // TODO: fix panic in zen
13 builtin.Os.freestanding, builtin.Os.zen => {13 builtin.Os.freestanding, builtin.Os.zen => {
14 while (true) {}14 while (true) {}
15 },15 },
16 builtin.Os.wasi => {
17 std.debug.warn("{}", msg);
18 _ = std.os.wasi.__wasi_proc_raise(std.os.wasi.__WASI_SIGABRT);
19 unreachable;
20 },
16 builtin.Os.uefi => {21 builtin.Os.uefi => {
17 // TODO look into using the debug info and logging helpful messages22 // TODO look into using the debug info and logging helpful messages
18 std.os.abort();23 std.os.abort();