Skip to content

Commit 6378644

Browse files
authored
Merge pull request #13907 from Vexu/call-merge
Remove `stack` option from `@call`
2 parents 65270cd + 51ed541 commit 6378644

38 files changed

Lines changed: 248 additions & 320 deletions

doc/langref.html.in

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4270,7 +4270,7 @@ test "using @typeInfo with runtime values" {
42704270
}
42714271

42724272
// Calls to `isFieldOptional` on `Struct1` get unrolled to an equivalent
4273-
// of this function:
4273+
// of this function:
42744274
fn isFieldOptionalUnrolled(field_index: usize) !bool {
42754275
return switch (field_index) {
42764276
0 => false,
@@ -7801,15 +7801,15 @@ comptime {
78017801
{#header_close#}
78027802

78037803
{#header_open|@call#}
7804-
<pre>{#syntax#}@call(options: std.builtin.CallOptions, function: anytype, args: anytype) anytype{#endsyntax#}</pre>
7804+
<pre>{#syntax#}@call(modifier: std.builtin.CallModifier, function: anytype, args: anytype) anytype{#endsyntax#}</pre>
78057805
<p>
78067806
Calls a function, in the same way that invoking an expression with parentheses does:
78077807
</p>
78087808
{#code_begin|test|call#}
78097809
const expect = @import("std").testing.expect;
78107810

78117811
test "noinline function call" {
7812-
try expect(@call(.{}, add, .{3, 9}) == 12);
7812+
try expect(@call(.auto, add, .{3, 9}) == 12);
78137813
}
78147814

78157815
fn add(a: i32, b: i32) i32 {
@@ -7818,48 +7818,41 @@ fn add(a: i32, b: i32) i32 {
78187818
{#code_end#}
78197819
<p>
78207820
{#syntax#}@call{#endsyntax#} allows more flexibility than normal function call syntax does. The
7821-
{#syntax#}CallOptions{#endsyntax#} struct is reproduced here:
7821+
{#syntax#}CallModifier{#endsyntax#} enum is reproduced here:
78227822
</p>
7823-
{#syntax_block|zig|builtin.CallOptions struct#}
7824-
pub const CallOptions = struct {
7825-
modifier: Modifier = .auto,
7826-
7827-
/// Only valid when `Modifier` is `Modifier.async_kw`.
7828-
stack: ?[]align(std.Target.stack_align) u8 = null,
7829-
7830-
pub const Modifier = enum {
7831-
/// Equivalent to function call syntax.
7832-
auto,
7823+
{#syntax_block|zig|builtin.CallModifier struct#}
7824+
pub const CallModifier = enum {
7825+
/// Equivalent to function call syntax.
7826+
auto,
78337827

7834-
/// Equivalent to async keyword used with function call syntax.
7835-
async_kw,
7828+
/// Equivalent to async keyword used with function call syntax.
7829+
async_kw,
78367830

7837-
/// Prevents tail call optimization. This guarantees that the return
7838-
/// address will point to the callsite, as opposed to the callsite's
7839-
/// callsite. If the call is otherwise required to be tail-called
7840-
/// or inlined, a compile error is emitted instead.
7841-
never_tail,
7831+
/// Prevents tail call optimization. This guarantees that the return
7832+
/// address will point to the callsite, as opposed to the callsite's
7833+
/// callsite. If the call is otherwise required to be tail-called
7834+
/// or inlined, a compile error is emitted instead.
7835+
never_tail,
78427836

7843-
/// Guarantees that the call will not be inlined. If the call is
7844-
/// otherwise required to be inlined, a compile error is emitted instead.
7845-
never_inline,
7837+
/// Guarantees that the call will not be inlined. If the call is
7838+
/// otherwise required to be inlined, a compile error is emitted instead.
7839+
never_inline,
78467840

7847-
/// Asserts that the function call will not suspend. This allows a
7848-
/// non-async function to call an async function.
7849-
no_async,
7841+
/// Asserts that the function call will not suspend. This allows a
7842+
/// non-async function to call an async function.
7843+
no_async,
78507844

7851-
/// Guarantees that the call will be generated with tail call optimization.
7852-
/// If this is not possible, a compile error is emitted instead.
7853-
always_tail,
7845+
/// Guarantees that the call will be generated with tail call optimization.
7846+
/// If this is not possible, a compile error is emitted instead.
7847+
always_tail,
78547848

7855-
/// Guarantees that the call will inlined at the callsite.
7856-
/// If this is not possible, a compile error is emitted instead.
7857-
always_inline,
7849+
/// Guarantees that the call will inlined at the callsite.
7850+
/// If this is not possible, a compile error is emitted instead.
7851+
always_inline,
78587852

7859-
/// Evaluates the call at compile-time. If the call cannot be completed at
7860-
/// compile-time, a compile error is emitted instead.
7861-
compile_time,
7862-
};
7853+
/// Evaluates the call at compile-time. If the call cannot be completed at
7854+
/// compile-time, a compile error is emitted instead.
7855+
compile_time,
78637856
};
78647857
{#end_syntax_block#}
78657858
{#header_close#}

lib/compiler_rt/stack_probe.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -236,27 +236,27 @@ fn win_probe_stack_adjust_sp() void {
236236

237237
pub fn _chkstk() callconv(.Naked) void {
238238
@setRuntimeSafety(false);
239-
@call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{});
239+
@call(.always_inline, win_probe_stack_adjust_sp, .{});
240240
}
241241
pub fn __chkstk() callconv(.Naked) void {
242242
@setRuntimeSafety(false);
243243
if (comptime arch.isAARCH64()) {
244-
@call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});
244+
@call(.always_inline, win_probe_stack_only, .{});
245245
} else switch (arch) {
246-
.x86 => @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}),
247-
.x86_64 => @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}),
246+
.x86 => @call(.always_inline, win_probe_stack_adjust_sp, .{}),
247+
.x86_64 => @call(.always_inline, win_probe_stack_only, .{}),
248248
else => unreachable,
249249
}
250250
}
251251
pub fn ___chkstk() callconv(.Naked) void {
252252
@setRuntimeSafety(false);
253-
@call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{});
253+
@call(.always_inline, win_probe_stack_adjust_sp, .{});
254254
}
255255
pub fn __chkstk_ms() callconv(.Naked) void {
256256
@setRuntimeSafety(false);
257-
@call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});
257+
@call(.always_inline, win_probe_stack_only, .{});
258258
}
259259
pub fn ___chkstk_ms() callconv(.Naked) void {
260260
@setRuntimeSafety(false);
261-
@call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});
261+
@call(.always_inline, win_probe_stack_only, .{});
262262
}

lib/std/Thread.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,18 +387,18 @@ fn callFn(comptime f: anytype, args: anytype) switch (Impl) {
387387

388388
switch (@typeInfo(@typeInfo(@TypeOf(f)).Fn.return_type.?)) {
389389
.NoReturn => {
390-
@call(.{}, f, args);
390+
@call(.auto, f, args);
391391
},
392392
.Void => {
393-
@call(.{}, f, args);
393+
@call(.auto, f, args);
394394
return default_value;
395395
},
396396
.Int => |info| {
397397
if (info.bits != 8) {
398398
@compileError(bad_fn_ret);
399399
}
400400

401-
const status = @call(.{}, f, args);
401+
const status = @call(.auto, f, args);
402402
if (Impl != PosixThreadImpl) {
403403
return status;
404404
}
@@ -411,7 +411,7 @@ fn callFn(comptime f: anytype, args: anytype) switch (Impl) {
411411
@compileError(bad_fn_ret);
412412
}
413413

414-
@call(.{}, f, args) catch |err| {
414+
@call(.auto, f, args) catch |err| {
415415
std.debug.print("error: {s}\n", .{@errorName(err)});
416416
if (@errorReturnTrace()) |trace| {
417417
std.debug.dumpStackTrace(trace.*);

lib/std/builtin.zig

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -591,45 +591,38 @@ fn testVersionParse() !void {
591591

592592
/// This data structure is used by the Zig language code generation and
593593
/// therefore must be kept in sync with the compiler implementation.
594-
pub const CallOptions = struct {
595-
modifier: Modifier = .auto,
596-
597-
/// Only valid when `Modifier` is `Modifier.async_kw`.
598-
stack: ?[]align(std.Target.stack_align) u8 = null,
599-
600-
pub const Modifier = enum {
601-
/// Equivalent to function call syntax.
602-
auto,
603-
604-
/// Equivalent to async keyword used with function call syntax.
605-
async_kw,
606-
607-
/// Prevents tail call optimization. This guarantees that the return
608-
/// address will point to the callsite, as opposed to the callsite's
609-
/// callsite. If the call is otherwise required to be tail-called
610-
/// or inlined, a compile error is emitted instead.
611-
never_tail,
612-
613-
/// Guarantees that the call will not be inlined. If the call is
614-
/// otherwise required to be inlined, a compile error is emitted instead.
615-
never_inline,
616-
617-
/// Asserts that the function call will not suspend. This allows a
618-
/// non-async function to call an async function.
619-
no_async,
620-
621-
/// Guarantees that the call will be generated with tail call optimization.
622-
/// If this is not possible, a compile error is emitted instead.
623-
always_tail,
624-
625-
/// Guarantees that the call will inlined at the callsite.
626-
/// If this is not possible, a compile error is emitted instead.
627-
always_inline,
628-
629-
/// Evaluates the call at compile-time. If the call cannot be completed at
630-
/// compile-time, a compile error is emitted instead.
631-
compile_time,
632-
};
594+
pub const CallModifier = enum {
595+
/// Equivalent to function call syntax.
596+
auto,
597+
598+
/// Equivalent to async keyword used with function call syntax.
599+
async_kw,
600+
601+
/// Prevents tail call optimization. This guarantees that the return
602+
/// address will point to the callsite, as opposed to the callsite's
603+
/// callsite. If the call is otherwise required to be tail-called
604+
/// or inlined, a compile error is emitted instead.
605+
never_tail,
606+
607+
/// Guarantees that the call will not be inlined. If the call is
608+
/// otherwise required to be inlined, a compile error is emitted instead.
609+
never_inline,
610+
611+
/// Asserts that the function call will not suspend. This allows a
612+
/// non-async function to call an async function.
613+
no_async,
614+
615+
/// Guarantees that the call will be generated with tail call optimization.
616+
/// If this is not possible, a compile error is emitted instead.
617+
always_tail,
618+
619+
/// Guarantees that the call will inlined at the callsite.
620+
/// If this is not possible, a compile error is emitted instead.
621+
always_inline,
622+
623+
/// Evaluates the call at compile-time. If the call cannot be completed at
624+
/// compile-time, a compile error is emitted instead.
625+
compile_time,
633626
};
634627

635628
/// This data structure is used by the Zig language code generation and

lib/std/crypto/siphash.zig

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,10 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
7878
pub fn update(self: *Self, b: []const u8) void {
7979
std.debug.assert(b.len % 8 == 0);
8080

81-
const inl = std.builtin.CallOptions{ .modifier = .always_inline };
82-
8381
var off: usize = 0;
8482
while (off < b.len) : (off += 8) {
8583
const blob = b[off..][0..8].*;
86-
@call(inl, round, .{ self, blob });
84+
@call(.always_inline, round, .{ self, blob });
8785
}
8886

8987
self.msg_len +%= @truncate(u8, b.len);
@@ -105,12 +103,9 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
105103
self.v2 ^= 0xff;
106104
}
107105

108-
// TODO this is a workaround, should be able to supply the value without a separate variable
109-
const inl = std.builtin.CallOptions{ .modifier = .always_inline };
110-
111106
comptime var i: usize = 0;
112107
inline while (i < d_rounds) : (i += 1) {
113-
@call(inl, sipRound, .{self});
108+
@call(.always_inline, sipRound, .{self});
114109
}
115110

116111
const b1 = self.v0 ^ self.v1 ^ self.v2 ^ self.v3;
@@ -122,7 +117,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
122117

123118
comptime var j: usize = 0;
124119
inline while (j < d_rounds) : (j += 1) {
125-
@call(inl, sipRound, .{self});
120+
@call(.always_inline, sipRound, .{self});
126121
}
127122

128123
const b2 = self.v0 ^ self.v1 ^ self.v2 ^ self.v3;
@@ -133,11 +128,9 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
133128
const m = mem.readIntLittle(u64, b[0..8]);
134129
self.v3 ^= m;
135130

136-
// TODO this is a workaround, should be able to supply the value without a separate variable
137-
const inl = std.builtin.CallOptions{ .modifier = .always_inline };
138131
comptime var i: usize = 0;
139132
inline while (i < c_rounds) : (i += 1) {
140-
@call(inl, sipRound, .{self});
133+
@call(.always_inline, sipRound, .{self});
141134
}
142135

143136
self.v0 ^= m;
@@ -163,8 +156,8 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
163156
pub fn hash(msg: []const u8, key: *const [key_length]u8) T {
164157
const aligned_len = msg.len - (msg.len % 8);
165158
var c = Self.init(key);
166-
@call(.{ .modifier = .always_inline }, c.update, .{msg[0..aligned_len]});
167-
return @call(.{ .modifier = .always_inline }, c.final, .{msg[aligned_len..]});
159+
@call(.always_inline, c.update, .{msg[0..aligned_len]});
160+
return @call(.always_inline, c.final, .{msg[aligned_len..]});
168161
}
169162
};
170163
}

lib/std/dynamic_library.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ pub const DlDynlib = struct {
381381
pub fn lookup(self: *DlDynlib, comptime T: type, name: [:0]const u8) ?T {
382382
// dlsym (and other dl-functions) secretly take shadow parameter - return address on stack
383383
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66826
384-
if (@call(.{ .modifier = .never_tail }, system.dlsym, .{ self.handle, name.ptr })) |symbol| {
384+
if (@call(.never_tail, system.dlsym, .{ self.handle, name.ptr })) |symbol| {
385385
return @ptrCast(T, symbol);
386386
} else {
387387
return null;

lib/std/hash/auto_hash.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
6666
const Key = @TypeOf(key);
6767

6868
if (strat == .Shallow and comptime meta.trait.hasUniqueRepresentation(Key)) {
69-
@call(.{ .modifier = .always_inline }, hasher.update, .{mem.asBytes(&key)});
69+
@call(.always_inline, hasher.update, .{mem.asBytes(&key)});
7070
return;
7171
}
7272

@@ -89,12 +89,12 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
8989
// TODO Check if the situation is better after #561 is resolved.
9090
.Int => {
9191
if (comptime meta.trait.hasUniqueRepresentation(Key)) {
92-
@call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)});
92+
@call(.always_inline, hasher.update, .{std.mem.asBytes(&key)});
9393
} else {
9494
// Take only the part containing the key value, the remaining
9595
// bytes are undefined and must not be hashed!
9696
const byte_size = comptime std.math.divCeil(comptime_int, @bitSizeOf(Key), 8) catch unreachable;
97-
@call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)[0..byte_size]});
97+
@call(.always_inline, hasher.update, .{std.mem.asBytes(&key)[0..byte_size]});
9898
}
9999
},
100100

@@ -103,7 +103,7 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
103103
.ErrorSet => hash(hasher, @errorToInt(key), strat),
104104
.AnyFrame, .Fn => hash(hasher, @ptrToInt(key), strat),
105105

106-
.Pointer => @call(.{ .modifier = .always_inline }, hashPointer, .{ hasher, key, strat }),
106+
.Pointer => @call(.always_inline, hashPointer, .{ hasher, key, strat }),
107107

108108
.Optional => if (key) |k| hash(hasher, k, strat),
109109

lib/std/hash/cityhash.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ pub const CityHash64 = struct {
185185
}
186186

187187
fn hashLen16(u: u64, v: u64) u64 {
188-
return @call(.{ .modifier = .always_inline }, hash128To64, .{ u, v });
188+
return @call(.always_inline, hash128To64, .{ u, v });
189189
}
190190

191191
fn hashLen16Mul(low: u64, high: u64, mul: u64) u64 {
@@ -198,7 +198,7 @@ pub const CityHash64 = struct {
198198
}
199199

200200
fn hash128To64(low: u64, high: u64) u64 {
201-
return @call(.{ .modifier = .always_inline }, hashLen16Mul, .{ low, high, 0x9ddfea08eb382d69 });
201+
return @call(.always_inline, hashLen16Mul, .{ low, high, 0x9ddfea08eb382d69 });
202202
}
203203

204204
fn hashLen0To16(str: []const u8) u64 {
@@ -279,7 +279,7 @@ pub const CityHash64 = struct {
279279
}
280280

281281
fn weakHashLen32WithSeeds(ptr: [*]const u8, a: u64, b: u64) WeakPair {
282-
return @call(.{ .modifier = .always_inline }, weakHashLen32WithSeedsHelper, .{
282+
return @call(.always_inline, weakHashLen32WithSeedsHelper, .{
283283
fetch64(ptr, 0),
284284
fetch64(ptr, 8),
285285
fetch64(ptr, 16),
@@ -334,7 +334,7 @@ pub const CityHash64 = struct {
334334
}
335335

336336
pub fn hashWithSeed(str: []const u8, seed: u64) u64 {
337-
return @call(.{ .modifier = .always_inline }, Self.hashWithSeeds, .{ str, k2, seed });
337+
return @call(.always_inline, Self.hashWithSeeds, .{ str, k2, seed });
338338
}
339339

340340
pub fn hashWithSeeds(str: []const u8, seed0: u64, seed1: u64) u64 {

0 commit comments

Comments
 (0)