Skip to content

Introduce callconv annotation #3977

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/docgen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
.Keyword_resume,
.Keyword_return,
.Keyword_linksection,
.Keyword_callconv,
.Keyword_stdcallcc,
.Keyword_struct,
.Keyword_suspend,
Expand Down
2 changes: 1 addition & 1 deletion doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -2829,7 +2829,7 @@ test "@tagName" {
<p>
By default, enums are not guaranteed to be compatible with the C ABI:
</p>
{#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'ccc'#}
{#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#}
const Foo = enum { A, B, C };
export fn entry(foo: Foo) void { }
{#code_end#}
Expand Down
32 changes: 20 additions & 12 deletions lib/std/builtin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,25 @@ pub const Mode = enum {
ReleaseSmall,
};

/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const CallingConvention = enum {
Unspecified,
C,
Cold,
Naked,
Async,
Interrupt,
Signal,
Stdcall,
Fastcall,
Vectorcall,
Thiscall,
APCS,
AAPCS,
AAPCSVFP,
};

pub const TypeId = @TagType(TypeInfo);

/// This data structure is used by the Zig language code generation and
Expand Down Expand Up @@ -253,17 +272,6 @@ pub const TypeInfo = union(enum) {
decls: []Declaration,
};

/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const CallingConvention = enum {
Unspecified,
C,
Cold,
Naked,
Stdcall,
Async,
};

/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const FnArg = struct {
Expand Down Expand Up @@ -416,7 +424,7 @@ pub const CallOptions = struct {
/// therefore must be kept in sync with the compiler implementation.
pub const TestFn = struct {
name: []const u8,
func: fn()anyerror!void,
func: fn () anyerror!void,
};

/// This function type is used by the Zig language code generation and
Expand Down
2 changes: 1 addition & 1 deletion lib/std/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2475,7 +2475,7 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con
os.abort();
}

stdcallcc fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) c_long {
fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(.Stdcall) c_long {
const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress);
switch (info.ExceptionRecord.ExceptionCode) {
windows.EXCEPTION_DATATYPE_MISALIGNMENT => panicExtra(null, exception_address, "Unaligned Memory Access", .{}),
Expand Down
2 changes: 1 addition & 1 deletion lib/std/fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ pub const AtomicFile = struct {
b64_fs_encoder.encode(tmp_path_slice[dirname_component_len..tmp_path_len], &rand_buf);

const file = my_cwd.createFileC(
tmp_path_slice,
tmp_path_slice,
.{ .mode = mode, .exclusive = true },
) catch |err| switch (err) {
error.PathAlreadyExists => continue,
Expand Down
27 changes: 14 additions & 13 deletions lib/std/mutex.zig
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ pub const Mutex = if (builtin.single_threaded)
return self.tryAcquire() orelse @panic("deadlock detected");
}
}
else if (builtin.os == .windows)
// https://locklessinc.com/articles/keyed_events/
else if (builtin.os == .windows)
// https://locklessinc.com/articles/keyed_events/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right to me. Created #3978

extern union {
locked: u8,
waiters: u32,
Expand Down Expand Up @@ -97,8 +97,8 @@ else if (builtin.os == .windows)
return Held{ .mutex = self };
}

// otherwise, try and update the waiting count.
// then unset the WAKE bit so that another unlocker can wake up a thread.
// otherwise, try and update the waiting count.
// then unset the WAKE bit so that another unlocker can wake up a thread.
} else if (@cmpxchgWeak(u32, &self.waiters, waiters, (waiters + WAIT) | 1, .Monotonic, .Monotonic) == null) {
const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
assert(rc == 0);
Expand All @@ -118,7 +118,7 @@ else if (builtin.os == .windows)

while (true) : (SpinLock.loopHint(1)) {
const waiters = @atomicLoad(u32, &self.mutex.waiters, .Monotonic);

// no one is waiting
if (waiters < WAIT) return;
// someone grabbed the lock and will do the wake instead
Expand All @@ -130,14 +130,14 @@ else if (builtin.os == .windows)
if (@cmpxchgWeak(u32, &self.mutex.waiters, waiters, waiters - WAIT + WAKE, .Release, .Monotonic) == null) {
const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
assert(rc == 0);
return;
return;
}
}
}
};
}
else if (builtin.link_libc or builtin.os == .linux)
// stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs
// stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs
struct {
state: usize,

Expand Down Expand Up @@ -170,8 +170,8 @@ else if (builtin.link_libc or builtin.os == .linux)

pub fn acquire(self: *Mutex) Held {
return self.tryAcquire() orelse {
self.acquireSlow();
return Held{ .mutex = self };
self.acquireSlow();
return Held{ .mutex = self };
};
}

Expand Down Expand Up @@ -237,7 +237,7 @@ else if (builtin.link_libc or builtin.os == .linux)

fn releaseSlow(self: *Mutex) void {
@setCold(true);

// try and lock the LFIO queue to pop a node off,
// stopping altogether if its already locked or the queue is empty
var state = @atomicLoad(usize, &self.state, .Monotonic);
Expand Down Expand Up @@ -265,9 +265,10 @@ else if (builtin.link_libc or builtin.os == .linux)
}
}

// for platforms without a known OS blocking
// primitive, default to SpinLock for correctness
else SpinLock;
// for platforms without a known OS blocking
// primitive, default to SpinLock for correctness
else
SpinLock;

const TestContext = struct {
mutex: *Mutex,
Expand Down
6 changes: 1 addition & 5 deletions lib/std/net.zig
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
.next = null,
};
var res: *os.addrinfo = undefined;
switch (os.system.getaddrinfo(
name_c.ptr,
@ptrCast([*:0]const u8, port_c.ptr),
&hints,
&res)) {
switch (os.system.getaddrinfo(name_c.ptr, @ptrCast([*:0]const u8, port_c.ptr), &hints, &res)) {
0 => {},
c.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses,
c.EAI_AGAIN => return error.TemporaryNameServerFailure,
Expand Down
4 changes: 2 additions & 2 deletions lib/std/os/linux/arm-eabi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ pub extern fn getThreadPointer() usize {
);
}

pub nakedcc fn restore() void {
pub fn restore() callconv(.Naked) void {
return asm volatile ("svc #0"
:
: [number] "{r7}" (@as(usize, SYS_sigreturn))
: "memory"
);
}

pub nakedcc fn restore_rt() void {
pub fn restore_rt() callconv(.Naked) void {
return asm volatile ("svc #0"
:
: [number] "{r7}" (@as(usize, SYS_rt_sigreturn))
Expand Down
2 changes: 1 addition & 1 deletion lib/std/os/linux/arm64.zig
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a

pub const restore = restore_rt;

pub nakedcc fn restore_rt() void {
pub fn restore_rt() callconv(.Naked) void {
return asm volatile ("svc #0"
:
: [number] "{x8}" (@as(usize, SYS_rt_sigreturn))
Expand Down
4 changes: 2 additions & 2 deletions lib/std/os/linux/i386.zig
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ pub fn socketcall(call: usize, args: [*]usize) usize {
/// This matches the libc clone function.
pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;

pub nakedcc fn restore() void {
pub fn restore() callconv(.Naked) void {
return asm volatile ("int $0x80"
:
: [number] "{eax}" (@as(usize, SYS_sigreturn))
: "memory"
);
}

pub nakedcc fn restore_rt() void {
pub fn restore_rt() callconv(.Naked) void {
return asm volatile ("int $0x80"
:
: [number] "{eax}" (@as(usize, SYS_rt_sigreturn))
Expand Down
4 changes: 2 additions & 2 deletions lib/std/os/linux/mipsel.zig
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,15 @@ pub fn syscall6(
/// This matches the libc clone function.
pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;

pub nakedcc fn restore() void {
pub fn restore() callconv(.Naked) void {
return asm volatile ("syscall"
:
: [number] "{$2}" (@as(usize, SYS_sigreturn))
: "memory", "cc", "$7"
);
}

pub nakedcc fn restore_rt() void {
pub fn restore_rt() callconv(.Naked) void {
return asm volatile ("syscall"
:
: [number] "{$2}" (@as(usize, SYS_rt_sigreturn))
Expand Down
2 changes: 1 addition & 1 deletion lib/std/os/linux/riscv64.zig
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a

pub const restore = restore_rt;

pub nakedcc fn restore_rt() void {
pub fn restore_rt() callconv(.Naked) void {
return asm volatile ("ecall"
:
: [number] "{x17}" (@as(usize, SYS_rt_sigreturn))
Expand Down
2 changes: 1 addition & 1 deletion lib/std/os/linux/x86_64.zig
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize,

pub const restore = restore_rt;

pub nakedcc fn restore_rt() void {
pub fn restore_rt() callconv(.Naked) void {
return asm volatile ("syscall"
:
: [number] "{rax}" (@as(usize, SYS_rt_sigreturn))
Expand Down
2 changes: 1 addition & 1 deletion lib/std/os/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ test "sigaltstack" {
// analyzed
const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void;

export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 {
extern fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 {
if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx)
return 0;

Expand Down
1 change: 0 additions & 1 deletion lib/std/os/uefi/protocols/simple_text_input_protocol.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,3 @@ pub const SimpleTextInputProtocol = extern struct {
.node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
};
};

10 changes: 5 additions & 5 deletions lib/std/os/windows/advapi32.zig
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
usingnamespace @import("bits.zig");

pub extern "advapi32" stdcallcc fn RegOpenKeyExW(
pub extern "advapi32" fn RegOpenKeyExW(
hKey: HKEY,
lpSubKey: LPCWSTR,
ulOptions: DWORD,
samDesired: REGSAM,
phkResult: *HKEY,
) LSTATUS;
) callconv(.Stdcall) LSTATUS;

pub extern "advapi32" stdcallcc fn RegQueryValueExW(
pub extern "advapi32" fn RegQueryValueExW(
hKey: HKEY,
lpValueName: LPCWSTR,
lpReserved: LPDWORD,
lpType: LPDWORD,
lpData: LPBYTE,
lpcbData: LPDWORD,
) LSTATUS;
) callconv(.Stdcall) LSTATUS;

// RtlGenRandom is known as SystemFunction036 under advapi32
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */
pub extern "advapi32" stdcallcc fn SystemFunction036(output: [*]u8, length: ULONG) BOOL;
pub extern "advapi32" fn SystemFunction036(output: [*]u8, length: ULONG) callconv(.Stdcall) BOOL;
pub const RtlGenRandom = SystemFunction036;
2 changes: 1 addition & 1 deletion lib/std/os/windows/bits.zig
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ pub const EXCEPTION_POINTERS = extern struct {
ContextRecord: *c_void,
};

pub const VECTORED_EXCEPTION_HANDLER = stdcallcc fn (ExceptionInfo: *EXCEPTION_POINTERS) c_long;
pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(.Stdcall) c_long;

pub const OBJECT_ATTRIBUTES = extern struct {
Length: ULONG,
Expand Down
Loading