Zig: NoTailCall option

Created on 20 Nov 2019  路  6Comments  路  Source: ziglang/zig

_Originally from https://github.com/ziglang/zig/pull/2598_

I just recalled something from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66826

Now dlsym (and other dl-functions) secretly take shadow parameter - return address on stack

We need a way to ensure that a given call is not a tail call.

LLVM does have a notail option

accepted proposal

Most helpful comment

To avoid proliferation of @inlineCall/@noInlineCall/@newStackCall/@noTailCall, etc.
I propose a @call builtin that takes a structure of options:

const Maybe = enum {
    Default,
    Always,
    Never,
};
@call(comptime options: struct {
    tailCall: Maybe = .Default,
    inlineCall: Maybe = .Default,
    newStack: ?[]align(target_stack_align) u8 = null,
}, function: var, args: ...);

All 6 comments

To avoid proliferation of @inlineCall/@noInlineCall/@newStackCall/@noTailCall, etc.
I propose a @call builtin that takes a structure of options:

const Maybe = enum {
    Default,
    Always,
    Never,
};
@call(comptime options: struct {
    tailCall: Maybe = .Default,
    inlineCall: Maybe = .Default,
    newStack: ?[]align(target_stack_align) u8 = null,
}, function: var, args: ...);

perhaps asyncCall could be merged with this?

Your code example is missing the handle to the function itself, and if we are getting rid of var args (#208) then the args argument should be a var which is filled using anonymous literal syntax. That would end up looking like this:

const result = @call(myFunc, .{ .tailCall = false }, .{ false, 1, "three" });

How about just 1 argument?

 @call(.{
    .tailCall = false,
    .func = myFunc,
    .args = .{ false, 1, "three" })
});

How about just 1 argument?

I think this looks harder to use. Also the call type needs to be comptime known, while the function and arguments can be runtime known.

Your code example is missing the handle to the function itself,

Fixed.

and if we are getting rid of var args (#208) then the args argument should be a var which is filled using anonymous literal syntax. That would end up looking like this:

const result = @call(myFunc, .{ .tailCall = false }, .{ false, 1, "three" });

Builtins don't need to follow the rest of the language like this: they aren't normal functions. see e.g. @field

Was this page helpful?
0 / 5 - 0 ratings