authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-08 12:02:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-08 12:02:56-04:00
logd813805f775b74416337ce8f1bd7b2e789caf185
tree8c45e975c730fde6196e925ffe409e31255b4a11
parent34bfdf193aee4cb4fc931c6cc4ee82ef0a3a506f
signaturelock-open Commit is signed but in an unrecognized format.

more debuggable safety for awaiting twice


2 files changed, 29 insertions(+), 5 deletions(-)

src/codegen.cpp+5-5
...@@ -2259,7 +2259,7 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,...@@ -2259,7 +2259,7 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
22592259
2260 LLVMValueRef zero = LLVMConstNull(usize_type_ref);2260 LLVMValueRef zero = LLVMConstNull(usize_type_ref);
2261 LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);2261 LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);
2262 LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXchg, g->cur_async_awaiter_ptr,2262 LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXor, g->cur_async_awaiter_ptr,
2263 all_ones, LLVMAtomicOrderingAcquire, g->is_single_threaded);2263 all_ones, LLVMAtomicOrderingAcquire, g->is_single_threaded);
22642264
2265 LLVMBasicBlockRef bad_return_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadReturn");2265 LLVMBasicBlockRef bad_return_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadReturn");
...@@ -2346,7 +2346,7 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns...@@ -2346,7 +2346,7 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
2346 LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, masked_prev_val,2346 LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, masked_prev_val,
2347 get_llvm_type(g, any_frame_type), "");2347 get_llvm_type(g, any_frame_type), "");
2348 LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn, nullptr);2348 LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn, nullptr);
2349 ZigLLVMSetTailCall(call_inst);2349 LLVMSetTailCall(call_inst, true);
2350 LLVMBuildRetVoid(g->builder);2350 LLVMBuildRetVoid(g->builder);
23512351
2352 return nullptr;2352 return nullptr;
...@@ -3956,7 +3956,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3956,7 +3956,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3956 LLVMBasicBlockRef call_bb = gen_suspend_begin(g, "CallResume");3956 LLVMBasicBlockRef call_bb = gen_suspend_begin(g, "CallResume");
39573957
3958 LLVMValueRef call_inst = gen_resume(g, fn_val, frame_result_loc, ResumeIdCall, nullptr);3958 LLVMValueRef call_inst = gen_resume(g, fn_val, frame_result_loc, ResumeIdCall, nullptr);
3959 ZigLLVMSetTailCall(call_inst);3959 LLVMSetTailCall(call_inst, true);
3960 LLVMBuildRetVoid(g->builder);3960 LLVMBuildRetVoid(g->builder);
39613961
3962 LLVMPositionBuilderAtEnd(g->builder, call_bb);3962 LLVMPositionBuilderAtEnd(g->builder, call_bb);
...@@ -5456,7 +5456,7 @@ static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrIns...@@ -5456,7 +5456,7 @@ static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrIns
54565456
5457 LLVMPositionBuilderAtEnd(g->builder, early_return_block);5457 LLVMPositionBuilderAtEnd(g->builder, early_return_block);
5458 LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_ored_val);5458 LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_ored_val);
5459 ZigLLVMSetTailCall(call_inst);5459 LLVMSetTailCall(call_inst, true);
5460 LLVMBuildRetVoid(g->builder);5460 LLVMBuildRetVoid(g->builder);
54615461
5462 LLVMPositionBuilderAtEnd(g->builder, resume_bb);5462 LLVMPositionBuilderAtEnd(g->builder, resume_bb);
...@@ -5524,7 +5524,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst...@@ -5524,7 +5524,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
5524 // Tail resume it now, so that it can complete.5524 // Tail resume it now, so that it can complete.
5525 LLVMPositionBuilderAtEnd(g->builder, early_return_block);5525 LLVMPositionBuilderAtEnd(g->builder, early_return_block);
5526 LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_init_val);5526 LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_init_val);
5527 ZigLLVMSetTailCall(call_inst);5527 LLVMSetTailCall(call_inst, true);
5528 LLVMBuildRetVoid(g->builder);5528 LLVMBuildRetVoid(g->builder);
55295529
5530 // Rely on the target to resume us from suspension.5530 // Rely on the target to resume us from suspension.
test/runtime_safety.zig+24
...@@ -1,6 +1,30 @@...@@ -1,6 +1,30 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompareOutputContext) void {3pub fn addCases(cases: *tests.CompareOutputContext) void {
4 cases.addRuntimeSafety("awaiting twice",
5 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
6 \\ @import("std").os.exit(126);
7 \\}
8 \\var frame: anyframe = undefined;
9 \\
10 \\pub fn main() void {
11 \\ _ = async amain();
12 \\ resume frame;
13 \\}
14 \\
15 \\fn amain() void {
16 \\ var f = async func();
17 \\ await f;
18 \\ await f;
19 \\}
20 \\
21 \\fn func() void {
22 \\ suspend {
23 \\ frame = @frame();
24 \\ }
25 \\}
26 );
27
4 cases.addRuntimeSafety("@asyncCall with too small a frame",28 cases.addRuntimeSafety("@asyncCall with too small a frame",
5 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {29 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
6 \\ @import("std").os.exit(126);30 \\ @import("std").os.exit(126);