move logic to the appropriate layers; add new compile error
parent
659c1bdeee
commit
4261fa3c49
|
@ -273,17 +273,17 @@ const WasmPageAllocator = struct {
|
||||||
if (new_end_index > num_pages * mem.page_size) {
|
if (new_end_index > num_pages * mem.page_size) {
|
||||||
const required_memory = new_end_index - (num_pages * mem.page_size);
|
const required_memory = new_end_index - (num_pages * mem.page_size);
|
||||||
|
|
||||||
var num_pages: usize = required_memory / mem.page_size;
|
var inner_num_pages: usize = required_memory / mem.page_size;
|
||||||
if (required_memory % mem.page_size != 0) {
|
if (required_memory % mem.page_size != 0) {
|
||||||
num_pages += 1;
|
inner_num_pages += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prev_page = @"llvm.wasm.memory.grow.i32"(0, @intCast(u32, num_pages));
|
const prev_page = @"llvm.wasm.memory.grow.i32"(0, @intCast(u32, inner_num_pages));
|
||||||
if (prev_page == -1) {
|
if (prev_page == -1) {
|
||||||
return error.OutOfMemory;
|
return error.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_pages += num_pages;
|
num_pages += inner_num_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = start_ptr[adjusted_index..new_end_index];
|
const result = start_ptr[adjusted_index..new_end_index];
|
||||||
|
|
|
@ -1527,7 +1527,22 @@ pub fn isatty(handle: fd_t) bool {
|
||||||
return system.isatty(handle) != 0;
|
return system.isatty(handle) != 0;
|
||||||
}
|
}
|
||||||
if (builtin.os == .wasi) {
|
if (builtin.os == .wasi) {
|
||||||
return system.isatty(handle);
|
var statbuf: fdstat_t = undefined;
|
||||||
|
const err = system.fd_fdstat_get(handle, &statbuf);
|
||||||
|
if (err != 0) {
|
||||||
|
// errno = err;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A tty is a character device that we can't seek or tell on.
|
||||||
|
if (statbuf.fs_filetype != FILETYPE_CHARACTER_DEVICE or
|
||||||
|
(statbuf.fs_rights_base & (RIGHT_FD_SEEK | RIGHT_FD_TELL)) != 0)
|
||||||
|
{
|
||||||
|
// errno = ENOTTY;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (builtin.os == .linux) {
|
if (builtin.os == .linux) {
|
||||||
var wsz: linux.winsize = undefined;
|
var wsz: linux.winsize = undefined;
|
||||||
|
@ -2720,6 +2735,20 @@ pub fn dl_iterate_phdr(
|
||||||
pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
|
pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
|
||||||
|
|
||||||
pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
|
pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
|
||||||
|
if (comptime std.Target.current.getOs() == .wasi) {
|
||||||
|
var ts: timestamp_t = undefined;
|
||||||
|
switch (system.clock_time_get(@bitCast(u32, clk_id), 1, &ts)) {
|
||||||
|
0 => {
|
||||||
|
tp.* = .{
|
||||||
|
.tv_sec = @intCast(i64, ts / std.time.ns_per_s),
|
||||||
|
.tv_nsec = @intCast(isize, ts % std.time.ns_per_s),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
EINVAL => return error.UnsupportedClock,
|
||||||
|
else => |err| return unexpectedErrno(err),
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (errno(system.clock_gettime(clk_id, tp))) {
|
switch (errno(system.clock_gettime(clk_id, tp))) {
|
||||||
0 => return,
|
0 => return,
|
||||||
EFAULT => unreachable,
|
EFAULT => unreachable,
|
||||||
|
@ -2729,6 +2758,19 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
|
pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
|
||||||
|
if (comptime std.Target.current.getOs() == .wasi) {
|
||||||
|
var ts: timestamp_t = undefined;
|
||||||
|
switch (system.clock_res_get(@bitCast(u32, clk_id), &ts)) {
|
||||||
|
0 => res.* = .{
|
||||||
|
.tv_sec = @intCast(i64, ts / std.time.ns_per_s),
|
||||||
|
.tv_nsec = @intCast(isize, ts % std.time.ns_per_s),
|
||||||
|
},
|
||||||
|
EINVAL => return error.UnsupportedClock,
|
||||||
|
else => |err| return unexpectedErrno(err),
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (errno(system.clock_getres(clk_id, res))) {
|
switch (errno(system.clock_getres(clk_id, res))) {
|
||||||
0 => return,
|
0 => return,
|
||||||
EFAULT => unreachable,
|
EFAULT => unreachable,
|
||||||
|
|
|
@ -78,52 +78,6 @@ pub extern "wasi_unstable" fn sock_send(sock: fd_t, si_data: *const ciovec_t, si
|
||||||
pub extern "wasi_unstable" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t;
|
pub extern "wasi_unstable" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t;
|
||||||
|
|
||||||
/// Get the errno from a syscall return value, or 0 for no error.
|
/// Get the errno from a syscall return value, or 0 for no error.
|
||||||
pub fn getErrno(r: usize) usize {
|
pub fn getErrno(r: errno_t) usize {
|
||||||
const signed_r = @bitCast(isize, r);
|
return r;
|
||||||
return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clock_getres(clock_id: i32, res: *timespec) errno_t {
|
|
||||||
var ts: timestamp_t = undefined;
|
|
||||||
const err = clock_res_get(@bitCast(u32, clock_id), &ts);
|
|
||||||
if (err != 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
res.* = .{
|
|
||||||
.tv_sec = @intCast(i64, ts / std.time.ns_per_s),
|
|
||||||
.tv_nsec = @intCast(isize, ts % std.time.ns_per_s),
|
|
||||||
};
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clock_gettime(clock_id: i32, tp: *timespec) errno_t {
|
|
||||||
var ts: timestamp_t = undefined;
|
|
||||||
const err = clock_time_get(@bitCast(u32, clock_id), 1, &ts);
|
|
||||||
if (err != 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
tp.* = .{
|
|
||||||
.tv_sec = @intCast(i64, ts / std.time.ns_per_s),
|
|
||||||
.tv_nsec = @intCast(isize, ts % std.time.ns_per_s),
|
|
||||||
};
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isatty(fd: fd_t) bool {
|
|
||||||
var statbuf: fdstat_t = undefined;
|
|
||||||
const err = fd_fdstat_get(fd, &statbuf);
|
|
||||||
if (err != 0) {
|
|
||||||
// errno = err;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A tty is a character device that we can't seek or tell on.
|
|
||||||
if (statbuf.fs_filetype != FILETYPE_CHARACTER_DEVICE or
|
|
||||||
(statbuf.fs_rights_base & (RIGHT_FD_SEEK | RIGHT_FD_TELL)) != 0)
|
|
||||||
{
|
|
||||||
// errno = ENOTTY;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -607,6 +607,10 @@ pub const Target = union(enum) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn supportsNewStackCall(self: Target) bool {
|
||||||
|
return !self.isWasm();
|
||||||
|
}
|
||||||
|
|
||||||
pub const Executor = union(enum) {
|
pub const Executor = union(enum) {
|
||||||
native,
|
native,
|
||||||
qemu: []const u8,
|
qemu: []const u8,
|
||||||
|
@ -650,7 +654,7 @@ pub const Target = union(enum) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.isWasm()) {
|
if (self.getOs() == .wasi) {
|
||||||
switch (self.getArchPtrBitWidth()) {
|
switch (self.getArchPtrBitWidth()) {
|
||||||
32 => return Executor{ .wasmtime = "wasmtime" },
|
32 => return Executor{ .wasmtime = "wasmtime" },
|
||||||
else => return .unavailable,
|
else => return .unavailable,
|
||||||
|
|
|
@ -978,7 +978,8 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
|
||||||
if (g->zig_target->arch == ZigLLVM_x86 ||
|
if (g->zig_target->arch == ZigLLVM_x86 ||
|
||||||
g->zig_target->arch == ZigLLVM_x86_64 ||
|
g->zig_target->arch == ZigLLVM_x86_64 ||
|
||||||
target_is_arm(g->zig_target) ||
|
target_is_arm(g->zig_target) ||
|
||||||
target_is_riscv(g->zig_target))
|
target_is_riscv(g->zig_target) ||
|
||||||
|
target_is_wasm(g->zig_target))
|
||||||
{
|
{
|
||||||
X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
|
X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
|
||||||
return abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval;
|
return abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval;
|
||||||
|
|
|
@ -17095,6 +17095,14 @@ static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstructionCall
|
||||||
if (call_instruction->new_stack == nullptr)
|
if (call_instruction->new_stack == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
if (!call_instruction->is_async_call_builtin &&
|
||||||
|
arch_stack_pointer_register_name(ira->codegen->zig_target->arch) == nullptr)
|
||||||
|
{
|
||||||
|
ir_add_error(ira, &call_instruction->base,
|
||||||
|
buf_sprintf("target arch '%s' does not support @newStackCall",
|
||||||
|
target_arch_name(ira->codegen->zig_target->arch)));
|
||||||
|
}
|
||||||
|
|
||||||
IrInstruction *new_stack = call_instruction->new_stack->child;
|
IrInstruction *new_stack = call_instruction->new_stack->child;
|
||||||
if (type_is_invalid(new_stack->value->type))
|
if (type_is_invalid(new_stack->value->type))
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
|
|
|
@ -1458,6 +1458,10 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
|
||||||
case ZigLLVM_mipsel:
|
case ZigLLVM_mipsel:
|
||||||
return "sp";
|
return "sp";
|
||||||
|
|
||||||
|
case ZigLLVM_wasm32:
|
||||||
|
case ZigLLVM_wasm64:
|
||||||
|
return nullptr; // known to be not available
|
||||||
|
|
||||||
case ZigLLVM_amdgcn:
|
case ZigLLVM_amdgcn:
|
||||||
case ZigLLVM_amdil:
|
case ZigLLVM_amdil:
|
||||||
case ZigLLVM_amdil64:
|
case ZigLLVM_amdil64:
|
||||||
|
@ -1491,8 +1495,6 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
|
||||||
case ZigLLVM_systemz:
|
case ZigLLVM_systemz:
|
||||||
case ZigLLVM_tce:
|
case ZigLLVM_tce:
|
||||||
case ZigLLVM_tcele:
|
case ZigLLVM_tcele:
|
||||||
case ZigLLVM_wasm32:
|
|
||||||
case ZigLLVM_wasm64:
|
|
||||||
case ZigLLVM_xcore:
|
case ZigLLVM_xcore:
|
||||||
case ZigLLVM_ppc:
|
case ZigLLVM_ppc:
|
||||||
case ZigLLVM_ppc64:
|
case ZigLLVM_ppc64:
|
||||||
|
|
|
@ -2,6 +2,24 @@ const tests = @import("tests.zig");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
|
cases.addCase(x: {
|
||||||
|
var tc = cases.create("@newStackCall on unsupported target",
|
||||||
|
\\export fn entry() void {
|
||||||
|
\\ var buf: [10]u8 align(16) = undefined;
|
||||||
|
\\ @newStackCall(&buf, foo);
|
||||||
|
\\}
|
||||||
|
\\fn foo() void {}
|
||||||
|
, "tmp.zig:3:5: error: target arch 'wasm32' does not support @newStackCall");
|
||||||
|
tc.target = tests.Target{
|
||||||
|
.Cross = tests.CrossTarget{
|
||||||
|
.arch = .wasm32,
|
||||||
|
.os = .wasi,
|
||||||
|
.abi = .none,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
break :x tc;
|
||||||
|
});
|
||||||
|
|
||||||
cases.add(
|
cases.add(
|
||||||
"incompatible sentinels",
|
"incompatible sentinels",
|
||||||
\\export fn entry1(ptr: [*:255]u8) [*:0]u8 {
|
\\export fn entry1(ptr: [*:255]u8) [*:0]u8 {
|
||||||
|
@ -26,7 +44,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
"tmp.zig:8:35: note: destination array requires a terminating '0' sentinel, but source array has a terminating '255' sentinel",
|
"tmp.zig:8:35: note: destination array requires a terminating '0' sentinel, but source array has a terminating '255' sentinel",
|
||||||
"tmp.zig:11:31: error: expected type '[2:0]u8', found '[2]u8'",
|
"tmp.zig:11:31: error: expected type '[2:0]u8', found '[2]u8'",
|
||||||
"tmp.zig:11:31: note: destination array requires a terminating '0' sentinel",
|
"tmp.zig:11:31: note: destination array requires a terminating '0' sentinel",
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
cases.add(
|
cases.add(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
const std = @import("std");
|
||||||
const config = @import("builtin");
|
const config = @import("builtin");
|
||||||
const expect = @import("std").testing.expect;
|
const expect = std.testing.expect;
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
|
if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
|
||||||
|
|
|
@ -12,6 +12,9 @@ test "calling a function with a new stack" {
|
||||||
// TODO: https://github.com/ziglang/zig/issues/3338
|
// TODO: https://github.com/ziglang/zig/issues/3338
|
||||||
return error.SkipZigTest;
|
return error.SkipZigTest;
|
||||||
}
|
}
|
||||||
|
if (comptime !std.Target.current.supportsNewStackCall()) {
|
||||||
|
return error.SkipZigTest;
|
||||||
|
}
|
||||||
|
|
||||||
const arg = 1234;
|
const arg = 1234;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue