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) {
20712071 LLVMPositionBuilderAtEnd(g->builder, entry_block);
20722072 ZigLLVMClearCurrentDebugLocation(g->builder);
20732073
2074 // if (dest_stack_trace == null) return;
20742075 // var frame_index: usize = undefined;
20752076 // var frames_left: usize = undefined;
20762077 // 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) {
20882089 // frame_index = (frame_index + 1) % src_stack_trace.instruction_addresses.len;
20892090 // }
20902091 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");
2092 LLVMBasicBlockRef dest_non_null_block = LLVMAppendBasicBlock(fn_val, "DestNonNull");
20912093
20922094 LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index");
20932095 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) {
20952097 LLVMValueRef dest_stack_trace_ptr = LLVMGetParam(fn_val, 0);
20962098 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);
20982105 size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
20992106 size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
21002107 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
54805487 LLVMValueRef zero = LLVMConstNull(usize_type_ref);
54815488 LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);
54825489 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
54845493 LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);
54855494 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
54875504 LLVMValueRef awaiter_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, "");
54885505 LLVMValueRef awaiter_ored_val = LLVMBuildOr(g->builder, awaiter_val, one, "");
54895506 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,
2465624656 return ir_build_suspend_finish(&ira->new_irb, instruction->base.scope, instruction->base.source_node, begin);
2465724657}
2465824658
24659static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) {
24660 IrInstruction *frame_ptr = instruction->frame->child;
24659static IrInstruction *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInstruction *source_instr,
24660 IrInstruction *frame_ptr)
24661{
2466124662 if (type_is_invalid(frame_ptr->value.type))
2466224663 return ira->codegen->invalid_instruction;
2466324664
24665 ZigType *result_type;
2466424666 IrInstruction *frame;
2466524667 if (frame_ptr->value.type->id == ZigTypeIdPointer &&
2466624668 frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle &&
2466724669 frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdCoroFrame)
2466824670 {
24671 result_type = frame_ptr->value.type->data.pointer.child_type->data.frame.fn->type_entry->data.fn.fn_type_id.return_type;
2466924672 frame = frame_ptr;
2467024673 } 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 }
2467224689 }
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);
2467524692 IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type);
2467624693 if (type_is_invalid(casted_frame->value.type))
2467724694 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
2467924704 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
2468024705 ir_assert(fn_entry != nullptr, &instruction->base);
2468124706
......@@ -24683,38 +24708,15 @@ static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructio
2468324708 fn_entry->inferred_async_node = instruction->base.source_node;
2468424709 }
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);
2468724712}
2468824713
2468924714static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwaitSrc *instruction) {
24690 IrInstruction *frame_ptr = instruction->frame->child;
24691 if (type_is_invalid(frame_ptr->value.type))
24715 IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, instruction->frame->child);
24716 if (type_is_invalid(frame->value.type))
2469224717 return ira->codegen->invalid_instruction;
2469324718
24694 ZigType *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;
24719 ZigType *result_type = frame->value.type->data.any_frame.result_type;
2471824720
2471924721 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
2472024722 ir_assert(fn_entry != nullptr, &instruction->base);