| ... | @@ -933,6 +933,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { | ... | @@ -933,6 +933,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { |
| 933 | return buf_create_from_str("resumed an async function which can only be awaited"); | 933 | return buf_create_from_str("resumed an async function which can only be awaited"); |
| 934 | case PanicMsgIdBadNoAsyncCall: | 934 | case PanicMsgIdBadNoAsyncCall: |
| 935 | return buf_create_from_str("async function called with noasync suspended"); | 935 | return buf_create_from_str("async function called with noasync suspended"); |
| | 936 | case PanicMsgIdResumeNotSuspendedFn: |
| | 937 | return buf_create_from_str("resumed a non-suspended function"); |
| 936 | } | 938 | } |
| 937 | zig_unreachable(); | 939 | zig_unreachable(); |
| 938 | } | 940 | } |
| ... | @@ -2234,6 +2236,12 @@ static void gen_assert_resume_id(CodeGen *g, IrInstruction *source_instr, Resume | ... | @@ -2234,6 +2236,12 @@ static void gen_assert_resume_id(CodeGen *g, IrInstruction *source_instr, Resume |
| 2234 | LLVMBasicBlockRef end_bb) | 2236 | LLVMBasicBlockRef end_bb) |
| 2235 | { | 2237 | { |
| 2236 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; | 2238 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| | 2239 | |
| | 2240 | if (ir_want_runtime_safety(g, source_instr)) { |
| | 2241 | // Write a value to the resume index which indicates the function was resumed while not suspended. |
| | 2242 | LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr); |
| | 2243 | } |
| | 2244 | |
| 2237 | LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume"); | 2245 | LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume"); |
| 2238 | if (end_bb == nullptr) end_bb = LLVMAppendBasicBlock(g->cur_fn_val, "OkResume"); | 2246 | if (end_bb == nullptr) end_bb = LLVMAppendBasicBlock(g->cur_fn_val, "OkResume"); |
| 2239 | LLVMValueRef expected_value = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), | 2247 | LLVMValueRef expected_value = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), |
| ... | @@ -5764,6 +5772,9 @@ static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutable *executabl | ... | @@ -5764,6 +5772,9 @@ static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutable *executabl |
| 5764 | LLVMBuildRetVoid(g->builder); | 5772 | LLVMBuildRetVoid(g->builder); |
| 5765 | | 5773 | |
| 5766 | LLVMPositionBuilderAtEnd(g->builder, instruction->begin->resume_bb); | 5774 | LLVMPositionBuilderAtEnd(g->builder, instruction->begin->resume_bb); |
| | 5775 | if (ir_want_runtime_safety(g, &instruction->base)) { |
| | 5776 | LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr); |
| | 5777 | } |
| 5767 | render_async_var_decls(g, instruction->base.scope); | 5778 | render_async_var_decls(g, instruction->base.scope); |
| 5768 | return nullptr; | 5779 | return nullptr; |
| 5769 | } | 5780 | } |
| ... | @@ -7542,7 +7553,20 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -7542,7 +7553,20 @@ static void do_code_gen(CodeGen *g) { |
| 7542 | IrBasicBlock *entry_block = executable->basic_block_list.at(0); | 7553 | IrBasicBlock *entry_block = executable->basic_block_list.at(0); |
| 7543 | LLVMAddCase(switch_instr, zero, entry_block->llvm_block); | 7554 | LLVMAddCase(switch_instr, zero, entry_block->llvm_block); |
| 7544 | g->cur_resume_block_count += 1; | 7555 | g->cur_resume_block_count += 1; |
| | 7556 | |
| | 7557 | { |
| | 7558 | LLVMBasicBlockRef bad_not_suspended_bb = LLVMAppendBasicBlock(g->cur_fn_val, "NotSuspended"); |
| | 7559 | size_t new_block_index = g->cur_resume_block_count; |
| | 7560 | g->cur_resume_block_count += 1; |
| | 7561 | g->cur_bad_not_suspended_index = LLVMConstInt(usize_type_ref, new_block_index, false); |
| | 7562 | LLVMAddCase(g->cur_async_switch_instr, g->cur_bad_not_suspended_index, bad_not_suspended_bb); |
| | 7563 | |
| | 7564 | LLVMPositionBuilderAtEnd(g->builder, bad_not_suspended_bb); |
| | 7565 | gen_assertion_scope(g, PanicMsgIdResumeNotSuspendedFn, fn_table_entry->child_scope); |
| | 7566 | } |
| | 7567 | |
| 7545 | LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block); | 7568 | LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block); |
| | 7569 | LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr); |
| 7546 | if (trace_field_index_stack != UINT32_MAX) { | 7570 | if (trace_field_index_stack != UINT32_MAX) { |
| 7547 | if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) { | 7571 | if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) { |
| 7548 | LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, | 7572 | LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, |