authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-25 18:46:17-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-25 18:46:17-05:00
log4261fa3c49be715355c9623102bad0bf93d537a3
treeba8da3ef0611a547fe67c61ed2d42d4ea67e6d2e
parent659c1bdeeebce7bf32e122be6a728fe727112c56
signaturelock-open Commit is signed but in an unrecognized format.

move logic to the appropriate layers; add new compile error


10 files changed, 91 insertions(+), 59 deletions(-)

lib/std/heap.zig+4-4
......@@ -273,17 +273,17 @@ const WasmPageAllocator = struct {
273273 if (new_end_index > num_pages * mem.page_size) {
274274 const required_memory = new_end_index - (num_pages * mem.page_size);
275275
276 var num_pages: usize = required_memory / mem.page_size;
276 var inner_num_pages: usize = required_memory / mem.page_size;
277277 if (required_memory % mem.page_size != 0) {
278 num_pages += 1;
278 inner_num_pages += 1;
279279 }
280280
281 const prev_page = @"llvm.wasm.memory.grow.i32"(0, @intCast(u32, num_pages));
281 const prev_page = @"llvm.wasm.memory.grow.i32"(0, @intCast(u32, inner_num_pages));
282282 if (prev_page == -1) {
283283 return error.OutOfMemory;
284284 }
285285
286 num_pages += num_pages;
286 num_pages += inner_num_pages;
287287 }
288288
289289 const result = start_ptr[adjusted_index..new_end_index];
lib/std/os.zig+43-1
......@@ -1527,7 +1527,22 @@ pub fn isatty(handle: fd_t) bool {
15271527 return system.isatty(handle) != 0;
15281528 }
15291529 if (builtin.os == .wasi) {
1530 return system.isatty(handle);
1530 var statbuf: fdstat_t = undefined;
1531 const err = system.fd_fdstat_get(handle, &statbuf);
1532 if (err != 0) {
1533 // errno = err;
1534 return false;
1535 }
1536
1537 // A tty is a character device that we can't seek or tell on.
1538 if (statbuf.fs_filetype != FILETYPE_CHARACTER_DEVICE or
1539 (statbuf.fs_rights_base & (RIGHT_FD_SEEK | RIGHT_FD_TELL)) != 0)
1540 {
1541 // errno = ENOTTY;
1542 return false;
1543 }
1544
1545 return true;
15311546 }
15321547 if (builtin.os == .linux) {
15331548 var wsz: linux.winsize = undefined;
......@@ -2720,6 +2735,20 @@ pub fn dl_iterate_phdr(
27202735pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
27212736
27222737pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
2738 if (comptime std.Target.current.getOs() == .wasi) {
2739 var ts: timestamp_t = undefined;
2740 switch (system.clock_time_get(@bitCast(u32, clk_id), 1, &ts)) {
2741 0 => {
2742 tp.* = .{
2743 .tv_sec = @intCast(i64, ts / std.time.ns_per_s),
2744 .tv_nsec = @intCast(isize, ts % std.time.ns_per_s),
2745 };
2746 },
2747 EINVAL => return error.UnsupportedClock,
2748 else => |err| return unexpectedErrno(err),
2749 }
2750 return;
2751 }
27232752 switch (errno(system.clock_gettime(clk_id, tp))) {
27242753 0 => return,
27252754 EFAULT => unreachable,
......@@ -2729,6 +2758,19 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
27292758}
27302759
27312760pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
2761 if (comptime std.Target.current.getOs() == .wasi) {
2762 var ts: timestamp_t = undefined;
2763 switch (system.clock_res_get(@bitCast(u32, clk_id), &ts)) {
2764 0 => res.* = .{
2765 .tv_sec = @intCast(i64, ts / std.time.ns_per_s),
2766 .tv_nsec = @intCast(isize, ts % std.time.ns_per_s),
2767 },
2768 EINVAL => return error.UnsupportedClock,
2769 else => |err| return unexpectedErrno(err),
2770 }
2771 return;
2772 }
2773
27322774 switch (errno(system.clock_getres(clk_id, res))) {
27332775 0 => return,
27342776 EFAULT => unreachable,
lib/std/os/wasi.zig+2-48
......@@ -78,52 +78,6 @@ pub extern "wasi_unstable" fn sock_send(sock: fd_t, si_data: *const ciovec_t, si
7878pub extern "wasi_unstable" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t;
7979
8080/// Get the errno from a syscall return value, or 0 for no error.
81pub fn getErrno(r: usize) usize {
82 const signed_r = @bitCast(isize, r);
83 return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0;
84}
85
86pub fn clock_getres(clock_id: i32, res: *timespec) errno_t {
87 var ts: timestamp_t = undefined;
88 const err = clock_res_get(@bitCast(u32, clock_id), &ts);
89 if (err != 0) {
90 return err;
91 }
92 res.* = .{
93 .tv_sec = @intCast(i64, ts / std.time.ns_per_s),
94 .tv_nsec = @intCast(isize, ts % std.time.ns_per_s),
95 };
96 return 0;
97}
98
99pub fn clock_gettime(clock_id: i32, tp: *timespec) errno_t {
100 var ts: timestamp_t = undefined;
101 const err = clock_time_get(@bitCast(u32, clock_id), 1, &ts);
102 if (err != 0) {
103 return err;
104 }
105 tp.* = .{
106 .tv_sec = @intCast(i64, ts / std.time.ns_per_s),
107 .tv_nsec = @intCast(isize, ts % std.time.ns_per_s),
108 };
109 return 0;
110}
111
112pub fn isatty(fd: fd_t) bool {
113 var statbuf: fdstat_t = undefined;
114 const err = fd_fdstat_get(fd, &statbuf);
115 if (err != 0) {
116 // errno = err;
117 return false;
118 }
119
120 // A tty is a character device that we can't seek or tell on.
121 if (statbuf.fs_filetype != FILETYPE_CHARACTER_DEVICE or
122 (statbuf.fs_rights_base & (RIGHT_FD_SEEK | RIGHT_FD_TELL)) != 0)
123 {
124 // errno = ENOTTY;
125 return false;
126 }
127
128 return true;
81pub fn getErrno(r: errno_t) usize {
82 return r;
12983}
lib/std/target.zig+5-1
......@@ -607,6 +607,10 @@ pub const Target = union(enum) {
607607 }
608608 }
609609
610 pub fn supportsNewStackCall(self: Target) bool {
611 return !self.isWasm();
612 }
613
610614 pub const Executor = union(enum) {
611615 native,
612616 qemu: []const u8,
......@@ -650,7 +654,7 @@ pub const Target = union(enum) {
650654 }
651655 }
652656
653 if (self.isWasm()) {
657 if (self.getOs() == .wasi) {
654658 switch (self.getArchPtrBitWidth()) {
655659 32 => return Executor{ .wasmtime = "wasmtime" },
656660 else => return .unavailable,
src/analyze.cpp+2-1
......@@ -978,7 +978,8 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
978978 if (g->zig_target->arch == ZigLLVM_x86 ||
979979 g->zig_target->arch == ZigLLVM_x86_64 ||
980980 target_is_arm(g->zig_target) ||
981 target_is_riscv(g->zig_target))
981 target_is_riscv(g->zig_target) ||
982 target_is_wasm(g->zig_target))
982983 {
983984 X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
984985 return abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval;
src/ir.cpp+8
......@@ -17095,6 +17095,14 @@ static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstructionCall
1709517095 if (call_instruction->new_stack == nullptr)
1709617096 return nullptr;
1709717097
17098 if (!call_instruction->is_async_call_builtin &&
17099 arch_stack_pointer_register_name(ira->codegen->zig_target->arch) == nullptr)
17100 {
17101 ir_add_error(ira, &call_instruction->base,
17102 buf_sprintf("target arch '%s' does not support @newStackCall",
17103 target_arch_name(ira->codegen->zig_target->arch)));
17104 }
17105
1709817106 IrInstruction *new_stack = call_instruction->new_stack->child;
1709917107 if (type_is_invalid(new_stack->value->type))
1710017108 return ira->codegen->invalid_instruction;
src/target.cpp+4-2
......@@ -1458,6 +1458,10 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
14581458 case ZigLLVM_mipsel:
14591459 return "sp";
14601460
1461 case ZigLLVM_wasm32:
1462 case ZigLLVM_wasm64:
1463 return nullptr; // known to be not available
1464
14611465 case ZigLLVM_amdgcn:
14621466 case ZigLLVM_amdil:
14631467 case ZigLLVM_amdil64:
......@@ -1491,8 +1495,6 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
14911495 case ZigLLVM_systemz:
14921496 case ZigLLVM_tce:
14931497 case ZigLLVM_tcele:
1494 case ZigLLVM_wasm32:
1495 case ZigLLVM_wasm64:
14961498 case ZigLLVM_xcore:
14971499 case ZigLLVM_ppc:
14981500 case ZigLLVM_ppc64:
test/compile_errors.zig+18-1
......@@ -2,6 +2,24 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.addCase(x: {
6 var tc = cases.create("@newStackCall on unsupported target",
7 \\export fn entry() void {
8 \\ var buf: [10]u8 align(16) = undefined;
9 \\ @newStackCall(&buf, foo);
10 \\}
11 \\fn foo() void {}
12 , "tmp.zig:3:5: error: target arch 'wasm32' does not support @newStackCall");
13 tc.target = tests.Target{
14 .Cross = tests.CrossTarget{
15 .arch = .wasm32,
16 .os = .wasi,
17 .abi = .none,
18 },
19 };
20 break :x tc;
21 });
22
523 cases.add(
624 "incompatible sentinels",
725 \\export fn entry1(ptr: [*:255]u8) [*:0]u8 {
......@@ -26,7 +44,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2644 "tmp.zig:8:35: note: destination array requires a terminating '0' sentinel, but source array has a terminating '255' sentinel",
2745 "tmp.zig:11:31: error: expected type '[2:0]u8', found '[2]u8'",
2846 "tmp.zig:11:31: note: destination array requires a terminating '0' sentinel",
29
3047 );
3148
3249 cases.add(
test/stage1/behavior/asm.zig+2-1
......@@ -1,5 +1,6 @@
1const std = @import("std");
12const config = @import("builtin");
2const expect = @import("std").testing.expect;
3const expect = std.testing.expect;
34
45comptime {
56 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
test/stage1/behavior/new_stack_call.zig+3
......@@ -12,6 +12,9 @@ test "calling a function with a new stack" {
1212 // TODO: https://github.com/ziglang/zig/issues/3338
1313 return error.SkipZigTest;
1414 }
15 if (comptime !std.Target.current.supportsNewStackCall()) {
16 return error.SkipZigTest;
17 }
1518
1619 const arg = 1234;
1720