authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-11 14:26:34-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-11 14:26:34-04:00
logaf8c6ccb4bcae7baf30f3b1032a98b82f39d9c26
treed9e4265a81a3054f59c04febe22fab2e5d40c62b
parent3f5c6d7a891a22ce6c38c93498339319a36dd2fe
signaturelock-open Commit is signed but in an unrecognized format.

fix canceling async functions which have error return tracing


2 files changed, 50 insertions(+), 31 deletions(-)

src/codegen.cpp+17
...@@ -2071,6 +2071,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {...@@ -2071,6 +2071,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
2071 LLVMPositionBuilderAtEnd(g->builder, entry_block);2071 LLVMPositionBuilderAtEnd(g->builder, entry_block);
2072 ZigLLVMClearCurrentDebugLocation(g->builder);2072 ZigLLVMClearCurrentDebugLocation(g->builder);
20732073
2074 // if (dest_stack_trace == null) return;
2074 // var frame_index: usize = undefined;2075 // var frame_index: usize = undefined;
2075 // var frames_left: usize = undefined;2076 // var frames_left: usize = undefined;
2076 // if (src_stack_trace.index < src_stack_trace.instruction_addresses.len) {2077 // if (src_stack_trace.index < src_stack_trace.instruction_addresses.len) {
...@@ -2088,6 +2089,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {...@@ -2088,6 +2089,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
2088 // frame_index = (frame_index + 1) % src_stack_trace.instruction_addresses.len;2089 // frame_index = (frame_index + 1) % src_stack_trace.instruction_addresses.len;
2089 // }2090 // }
2090 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");2091 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");
2092 LLVMBasicBlockRef dest_non_null_block = LLVMAppendBasicBlock(fn_val, "DestNonNull");
20912093
2092 LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index");2094 LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index");
2093 LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frames_left");2095 LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frames_left");
...@@ -2095,6 +2097,11 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {...@@ -2095,6 +2097,11 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
2095 LLVMValueRef dest_stack_trace_ptr = LLVMGetParam(fn_val, 0);2097 LLVMValueRef dest_stack_trace_ptr = LLVMGetParam(fn_val, 0);
2096 LLVMValueRef src_stack_trace_ptr = LLVMGetParam(fn_val, 1);2098 LLVMValueRef src_stack_trace_ptr = LLVMGetParam(fn_val, 1);
20972099
2100 LLVMValueRef null_dest_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, dest_stack_trace_ptr,
2101 LLVMConstNull(LLVMTypeOf(dest_stack_trace_ptr)), "");
2102 LLVMBuildCondBr(g->builder, null_dest_bit, return_block, dest_non_null_block);
2103
2104 LLVMPositionBuilderAtEnd(g->builder, dest_non_null_block);
2098 size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;2105 size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
2099 size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;2106 size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
2100 LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,2107 LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
...@@ -5480,10 +5487,20 @@ static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrIns...@@ -5480,10 +5487,20 @@ static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrIns
5480 LLVMValueRef zero = LLVMConstNull(usize_type_ref);5487 LLVMValueRef zero = LLVMConstNull(usize_type_ref);
5481 LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);5488 LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);
5482 LLVMValueRef one = LLVMConstInt(usize_type_ref, 1, false);5489 LLVMValueRef one = LLVMConstInt(usize_type_ref, 1, false);
5490 src_assert(instruction->frame->value.type->id == ZigTypeIdAnyFrame, instruction->base.source_node);
5491 ZigType *result_type = instruction->frame->value.type->data.any_frame.result_type;
54835492
5484 LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);5493 LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);
5485 LLVMBasicBlockRef resume_bb = gen_suspend_begin(g, "CancelResume");5494 LLVMBasicBlockRef resume_bb = gen_suspend_begin(g, "CancelResume");
54865495
5496 // supply null for the error return trace pointer
5497 if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
5498 LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr,
5499 frame_index_trace_arg(g, result_type), "");
5500 LLVMBuildStore(g->builder, LLVMConstNull(LLVMGetElementType(LLVMTypeOf(err_ret_trace_ptr_ptr))),
5501 err_ret_trace_ptr_ptr);
5502 }
5503
5487 LLVMValueRef awaiter_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, "");5504 LLVMValueRef awaiter_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, "");
5488 LLVMValueRef awaiter_ored_val = LLVMBuildOr(g->builder, awaiter_val, one, "");5505 LLVMValueRef awaiter_ored_val = LLVMBuildOr(g->builder, awaiter_val, one, "");
5489 LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, coro_awaiter_index, "");5506 LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, coro_awaiter_index, "");
src/ir.cpp+33-31
...@@ -24656,26 +24656,51 @@ static IrInstruction *ir_analyze_instruction_suspend_finish(IrAnalyze *ira,...@@ -24656,26 +24656,51 @@ static IrInstruction *ir_analyze_instruction_suspend_finish(IrAnalyze *ira,
24656 return ir_build_suspend_finish(&ira->new_irb, instruction->base.scope, instruction->base.source_node, begin);24656 return ir_build_suspend_finish(&ira->new_irb, instruction->base.scope, instruction->base.source_node, begin);
24657}24657}
2465824658
24659static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) {24659static IrInstruction *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInstruction *source_instr,
24660 IrInstruction *frame_ptr = instruction->frame->child;24660 IrInstruction *frame_ptr)
24661{
24661 if (type_is_invalid(frame_ptr->value.type))24662 if (type_is_invalid(frame_ptr->value.type))
24662 return ira->codegen->invalid_instruction;24663 return ira->codegen->invalid_instruction;
2466324664
24665 ZigType *result_type;
24664 IrInstruction *frame;24666 IrInstruction *frame;
24665 if (frame_ptr->value.type->id == ZigTypeIdPointer &&24667 if (frame_ptr->value.type->id == ZigTypeIdPointer &&
24666 frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle &&24668 frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle &&
24667 frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdCoroFrame)24669 frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdCoroFrame)
24668 {24670 {
24671 result_type = frame_ptr->value.type->data.pointer.child_type->data.frame.fn->type_entry->data.fn.fn_type_id.return_type;
24669 frame = frame_ptr;24672 frame = frame_ptr;
24670 } else {24673 } else {
24671 frame = ir_get_deref(ira, &instruction->base, frame_ptr, nullptr);24674 frame = ir_get_deref(ira, source_instr, frame_ptr, nullptr);
24675 if (frame->value.type->id == ZigTypeIdPointer &&
24676 frame->value.type->data.pointer.ptr_len == PtrLenSingle &&
24677 frame->value.type->data.pointer.child_type->id == ZigTypeIdCoroFrame)
24678 {
24679 result_type = frame->value.type->data.pointer.child_type->data.frame.fn->type_entry->data.fn.fn_type_id.return_type;
24680 } else if (frame->value.type->id != ZigTypeIdAnyFrame ||
24681 frame->value.type->data.any_frame.result_type == nullptr)
24682 {
24683 ir_add_error(ira, source_instr,
24684 buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value.type->name)));
24685 return ira->codegen->invalid_instruction;
24686 } else {
24687 result_type = frame->value.type->data.any_frame.result_type;
24688 }
24672 }24689 }
2467324690
24674 ZigType *any_frame_type = get_any_frame_type(ira->codegen, nullptr);24691 ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type);
24675 IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type);24692 IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type);
24676 if (type_is_invalid(casted_frame->value.type))24693 if (type_is_invalid(casted_frame->value.type))
24677 return ira->codegen->invalid_instruction;24694 return ira->codegen->invalid_instruction;
2467824695
24696 return casted_frame;
24697}
24698
24699static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) {
24700 IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, instruction->frame->child);
24701 if (type_is_invalid(frame->value.type))
24702 return ira->codegen->invalid_instruction;
24703
24679 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);24704 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
24680 ir_assert(fn_entry != nullptr, &instruction->base);24705 ir_assert(fn_entry != nullptr, &instruction->base);
2468124706
...@@ -24683,38 +24708,15 @@ static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructio...@@ -24683,38 +24708,15 @@ static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructio
24683 fn_entry->inferred_async_node = instruction->base.source_node;24708 fn_entry->inferred_async_node = instruction->base.source_node;
24684 }24709 }
2468524710
24686 return ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_frame);24711 return ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, frame);
24687}24712}
2468824713
24689static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwaitSrc *instruction) {24714static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwaitSrc *instruction) {
24690 IrInstruction *frame_ptr = instruction->frame->child;24715 IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, instruction->frame->child);
24691 if (type_is_invalid(frame_ptr->value.type))24716 if (type_is_invalid(frame->value.type))
24692 return ira->codegen->invalid_instruction;24717 return ira->codegen->invalid_instruction;
2469324718
24694 ZigType *result_type;24719 ZigType *result_type = frame->value.type->data.any_frame.result_type;
24695 IrInstruction *frame;
24696 if (frame_ptr->value.type->id == ZigTypeIdPointer &&
24697 frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle &&
24698 frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdCoroFrame)
24699 {
24700 result_type = frame_ptr->value.type->data.pointer.child_type->data.frame.fn->type_entry->data.fn.fn_type_id.return_type;
24701 frame = frame_ptr;
24702 } else {
24703 frame = ir_get_deref(ira, &instruction->base, frame_ptr, nullptr);
24704 if (frame->value.type->id != ZigTypeIdAnyFrame ||
24705 frame->value.type->data.any_frame.result_type == nullptr)
24706 {
24707 ir_add_error(ira, &instruction->base,
24708 buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value.type->name)));
24709 return ira->codegen->invalid_instruction;
24710 }
24711 result_type = frame->value.type->data.any_frame.result_type;
24712 }
24713
24714 ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type);
24715 IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type);
24716 if (type_is_invalid(casted_frame->value.type))
24717 return ira->codegen->invalid_instruction;
2471824720
24719 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);24721 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
24720 ir_assert(fn_entry != nullptr, &instruction->base);24722 ir_assert(fn_entry != nullptr, &instruction->base);