| ... | @@ -877,6 +877,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { | ... | @@ -877,6 +877,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { |
| 877 | return buf_create_from_str("async function awaited twice"); | 877 | return buf_create_from_str("async function awaited twice"); |
| 878 | case PanicMsgIdBadReturn: | 878 | case PanicMsgIdBadReturn: |
| 879 | return buf_create_from_str("async function returned twice"); | 879 | return buf_create_from_str("async function returned twice"); |
| | 880 | case PanicMsgIdResumedAnAwaitingFn: |
| | 881 | return buf_create_from_str("awaiting function resumed"); |
| 880 | } | 882 | } |
| 881 | zig_unreachable(); | 883 | zig_unreachable(); |
| 882 | } | 884 | } |
| ... | @@ -2018,7 +2020,10 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns | ... | @@ -2018,7 +2020,10 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns |
| 2018 | } | 2020 | } |
| 2019 | result_ptr_as_usize = LLVMBuildPtrToInt(g->builder, result_ptr, usize_type_ref, ""); | 2021 | result_ptr_as_usize = LLVMBuildPtrToInt(g->builder, result_ptr, usize_type_ref, ""); |
| 2020 | } else { | 2022 | } else { |
| 2021 | result_ptr_as_usize = LLVMGetUndef(usize_type_ref); | 2023 | // For debug safety, this value has to be anything other than all 1's, which signals |
| | 2024 | // that it is being resumed. 0 is a bad choice since null pointers are special. |
| | 2025 | result_ptr_as_usize = ir_want_runtime_safety(g, &return_instruction->base) ? |
| | 2026 | LLVMConstInt(usize_type_ref, 1, false) : LLVMGetUndef(usize_type_ref); |
| 2022 | } | 2027 | } |
| 2023 | LLVMValueRef zero = LLVMConstNull(usize_type_ref); | 2028 | LLVMValueRef zero = LLVMConstNull(usize_type_ref); |
| 2024 | LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref); | 2029 | LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref); |
| ... | @@ -3582,8 +3587,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -3582,8 +3587,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3582 | LLVMBuildStore(g->builder, gen_param_values.at(arg_i), arg_ptr); | 3587 | LLVMBuildStore(g->builder, gen_param_values.at(arg_i), arg_ptr); |
| 3583 | } | 3588 | } |
| 3584 | } | 3589 | } |
| | 3590 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 3585 | if (instruction->is_async) { | 3591 | if (instruction->is_async) { |
| 3586 | LLVMValueRef args[] = {frame_result_loc, LLVMGetUndef(g->builtin_types.entry_usize->llvm_type)}; | 3592 | LLVMValueRef args[] = {frame_result_loc, LLVMGetUndef(usize_type_ref)}; |
| 3587 | ZigLLVMBuildCall(g->builder, fn_val, args, 2, llvm_cc, fn_inline, ""); | 3593 | ZigLLVMBuildCall(g->builder, fn_val, args, 2, llvm_cc, fn_inline, ""); |
| 3588 | return nullptr; | 3594 | return nullptr; |
| 3589 | } else if (callee_is_async) { | 3595 | } else if (callee_is_async) { |
| ... | @@ -3591,8 +3597,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -3591,8 +3597,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3591 | LLVMValueRef split_llvm_fn = make_fn_llvm_value(g, g->cur_fn); | 3597 | LLVMValueRef split_llvm_fn = make_fn_llvm_value(g, g->cur_fn); |
| 3592 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_fn_ptr_index, ""); | 3598 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_fn_ptr_index, ""); |
| 3593 | LLVMBuildStore(g->builder, split_llvm_fn, fn_ptr_ptr); | 3599 | LLVMBuildStore(g->builder, split_llvm_fn, fn_ptr_ptr); |
| 3594 | | 3600 | LLVMValueRef args[] = {frame_result_loc, LLVMGetUndef(usize_type_ref)}; |
| 3595 | LLVMValueRef args[] = {frame_result_loc, LLVMGetUndef(g->builtin_types.entry_usize->llvm_type)}; | | |
| 3596 | LLVMValueRef call_inst = ZigLLVMBuildCall(g->builder, fn_val, args, 2, llvm_cc, fn_inline, ""); | 3601 | LLVMValueRef call_inst = ZigLLVMBuildCall(g->builder, fn_val, args, 2, llvm_cc, fn_inline, ""); |
| 3597 | ZigLLVMSetTailCall(call_inst); | 3602 | ZigLLVMSetTailCall(call_inst); |
| 3598 | LLVMBuildRetVoid(g->builder); | 3603 | LLVMBuildRetVoid(g->builder); |
| ... | @@ -3601,6 +3606,21 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -3601,6 +3606,21 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3601 | g->cur_ret_ptr = LLVMGetParam(split_llvm_fn, 0); | 3606 | g->cur_ret_ptr = LLVMGetParam(split_llvm_fn, 0); |
| 3602 | LLVMBasicBlockRef call_bb = LLVMAppendBasicBlock(split_llvm_fn, "CallResume"); | 3607 | LLVMBasicBlockRef call_bb = LLVMAppendBasicBlock(split_llvm_fn, "CallResume"); |
| 3603 | LLVMPositionBuilderAtEnd(g->builder, call_bb); | 3608 | LLVMPositionBuilderAtEnd(g->builder, call_bb); |
| | 3609 | |
| | 3610 | if (ir_want_runtime_safety(g, &instruction->base)) { |
| | 3611 | LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(split_llvm_fn, "BadResume"); |
| | 3612 | LLVMBasicBlockRef ok_resume_block = LLVMAppendBasicBlock(split_llvm_fn, "OkResume"); |
| | 3613 | LLVMValueRef arg_val = LLVMGetParam(split_llvm_fn, 1); |
| | 3614 | LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref); |
| | 3615 | LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntNE, arg_val, all_ones, ""); |
| | 3616 | LLVMBuildCondBr(g->builder, ok_bit, ok_resume_block, bad_resume_block); |
| | 3617 | |
| | 3618 | LLVMPositionBuilderAtEnd(g->builder, bad_resume_block); |
| | 3619 | gen_safety_crash(g, PanicMsgIdResumedAnAwaitingFn); |
| | 3620 | |
| | 3621 | LLVMPositionBuilderAtEnd(g->builder, ok_resume_block); |
| | 3622 | } |
| | 3623 | |
| 3604 | render_async_var_decls(g, instruction->base.scope); | 3624 | render_async_var_decls(g, instruction->base.scope); |
| 3605 | | 3625 | |
| 3606 | if (type_has_bits(src_return_type)) { | 3626 | if (type_has_bits(src_return_type)) { |
| ... | @@ -5139,6 +5159,21 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst | ... | @@ -5139,6 +5159,21 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst |
| 5139 | g->cur_ret_ptr = LLVMGetParam(split_llvm_fn, 0); | 5159 | g->cur_ret_ptr = LLVMGetParam(split_llvm_fn, 0); |
| 5140 | LLVMBasicBlockRef call_bb = LLVMAppendBasicBlock(split_llvm_fn, "AwaitResume"); | 5160 | LLVMBasicBlockRef call_bb = LLVMAppendBasicBlock(split_llvm_fn, "AwaitResume"); |
| 5141 | LLVMPositionBuilderAtEnd(g->builder, call_bb); | 5161 | LLVMPositionBuilderAtEnd(g->builder, call_bb); |
| | 5162 | |
| | 5163 | if (ir_want_runtime_safety(g, &instruction->base)) { |
| | 5164 | LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(split_llvm_fn, "BadResume"); |
| | 5165 | LLVMBasicBlockRef ok_resume_block = LLVMAppendBasicBlock(split_llvm_fn, "OkResume"); |
| | 5166 | LLVMValueRef arg_val = LLVMGetParam(split_llvm_fn, 1); |
| | 5167 | LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref); |
| | 5168 | LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntNE, arg_val, all_ones, ""); |
| | 5169 | LLVMBuildCondBr(g->builder, ok_bit, ok_resume_block, bad_resume_block); |
| | 5170 | |
| | 5171 | LLVMPositionBuilderAtEnd(g->builder, bad_resume_block); |
| | 5172 | gen_safety_crash(g, PanicMsgIdResumedAnAwaitingFn); |
| | 5173 | |
| | 5174 | LLVMPositionBuilderAtEnd(g->builder, ok_resume_block); |
| | 5175 | } |
| | 5176 | |
| 5142 | render_async_var_decls(g, instruction->base.scope); | 5177 | render_async_var_decls(g, instruction->base.scope); |
| 5143 | | 5178 | |
| 5144 | if (type_has_bits(result_type)) { | 5179 | if (type_has_bits(result_type)) { |
| ... | @@ -5178,7 +5213,9 @@ static LLVMValueRef ir_render_coro_resume(CodeGen *g, IrExecutable *executable, | ... | @@ -5178,7 +5213,9 @@ static LLVMValueRef ir_render_coro_resume(CodeGen *g, IrExecutable *executable, |
| 5178 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, frame, coro_fn_ptr_index, ""); | 5213 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, frame, coro_fn_ptr_index, ""); |
| 5179 | LLVMValueRef uncasted_fn_val = LLVMBuildLoad(g->builder, fn_ptr_ptr, ""); | 5214 | LLVMValueRef uncasted_fn_val = LLVMBuildLoad(g->builder, fn_ptr_ptr, ""); |
| 5180 | LLVMValueRef fn_val = LLVMBuildIntToPtr(g->builder, uncasted_fn_val, anyframe_fn_type(g), ""); | 5215 | LLVMValueRef fn_val = LLVMBuildIntToPtr(g->builder, uncasted_fn_val, anyframe_fn_type(g), ""); |
| 5181 | LLVMValueRef args[] = {frame, LLVMGetUndef(usize_type_ref)}; | 5216 | LLVMValueRef arg_val = ir_want_runtime_safety(g, &instruction->base) ? |
| | 5217 | LLVMConstAllOnes(usize_type_ref) : LLVMGetUndef(usize_type_ref); |
| | 5218 | LLVMValueRef args[] = {frame, arg_val}; |
| 5182 | ZigLLVMBuildCall(g->builder, fn_val, args, 2, LLVMFastCallConv, ZigLLVM_FnInlineAuto, ""); | 5219 | ZigLLVMBuildCall(g->builder, fn_val, args, 2, LLVMFastCallConv, ZigLLVM_FnInlineAuto, ""); |
| 5183 | return nullptr; | 5220 | return nullptr; |
| 5184 | } | 5221 | } |