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 {...@@ -273,17 +273,17 @@ const WasmPageAllocator = struct {
273 if (new_end_index > num_pages * mem.page_size) {273 if (new_end_index > num_pages * mem.page_size) {
274 const required_memory = new_end_index - (num_pages * mem.page_size);274 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;
277 if (required_memory % mem.page_size != 0) {277 if (required_memory % mem.page_size != 0) {
278 num_pages += 1;278 inner_num_pages += 1;
279 }279 }
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));
282 if (prev_page == -1) {282 if (prev_page == -1) {
283 return error.OutOfMemory;283 return error.OutOfMemory;
284 }284 }
285285
286 num_pages += num_pages;286 num_pages += inner_num_pages;
287 }287 }
288288
289 const result = start_ptr[adjusted_index..new_end_index];289 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 {...@@ -1527,7 +1527,22 @@ pub fn isatty(handle: fd_t) bool {
1527 return system.isatty(handle) != 0;1527 return system.isatty(handle) != 0;
1528 }1528 }
1529 if (builtin.os == .wasi) {1529 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;
1531 }1546 }
1532 if (builtin.os == .linux) {1547 if (builtin.os == .linux) {
1533 var wsz: linux.winsize = undefined;1548 var wsz: linux.winsize = undefined;
...@@ -2720,6 +2735,20 @@ pub fn dl_iterate_phdr(...@@ -2720,6 +2735,20 @@ pub fn dl_iterate_phdr(
2720pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;2735pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
27212736
2722pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {2737pub 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 }
2723 switch (errno(system.clock_gettime(clk_id, tp))) {2752 switch (errno(system.clock_gettime(clk_id, tp))) {
2724 0 => return,2753 0 => return,
2725 EFAULT => unreachable,2754 EFAULT => unreachable,
...@@ -2729,6 +2758,19 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {...@@ -2729,6 +2758,19 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
2729}2758}
27302759
2731pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {2760pub 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
2732 switch (errno(system.clock_getres(clk_id, res))) {2774 switch (errno(system.clock_getres(clk_id, res))) {
2733 0 => return,2775 0 => return,
2734 EFAULT => unreachable,2776 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...@@ -78,52 +78,6 @@ pub extern "wasi_unstable" fn sock_send(sock: fd_t, si_data: *const ciovec_t, si
78pub extern "wasi_unstable" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t;78pub extern "wasi_unstable" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t;
7979
80/// Get the errno from a syscall return value, or 0 for no error.80/// Get the errno from a syscall return value, or 0 for no error.
81pub fn getErrno(r: usize) usize {81pub fn getErrno(r: errno_t) usize {
82 const signed_r = @bitCast(isize, r);82 return 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;
129}83}
lib/std/target.zig+5-1
...@@ -607,6 +607,10 @@ pub const Target = union(enum) {...@@ -607,6 +607,10 @@ pub const Target = union(enum) {
607 }607 }
608 }608 }
609609
610 pub fn supportsNewStackCall(self: Target) bool {
611 return !self.isWasm();
612 }
613
610 pub const Executor = union(enum) {614 pub const Executor = union(enum) {
611 native,615 native,
612 qemu: []const u8,616 qemu: []const u8,
...@@ -650,7 +654,7 @@ pub const Target = union(enum) {...@@ -650,7 +654,7 @@ pub const Target = union(enum) {
650 }654 }
651 }655 }
652656
653 if (self.isWasm()) {657 if (self.getOs() == .wasi) {
654 switch (self.getArchPtrBitWidth()) {658 switch (self.getArchPtrBitWidth()) {
655 32 => return Executor{ .wasmtime = "wasmtime" },659 32 => return Executor{ .wasmtime = "wasmtime" },
656 else => return .unavailable,660 else => return .unavailable,
src/analyze.cpp+2-1
...@@ -978,7 +978,8 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {...@@ -978,7 +978,8 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
978 if (g->zig_target->arch == ZigLLVM_x86 ||978 if (g->zig_target->arch == ZigLLVM_x86 ||
979 g->zig_target->arch == ZigLLVM_x86_64 ||979 g->zig_target->arch == ZigLLVM_x86_64 ||
980 target_is_arm(g->zig_target) ||980 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))
982 {983 {
983 X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);984 X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
984 return abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval;985 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...@@ -17095,6 +17095,14 @@ static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstructionCall
17095 if (call_instruction->new_stack == nullptr)17095 if (call_instruction->new_stack == nullptr)
17096 return nullptr;17096 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
17098 IrInstruction *new_stack = call_instruction->new_stack->child;17106 IrInstruction *new_stack = call_instruction->new_stack->child;
17099 if (type_is_invalid(new_stack->value->type))17107 if (type_is_invalid(new_stack->value->type))
17100 return ira->codegen->invalid_instruction;17108 return ira->codegen->invalid_instruction;
src/target.cpp+4-2
...@@ -1458,6 +1458,10 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {...@@ -1458,6 +1458,10 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
1458 case ZigLLVM_mipsel:1458 case ZigLLVM_mipsel:
1459 return "sp";1459 return "sp";
14601460
1461 case ZigLLVM_wasm32:
1462 case ZigLLVM_wasm64:
1463 return nullptr; // known to be not available
1464
1461 case ZigLLVM_amdgcn:1465 case ZigLLVM_amdgcn:
1462 case ZigLLVM_amdil:1466 case ZigLLVM_amdil:
1463 case ZigLLVM_amdil64:1467 case ZigLLVM_amdil64:
...@@ -1491,8 +1495,6 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {...@@ -1491,8 +1495,6 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
1491 case ZigLLVM_systemz:1495 case ZigLLVM_systemz:
1492 case ZigLLVM_tce:1496 case ZigLLVM_tce:
1493 case ZigLLVM_tcele:1497 case ZigLLVM_tcele:
1494 case ZigLLVM_wasm32:
1495 case ZigLLVM_wasm64:
1496 case ZigLLVM_xcore:1498 case ZigLLVM_xcore:
1497 case ZigLLVM_ppc:1499 case ZigLLVM_ppc:
1498 case ZigLLVM_ppc64:1500 case ZigLLVM_ppc64:
test/compile_errors.zig+18-1
...@@ -2,6 +2,24 @@ const tests = @import("tests.zig");...@@ -2,6 +2,24 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub 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
5 cases.add(23 cases.add(
6 "incompatible sentinels",24 "incompatible sentinels",
7 \\export fn entry1(ptr: [*:255]u8) [*:0]u8 {25 \\export fn entry1(ptr: [*:255]u8) [*:0]u8 {
...@@ -26,7 +44,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -26,7 +44,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
26 "tmp.zig:8:35: note: destination array requires a terminating '0' sentinel, but source array has a terminating '255' sentinel",44 "tmp.zig:8:35: note: destination array requires a terminating '0' sentinel, but source array has a terminating '255' sentinel",
27 "tmp.zig:11:31: error: expected type '[2:0]u8', found '[2]u8'",45 "tmp.zig:11:31: error: expected type '[2:0]u8', found '[2]u8'",
28 "tmp.zig:11:31: note: destination array requires a terminating '0' sentinel",46 "tmp.zig:11:31: note: destination array requires a terminating '0' sentinel",
29
30 );47 );
3148
32 cases.add(49 cases.add(
test/stage1/behavior/asm.zig+2-1
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("std");
1const config = @import("builtin");2const config = @import("builtin");
2const expect = @import("std").testing.expect;3const expect = std.testing.expect;
34
4comptime {5comptime {
5 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {6 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" {...@@ -12,6 +12,9 @@ test "calling a function with a new stack" {
12 // TODO: https://github.com/ziglang/zig/issues/333812 // TODO: https://github.com/ziglang/zig/issues/3338
13 return error.SkipZigTest;13 return error.SkipZigTest;
14 }14 }
15 if (comptime !std.Target.current.supportsNewStackCall()) {
16 return error.SkipZigTest;
17 }
1518
16 const arg = 1234;19 const arg = 1234;
1720