From af8c6ccb4bcae7baf30f3b1032a98b82f39d9c26 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 11 Aug 2019 14:26:34 -0400 Subject: fix canceling async functions which have error return tracing --- src/ir.cpp | 64 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 31 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 97971efd50..f1d4b80a2c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -24656,26 +24656,51 @@ static IrInstruction *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, return ir_build_suspend_finish(&ira->new_irb, instruction->base.scope, instruction->base.source_node, begin); } -static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) { - IrInstruction *frame_ptr = instruction->frame->child; +static IrInstruction *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *frame_ptr) +{ if (type_is_invalid(frame_ptr->value.type)) return ira->codegen->invalid_instruction; + ZigType *result_type; IrInstruction *frame; if (frame_ptr->value.type->id == ZigTypeIdPointer && frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle && frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdCoroFrame) { + result_type = frame_ptr->value.type->data.pointer.child_type->data.frame.fn->type_entry->data.fn.fn_type_id.return_type; frame = frame_ptr; } else { - frame = ir_get_deref(ira, &instruction->base, frame_ptr, nullptr); + frame = ir_get_deref(ira, source_instr, frame_ptr, nullptr); + if (frame->value.type->id == ZigTypeIdPointer && + frame->value.type->data.pointer.ptr_len == PtrLenSingle && + frame->value.type->data.pointer.child_type->id == ZigTypeIdCoroFrame) + { + result_type = frame->value.type->data.pointer.child_type->data.frame.fn->type_entry->data.fn.fn_type_id.return_type; + } else if (frame->value.type->id != ZigTypeIdAnyFrame || + frame->value.type->data.any_frame.result_type == nullptr) + { + ir_add_error(ira, source_instr, + buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value.type->name))); + return ira->codegen->invalid_instruction; + } else { + result_type = frame->value.type->data.any_frame.result_type; + } } - ZigType *any_frame_type = get_any_frame_type(ira->codegen, nullptr); + ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type); IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); if (type_is_invalid(casted_frame->value.type)) return ira->codegen->invalid_instruction; + return casted_frame; +} + +static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) { + IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, instruction->frame->child); + if (type_is_invalid(frame->value.type)) + return ira->codegen->invalid_instruction; + ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); ir_assert(fn_entry != nullptr, &instruction->base); @@ -24683,38 +24708,15 @@ static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructio fn_entry->inferred_async_node = instruction->base.source_node; } - return ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_frame); + return ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, frame); } static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwaitSrc *instruction) { - IrInstruction *frame_ptr = instruction->frame->child; - if (type_is_invalid(frame_ptr->value.type)) + IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, instruction->frame->child); + if (type_is_invalid(frame->value.type)) return ira->codegen->invalid_instruction; - ZigType *result_type; - IrInstruction *frame; - if (frame_ptr->value.type->id == ZigTypeIdPointer && - frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle && - frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdCoroFrame) - { - result_type = frame_ptr->value.type->data.pointer.child_type->data.frame.fn->type_entry->data.fn.fn_type_id.return_type; - frame = frame_ptr; - } else { - frame = ir_get_deref(ira, &instruction->base, frame_ptr, nullptr); - if (frame->value.type->id != ZigTypeIdAnyFrame || - frame->value.type->data.any_frame.result_type == nullptr) - { - ir_add_error(ira, &instruction->base, - buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value.type->name))); - return ira->codegen->invalid_instruction; - } - result_type = frame->value.type->data.any_frame.result_type; - } - - ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type); - IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); - if (type_is_invalid(casted_frame->value.type)) - return ira->codegen->invalid_instruction; + ZigType *result_type = frame->value.type->data.any_frame.result_type; ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); ir_assert(fn_entry != nullptr, &instruction->base); -- cgit v1.2.3