| author | |
| committer | |
| log | 63a970a548c1973a216d9cf5109138451a0d214a |
| tree | 284bc38814d5ee31be03df1a15447c5d6fe20d45 |
| parent | 0f1d92e2cfda7ac633cc66fdf2b0e5e27cdf0f98 |
| parent | 94e0871603add796e87ac53a3271cf5b9b3d6b0e |
| signature | Signed by PGP key 4AEE18F83AFDEB23 |
wasm: preliminary WASI OS support8 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 | } |
| 15830 | 15830 | ||
| 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 | } |
| 15838 | 15845 | ||
| 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; |
| 1092 | 1092 | ||
| 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 | } |
| 28 | 29 | ||
| ... | @@ -33,6 +34,7 @@ pub const freebsd = @import("os/freebsd.zig"); | ... | @@ -33,6 +34,7 @@ pub const freebsd = @import("os/freebsd.zig"); |
| 33 | pub const netbsd = @import("os/netbsd.zig"); | 34 | pub const netbsd = @import("os/netbsd.zig"); |
| 34 | pub const zen = @import("os/zen.zig"); | 35 | pub const zen = @import("os/zen.zig"); |
| 35 | pub const uefi = @import("os/uefi.zig"); | 36 | pub const uefi = @import("os/uefi.zig"); |
| 37 | pub const wasi = @import("os/wasi.zig"); | ||
| 36 | 38 | ||
| 37 | pub const posix = switch (builtin.os) { | 39 | pub 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 | }; |
| 45 | 48 | ||
| ... | @@ -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 @@ | ||
| 1 | pub 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 | |||
| 6 | pub const STDIN_FILENO = 0; | ||
| 7 | pub const STDOUT_FILENO = 1; | ||
| 8 | pub const STDERR_FILENO = 2; | ||
| 9 | |||
| 10 | pub const ESUCCESS = 0; | ||
| 11 | pub const E2BIG = 1; | ||
| 12 | pub const EACCES = 2; | ||
| 13 | pub const EADDRINUSE = 3; | ||
| 14 | pub const EADDRNOTAVAIL = 4; | ||
| 15 | pub const EAFNOSUPPORT = 5; | ||
| 16 | pub const EAGAIN = 6; | ||
| 17 | pub const EALREADY = 7; | ||
| 18 | pub const EBADF = 8; | ||
| 19 | pub const EBADMSG = 9; | ||
| 20 | pub const EBUSY = 10; | ||
| 21 | pub const ECANCELED = 11; | ||
| 22 | pub const ECHILD = 12; | ||
| 23 | pub const ECONNABORTED = 13; | ||
| 24 | pub const ECONNREFUSED = 14; | ||
| 25 | pub const ECONNRESET = 15; | ||
| 26 | pub const EDEADLK = 16; | ||
| 27 | pub const EDESTADDRREQ = 17; | ||
| 28 | pub const EDOM = 18; | ||
| 29 | pub const EDQUOT = 19; | ||
| 30 | pub const EEXIST = 20; | ||
| 31 | pub const EFAULT = 21; | ||
| 32 | pub const EFBIG = 22; | ||
| 33 | pub const EHOSTUNREACH = 23; | ||
| 34 | pub const EIDRM = 24; | ||
| 35 | pub const EILSEQ = 25; | ||
| 36 | pub const EINPROGRESS = 26; | ||
| 37 | pub const EINTR = 27; | ||
| 38 | pub const EINVAL = 28; | ||
| 39 | pub const EIO = 29; | ||
| 40 | pub const EISCONN = 30; | ||
| 41 | pub const EISDIR = 31; | ||
| 42 | pub const ELOOP = 32; | ||
| 43 | pub const EMFILE = 33; | ||
| 44 | pub const EMLINK = 34; | ||
| 45 | pub const EMSGSIZE = 35; | ||
| 46 | pub const EMULTIHOP = 36; | ||
| 47 | pub const ENAMETOOLONG = 37; | ||
| 48 | pub const ENETDOWN = 38; | ||
| 49 | pub const ENETRESET = 39; | ||
| 50 | pub const ENETUNREACH = 40; | ||
| 51 | pub const ENFILE = 41; | ||
| 52 | pub const ENOBUFS = 42; | ||
| 53 | pub const ENODEV = 43; | ||
| 54 | pub const ENOENT = 44; | ||
| 55 | pub const ENOEXEC = 45; | ||
| 56 | pub const ENOLCK = 46; | ||
| 57 | pub const ENOLINK = 47; | ||
| 58 | pub const ENOMEM = 48; | ||
| 59 | pub const ENOMSG = 49; | ||
| 60 | pub const ENOPROTOOPT = 50; | ||
| 61 | pub const ENOSPC = 51; | ||
| 62 | pub const ENOSYS = 52; | ||
| 63 | pub const ENOTCONN = 53; | ||
| 64 | pub const ENOTDIR = 54; | ||
| 65 | pub const ENOTEMPTY = 55; | ||
| 66 | pub const ENOTRECOVERABLE = 56; | ||
| 67 | pub const ENOTSOCK = 57; | ||
| 68 | pub const ENOTSUP = 58; | ||
| 69 | pub const ENOTTY = 59; | ||
| 70 | pub const ENXIO = 60; | ||
| 71 | pub const EOVERFLOW = 61; | ||
| 72 | pub const EOWNERDEAD = 62; | ||
| 73 | pub const EPERM = 63; | ||
| 74 | pub const EPIPE = 64; | ||
| 75 | pub const EPROTO = 65; | ||
| 76 | pub const EPROTONOSUPPORT = 66; | ||
| 77 | pub const EPROTOTYPE = 67; | ||
| 78 | pub const ERANGE = 68; | ||
| 79 | pub const EROFS = 69; | ||
| 80 | pub const ESPIPE = 70; | ||
| 81 | pub const ESRCH = 71; | ||
| 82 | pub const ESTALE = 72; | ||
| 83 | pub const ETIMEDOUT = 73; | ||
| 84 | pub const ETXTBSY = 74; | ||
| 85 | pub const EXDEV = 75; | ||
| 86 | pub const ENOTCAPABLE = 76; | ||
| 87 | |||
| 88 | // TODO: implement this like darwin does | ||
| 89 | pub 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 | |||
| 94 | pub fn exit(status: i32) noreturn { | ||
| 95 | __wasi_proc_exit(@bitCast(__wasi_exitcode_t, isize(status))); | ||
| 96 | } | ||
| 97 | |||
| 98 | pub 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 @@ | ||
| 1 | pub const __wasi_errno_t = u16; | ||
| 2 | pub const __wasi_exitcode_t = u32; | ||
| 3 | pub const __wasi_fd_t = u32; | ||
| 4 | pub const __wasi_signal_t = u8; | ||
| 5 | |||
| 6 | pub const __wasi_ciovec_t = extern struct { | ||
| 7 | buf: [*]const u8, | ||
| 8 | buf_len: usize, | ||
| 9 | }; | ||
| 10 | |||
| 11 | pub const __WASI_SIGABRT: __wasi_signal_t = 6; | ||
| 12 | |||
| 13 | pub extern "wasi" fn __wasi_proc_raise(sig: __wasi_signal_t) __wasi_errno_t; | ||
| 14 | |||
| 15 | pub extern "wasi" fn __wasi_proc_exit(rval: __wasi_exitcode_t) noreturn; | ||
| 16 | |||
| 17 | pub 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 | } |
| 21 | 21 | ||
| 22 | nakedcc fn _start() noreturn { | 22 | nakedcc 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"); |
| 9 | pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn { | 9 | pub 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 messages | 22 | // TODO look into using the debug info and logging helpful messages |
| 18 | std.os.abort(); | 23 | std.os.abort(); |