| ... | @@ -46,7 +46,10 @@ static LVal make_lval_addr(bool is_const, bool is_volatile) { | ... | @@ -46,7 +46,10 @@ static LVal make_lval_addr(bool is_const, bool is_volatile) { |
| 46 | } | 46 | } |
| 47 | | 47 | |
| 48 | static const char * ASYNC_ALLOC_FIELD_NAME = "allocFn"; | 48 | static const char * ASYNC_ALLOC_FIELD_NAME = "allocFn"; |
| 49 | //static const char * ASYNC_FREE_FIELD_NAME = "freeFn"; | 49 | static const char * ASYNC_FREE_FIELD_NAME = "freeFn"; |
| | 50 | static const char * AWAITER_HANDLE_FIELD_NAME = "awaiter_handle"; |
| | 51 | static const char * RESULT_FIELD_NAME = "result"; |
| | 52 | static const char * RESULT_PTR_FIELD_NAME = "result_ptr"; |
| 50 | | 53 | |
| 51 | enum ConstCastResultId { | 54 | enum ConstCastResultId { |
| 52 | ConstCastResultIdOk, | 55 | ConstCastResultIdOk, |
| ... | @@ -672,6 +675,22 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) | ... | @@ -672,6 +675,22 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) |
| 672 | return IrInstructionIdCoroAllocFail; | 675 | return IrInstructionIdCoroAllocFail; |
| 673 | } | 676 | } |
| 674 | | 677 | |
| | 678 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSuspend *) { |
| | 679 | return IrInstructionIdCoroSuspend; |
| | 680 | } |
| | 681 | |
| | 682 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroEnd *) { |
| | 683 | return IrInstructionIdCoroEnd; |
| | 684 | } |
| | 685 | |
| | 686 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroFree *) { |
| | 687 | return IrInstructionIdCoroFree; |
| | 688 | } |
| | 689 | |
| | 690 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroResume *) { |
| | 691 | return IrInstructionIdCoroResume; |
| | 692 | } |
| | 693 | |
| 675 | template<typename T> | 694 | template<typename T> |
| 676 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 695 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 677 | T *special_instruction = allocate<T>(1); | 696 | T *special_instruction = allocate<T>(1); |
| ... | @@ -743,14 +762,6 @@ static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *sou | ... | @@ -743,14 +762,6 @@ static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *sou |
| 743 | return &return_instruction->base; | 762 | return &return_instruction->base; |
| 744 | } | 763 | } |
| 745 | | 764 | |
| 746 | static IrInstruction *ir_build_return_from(IrBuilder *irb, IrInstruction *old_instruction, | | |
| 747 | IrInstruction *return_value) | | |
| 748 | { | | |
| 749 | IrInstruction *new_instruction = ir_build_return(irb, old_instruction->scope, old_instruction->source_node, return_value); | | |
| 750 | ir_link_new_instruction(new_instruction, old_instruction); | | |
| 751 | return new_instruction; | | |
| 752 | } | | |
| 753 | | | |
| 754 | static IrInstruction *ir_create_const(IrBuilder *irb, Scope *scope, AstNode *source_node, | 765 | static IrInstruction *ir_create_const(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 755 | TypeTableEntry *type_entry) | 766 | TypeTableEntry *type_entry) |
| 756 | { | 767 | { |
| ... | @@ -822,6 +833,14 @@ static IrInstruction *ir_build_const_u29(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -822,6 +833,14 @@ static IrInstruction *ir_build_const_u29(IrBuilder *irb, Scope *scope, AstNode * |
| 822 | return &const_instruction->base; | 833 | return &const_instruction->base; |
| 823 | } | 834 | } |
| 824 | | 835 | |
| | 836 | static IrInstruction *ir_build_const_u8(IrBuilder *irb, Scope *scope, AstNode *source_node, uint8_t value) { |
| | 837 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); |
| | 838 | const_instruction->base.value.type = irb->codegen->builtin_types.entry_u8; |
| | 839 | const_instruction->base.value.special = ConstValSpecialStatic; |
| | 840 | bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); |
| | 841 | return &const_instruction->base; |
| | 842 | } |
| | 843 | |
| 825 | static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, | 844 | static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 826 | TypeTableEntry *type_entry) | 845 | TypeTableEntry *type_entry) |
| 827 | { | 846 | { |
| ... | @@ -909,6 +928,33 @@ static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, Ast | ... | @@ -909,6 +928,33 @@ static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, Ast |
| 909 | return &const_instruction->base; | 928 | return &const_instruction->base; |
| 910 | } | 929 | } |
| 911 | | 930 | |
| | 931 | static IrInstruction *ir_build_const_promise_init(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 932 | TypeTableEntry *return_type) |
| | 933 | { |
| | 934 | TypeTableEntry *awaiter_handle_type = get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise); |
| | 935 | TypeTableEntry *result_ptr_type = get_pointer_to_type(irb->codegen, return_type, false); |
| | 936 | const char *field_names[] = {AWAITER_HANDLE_FIELD_NAME, RESULT_FIELD_NAME, RESULT_PTR_FIELD_NAME}; |
| | 937 | TypeTableEntry *field_types[] = {awaiter_handle_type, return_type, result_ptr_type}; |
| | 938 | size_t field_count = type_has_bits(result_ptr_type) ? 3 : 1; |
| | 939 | TypeTableEntry *struct_type = get_struct_type(irb->codegen, "AsyncFramePromise", field_names, field_types, |
| | 940 | field_count); |
| | 941 | |
| | 942 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); |
| | 943 | const_instruction->base.value.type = struct_type; |
| | 944 | const_instruction->base.value.special = ConstValSpecialStatic; |
| | 945 | const_instruction->base.value.data.x_struct.fields = allocate<ConstExprValue>(2); |
| | 946 | const_instruction->base.value.data.x_struct.fields[0].type = awaiter_handle_type; |
| | 947 | const_instruction->base.value.data.x_struct.fields[0].special = ConstValSpecialStatic; |
| | 948 | const_instruction->base.value.data.x_struct.fields[0].data.x_maybe = nullptr; |
| | 949 | if (field_count == 3) { |
| | 950 | const_instruction->base.value.data.x_struct.fields[1].type = return_type; |
| | 951 | const_instruction->base.value.data.x_struct.fields[1].special = ConstValSpecialUndef; |
| | 952 | const_instruction->base.value.data.x_struct.fields[2].type = result_ptr_type; |
| | 953 | const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef; |
| | 954 | } |
| | 955 | return &const_instruction->base; |
| | 956 | } |
| | 957 | |
| 912 | static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, | 958 | static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, |
| 913 | IrInstruction *op1, IrInstruction *op2, bool safety_check_on) | 959 | IrInstruction *op1, IrInstruction *op2, bool safety_check_on) |
| 914 | { | 960 | { |
| ... | @@ -2451,8 +2497,11 @@ static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *sco | ... | @@ -2451,8 +2497,11 @@ static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *sco |
| 2451 | return &instruction->base; | 2497 | return &instruction->base; |
| 2452 | } | 2498 | } |
| 2453 | | 2499 | |
| 2454 | static IrInstruction *ir_build_coro_id(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 2500 | static IrInstruction *ir_build_coro_id(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *promise_ptr) { |
| 2455 | IrInstructionCoroId *instruction = ir_build_instruction<IrInstructionCoroId>(irb, scope, source_node); | 2501 | IrInstructionCoroId *instruction = ir_build_instruction<IrInstructionCoroId>(irb, scope, source_node); |
| | 2502 | instruction->promise_ptr = promise_ptr; |
| | 2503 | |
| | 2504 | ir_ref_instruction(promise_ptr, irb->current_basic_block); |
| 2456 | | 2505 | |
| 2457 | return &instruction->base; | 2506 | return &instruction->base; |
| 2458 | } | 2507 | } |
| ... | @@ -2494,6 +2543,48 @@ static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, Ast | ... | @@ -2494,6 +2543,48 @@ static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, Ast |
| 2494 | return &instruction->base; | 2543 | return &instruction->base; |
| 2495 | } | 2544 | } |
| 2496 | | 2545 | |
| | 2546 | static IrInstruction *ir_build_coro_suspend(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2547 | IrInstruction *save_point, IrInstruction *is_final) |
| | 2548 | { |
| | 2549 | IrInstructionCoroSuspend *instruction = ir_build_instruction<IrInstructionCoroSuspend>(irb, scope, source_node); |
| | 2550 | instruction->save_point = save_point; |
| | 2551 | instruction->is_final = is_final; |
| | 2552 | |
| | 2553 | if (save_point != nullptr) ir_ref_instruction(save_point, irb->current_basic_block); |
| | 2554 | ir_ref_instruction(is_final, irb->current_basic_block); |
| | 2555 | |
| | 2556 | return &instruction->base; |
| | 2557 | } |
| | 2558 | |
| | 2559 | static IrInstruction *ir_build_coro_end(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| | 2560 | IrInstructionCoroEnd *instruction = ir_build_instruction<IrInstructionCoroEnd>(irb, scope, source_node); |
| | 2561 | return &instruction->base; |
| | 2562 | } |
| | 2563 | |
| | 2564 | static IrInstruction *ir_build_coro_free(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2565 | IrInstruction *coro_id, IrInstruction *coro_handle) |
| | 2566 | { |
| | 2567 | IrInstructionCoroFree *instruction = ir_build_instruction<IrInstructionCoroFree>(irb, scope, source_node); |
| | 2568 | instruction->coro_id = coro_id; |
| | 2569 | instruction->coro_handle = coro_handle; |
| | 2570 | |
| | 2571 | ir_ref_instruction(coro_id, irb->current_basic_block); |
| | 2572 | ir_ref_instruction(coro_handle, irb->current_basic_block); |
| | 2573 | |
| | 2574 | return &instruction->base; |
| | 2575 | } |
| | 2576 | |
| | 2577 | static IrInstruction *ir_build_coro_resume(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2578 | IrInstruction *awaiter_handle) |
| | 2579 | { |
| | 2580 | IrInstructionCoroResume *instruction = ir_build_instruction<IrInstructionCoroResume>(irb, scope, source_node); |
| | 2581 | instruction->awaiter_handle = awaiter_handle; |
| | 2582 | |
| | 2583 | ir_ref_instruction(awaiter_handle, irb->current_basic_block); |
| | 2584 | |
| | 2585 | return &instruction->base; |
| | 2586 | } |
| | 2587 | |
| 2497 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { | 2588 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 2498 | results[ReturnKindUnconditional] = 0; | 2589 | results[ReturnKindUnconditional] = 0; |
| 2499 | results[ReturnKindError] = 0; | 2590 | results[ReturnKindError] = 0; |
| ... | @@ -2566,6 +2657,29 @@ static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { | ... | @@ -2566,6 +2657,29 @@ static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { |
| 2566 | return nullptr; | 2657 | return nullptr; |
| 2567 | } | 2658 | } |
| 2568 | | 2659 | |
| | 2660 | static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode *node, IrInstruction *return_value, |
| | 2661 | bool is_generated_code) |
| | 2662 | { |
| | 2663 | FnTableEntry *fn_entry = exec_fn_entry(irb->exec); |
| | 2664 | bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; |
| | 2665 | if (!is_async) { |
| | 2666 | IrInstruction *return_inst = ir_build_return(irb, scope, node, return_value); |
| | 2667 | return_inst->is_gen = is_generated_code; |
| | 2668 | return return_inst; |
| | 2669 | } |
| | 2670 | |
| | 2671 | if (irb->exec->coro_result_ptr_field_ptr) { |
| | 2672 | IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr); |
| | 2673 | ir_build_store_ptr(irb, scope, node, result_ptr, return_value); |
| | 2674 | } |
| | 2675 | IrInstruction *maybe_await_handle = ir_build_load_ptr(irb, scope, node, irb->exec->coro_awaiter_field_ptr); |
| | 2676 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_await_handle); |
| | 2677 | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); |
| | 2678 | return ir_build_cond_br(irb, scope, node, is_non_null, irb->exec->coro_normal_final, irb->exec->coro_early_final, |
| | 2679 | is_comptime); |
| | 2680 | // the above blocks are rendered by ir_gen after the rest of codegen |
| | 2681 | } |
| | 2682 | |
| 2569 | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | 2683 | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 2570 | assert(node->type == NodeTypeReturnExpr); | 2684 | assert(node->type == NodeTypeReturnExpr); |
| 2571 | | 2685 | |
| ... | @@ -2615,18 +2729,22 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -2615,18 +2729,22 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 2615 | } | 2729 | } |
| 2616 | | 2730 | |
| 2617 | ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); | 2731 | ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); |
| | 2732 | IrBasicBlock *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); |
| 2618 | | 2733 | |
| 2619 | ir_set_cursor_at_end_and_append_block(irb, err_block); | 2734 | ir_set_cursor_at_end_and_append_block(irb, err_block); |
| 2620 | ir_gen_defers_for_block(irb, scope, outer_scope, true); | 2735 | ir_gen_defers_for_block(irb, scope, outer_scope, true); |
| 2621 | ir_build_return(irb, scope, node, return_value); | 2736 | ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); |
| 2622 | | 2737 | |
| 2623 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 2738 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 2624 | ir_gen_defers_for_block(irb, scope, outer_scope, false); | 2739 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 2625 | return ir_build_return(irb, scope, node, return_value); | 2740 | ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); |
| | 2741 | |
| | 2742 | ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); |
| | 2743 | return ir_gen_async_return(irb, scope, node, return_value, false); |
| 2626 | } else { | 2744 | } else { |
| 2627 | // generate unconditional defers | 2745 | // generate unconditional defers |
| 2628 | ir_gen_defers_for_block(irb, scope, outer_scope, false); | 2746 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 2629 | return ir_build_return(irb, scope, node, return_value); | 2747 | return ir_gen_async_return(irb, scope, node, return_value, false); |
| 2630 | } | 2748 | } |
| 2631 | } | 2749 | } |
| 2632 | case ReturnKindError: | 2750 | case ReturnKindError: |
| ... | @@ -2646,7 +2764,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -2646,7 +2764,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 2646 | ir_set_cursor_at_end_and_append_block(irb, return_block); | 2764 | ir_set_cursor_at_end_and_append_block(irb, return_block); |
| 2647 | ir_gen_defers_for_block(irb, scope, outer_scope, true); | 2765 | ir_gen_defers_for_block(irb, scope, outer_scope, true); |
| 2648 | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); | 2766 | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); |
| 2649 | ir_build_return(irb, scope, node, err_val); | 2767 | ir_gen_async_return(irb, scope, node, err_val, false); |
| 2650 | | 2768 | |
| 2651 | ir_set_cursor_at_end_and_append_block(irb, continue_block); | 2769 | ir_set_cursor_at_end_and_append_block(irb, continue_block); |
| 2652 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false); | 2770 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false); |
| ... | @@ -5842,6 +5960,7 @@ static void invalidate_exec(IrExecutable *exec) { | ... | @@ -5842,6 +5960,7 @@ static void invalidate_exec(IrExecutable *exec) { |
| 5842 | invalidate_exec(exec->source_exec); | 5960 | invalidate_exec(exec->source_exec); |
| 5843 | } | 5961 | } |
| 5844 | | 5962 | |
| | 5963 | |
| 5845 | bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { | 5964 | bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { |
| 5846 | assert(node->owner); | 5965 | assert(node->owner); |
| 5847 | | 5966 | |
| ... | @@ -5858,48 +5977,81 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -5858,48 +5977,81 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 5858 | | 5977 | |
| 5859 | FnTableEntry *fn_entry = exec_fn_entry(irb->exec); | 5978 | FnTableEntry *fn_entry = exec_fn_entry(irb->exec); |
| 5860 | bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; | 5979 | bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; |
| | 5980 | IrInstruction *u8_ptr_type; |
| | 5981 | IrInstruction *const_bool_false; |
| | 5982 | IrInstruction *coro_unwrapped_mem_ptr; |
| | 5983 | IrInstruction *coro_id; |
| | 5984 | IrInstruction *coro_promise_ptr; |
| | 5985 | IrInstruction *coro_result_field_ptr; |
| | 5986 | TypeTableEntry *return_type; |
| | 5987 | Buf *result_ptr_field_name; |
| 5861 | if (is_async) { | 5988 | if (is_async) { |
| 5862 | IrInstruction *is_comptime_false = ir_build_const_bool(irb, scope, node, false); | 5989 | // create the coro promise |
| 5863 | IrInstruction *coro_id = ir_build_coro_id(irb, scope, node); | 5990 | const_bool_false = ir_build_const_bool(irb, scope, node, false); |
| | 5991 | VariableTableEntry *promise_var = ir_create_var(irb, node, scope, nullptr, false, false, true, const_bool_false); |
| | 5992 | //scope = promise_var->child_scope; |
| | 5993 | |
| | 5994 | return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; |
| | 5995 | IrInstruction *promise_init = ir_build_const_promise_init(irb, scope, node, return_type); |
| | 5996 | ir_build_var_decl(irb, scope, node, promise_var, nullptr, nullptr, promise_init); |
| | 5997 | |
| | 5998 | coro_promise_ptr = ir_build_var_ptr(irb, scope, node, promise_var, false, false); |
| | 5999 | Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME); |
| | 6000 | irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| | 6001 | awaiter_handle_field_name); |
| | 6002 | if (type_has_bits(return_type)) { |
| | 6003 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| | 6004 | coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); |
| | 6005 | result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| | 6006 | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| | 6007 | result_ptr_field_name); |
| | 6008 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, coro_result_field_ptr); |
| | 6009 | } |
| | 6010 | |
| | 6011 | u8_ptr_type = ir_build_const_type(irb, scope, node, |
| | 6012 | get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); |
| | 6013 | IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_promise_ptr); |
| | 6014 | coro_id = ir_build_coro_id(irb, scope, node, promise_as_u8_ptr); |
| 5864 | IrInstruction *need_dyn_alloc = ir_build_coro_alloc(irb, scope, node, coro_id); | 6015 | IrInstruction *need_dyn_alloc = ir_build_coro_alloc(irb, scope, node, coro_id); |
| 5865 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); | 6016 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 5866 | IrInstruction *u8_ptr_type = ir_build_const_type(irb, scope, node, | | |
| 5867 | get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); | | |
| 5868 | IrInstruction *null_ptr = ir_build_int_to_ptr(irb, scope, node, u8_ptr_type, zero); | 6017 | IrInstruction *null_ptr = ir_build_int_to_ptr(irb, scope, node, u8_ptr_type, zero); |
| 5869 | | 6018 | |
| 5870 | IrBasicBlock *dyn_alloc_block = ir_create_basic_block(irb, scope, "DynAlloc"); | 6019 | IrBasicBlock *dyn_alloc_block = ir_create_basic_block(irb, scope, "DynAlloc"); |
| 5871 | IrBasicBlock *coro_begin_block = ir_create_basic_block(irb, scope, "CoroBegin"); | 6020 | IrBasicBlock *coro_begin_block = ir_create_basic_block(irb, scope, "CoroBegin"); |
| 5872 | ir_build_cond_br(irb, scope, node, need_dyn_alloc, dyn_alloc_block, coro_begin_block, is_comptime_false); | 6021 | ir_build_cond_br(irb, scope, node, need_dyn_alloc, dyn_alloc_block, coro_begin_block, const_bool_false); |
| 5873 | | 6022 | |
| 5874 | ir_set_cursor_at_end_and_append_block(irb, dyn_alloc_block); | 6023 | ir_set_cursor_at_end_and_append_block(irb, dyn_alloc_block); |
| 5875 | IrInstruction *coro_size = ir_build_coro_size(irb, scope, node); | 6024 | IrInstruction *coro_size = ir_build_coro_size(irb, scope, node); |
| 5876 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node); | 6025 | irb->exec->implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node); |
| 5877 | Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME); | 6026 | Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME); |
| 5878 | IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, alloc_field_name); | 6027 | IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, irb->exec->implicit_allocator_ptr, |
| | 6028 | alloc_field_name); |
| 5879 | IrInstruction *alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr); | 6029 | IrInstruction *alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr); |
| 5880 | IrInstruction *alignment = ir_build_const_u29(irb, scope, node, irb->codegen->pointer_size_bytes * 2); | 6030 | IrInstruction *alignment = ir_build_const_u29(irb, scope, node, irb->codegen->pointer_size_bytes * 2); |
| 5881 | size_t arg_count = 3; | 6031 | size_t arg_count = 3; |
| 5882 | IrInstruction **args = allocate<IrInstruction *>(arg_count); | 6032 | IrInstruction **args = allocate<IrInstruction *>(arg_count); |
| 5883 | args[0] = implicit_allocator_ptr; // self | 6033 | args[0] = irb->exec->implicit_allocator_ptr; // self |
| 5884 | args[1] = coro_size; // byte_count | 6034 | args[1] = coro_size; // byte_count |
| 5885 | args[2] = alignment; // alignment | 6035 | args[2] = alignment; // alignment |
| 5886 | IrInstruction *alloc_result = ir_build_call(irb, scope, node, nullptr, alloc_fn, arg_count, args, false, FnInlineAuto, false, nullptr); | 6036 | IrInstruction *alloc_result = ir_build_call(irb, scope, node, nullptr, alloc_fn, arg_count, args, false, |
| | 6037 | FnInlineAuto, false, nullptr); |
| 5887 | IrInstruction *alloc_result_ptr = ir_build_ref(irb, scope, node, alloc_result, true, false); | 6038 | IrInstruction *alloc_result_ptr = ir_build_ref(irb, scope, node, alloc_result, true, false); |
| 5888 | IrInstruction *alloc_result_is_err = ir_build_test_err(irb, scope, node, alloc_result); | 6039 | IrInstruction *alloc_result_is_err = ir_build_test_err(irb, scope, node, alloc_result); |
| 5889 | IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, scope, "AllocError"); | 6040 | IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, scope, "AllocError"); |
| 5890 | IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, scope, "AllocOk"); | 6041 | IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, scope, "AllocOk"); |
| 5891 | ir_build_cond_br(irb, scope, node, alloc_result_is_err, alloc_err_block, alloc_ok_block, is_comptime_false); | 6042 | ir_build_cond_br(irb, scope, node, alloc_result_is_err, alloc_err_block, alloc_ok_block, const_bool_false); |
| 5892 | | 6043 | |
| 5893 | ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); | 6044 | ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); |
| 5894 | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, alloc_result_ptr); | 6045 | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, alloc_result_ptr); |
| 5895 | ir_build_coro_alloc_fail(irb, scope, node, err_val); | 6046 | ir_build_coro_alloc_fail(irb, scope, node, err_val); |
| 5896 | | 6047 | |
| 5897 | ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); | 6048 | ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); |
| 5898 | IrInstruction *unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false); | 6049 | coro_unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false); |
| 5899 | Buf *ptr_field_name = buf_create_from_str("ptr"); | 6050 | Buf *ptr_field_name = buf_create_from_str("ptr"); |
| 5900 | IrInstruction *coro_mem_ptr_field = ir_build_field_ptr(irb, scope, node, unwrapped_mem_ptr, ptr_field_name); | 6051 | IrInstruction *coro_mem_ptr_field = ir_build_field_ptr(irb, scope, node, coro_unwrapped_mem_ptr, |
| | 6052 | ptr_field_name); |
| 5901 | IrInstruction *coro_mem_ptr = ir_build_load_ptr(irb, scope, node, coro_mem_ptr_field); | 6053 | IrInstruction *coro_mem_ptr = ir_build_load_ptr(irb, scope, node, coro_mem_ptr_field); |
| 5902 | ir_build_br(irb, scope, node, coro_begin_block, is_comptime_false); | 6054 | ir_build_br(irb, scope, node, coro_begin_block, const_bool_false); |
| 5903 | | 6055 | |
| 5904 | ir_set_cursor_at_end_and_append_block(irb, coro_begin_block); | 6056 | ir_set_cursor_at_end_and_append_block(irb, coro_begin_block); |
| 5905 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); | 6057 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| ... | @@ -5910,6 +6062,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -5910,6 +6062,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 5910 | incoming_values[1] = coro_mem_ptr; | 6062 | incoming_values[1] = coro_mem_ptr; |
| 5911 | IrInstruction *coro_mem = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 6063 | IrInstruction *coro_mem = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 5912 | irb->exec->coro_handle = ir_build_coro_begin(irb, scope, node, coro_id, coro_mem); | 6064 | irb->exec->coro_handle = ir_build_coro_begin(irb, scope, node, coro_id, coro_mem); |
| | 6065 | irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal"); |
| | 6066 | irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal"); |
| 5913 | } | 6067 | } |
| 5914 | | 6068 | |
| 5915 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LVAL_NONE); | 6069 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LVAL_NONE); |
| ... | @@ -5918,7 +6072,84 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -5918,7 +6072,84 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 5918 | return false; | 6072 | return false; |
| 5919 | | 6073 | |
| 5920 | if (!instr_is_unreachable(result)) { | 6074 | if (!instr_is_unreachable(result)) { |
| 5921 | ir_mark_gen(ir_build_return(irb, scope, result->source_node, result)); | 6075 | ir_gen_async_return(irb, scope, result->source_node, result, true); |
| | 6076 | } |
| | 6077 | |
| | 6078 | if (is_async) { |
| | 6079 | IrBasicBlock *invalid_resume_block = ir_create_basic_block(irb, scope, "InvalidResume"); |
| | 6080 | IrBasicBlock *final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); |
| | 6081 | IrBasicBlock *suspend_block = ir_create_basic_block(irb, scope, "Suspend"); |
| | 6082 | IrBasicBlock *check_free_block = ir_create_basic_block(irb, scope, "CheckFree"); |
| | 6083 | |
| | 6084 | ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_early_final); |
| | 6085 | IrInstruction *const_bool_true = ir_build_const_bool(irb, scope, node, true); |
| | 6086 | IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, nullptr, const_bool_true); |
| | 6087 | IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); |
| | 6088 | cases[0].value = ir_build_const_u8(irb, scope, node, 0); |
| | 6089 | cases[0].block = invalid_resume_block; |
| | 6090 | cases[1].value = ir_build_const_u8(irb, scope, node, 1); |
| | 6091 | cases[1].block = final_cleanup_block; |
| | 6092 | ir_build_switch_br(irb, scope, node, suspend_code, suspend_block, 2, cases, const_bool_false); |
| | 6093 | |
| | 6094 | ir_set_cursor_at_end_and_append_block(irb, suspend_block); |
| | 6095 | ir_build_coro_end(irb, scope, node); |
| | 6096 | ir_build_return(irb, scope, node, irb->exec->coro_handle); |
| | 6097 | |
| | 6098 | ir_set_cursor_at_end_and_append_block(irb, invalid_resume_block); |
| | 6099 | ir_build_unreachable(irb, scope, node); |
| | 6100 | |
| | 6101 | ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_normal_final); |
| | 6102 | ir_build_br(irb, scope, node, check_free_block, const_bool_false); |
| | 6103 | |
| | 6104 | ir_set_cursor_at_end_and_append_block(irb, final_cleanup_block); |
| | 6105 | if (type_has_bits(return_type)) { |
| | 6106 | IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr); |
| | 6107 | IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, result_ptr); |
| | 6108 | IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, |
| | 6109 | coro_result_field_ptr); |
| | 6110 | IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node, |
| | 6111 | fn_entry->type_entry->data.fn.fn_type_id.return_type); |
| | 6112 | IrInstruction *size_of_ret_val = ir_build_size_of(irb, scope, node, return_type_inst); |
| | 6113 | ir_build_memcpy(irb, scope, node, result_ptr_as_u8_ptr, return_value_ptr_as_u8_ptr, size_of_ret_val); |
| | 6114 | } |
| | 6115 | ir_build_br(irb, scope, node, check_free_block, const_bool_false); |
| | 6116 | |
| | 6117 | ir_set_cursor_at_end_and_append_block(irb, check_free_block); |
| | 6118 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| | 6119 | IrInstruction **incoming_values = allocate<IrInstruction *>(2); |
| | 6120 | incoming_blocks[0] = final_cleanup_block; |
| | 6121 | incoming_values[0] = const_bool_false; |
| | 6122 | incoming_blocks[1] = irb->exec->coro_normal_final; |
| | 6123 | incoming_values[1] = const_bool_true; |
| | 6124 | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| | 6125 | IrInstruction *mem_to_free = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); |
| | 6126 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, mem_to_free); |
| | 6127 | IrBasicBlock *dyn_free_block = ir_create_basic_block(irb, scope, "DynFree"); |
| | 6128 | IrBasicBlock *end_free_block = ir_create_basic_block(irb, scope, "EndFree"); |
| | 6129 | ir_build_cond_br(irb, scope, node, is_non_null, dyn_free_block, end_free_block, const_bool_false); |
| | 6130 | |
| | 6131 | ir_set_cursor_at_end_and_append_block(irb, dyn_free_block); |
| | 6132 | Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME); |
| | 6133 | IrInstruction *free_fn_ptr = ir_build_field_ptr(irb, scope, node, irb->exec->implicit_allocator_ptr, |
| | 6134 | free_field_name); |
| | 6135 | IrInstruction *free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr); |
| | 6136 | size_t arg_count = 2; |
| | 6137 | IrInstruction **args = allocate<IrInstruction *>(arg_count); |
| | 6138 | args[0] = irb->exec->implicit_allocator_ptr; // self |
| | 6139 | args[1] = ir_build_load_ptr(irb, scope, node, coro_unwrapped_mem_ptr); // old_mem |
| | 6140 | ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr); |
| | 6141 | ir_build_br(irb, scope, node, end_free_block, const_bool_false); |
| | 6142 | |
| | 6143 | ir_set_cursor_at_end_and_append_block(irb, end_free_block); |
| | 6144 | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); |
| | 6145 | ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, suspend_block, const_bool_false); |
| | 6146 | |
| | 6147 | ir_set_cursor_at_end_and_append_block(irb, resume_block); |
| | 6148 | IrInstruction *unwrapped_await_handle_ptr = ir_build_unwrap_maybe(irb, scope, node, |
| | 6149 | irb->exec->coro_awaiter_field_ptr, false); |
| | 6150 | IrInstruction *awaiter_handle = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); |
| | 6151 | ir_build_coro_resume(irb, scope, node, awaiter_handle); |
| | 6152 | ir_build_br(irb, scope, node, suspend_block, const_bool_false); |
| 5922 | } | 6153 | } |
| 5923 | | 6154 | |
| 5924 | return true; | 6155 | return true; |
| ... | @@ -9514,8 +9745,11 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira, | ... | @@ -9514,8 +9745,11 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira, |
| 9514 | ir_add_error(ira, casted_value, buf_sprintf("function returns address of local variable")); | 9745 | ir_add_error(ira, casted_value, buf_sprintf("function returns address of local variable")); |
| 9515 | return ir_unreach_error(ira); | 9746 | return ir_unreach_error(ira); |
| 9516 | } | 9747 | } |
| 9517 | ir_build_return_from(&ira->new_irb, &return_instruction->base, casted_value); | 9748 | IrInstruction *result = ir_build_return(&ira->new_irb, return_instruction->base.scope, |
| 9518 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); | 9749 | return_instruction->base.source_node, casted_value); |
| | 9750 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| | 9751 | ir_link_new_instruction(result, &return_instruction->base); |
| | 9752 | return ir_finish_anal(ira, result->value.type); |
| 9519 | } | 9753 | } |
| 9520 | | 9754 | |
| 9521 | static TypeTableEntry *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *const_instruction) { | 9755 | static TypeTableEntry *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *const_instruction) { |
| ... | @@ -16624,11 +16858,8 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr | ... | @@ -16624,11 +16858,8 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr |
| 16624 | | 16858 | |
| 16625 | TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize; | 16859 | TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize; |
| 16626 | | 16860 | |
| 16627 | if (!(target->value.type->id == TypeTableEntryIdPointer || | 16861 | if (!(type_is_codegen_pointer(target->value.type) || (target->value.type->id == TypeTableEntryIdMaybe && |
| 16628 | target->value.type->id == TypeTableEntryIdFn || | 16862 | type_is_codegen_pointer(target->value.type->data.maybe.child_type)))) |
| 16629 | (target->value.type->id == TypeTableEntryIdMaybe && | | |
| 16630 | (target->value.type->data.maybe.child_type->id == TypeTableEntryIdPointer || | | |
| 16631 | target->value.type->data.maybe.child_type->id == TypeTableEntryIdFn)))) | | |
| 16632 | { | 16863 | { |
| 16633 | ir_add_error(ira, target, | 16864 | ir_add_error(ira, target, |
| 16634 | buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value.type->name))); | 16865 | buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value.type->name))); |
| ... | @@ -16829,7 +17060,12 @@ static TypeTableEntry *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructi | ... | @@ -16829,7 +17060,12 @@ static TypeTableEntry *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructi |
| 16829 | } | 17060 | } |
| 16830 | | 17061 | |
| 16831 | static TypeTableEntry *ir_analyze_instruction_coro_id(IrAnalyze *ira, IrInstructionCoroId *instruction) { | 17062 | static TypeTableEntry *ir_analyze_instruction_coro_id(IrAnalyze *ira, IrInstructionCoroId *instruction) { |
| 16832 | IrInstruction *result = ir_build_coro_id(&ira->new_irb, instruction->base.scope, instruction->base.source_node); | 17063 | IrInstruction *promise_ptr = instruction->promise_ptr->other; |
| | 17064 | if (type_is_invalid(promise_ptr->value.type)) |
| | 17065 | return ira->codegen->builtin_types.entry_invalid; |
| | 17066 | |
| | 17067 | IrInstruction *result = ir_build_coro_id(&ira->new_irb, instruction->base.scope, instruction->base.source_node, |
| | 17068 | promise_ptr); |
| 16833 | ir_link_new_instruction(result, &instruction->base); | 17069 | ir_link_new_instruction(result, &instruction->base); |
| 16834 | result->value.type = ira->codegen->builtin_types.entry_usize; | 17070 | result->value.type = ira->codegen->builtin_types.entry_usize; |
| 16835 | return result->value.type; | 17071 | return result->value.type; |
| ... | @@ -16889,6 +17125,63 @@ static TypeTableEntry *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, Ir | ... | @@ -16889,6 +17125,63 @@ static TypeTableEntry *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, Ir |
| 16889 | return ir_finish_anal(ira, result->value.type); | 17125 | return ir_finish_anal(ira, result->value.type); |
| 16890 | } | 17126 | } |
| 16891 | | 17127 | |
| | 17128 | static TypeTableEntry *ir_analyze_instruction_coro_suspend(IrAnalyze *ira, IrInstructionCoroSuspend *instruction) { |
| | 17129 | IrInstruction *save_point = nullptr; |
| | 17130 | if (instruction->save_point != nullptr) { |
| | 17131 | save_point = instruction->save_point->other; |
| | 17132 | if (type_is_invalid(save_point->value.type)) |
| | 17133 | return ira->codegen->builtin_types.entry_invalid; |
| | 17134 | } |
| | 17135 | |
| | 17136 | IrInstruction *is_final = instruction->is_final->other; |
| | 17137 | if (type_is_invalid(is_final->value.type)) |
| | 17138 | return ira->codegen->builtin_types.entry_invalid; |
| | 17139 | |
| | 17140 | IrInstruction *result = ir_build_coro_suspend(&ira->new_irb, instruction->base.scope, |
| | 17141 | instruction->base.source_node, save_point, is_final); |
| | 17142 | ir_link_new_instruction(result, &instruction->base); |
| | 17143 | result->value.type = ira->codegen->builtin_types.entry_u8; |
| | 17144 | return result->value.type; |
| | 17145 | } |
| | 17146 | |
| | 17147 | static TypeTableEntry *ir_analyze_instruction_coro_end(IrAnalyze *ira, IrInstructionCoroEnd *instruction) { |
| | 17148 | IrInstruction *result = ir_build_coro_end(&ira->new_irb, instruction->base.scope, |
| | 17149 | instruction->base.source_node); |
| | 17150 | ir_link_new_instruction(result, &instruction->base); |
| | 17151 | result->value.type = ira->codegen->builtin_types.entry_void; |
| | 17152 | return result->value.type; |
| | 17153 | } |
| | 17154 | |
| | 17155 | static TypeTableEntry *ir_analyze_instruction_coro_free(IrAnalyze *ira, IrInstructionCoroFree *instruction) { |
| | 17156 | IrInstruction *coro_id = instruction->coro_id->other; |
| | 17157 | if (type_is_invalid(coro_id->value.type)) |
| | 17158 | return ira->codegen->builtin_types.entry_invalid; |
| | 17159 | |
| | 17160 | IrInstruction *coro_handle = instruction->coro_handle->other; |
| | 17161 | if (type_is_invalid(coro_handle->value.type)) |
| | 17162 | return ira->codegen->builtin_types.entry_invalid; |
| | 17163 | |
| | 17164 | IrInstruction *result = ir_build_coro_free(&ira->new_irb, instruction->base.scope, |
| | 17165 | instruction->base.source_node, coro_id, coro_handle); |
| | 17166 | ir_link_new_instruction(result, &instruction->base); |
| | 17167 | TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); |
| | 17168 | result->value.type = get_maybe_type(ira->codegen, ptr_type); |
| | 17169 | return result->value.type; |
| | 17170 | } |
| | 17171 | |
| | 17172 | static TypeTableEntry *ir_analyze_instruction_coro_resume(IrAnalyze *ira, IrInstructionCoroResume *instruction) { |
| | 17173 | IrInstruction *awaiter_handle = instruction->awaiter_handle->other; |
| | 17174 | if (type_is_invalid(awaiter_handle->value.type)) |
| | 17175 | return ira->codegen->builtin_types.entry_invalid; |
| | 17176 | |
| | 17177 | IrInstruction *result = ir_build_coro_resume(&ira->new_irb, instruction->base.scope, |
| | 17178 | instruction->base.source_node, awaiter_handle); |
| | 17179 | ir_link_new_instruction(result, &instruction->base); |
| | 17180 | result->value.type = ira->codegen->builtin_types.entry_void; |
| | 17181 | return result->value.type; |
| | 17182 | } |
| | 17183 | |
| | 17184 | |
| 16892 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 17185 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 16893 | switch (instruction->id) { | 17186 | switch (instruction->id) { |
| 16894 | case IrInstructionIdInvalid: | 17187 | case IrInstructionIdInvalid: |
| ... | @@ -17105,6 +17398,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -17105,6 +17398,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 17105 | return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction); | 17398 | return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction); |
| 17106 | case IrInstructionIdCoroAllocFail: | 17399 | case IrInstructionIdCoroAllocFail: |
| 17107 | return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction); | 17400 | return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction); |
| | 17401 | case IrInstructionIdCoroSuspend: |
| | 17402 | return ir_analyze_instruction_coro_suspend(ira, (IrInstructionCoroSuspend *)instruction); |
| | 17403 | case IrInstructionIdCoroEnd: |
| | 17404 | return ir_analyze_instruction_coro_end(ira, (IrInstructionCoroEnd *)instruction); |
| | 17405 | case IrInstructionIdCoroFree: |
| | 17406 | return ir_analyze_instruction_coro_free(ira, (IrInstructionCoroFree *)instruction); |
| | 17407 | case IrInstructionIdCoroResume: |
| | 17408 | return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction); |
| 17108 | } | 17409 | } |
| 17109 | zig_unreachable(); | 17410 | zig_unreachable(); |
| 17110 | } | 17411 | } |
| ... | @@ -17134,7 +17435,10 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl | ... | @@ -17134,7 +17435,10 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl |
| 17134 | IrAnalyze *ira = allocate<IrAnalyze>(1); | 17435 | IrAnalyze *ira = allocate<IrAnalyze>(1); |
| 17135 | old_exec->analysis = ira; | 17436 | old_exec->analysis = ira; |
| 17136 | ira->codegen = codegen; | 17437 | ira->codegen = codegen; |
| 17137 | ira->explicit_return_type = expected_type; | 17438 | |
| | 17439 | FnTableEntry *fn_entry = exec_fn_entry(old_exec); |
| | 17440 | bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; |
| | 17441 | ira->explicit_return_type = is_async ? get_promise_type(codegen, expected_type) : expected_type; |
| 17138 | | 17442 | |
| 17139 | ira->old_irb.codegen = codegen; | 17443 | ira->old_irb.codegen = codegen; |
| 17140 | ira->old_irb.exec = old_exec; | 17444 | ira->old_irb.exec = old_exec; |
| ... | @@ -17222,6 +17526,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -17222,6 +17526,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 17222 | case IrInstructionIdCoroId: | 17526 | case IrInstructionIdCoroId: |
| 17223 | case IrInstructionIdCoroBegin: | 17527 | case IrInstructionIdCoroBegin: |
| 17224 | case IrInstructionIdCoroAllocFail: | 17528 | case IrInstructionIdCoroAllocFail: |
| | 17529 | case IrInstructionIdCoroEnd: |
| | 17530 | case IrInstructionIdCoroResume: |
| 17225 | return true; | 17531 | return true; |
| 17226 | | 17532 | |
| 17227 | case IrInstructionIdPhi: | 17533 | case IrInstructionIdPhi: |
| ... | @@ -17299,6 +17605,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -17299,6 +17605,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 17299 | case IrInstructionIdGetImplicitAllocator: | 17605 | case IrInstructionIdGetImplicitAllocator: |
| 17300 | case IrInstructionIdCoroAlloc: | 17606 | case IrInstructionIdCoroAlloc: |
| 17301 | case IrInstructionIdCoroSize: | 17607 | case IrInstructionIdCoroSize: |
| | 17608 | case IrInstructionIdCoroSuspend: |
| | 17609 | case IrInstructionIdCoroFree: |
| 17302 | return false; | 17610 | return false; |
| 17303 | | 17611 | |
| 17304 | case IrInstructionIdAsm: | 17612 | case IrInstructionIdAsm: |