authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-06 14:52:09-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-06 14:52:09-05:00
log71b7f4b47f69e9b3241e9d44554572258f5eb5b1
tree9e60d95d273bb488d7ffcef8eaa5217c72f32079
parent343987cd057c5f2f0aad197518d7d573579d0d08
signaturelock-open Commit is signed but in an unrecognized format.

remove `@newStackCall` from zig


6 files changed, 66 insertions(+), 56 deletions(-)

doc/langref.html.in+35-42
......@@ -6904,6 +6904,41 @@ pub const CallOptions = struct {
69046904 };
69056905};
69066906 {#code_end#}
6907
6908 {#header_open|Calling with a New Stack#}
6909 <p>
6910 When the {#syntax#}stack{#endsyntax#} option is provided, instead of using the same stack as the caller, the function uses the provided stack.
6911 </p>
6912 {#code_begin|test|new_stack_call#}
6913const std = @import("std");
6914const assert = std.debug.assert;
6915
6916var new_stack_bytes: [1024]u8 align(16) = undefined;
6917
6918test "calling a function with a new stack" {
6919 const arg = 1234;
6920
6921 const a = @call(.{.stack = new_stack_bytes[0..512]}, targetFunction, .{arg});
6922 const b = @call(.{.stack = new_stack_bytes[512..]}, targetFunction, .{arg});
6923 _ = targetFunction(arg);
6924
6925 assert(arg == 1234);
6926 assert(a < b);
6927}
6928
6929fn targetFunction(x: i32) usize {
6930 assert(x == 1234);
6931
6932 var local_variable: i32 = 42;
6933 const ptr = &local_variable;
6934 ptr.* += 1;
6935
6936 assert(local_variable == 43);
6937 return @ptrToInt(ptr);
6938}
6939 {#code_end#}
6940 {#header_close#}
6941
69076942 {#header_close#}
69086943
69096944 {#header_open|@cDefine#}
......@@ -7649,48 +7684,6 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>
76497684 </p>
76507685 {#header_close#}
76517686
7652 {#header_open|@newStackCall#}
7653 <pre>{#syntax#}@newStackCall(new_stack: []align(target_stack_align) u8, function: var, args: ...) var{#endsyntax#}</pre>
7654 <p>
7655 This calls a function, in the same way that invoking an expression with parentheses does. However,
7656 instead of using the same stack as the caller, the function uses the stack provided in the {#syntax#}new_stack{#endsyntax#}
7657 parameter.
7658 </p>
7659 <p>
7660 The new stack must be aligned to {#syntax#}target_stack_align{#endsyntax#} bytes. This is a target-specific
7661 number. A safe value that will work on all targets is {#syntax#}16{#endsyntax#}. This value can
7662 also be obtained by using {#link|@sizeOf#} on the {#link|@Frame#} type of {#link|Async Functions#}.
7663 </p>
7664 {#code_begin|test#}
7665const std = @import("std");
7666const assert = std.debug.assert;
7667
7668var new_stack_bytes: [1024]u8 align(16) = undefined;
7669
7670test "calling a function with a new stack" {
7671 const arg = 1234;
7672
7673 const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg);
7674 const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
7675 _ = targetFunction(arg);
7676
7677 assert(arg == 1234);
7678 assert(a < b);
7679}
7680
7681fn targetFunction(x: i32) usize {
7682 assert(x == 1234);
7683
7684 var local_variable: i32 = 42;
7685 const ptr = &local_variable;
7686 ptr.* += 1;
7687
7688 assert(local_variable == 43);
7689 return @ptrToInt(ptr);
7690}
7691 {#code_end#}
7692 {#header_close#}
7693
76947687 {#header_open|@OpaqueType#}
76957688 <pre>{#syntax#}@OpaqueType() type{#endsyntax#}</pre>
76967689 <p>
lib/std/special/start.zig+1-1
......@@ -184,7 +184,7 @@ fn posixCallMainAndExit() noreturn {
184184 // 0,
185185 //) catch @panic("out of memory");
186186 //std.os.mprotect(new_stack[0..std.mem.page_size], std.os.PROT_NONE) catch {};
187 //std.os.exit(@newStackCall(new_stack, callMainWithArgs, argc, argv, envp));
187 //std.os.exit(@call(.{.stack = new_stack}, callMainWithArgs, .{argc, argv, envp}));
188188 }
189189
190190 std.os.exit(@call(.{ .modifier = .always_inline }, callMainWithArgs, .{ argc, argv, envp }));
src-self-hosted/ir.zig+2-2
......@@ -321,7 +321,7 @@ pub const Inst = struct {
321321 }
322322
323323 const llvm_cc = llvm.CCallConv;
324 const fn_inline = llvm.FnInline.Auto;
324 const call_attr = llvm.CallAttr.Auto;
325325
326326 return llvm.BuildCall(
327327 ofile.builder,
......@@ -329,7 +329,7 @@ pub const Inst = struct {
329329 args.ptr,
330330 @intCast(c_uint, args.len),
331331 llvm_cc,
332 fn_inline,
332 call_attr,
333333 "",
334334 ) orelse error.OutOfMemory;
335335 }
src/ir.cpp+21-4
......@@ -13358,6 +13358,15 @@ static IrInstruction *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst
1335813358 return ir_get_deref(ira, source_instr, field_ptr, nullptr);
1335913359}
1336013360
13361static IrInstruction *ir_analyze_optional_value_payload_value(IrAnalyze *ira, IrInstruction *source_instr,
13362 IrInstruction *optional_operand, bool safety_check_on)
13363{
13364 IrInstruction *opt_ptr = ir_get_ref(ira, source_instr, optional_operand, true, false);
13365 IrInstruction *payload_ptr = ir_analyze_unwrap_optional_payload(ira, source_instr, opt_ptr,
13366 safety_check_on, false);
13367 return ir_get_deref(ira, source_instr, payload_ptr, nullptr);
13368}
13369
1336113370static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
1336213371 ZigType *wanted_type, IrInstruction *value)
1336313372{
......@@ -17521,7 +17530,7 @@ static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstruction *so
1752117530 arch_stack_pointer_register_name(ira->codegen->zig_target->arch) == nullptr)
1752217531 {
1752317532 ir_add_error(ira, source_instr,
17524 buf_sprintf("target arch '%s' does not support @newStackCall",
17533 buf_sprintf("target arch '%s' does not support calling with a new stack",
1752517534 target_arch_name(ira->codegen->zig_target->arch)));
1752617535 }
1752717536
......@@ -18223,13 +18232,21 @@ static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *sourc
1822318232
1822418233 TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack"));
1822518234 ir_assert(stack_field != nullptr, source_instr);
18226 IrInstruction *stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field);
18227 IrInstruction *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, stack);
18235 IrInstruction *opt_stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field);
18236 if (type_is_invalid(opt_stack->value->type))
18237 return ira->codegen->invalid_instruction;
18238 IrInstruction *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, opt_stack);
1822818239 bool stack_is_non_null;
1822918240 if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null))
1823018241 return ira->codegen->invalid_instruction;
18231 if (!stack_is_non_null)
18242 IrInstruction *stack;
18243 if (stack_is_non_null) {
18244 stack = ir_analyze_optional_value_payload_value(ira, source_instr, opt_stack, false);
18245 if (type_is_invalid(stack->value->type))
18246 return ira->codegen->invalid_instruction;
18247 } else {
1823218248 stack = nullptr;
18249 }
1823318250
1823418251 return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr,
1823518252 modifier, stack, false, args_ptr, args_len, nullptr, result_loc);
test/compile_errors.zig+5-5
......@@ -26,8 +26,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2626 \\fn baz2() void {}
2727 ,
2828 "tmp.zig:2:21: error: expected tuple or struct, found 'void'",
29 "tmp.zig:5:58: error: unable to perform 'never_inline' call at compile-time",
30 "tmp.zig:8:56: error: unable to perform 'never_tail' call at compile-time",
29 "tmp.zig:5:14: error: unable to perform 'never_inline' call at compile-time",
30 "tmp.zig:8:14: error: unable to perform 'never_tail' call at compile-time",
3131 "tmp.zig:11:5: error: no-inline call of inline function",
3232 "tmp.zig:15:43: error: unable to evaluate constant expression",
3333 );
......@@ -44,13 +44,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4444 );
4545
4646 cases.addCase(x: {
47 var tc = cases.create("@newStackCall on unsupported target",
47 var tc = cases.create("call with new stack on unsupported target",
4848 \\export fn entry() void {
4949 \\ var buf: [10]u8 align(16) = undefined;
50 \\ @newStackCall(&buf, foo);
50 \\ @call(.{.stack = &buf}, foo);
5151 \\}
5252 \\fn foo() void {}
53 , "tmp.zig:3:5: error: target arch 'wasm32' does not support @newStackCall");
53 , "tmp.zig:3:5: error: target arch 'wasm32' does not support calling with a new stack");
5454 tc.target = tests.Target{
5555 .Cross = tests.CrossTarget{
5656 .arch = .wasm32,
test/stage1/behavior/new_stack_call.zig+2-2
......@@ -18,8 +18,8 @@ test "calling a function with a new stack" {
1818
1919 const arg = 1234;
2020
21 const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg);
22 const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
21 const a = @call(.{ .stack = new_stack_bytes[0..512] }, targetFunction, .{arg});
22 const b = @call(.{ .stack = new_stack_bytes[512..] }, targetFunction, .{arg});
2323 _ = targetFunction(arg);
2424
2525 expect(arg == 1234);