| author | |
| committer | |
| log | 80f79cc9e8ed02f631c9d59f68e5f20a909e85fc |
| tree | ba8da3ef0611a547fe67c61ed2d42d4ea67e6d2e |
| parent | cb38bd0a1436bd18de8ed57c45ffc890c8ddfb78 |
| parent | 4261fa3c49be715355c9623102bad0bf93d537a3 |
| signature |
closes #373013 files changed, 205 insertions(+), 106 deletions(-)
lib/std/build.zig+8| ... | ... | @@ -1064,6 +1064,9 @@ pub const LibExeObjStep = struct { |
| 1064 | 1064 | /// Uses system QEMU installation to run cross compiled foreign architecture build artifacts. |
| 1065 | 1065 | enable_qemu: bool = false, |
| 1066 | 1066 | |
| 1067 | /// Uses system Wasmtime installation to run cross compiled wasm/wasi build artifacts. | |
| 1068 | enable_wasmtime: bool = false, | |
| 1069 | ||
| 1067 | 1070 | /// After following the steps in https://github.com/ziglang/zig/wiki/Updating-libc#glibc, |
| 1068 | 1071 | /// this will be the directory $glibc-build-dir/install/glibcs |
| 1069 | 1072 | /// Given the example of the aarch64 target, this is the directory |
| ... | ... | @@ -1863,6 +1866,11 @@ pub const LibExeObjStep = struct { |
| 1863 | 1866 | try zig_args.append(bin_name); |
| 1864 | 1867 | try zig_args.append("--test-cmd-bin"); |
| 1865 | 1868 | }, |
| 1869 | .wasmtime => |bin_name| if (self.enable_wasmtime) { | |
| 1870 | try zig_args.append("--test-cmd"); | |
| 1871 | try zig_args.append(bin_name); | |
| 1872 | try zig_args.append("--test-cmd-bin"); | |
| 1873 | }, | |
| 1866 | 1874 | } |
| 1867 | 1875 | for (self.packages.toSliceConst()) |pkg| { |
| 1868 | 1876 | zig_args.append("--pkg-begin") catch unreachable; |
lib/std/debug.zig+2-1| ... | ... | @@ -213,7 +213,8 @@ pub fn assert(ok: bool) void { |
| 213 | 213 | |
| 214 | 214 | pub fn panic(comptime format: []const u8, args: ...) noreturn { |
| 215 | 215 | @setCold(true); |
| 216 | const first_trace_addr = @returnAddress(); | |
| 216 | // TODO: remove conditional once wasi / LLVM defines __builtin_return_address | |
| 217 | const first_trace_addr = if (builtin.os == .wasi) null else @returnAddress(); | |
| 217 | 218 | panicExtra(null, first_trace_addr, format, args); |
| 218 | 219 | } |
| 219 | 220 |
lib/std/heap.zig+91-98| ... | ... | @@ -33,11 +33,19 @@ fn cShrink(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new |
| 33 | 33 | |
| 34 | 34 | /// This allocator makes a syscall directly for every allocation and free. |
| 35 | 35 | /// Thread-safe and lock-free. |
| 36 | pub const page_allocator = &page_allocator_state; | |
| 36 | pub const page_allocator = if (std.Target.current.isWasm()) | |
| 37 | &wasm_page_allocator_state | |
| 38 | else | |
| 39 | &page_allocator_state; | |
| 40 | ||
| 37 | 41 | var page_allocator_state = Allocator{ |
| 38 | 42 | .reallocFn = PageAllocator.realloc, |
| 39 | 43 | .shrinkFn = PageAllocator.shrink, |
| 40 | 44 | }; |
| 45 | var wasm_page_allocator_state = Allocator{ | |
| 46 | .reallocFn = WasmPageAllocator.realloc, | |
| 47 | .shrinkFn = WasmPageAllocator.shrink, | |
| 48 | }; | |
| 41 | 49 | |
| 42 | 50 | /// Deprecated. Use `page_allocator`. |
| 43 | 51 | pub const direct_allocator = page_allocator; |
| ... | ... | @@ -238,6 +246,88 @@ const PageAllocator = struct { |
| 238 | 246 | } |
| 239 | 247 | }; |
| 240 | 248 | |
| 249 | // TODO Exposed LLVM intrinsics is a bug | |
| 250 | // See: https://github.com/ziglang/zig/issues/2291 | |
| 251 | extern fn @"llvm.wasm.memory.size.i32"(u32) u32; | |
| 252 | extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32; | |
| 253 | ||
| 254 | /// TODO: make this re-use freed pages, and cooperate with other callers of these global intrinsics | |
| 255 | /// by better utilizing the return value of grow() | |
| 256 | const WasmPageAllocator = struct { | |
| 257 | var start_ptr: [*]u8 = undefined; | |
| 258 | var num_pages: usize = 0; | |
| 259 | var end_index: usize = 0; | |
| 260 | ||
| 261 | comptime { | |
| 262 | if (builtin.arch != .wasm32) { | |
| 263 | @compileError("WasmPageAllocator is only available for wasm32 arch"); | |
| 264 | } | |
| 265 | } | |
| 266 | ||
| 267 | fn alloc(allocator: *Allocator, size: usize, alignment: u29) ![]u8 { | |
| 268 | const addr = @ptrToInt(start_ptr) + end_index; | |
| 269 | const adjusted_addr = mem.alignForward(addr, alignment); | |
| 270 | const adjusted_index = end_index + (adjusted_addr - addr); | |
| 271 | const new_end_index = adjusted_index + size; | |
| 272 | ||
| 273 | if (new_end_index > num_pages * mem.page_size) { | |
| 274 | const required_memory = new_end_index - (num_pages * mem.page_size); | |
| 275 | ||
| 276 | var inner_num_pages: usize = required_memory / mem.page_size; | |
| 277 | if (required_memory % mem.page_size != 0) { | |
| 278 | inner_num_pages += 1; | |
| 279 | } | |
| 280 | ||
| 281 | const prev_page = @"llvm.wasm.memory.grow.i32"(0, @intCast(u32, inner_num_pages)); | |
| 282 | if (prev_page == -1) { | |
| 283 | return error.OutOfMemory; | |
| 284 | } | |
| 285 | ||
| 286 | num_pages += inner_num_pages; | |
| 287 | } | |
| 288 | ||
| 289 | const result = start_ptr[adjusted_index..new_end_index]; | |
| 290 | end_index = new_end_index; | |
| 291 | ||
| 292 | return result; | |
| 293 | } | |
| 294 | ||
| 295 | // Check if memory is the last "item" and is aligned correctly | |
| 296 | fn is_last_item(memory: []u8, alignment: u29) bool { | |
| 297 | return memory.ptr == start_ptr + end_index - memory.len and mem.alignForward(@ptrToInt(memory.ptr), alignment) == @ptrToInt(memory.ptr); | |
| 298 | } | |
| 299 | ||
| 300 | fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 { | |
| 301 | // Initialize start_ptr at the first realloc | |
| 302 | if (num_pages == 0) { | |
| 303 | start_ptr = @intToPtr([*]u8, @intCast(usize, @"llvm.wasm.memory.size.i32"(0)) * mem.page_size); | |
| 304 | } | |
| 305 | ||
| 306 | if (is_last_item(old_mem, new_align)) { | |
| 307 | const start_index = end_index - old_mem.len; | |
| 308 | const new_end_index = start_index + new_size; | |
| 309 | ||
| 310 | if (new_end_index > num_pages * mem.page_size) { | |
| 311 | _ = try alloc(allocator, new_end_index - end_index, new_align); | |
| 312 | } | |
| 313 | const result = start_ptr[start_index..new_end_index]; | |
| 314 | ||
| 315 | end_index = new_end_index; | |
| 316 | return result; | |
| 317 | } else if (new_size <= old_mem.len and new_align <= old_align) { | |
| 318 | return error.OutOfMemory; | |
| 319 | } else { | |
| 320 | const result = try alloc(allocator, new_size, new_align); | |
| 321 | mem.copy(u8, result, old_mem); | |
| 322 | return result; | |
| 323 | } | |
| 324 | } | |
| 325 | ||
| 326 | fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 { | |
| 327 | return old_mem[0..new_size]; | |
| 328 | } | |
| 329 | }; | |
| 330 | ||
| 241 | 331 | pub const HeapAllocator = switch (builtin.os) { |
| 242 | 332 | .windows => struct { |
| 243 | 333 | allocator: Allocator, |
| ... | ... | @@ -487,103 +577,6 @@ pub const FixedBufferAllocator = struct { |
| 487 | 577 | } |
| 488 | 578 | }; |
| 489 | 579 | |
| 490 | // TODO Exposed LLVM intrinsics is a bug | |
| 491 | // See: https://github.com/ziglang/zig/issues/2291 | |
| 492 | extern fn @"llvm.wasm.memory.size.i32"(u32) u32; | |
| 493 | extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32; | |
| 494 | ||
| 495 | pub const wasm_allocator = &wasm_allocator_state.allocator; | |
| 496 | var wasm_allocator_state = WasmAllocator{ | |
| 497 | .allocator = Allocator{ | |
| 498 | .reallocFn = WasmAllocator.realloc, | |
| 499 | .shrinkFn = WasmAllocator.shrink, | |
| 500 | }, | |
| 501 | .start_ptr = undefined, | |
| 502 | .num_pages = 0, | |
| 503 | .end_index = 0, | |
| 504 | }; | |
| 505 | ||
| 506 | const WasmAllocator = struct { | |
| 507 | allocator: Allocator, | |
| 508 | start_ptr: [*]u8, | |
| 509 | num_pages: usize, | |
| 510 | end_index: usize, | |
| 511 | ||
| 512 | comptime { | |
| 513 | if (builtin.arch != .wasm32) { | |
| 514 | @compileError("WasmAllocator is only available for wasm32 arch"); | |
| 515 | } | |
| 516 | } | |
| 517 | ||
| 518 | fn alloc(allocator: *Allocator, size: usize, alignment: u29) ![]u8 { | |
| 519 | const self = @fieldParentPtr(WasmAllocator, "allocator", allocator); | |
| 520 | ||
| 521 | const addr = @ptrToInt(self.start_ptr) + self.end_index; | |
| 522 | const adjusted_addr = mem.alignForward(addr, alignment); | |
| 523 | const adjusted_index = self.end_index + (adjusted_addr - addr); | |
| 524 | const new_end_index = adjusted_index + size; | |
| 525 | ||
| 526 | if (new_end_index > self.num_pages * mem.page_size) { | |
| 527 | const required_memory = new_end_index - (self.num_pages * mem.page_size); | |
| 528 | ||
| 529 | var num_pages: usize = required_memory / mem.page_size; | |
| 530 | if (required_memory % mem.page_size != 0) { | |
| 531 | num_pages += 1; | |
| 532 | } | |
| 533 | ||
| 534 | const prev_page = @"llvm.wasm.memory.grow.i32"(0, @intCast(u32, num_pages)); | |
| 535 | if (prev_page == -1) { | |
| 536 | return error.OutOfMemory; | |
| 537 | } | |
| 538 | ||
| 539 | self.num_pages += num_pages; | |
| 540 | } | |
| 541 | ||
| 542 | const result = self.start_ptr[adjusted_index..new_end_index]; | |
| 543 | self.end_index = new_end_index; | |
| 544 | ||
| 545 | return result; | |
| 546 | } | |
| 547 | ||
| 548 | // Check if memory is the last "item" and is aligned correctly | |
| 549 | fn is_last_item(allocator: *Allocator, memory: []u8, alignment: u29) bool { | |
| 550 | const self = @fieldParentPtr(WasmAllocator, "allocator", allocator); | |
| 551 | return memory.ptr == self.start_ptr + self.end_index - memory.len and mem.alignForward(@ptrToInt(memory.ptr), alignment) == @ptrToInt(memory.ptr); | |
| 552 | } | |
| 553 | ||
| 554 | fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 { | |
| 555 | const self = @fieldParentPtr(WasmAllocator, "allocator", allocator); | |
| 556 | ||
| 557 | // Initialize start_ptr at the first realloc | |
| 558 | if (self.num_pages == 0) { | |
| 559 | self.start_ptr = @intToPtr([*]u8, @intCast(usize, @"llvm.wasm.memory.size.i32"(0)) * mem.page_size); | |
| 560 | } | |
| 561 | ||
| 562 | if (is_last_item(allocator, old_mem, new_align)) { | |
| 563 | const start_index = self.end_index - old_mem.len; | |
| 564 | const new_end_index = start_index + new_size; | |
| 565 | ||
| 566 | if (new_end_index > self.num_pages * mem.page_size) { | |
| 567 | _ = try alloc(allocator, new_end_index - self.end_index, new_align); | |
| 568 | } | |
| 569 | const result = self.start_ptr[start_index..new_end_index]; | |
| 570 | ||
| 571 | self.end_index = new_end_index; | |
| 572 | return result; | |
| 573 | } else if (new_size <= old_mem.len and new_align <= old_align) { | |
| 574 | return error.OutOfMemory; | |
| 575 | } else { | |
| 576 | const result = try alloc(allocator, new_size, new_align); | |
| 577 | mem.copy(u8, result, old_mem); | |
| 578 | return result; | |
| 579 | } | |
| 580 | } | |
| 581 | ||
| 582 | fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 { | |
| 583 | return old_mem[0..new_size]; | |
| 584 | } | |
| 585 | }; | |
| 586 | ||
| 587 | 580 | pub const ThreadSafeFixedBufferAllocator = blk: { |
| 588 | 581 | if (builtin.single_threaded) { |
| 589 | 582 | break :blk FixedBufferAllocator; |
lib/std/os.zig+43-1| ... | ... | @@ -1527,7 +1527,22 @@ pub fn isatty(handle: fd_t) bool { |
| 1527 | 1527 | return system.isatty(handle) != 0; |
| 1528 | 1528 | } |
| 1529 | 1529 | if (builtin.os == .wasi) { |
| 1530 | @compileError("TODO implement std.os.isatty for WASI"); | |
| 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 | 1547 | if (builtin.os == .linux) { |
| 1533 | 1548 | var wsz: linux.winsize = undefined; |
| ... | ... | @@ -2720,6 +2735,20 @@ pub fn dl_iterate_phdr( |
| 2720 | 2735 | pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError; |
| 2721 | 2736 | |
| 2722 | 2737 | pub 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 | 2752 | switch (errno(system.clock_gettime(clk_id, tp))) { |
| 2724 | 2753 | 0 => return, |
| 2725 | 2754 | EFAULT => unreachable, |
| ... | ... | @@ -2729,6 +2758,19 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void { |
| 2729 | 2758 | } |
| 2730 | 2759 | |
| 2731 | 2760 | pub 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 | 2774 | switch (errno(system.clock_getres(clk_id, res))) { |
| 2733 | 2775 | 0 => return, |
| 2734 | 2776 | EFAULT => unreachable, |
lib/std/os/bits/wasi.zig+7-1| ... | ... | @@ -138,7 +138,7 @@ pub const FDFLAG_NONBLOCK: fdflags_t = 0x0004; |
| 138 | 138 | pub const FDFLAG_RSYNC: fdflags_t = 0x0008; |
| 139 | 139 | pub const FDFLAG_SYNC: fdflags_t = 0x0010; |
| 140 | 140 | |
| 141 | const fdstat_t = extern struct { | |
| 141 | pub const fdstat_t = extern struct { | |
| 142 | 142 | fs_filetype: filetype_t, |
| 143 | 143 | fs_flags: fdflags_t, |
| 144 | 144 | fs_rights_base: rights_t, |
| ... | ... | @@ -298,6 +298,7 @@ pub const subscription_t = extern struct { |
| 298 | 298 | }; |
| 299 | 299 | |
| 300 | 300 | pub const timestamp_t = u64; |
| 301 | pub const time_t = i64; // match https://github.com/CraneStation/wasi-libc | |
| 301 | 302 | |
| 302 | 303 | pub const userdata_t = u64; |
| 303 | 304 | |
| ... | ... | @@ -305,3 +306,8 @@ pub const whence_t = u8; |
| 305 | 306 | pub const WHENCE_CUR: whence_t = 0; |
| 306 | 307 | pub const WHENCE_END: whence_t = 1; |
| 307 | 308 | pub const WHENCE_SET: whence_t = 2; |
| 309 | ||
| 310 | pub const timespec = extern struct { | |
| 311 | tv_sec: time_t, | |
| 312 | tv_nsec: isize, | |
| 313 | }; |
lib/std/os/wasi.zig+5| ... | ... | @@ -76,3 +76,8 @@ pub extern "wasi_unstable" fn sched_yield() errno_t; |
| 76 | 76 | pub extern "wasi_unstable" fn sock_recv(sock: fd_t, ri_data: *const iovec_t, ri_data_len: usize, ri_flags: riflags_t, ro_datalen: *usize, ro_flags: *roflags_t) errno_t; |
| 77 | 77 | pub extern "wasi_unstable" fn sock_send(sock: fd_t, si_data: *const ciovec_t, si_data_len: usize, si_flags: siflags_t, so_datalen: *usize) errno_t; |
| 78 | 78 | pub extern "wasi_unstable" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t; |
| 79 | ||
| 80 | /// Get the errno from a syscall return value, or 0 for no error. | |
| 81 | pub fn getErrno(r: errno_t) usize { | |
| 82 | return r; | |
| 83 | } |
lib/std/target.zig+12| ... | ... | @@ -607,10 +607,15 @@ pub const Target = union(enum) { |
| 607 | 607 | } |
| 608 | 608 | } |
| 609 | 609 | |
| 610 | pub fn supportsNewStackCall(self: Target) bool { | |
| 611 | return !self.isWasm(); | |
| 612 | } | |
| 613 | ||
| 610 | 614 | pub const Executor = union(enum) { |
| 611 | 615 | native, |
| 612 | 616 | qemu: []const u8, |
| 613 | 617 | wine: []const u8, |
| 618 | wasmtime: []const u8, | |
| 614 | 619 | unavailable, |
| 615 | 620 | }; |
| 616 | 621 | |
| ... | ... | @@ -649,6 +654,13 @@ pub const Target = union(enum) { |
| 649 | 654 | } |
| 650 | 655 | } |
| 651 | 656 | |
| 657 | if (self.getOs() == .wasi) { | |
| 658 | switch (self.getArchPtrBitWidth()) { | |
| 659 | 32 => return Executor{ .wasmtime = "wasmtime" }, | |
| 660 | else => return .unavailable, | |
| 661 | } | |
| 662 | } | |
| 663 | ||
| 652 | 664 | return .unavailable; |
| 653 | 665 | } |
| 654 | 666 | }; |
src/analyze.cpp+2-1| ... | ... | @@ -978,7 +978,8 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) { |
| 978 | 978 | if (g->zig_target->arch == ZigLLVM_x86 || |
| 979 | 979 | g->zig_target->arch == ZigLLVM_x86_64 || |
| 980 | 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 | 984 | X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type); |
| 984 | 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 | 17095 | if (call_instruction->new_stack == nullptr) |
| 17096 | 17096 | return nullptr; |
| 17097 | 17097 | |
| 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 | 17106 | IrInstruction *new_stack = call_instruction->new_stack->child; |
| 17099 | 17107 | if (type_is_invalid(new_stack->value->type)) |
| 17100 | 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 | 1458 | case ZigLLVM_mipsel: |
| 1459 | 1459 | return "sp"; |
| 1460 | 1460 | |
| 1461 | case ZigLLVM_wasm32: | |
| 1462 | case ZigLLVM_wasm64: | |
| 1463 | return nullptr; // known to be not available | |
| 1464 | ||
| 1461 | 1465 | case ZigLLVM_amdgcn: |
| 1462 | 1466 | case ZigLLVM_amdil: |
| 1463 | 1467 | case ZigLLVM_amdil64: |
| ... | ... | @@ -1491,8 +1495,6 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) { |
| 1491 | 1495 | case ZigLLVM_systemz: |
| 1492 | 1496 | case ZigLLVM_tce: |
| 1493 | 1497 | case ZigLLVM_tcele: |
| 1494 | case ZigLLVM_wasm32: | |
| 1495 | case ZigLLVM_wasm64: | |
| 1496 | 1498 | case ZigLLVM_xcore: |
| 1497 | 1499 | case ZigLLVM_ppc: |
| 1498 | 1500 | case ZigLLVM_ppc64: |
test/compile_errors.zig+18-1| ... | ... | @@ -2,6 +2,24 @@ const tests = @import("tests.zig"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | |
| 4 | 4 | pub 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 | 23 | cases.add( |
| 6 | 24 | "incompatible sentinels", |
| 7 | 25 | \\export fn entry1(ptr: [*:255]u8) [*:0]u8 { |
| ... | ... | @@ -26,7 +44,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 26 | 44 | "tmp.zig:8:35: note: destination array requires a terminating '0' sentinel, but source array has a terminating '255' sentinel", |
| 27 | 45 | "tmp.zig:11:31: error: expected type '[2:0]u8', found '[2]u8'", |
| 28 | 46 | "tmp.zig:11:31: note: destination array requires a terminating '0' sentinel", |
| 29 | ||
| 30 | 47 | ); |
| 31 | 48 | |
| 32 | 49 | cases.add( |
test/stage1/behavior/asm.zig+2-1| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | const std = @import("std"); | |
| 1 | 2 | const config = @import("builtin"); |
| 2 | const expect = @import("std").testing.expect; | |
| 3 | const expect = std.testing.expect; | |
| 3 | 4 | |
| 4 | 5 | comptime { |
| 5 | 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 | 12 | // TODO: https://github.com/ziglang/zig/issues/3338 |
| 13 | 13 | return error.SkipZigTest; |
| 14 | 14 | } |
| 15 | if (comptime !std.Target.current.supportsNewStackCall()) { | |
| 16 | return error.SkipZigTest; | |
| 17 | } | |
| 15 | 18 | |
| 16 | 19 | const arg = 1234; |
| 17 | 20 |