authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-05 17:37:29-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-05 17:37:29-05:00
logef83358eb6702e8541816817e98c3e7279033672
tree2d57f0633a84f188cc4bd0c9e25fc0484a39b6f5
parent1f602fe8c5b3dea9f00f96e70dad73ebce405b49
signature Commit is signed but in an unrecognized format.

remove `@noInlineCall` from zig


7 files changed, 106 insertions(+), 42 deletions(-)

doc/langref.html.in+66-24
......@@ -6841,6 +6841,71 @@ async fn func(y: *i32) void {
68416841 </p>
68426842 {#header_close#}
68436843
6844 {#header_open|@call#}
6845 <pre>{#syntax#}@call(options: std.builtin.CallOptions, function: var, args: var) var{#endsyntax#}</pre>
6846 <p>
6847 Calls a function, in the same way that invoking an expression with parentheses does:
6848 </p>
6849 {#code_begin|test|call#}
6850const assert = @import("std").debug.assert;
6851
6852test "noinline function call" {
6853 assert(@call(.{}, add, .{3, 9}) == 12);
6854}
6855
6856fn add(a: i32, b: i32) i32 {
6857 return a + b;
6858}
6859 {#code_end#}
6860 <p>
6861 {#syntax#}@call{#endsyntax#} allows more flexibility than normal function call syntax does. The
6862 {#syntax#}CallOptions{#endsyntax#} struct is reproduced here:
6863 </p>
6864 {#code_begin|syntax#}
6865pub const CallOptions = struct {
6866 modifier: Modifier = .auto,
6867 stack: ?[]align(std.Target.stack_align) u8 = null,
6868
6869 pub const Modifier = enum {
6870 /// Equivalent to function call syntax.
6871 auto,
6872
6873 /// Asserts that the function call will not suspend. This allows a
6874 /// non-async function to call an async function.
6875 no_async,
6876
6877 /// The function call will return an async function frame instead of
6878 /// the function's result, which is expected to then be awaited.
6879 /// This is equivalent to using the `async` keyword in front of function
6880 /// call syntax.
6881 async_call,
6882
6883 /// Prevents tail call optimization. This guarantees that the return
6884 /// address will point to the callsite, as opposed to the callsite's
6885 /// callsite. If the call is otherwise required to be tail-called
6886 /// or inlined, a compile error is emitted instead.
6887 never_tail,
6888
6889 /// Guarantees that the call will not be inlined. If the call is
6890 /// otherwise required to be inlined, a compile error is emitted instead.
6891 never_inline,
6892
6893 /// Guarantees that the call will be generated with tail call optimization.
6894 /// If this is not possible, a compile error is emitted instead.
6895 always_tail,
6896
6897 /// Guarantees that the call will inlined at the callsite.
6898 /// If this is not possible, a compile error is emitted instead.
6899 always_inline,
6900
6901 /// Evaluates the call at compile-time. If the call cannot be completed at
6902 /// compile-time, a compile error is emitted instead.
6903 compile_time,
6904 };
6905};
6906 {#code_end#}
6907 {#header_close#}
6908
68446909 {#header_open|@cDefine#}
68456910 <pre>{#syntax#}@cDefine(comptime name: []u8, value){#endsyntax#}</pre>
68466911 <p>
......@@ -7445,7 +7510,7 @@ fn add(a: i32, b: i32) i32 { return a + b; }
74457510 Unlike a normal function call, however, {#syntax#}@inlineCall{#endsyntax#} guarantees that the call
74467511 will be inlined. If the call cannot be inlined, a compile error is emitted.
74477512 </p>
7448 {#see_also|@noInlineCall#}
7513 {#see_also|@call#}
74497514 {#header_close#}
74507515
74517516 {#header_open|@intCast#}
......@@ -7647,29 +7712,6 @@ fn targetFunction(x: i32) usize {
76477712 {#code_end#}
76487713 {#header_close#}
76497714
7650 {#header_open|@noInlineCall#}
7651 <pre>{#syntax#}@noInlineCall(function: var, args: ...) var{#endsyntax#}</pre>
7652 <p>
7653 This calls a function, in the same way that invoking an expression with parentheses does:
7654 </p>
7655 {#code_begin|test#}
7656const assert = @import("std").debug.assert;
7657
7658test "noinline function call" {
7659 assert(@noInlineCall(add, 3, 9) == 12);
7660}
7661
7662fn add(a: i32, b: i32) i32 {
7663 return a + b;
7664}
7665 {#code_end#}
7666 <p>
7667 Unlike a normal function call, however, {#syntax#}@noInlineCall{#endsyntax#} guarantees that the call
7668 will not be inlined. If the call must be inlined, a compile error is emitted.
7669 </p>
7670 {#see_also|@inlineCall#}
7671 {#header_close#}
7672
76737715 {#header_open|@OpaqueType#}
76747716 <pre>{#syntax#}@OpaqueType() type{#endsyntax#}</pre>
76757717 <p>
lib/std/builtin.zig+26
......@@ -379,13 +379,39 @@ pub const CallOptions = struct {
379379 stack: ?[]align(std.Target.stack_align) u8 = null,
380380
381381 pub const Modifier = enum {
382 /// Equivalent to function call syntax.
382383 auto,
384
385 /// Asserts that the function call will not suspend. This allows a
386 /// non-async function to call an async function.
383387 no_async,
388
389 /// The function call will return an async function frame instead of
390 /// the function's result, which is expected to then be awaited.
391 /// This is equivalent to using the `async` keyword in front of function
392 /// call syntax.
384393 async_call,
394
395 /// Prevents tail call optimization. This guarantees that the return
396 /// address will point to the callsite, as opposed to the callsite's
397 /// callsite. If the call is otherwise required to be tail-called
398 /// or inlined, a compile error is emitted instead.
385399 never_tail,
400
401 /// Guarantees that the call will not be inlined. If the call is
402 /// otherwise required to be inlined, a compile error is emitted instead.
386403 never_inline,
404
405 /// Guarantees that the call will be generated with tail call optimization.
406 /// If this is not possible, a compile error is emitted instead.
387407 always_tail,
408
409 /// Guarantees that the call will inlined at the callsite.
410 /// If this is not possible, a compile error is emitted instead.
388411 always_inline,
412
413 /// Evaluates the call at compile-time. If the call cannot be completed at
414 /// compile-time, a compile error is emitted instead.
389415 compile_time,
390416 };
391417};
lib/std/special/start.zig+1-1
......@@ -125,7 +125,7 @@ nakedcc fn _start() noreturn {
125125 }
126126 // If LLVM inlines stack variables into _start, they will overwrite
127127 // the command line argument data.
128 @noInlineCall(posixCallMainAndExit);
128 @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
129129}
130130
131131stdcallcc fn WinMainCRTStartup() noreturn {
src/all_types.hpp-1
......@@ -1701,7 +1701,6 @@ enum BuiltinFnId {
17011701 BuiltinFnIdByteOffsetOf,
17021702 BuiltinFnIdBitOffsetOf,
17031703 BuiltinFnIdInlineCall,
1704 BuiltinFnIdNoInlineCall,
17051704 BuiltinFnIdNewStackCall,
17061705 BuiltinFnIdAsyncCall,
17071706 BuiltinFnIdTypeId,
src/codegen.cpp-1
......@@ -8133,7 +8133,6 @@ static void define_builtin_fns(CodeGen *g) {
81338133 create_builtin_fn(g, BuiltinFnIdRound, "round", 2);
81348134 create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4);
81358135 create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX);
8136 create_builtin_fn(g, BuiltinFnIdNoInlineCall, "noInlineCall", SIZE_MAX);
81378136 create_builtin_fn(g, BuiltinFnIdNewStackCall, "newStackCall", SIZE_MAX);
81388137 create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX);
81398138 create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1);
src/ir.cpp+1-4
......@@ -6014,7 +6014,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
60146014 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc);
60156015 }
60166016 case BuiltinFnIdInlineCall:
6017 case BuiltinFnIdNoInlineCall:
60186017 {
60196018 if (node->data.fn_call_expr.params.length == 0) {
60206019 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0"));
......@@ -6035,11 +6034,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
60356034 if (args[i] == irb->codegen->invalid_instruction)
60366035 return args[i];
60376036 }
6038 CallModifier modifier = (builtin_fn->id == BuiltinFnIdInlineCall) ?
6039 CallModifierAlwaysInline : CallModifierNeverInline;
60406037
60416038 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args,
6042 nullptr, modifier, false, nullptr, result_loc);
6039 nullptr, CallModifierAlwaysInline, false, nullptr, result_loc);
60436040 return ir_lval_wrap(irb, scope, call, lval, result_loc);
60446041 }
60456042 case BuiltinFnIdNewStackCall:
test/compile_errors.zig+12-11
......@@ -13,11 +13,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1313 \\export fn entry3() void {
1414 \\ comptime @call(.{ .modifier = .never_tail }, foo, .{});
1515 \\}
16 \\export fn entry4() void {
17 \\ @call(.{ .modifier = .never_inline }, bar, .{});
18 \\}
19 \\export fn entry5(c: bool) void {
20 \\ var baz = if (c) baz1 else baz2;
21 \\ @call(.{ .modifier = .compile_time }, baz, .{});
22 \\}
1623 \\fn foo() void {}
24 \\inline fn bar() void {}
25 \\fn baz1() void {}
26 \\fn baz2() void {}
1727 ,
1828 "tmp.zig:2:21: error: expected tuple or struct, found 'void'",
1929 "tmp.zig:5:58: error: unable to perform 'never_inline' call at compile-time",
2030 "tmp.zig:8:56: error: unable to perform 'never_tail' call at compile-time",
31 "tmp.zig:11:5: error: no-inline call of inline function",
32 "tmp.zig:15:43: error: unable to evaluate constant expression",
2133 );
2234
2335 cases.add(
......@@ -1945,17 +1957,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
19451957 "tmp.zig:2:12: error: use of undeclared identifier 'SomeNonexistentType'",
19461958 );
19471959
1948 cases.add(
1949 "@noInlineCall on an inline function",
1950 \\inline fn foo() void {}
1951 \\
1952 \\export fn entry() void {
1953 \\ @noInlineCall(foo);
1954 \\}
1955 ,
1956 "tmp.zig:4:5: error: no-inline call of inline function",
1957 );
1958
19591960 cases.add(
19601961 "comptime continue inside runtime catch",
19611962 \\export fn entry(c: bool) void {