| ... | ... | @@ -99,7 +99,6 @@ struct ConstCastOnly { |
| 99 | 99 | ConstCastErrUnionErrSetMismatch *error_union_error_set; |
| 100 | 100 | ConstCastTypeMismatch *type_mismatch; |
| 101 | 101 | ConstCastOnly *return_type; |
| 102 | | ConstCastOnly *async_allocator_type; |
| 103 | 102 | ConstCastOnly *null_wrap_ptr_child; |
| 104 | 103 | ConstCastArg fn_arg; |
| 105 | 104 | ConstCastArgNoAlias arg_no_alias; |
| ... | ... | @@ -318,7 +317,6 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { |
| 318 | 317 | case ZigTypeIdUnion: |
| 319 | 318 | case ZigTypeIdFn: |
| 320 | 319 | case ZigTypeIdArgTuple: |
| 321 | | case ZigTypeIdPromise: |
| 322 | 320 | case ZigTypeIdVector: |
| 323 | 321 | return false; |
| 324 | 322 | } |
| ... | ... | @@ -564,10 +562,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { |
| 564 | 562 | return IrInstructionIdArrayType; |
| 565 | 563 | } |
| 566 | 564 | |
| 567 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseType *) { |
| 568 | | return IrInstructionIdPromiseType; |
| 569 | | } |
| 570 | | |
| 571 | 565 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { |
| 572 | 566 | return IrInstructionIdSliceType; |
| 573 | 567 | } |
| ... | ... | @@ -964,58 +958,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCancel *) { |
| 964 | 958 | return IrInstructionIdCancel; |
| 965 | 959 | } |
| 966 | 960 | |
| 967 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionGetImplicitAllocator *) { |
| 968 | | return IrInstructionIdGetImplicitAllocator; |
| 969 | | } |
| 970 | | |
| 971 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroId *) { |
| 972 | | return IrInstructionIdCoroId; |
| 973 | | } |
| 974 | | |
| 975 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAlloc *) { |
| 976 | | return IrInstructionIdCoroAlloc; |
| 977 | | } |
| 978 | | |
| 979 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSize *) { |
| 980 | | return IrInstructionIdCoroSize; |
| 981 | | } |
| 982 | | |
| 983 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) { |
| 984 | | return IrInstructionIdCoroBegin; |
| 985 | | } |
| 986 | | |
| 987 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) { |
| 988 | | return IrInstructionIdCoroAllocFail; |
| 989 | | } |
| 990 | | |
| 991 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSuspend *) { |
| 992 | | return IrInstructionIdCoroSuspend; |
| 993 | | } |
| 994 | | |
| 995 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroEnd *) { |
| 996 | | return IrInstructionIdCoroEnd; |
| 997 | | } |
| 998 | | |
| 999 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroFree *) { |
| 1000 | | return IrInstructionIdCoroFree; |
| 1001 | | } |
| 1002 | | |
| 1003 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroResume *) { |
| 1004 | | return IrInstructionIdCoroResume; |
| 1005 | | } |
| 1006 | | |
| 1007 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSave *) { |
| 1008 | | return IrInstructionIdCoroSave; |
| 1009 | | } |
| 1010 | | |
| 1011 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroPromise *) { |
| 1012 | | return IrInstructionIdCoroPromise; |
| 1013 | | } |
| 1014 | | |
| 1015 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocHelper *) { |
| 1016 | | return IrInstructionIdCoroAllocHelper; |
| 1017 | | } |
| 1018 | | |
| 1019 | 961 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) { |
| 1020 | 962 | return IrInstructionIdAtomicRmw; |
| 1021 | 963 | } |
| ... | ... | @@ -1024,14 +966,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) { |
| 1024 | 966 | return IrInstructionIdAtomicLoad; |
| 1025 | 967 | } |
| 1026 | 968 | |
| 1027 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseResultType *) { |
| 1028 | | return IrInstructionIdPromiseResultType; |
| 1029 | | } |
| 1030 | | |
| 1031 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitBookkeeping *) { |
| 1032 | | return IrInstructionIdAwaitBookkeeping; |
| 1033 | | } |
| 1034 | | |
| 1035 | 969 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) { |
| 1036 | 970 | return IrInstructionIdSaveErrRetAddr; |
| 1037 | 971 | } |
| ... | ... | @@ -1040,10 +974,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAddImplicitRetur |
| 1040 | 974 | return IrInstructionIdAddImplicitReturnType; |
| 1041 | 975 | } |
| 1042 | 976 | |
| 1043 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrRetTraces *) { |
| 1044 | | return IrInstructionIdMergeErrRetTraces; |
| 1045 | | } |
| 1046 | | |
| 1047 | 977 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTracePtr *) { |
| 1048 | 978 | return IrInstructionIdMarkErrRetTracePtr; |
| 1049 | 979 | } |
| ... | ... | @@ -1213,14 +1143,6 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode |
| 1213 | 1143 | return &const_instruction->base; |
| 1214 | 1144 | } |
| 1215 | 1145 | |
| 1216 | | static IrInstruction *ir_build_const_u8(IrBuilder *irb, Scope *scope, AstNode *source_node, uint8_t value) { |
| 1217 | | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); |
| 1218 | | const_instruction->base.value.type = irb->codegen->builtin_types.entry_u8; |
| 1219 | | const_instruction->base.value.special = ConstValSpecialStatic; |
| 1220 | | bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); |
| 1221 | | return &const_instruction->base; |
| 1222 | | } |
| 1223 | | |
| 1224 | 1146 | static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1225 | 1147 | ZigType *type_entry) |
| 1226 | 1148 | { |
| ... | ... | @@ -1428,7 +1350,7 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast |
| 1428 | 1350 | |
| 1429 | 1351 | static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1430 | 1352 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1431 | | bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, |
| 1353 | bool is_comptime, FnInline fn_inline, bool is_async, |
| 1432 | 1354 | IrInstruction *new_stack, ResultLoc *result_loc) |
| 1433 | 1355 | { |
| 1434 | 1356 | IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); |
| ... | ... | @@ -1439,14 +1361,12 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s |
| 1439 | 1361 | call_instruction->args = args; |
| 1440 | 1362 | call_instruction->arg_count = arg_count; |
| 1441 | 1363 | call_instruction->is_async = is_async; |
| 1442 | | call_instruction->async_allocator = async_allocator; |
| 1443 | 1364 | call_instruction->new_stack = new_stack; |
| 1444 | 1365 | call_instruction->result_loc = result_loc; |
| 1445 | 1366 | |
| 1446 | 1367 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); |
| 1447 | 1368 | for (size_t i = 0; i < arg_count; i += 1) |
| 1448 | 1369 | ir_ref_instruction(args[i], irb->current_basic_block); |
| 1449 | | if (async_allocator != nullptr) ir_ref_instruction(async_allocator, irb->current_basic_block); |
| 1450 | 1370 | if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block); |
| 1451 | 1371 | |
| 1452 | 1372 | return &call_instruction->base; |
| ... | ... | @@ -1454,7 +1374,7 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s |
| 1454 | 1374 | |
| 1455 | 1375 | static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1456 | 1376 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1457 | | FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack, |
| 1377 | FnInline fn_inline, bool is_async, IrInstruction *new_stack, |
| 1458 | 1378 | IrInstruction *result_loc, ZigType *return_type) |
| 1459 | 1379 | { |
| 1460 | 1380 | IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, |
| ... | ... | @@ -1466,14 +1386,12 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in |
| 1466 | 1386 | call_instruction->args = args; |
| 1467 | 1387 | call_instruction->arg_count = arg_count; |
| 1468 | 1388 | call_instruction->is_async = is_async; |
| 1469 | | call_instruction->async_allocator = async_allocator; |
| 1470 | 1389 | call_instruction->new_stack = new_stack; |
| 1471 | 1390 | call_instruction->result_loc = result_loc; |
| 1472 | 1391 | |
| 1473 | 1392 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); |
| 1474 | 1393 | for (size_t i = 0; i < arg_count; i += 1) |
| 1475 | 1394 | ir_ref_instruction(args[i], ira->new_irb.current_basic_block); |
| 1476 | | if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block); |
| 1477 | 1395 | if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); |
| 1478 | 1396 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1479 | 1397 | |
| ... | ... | @@ -1753,17 +1671,6 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode |
| 1753 | 1671 | return &instruction->base; |
| 1754 | 1672 | } |
| 1755 | 1673 | |
| 1756 | | static IrInstruction *ir_build_promise_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1757 | | IrInstruction *payload_type) |
| 1758 | | { |
| 1759 | | IrInstructionPromiseType *instruction = ir_build_instruction<IrInstructionPromiseType>(irb, scope, source_node); |
| 1760 | | instruction->payload_type = payload_type; |
| 1761 | | |
| 1762 | | if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); |
| 1763 | | |
| 1764 | | return &instruction->base; |
| 1765 | | } |
| 1766 | | |
| 1767 | 1674 | static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1768 | 1675 | IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero) |
| 1769 | 1676 | { |
| ... | ... | @@ -2595,13 +2502,12 @@ static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, |
| 2595 | 2502 | |
| 2596 | 2503 | static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2597 | 2504 | IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type, |
| 2598 | | IrInstruction *async_allocator_type_value, bool is_var_args) |
| 2505 | bool is_var_args) |
| 2599 | 2506 | { |
| 2600 | 2507 | IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node); |
| 2601 | 2508 | instruction->param_types = param_types; |
| 2602 | 2509 | instruction->align_value = align_value; |
| 2603 | 2510 | instruction->return_type = return_type; |
| 2604 | | instruction->async_allocator_type_value = async_allocator_type_value; |
| 2605 | 2511 | instruction->is_var_args = is_var_args; |
| 2606 | 2512 | |
| 2607 | 2513 | assert(source_node->type == NodeTypeFnProto); |
| ... | ... | @@ -2611,7 +2517,6 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s |
| 2611 | 2517 | if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); |
| 2612 | 2518 | } |
| 2613 | 2519 | if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); |
| 2614 | | if (async_allocator_type_value != nullptr) ir_ref_instruction(async_allocator_type_value, irb->current_basic_block); |
| 2615 | 2520 | ir_ref_instruction(return_type, irb->current_basic_block); |
| 2616 | 2521 | |
| 2617 | 2522 | return &instruction->base; |
| ... | ... | @@ -3055,149 +2960,6 @@ static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode |
| 3055 | 2960 | return &instruction->base; |
| 3056 | 2961 | } |
| 3057 | 2962 | |
| 3058 | | static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3059 | | IrInstruction *target) |
| 3060 | | { |
| 3061 | | IrInstructionCancel *instruction = ir_build_instruction<IrInstructionCancel>(irb, scope, source_node); |
| 3062 | | instruction->target = target; |
| 3063 | | |
| 3064 | | ir_ref_instruction(target, irb->current_basic_block); |
| 3065 | | |
| 3066 | | return &instruction->base; |
| 3067 | | } |
| 3068 | | |
| 3069 | | static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3070 | | ImplicitAllocatorId id) |
| 3071 | | { |
| 3072 | | IrInstructionGetImplicitAllocator *instruction = ir_build_instruction<IrInstructionGetImplicitAllocator>(irb, scope, source_node); |
| 3073 | | instruction->id = id; |
| 3074 | | |
| 3075 | | return &instruction->base; |
| 3076 | | } |
| 3077 | | |
| 3078 | | static IrInstruction *ir_build_coro_id(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *promise_ptr) { |
| 3079 | | IrInstructionCoroId *instruction = ir_build_instruction<IrInstructionCoroId>(irb, scope, source_node); |
| 3080 | | instruction->promise_ptr = promise_ptr; |
| 3081 | | |
| 3082 | | ir_ref_instruction(promise_ptr, irb->current_basic_block); |
| 3083 | | |
| 3084 | | return &instruction->base; |
| 3085 | | } |
| 3086 | | |
| 3087 | | static IrInstruction *ir_build_coro_alloc(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id) { |
| 3088 | | IrInstructionCoroAlloc *instruction = ir_build_instruction<IrInstructionCoroAlloc>(irb, scope, source_node); |
| 3089 | | instruction->coro_id = coro_id; |
| 3090 | | |
| 3091 | | ir_ref_instruction(coro_id, irb->current_basic_block); |
| 3092 | | |
| 3093 | | return &instruction->base; |
| 3094 | | } |
| 3095 | | |
| 3096 | | static IrInstruction *ir_build_coro_size(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 3097 | | IrInstructionCoroSize *instruction = ir_build_instruction<IrInstructionCoroSize>(irb, scope, source_node); |
| 3098 | | |
| 3099 | | return &instruction->base; |
| 3100 | | } |
| 3101 | | |
| 3102 | | static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id, IrInstruction *coro_mem_ptr) { |
| 3103 | | IrInstructionCoroBegin *instruction = ir_build_instruction<IrInstructionCoroBegin>(irb, scope, source_node); |
| 3104 | | instruction->coro_id = coro_id; |
| 3105 | | instruction->coro_mem_ptr = coro_mem_ptr; |
| 3106 | | |
| 3107 | | ir_ref_instruction(coro_id, irb->current_basic_block); |
| 3108 | | ir_ref_instruction(coro_mem_ptr, irb->current_basic_block); |
| 3109 | | |
| 3110 | | return &instruction->base; |
| 3111 | | } |
| 3112 | | |
| 3113 | | static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_val) { |
| 3114 | | IrInstructionCoroAllocFail *instruction = ir_build_instruction<IrInstructionCoroAllocFail>(irb, scope, source_node); |
| 3115 | | instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; |
| 3116 | | instruction->base.value.special = ConstValSpecialStatic; |
| 3117 | | instruction->err_val = err_val; |
| 3118 | | |
| 3119 | | ir_ref_instruction(err_val, irb->current_basic_block); |
| 3120 | | |
| 3121 | | return &instruction->base; |
| 3122 | | } |
| 3123 | | |
| 3124 | | static IrInstruction *ir_build_coro_suspend(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3125 | | IrInstruction *save_point, IrInstruction *is_final) |
| 3126 | | { |
| 3127 | | IrInstructionCoroSuspend *instruction = ir_build_instruction<IrInstructionCoroSuspend>(irb, scope, source_node); |
| 3128 | | instruction->save_point = save_point; |
| 3129 | | instruction->is_final = is_final; |
| 3130 | | |
| 3131 | | if (save_point != nullptr) ir_ref_instruction(save_point, irb->current_basic_block); |
| 3132 | | ir_ref_instruction(is_final, irb->current_basic_block); |
| 3133 | | |
| 3134 | | return &instruction->base; |
| 3135 | | } |
| 3136 | | |
| 3137 | | static IrInstruction *ir_build_coro_end(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 3138 | | IrInstructionCoroEnd *instruction = ir_build_instruction<IrInstructionCoroEnd>(irb, scope, source_node); |
| 3139 | | return &instruction->base; |
| 3140 | | } |
| 3141 | | |
| 3142 | | static IrInstruction *ir_build_coro_free(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3143 | | IrInstruction *coro_id, IrInstruction *coro_handle) |
| 3144 | | { |
| 3145 | | IrInstructionCoroFree *instruction = ir_build_instruction<IrInstructionCoroFree>(irb, scope, source_node); |
| 3146 | | instruction->coro_id = coro_id; |
| 3147 | | instruction->coro_handle = coro_handle; |
| 3148 | | |
| 3149 | | ir_ref_instruction(coro_id, irb->current_basic_block); |
| 3150 | | ir_ref_instruction(coro_handle, irb->current_basic_block); |
| 3151 | | |
| 3152 | | return &instruction->base; |
| 3153 | | } |
| 3154 | | |
| 3155 | | static IrInstruction *ir_build_coro_resume(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3156 | | IrInstruction *awaiter_handle) |
| 3157 | | { |
| 3158 | | IrInstructionCoroResume *instruction = ir_build_instruction<IrInstructionCoroResume>(irb, scope, source_node); |
| 3159 | | instruction->awaiter_handle = awaiter_handle; |
| 3160 | | |
| 3161 | | ir_ref_instruction(awaiter_handle, irb->current_basic_block); |
| 3162 | | |
| 3163 | | return &instruction->base; |
| 3164 | | } |
| 3165 | | |
| 3166 | | static IrInstruction *ir_build_coro_save(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3167 | | IrInstruction *coro_handle) |
| 3168 | | { |
| 3169 | | IrInstructionCoroSave *instruction = ir_build_instruction<IrInstructionCoroSave>(irb, scope, source_node); |
| 3170 | | instruction->coro_handle = coro_handle; |
| 3171 | | |
| 3172 | | ir_ref_instruction(coro_handle, irb->current_basic_block); |
| 3173 | | |
| 3174 | | return &instruction->base; |
| 3175 | | } |
| 3176 | | |
| 3177 | | static IrInstruction *ir_build_coro_promise(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3178 | | IrInstruction *coro_handle) |
| 3179 | | { |
| 3180 | | IrInstructionCoroPromise *instruction = ir_build_instruction<IrInstructionCoroPromise>(irb, scope, source_node); |
| 3181 | | instruction->coro_handle = coro_handle; |
| 3182 | | |
| 3183 | | ir_ref_instruction(coro_handle, irb->current_basic_block); |
| 3184 | | |
| 3185 | | return &instruction->base; |
| 3186 | | } |
| 3187 | | |
| 3188 | | static IrInstruction *ir_build_coro_alloc_helper(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3189 | | IrInstruction *realloc_fn, IrInstruction *coro_size) |
| 3190 | | { |
| 3191 | | IrInstructionCoroAllocHelper *instruction = ir_build_instruction<IrInstructionCoroAllocHelper>(irb, scope, source_node); |
| 3192 | | instruction->realloc_fn = realloc_fn; |
| 3193 | | instruction->coro_size = coro_size; |
| 3194 | | |
| 3195 | | ir_ref_instruction(realloc_fn, irb->current_basic_block); |
| 3196 | | ir_ref_instruction(coro_size, irb->current_basic_block); |
| 3197 | | |
| 3198 | | return &instruction->base; |
| 3199 | | } |
| 3200 | | |
| 3201 | 2963 | static IrInstruction *ir_build_atomic_rmw(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3202 | 2964 | IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *op, IrInstruction *operand, |
| 3203 | 2965 | IrInstruction *ordering, AtomicRmwOp resolved_op, AtomicOrder resolved_ordering) |
| ... | ... | @@ -3237,28 +2999,6 @@ static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode |
| 3237 | 2999 | return &instruction->base; |
| 3238 | 3000 | } |
| 3239 | 3001 | |
| 3240 | | static IrInstruction *ir_build_promise_result_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3241 | | IrInstruction *promise_type) |
| 3242 | | { |
| 3243 | | IrInstructionPromiseResultType *instruction = ir_build_instruction<IrInstructionPromiseResultType>(irb, scope, source_node); |
| 3244 | | instruction->promise_type = promise_type; |
| 3245 | | |
| 3246 | | ir_ref_instruction(promise_type, irb->current_basic_block); |
| 3247 | | |
| 3248 | | return &instruction->base; |
| 3249 | | } |
| 3250 | | |
| 3251 | | static IrInstruction *ir_build_await_bookkeeping(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3252 | | IrInstruction *promise_result_type) |
| 3253 | | { |
| 3254 | | IrInstructionAwaitBookkeeping *instruction = ir_build_instruction<IrInstructionAwaitBookkeeping>(irb, scope, source_node); |
| 3255 | | instruction->promise_result_type = promise_result_type; |
| 3256 | | |
| 3257 | | ir_ref_instruction(promise_result_type, irb->current_basic_block); |
| 3258 | | |
| 3259 | | return &instruction->base; |
| 3260 | | } |
| 3261 | | |
| 3262 | 3002 | static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 3263 | 3003 | IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node); |
| 3264 | 3004 | return &instruction->base; |
| ... | ... | @@ -3275,21 +3015,6 @@ static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *s |
| 3275 | 3015 | return &instruction->base; |
| 3276 | 3016 | } |
| 3277 | 3017 | |
| 3278 | | static IrInstruction *ir_build_merge_err_ret_traces(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3279 | | IrInstruction *coro_promise_ptr, IrInstruction *src_err_ret_trace_ptr, IrInstruction *dest_err_ret_trace_ptr) |
| 3280 | | { |
| 3281 | | IrInstructionMergeErrRetTraces *instruction = ir_build_instruction<IrInstructionMergeErrRetTraces>(irb, scope, source_node); |
| 3282 | | instruction->coro_promise_ptr = coro_promise_ptr; |
| 3283 | | instruction->src_err_ret_trace_ptr = src_err_ret_trace_ptr; |
| 3284 | | instruction->dest_err_ret_trace_ptr = dest_err_ret_trace_ptr; |
| 3285 | | |
| 3286 | | ir_ref_instruction(coro_promise_ptr, irb->current_basic_block); |
| 3287 | | ir_ref_instruction(src_err_ret_trace_ptr, irb->current_basic_block); |
| 3288 | | ir_ref_instruction(dest_err_ret_trace_ptr, irb->current_basic_block); |
| 3289 | | |
| 3290 | | return &instruction->base; |
| 3291 | | } |
| 3292 | | |
| 3293 | 3018 | static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_ret_trace_ptr) { |
| 3294 | 3019 | IrInstructionMarkErrRetTracePtr *instruction = ir_build_instruction<IrInstructionMarkErrRetTracePtr>(irb, scope, source_node); |
| 3295 | 3020 | instruction->err_ret_trace_ptr = err_ret_trace_ptr; |
| ... | ... | @@ -3488,7 +3213,6 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco |
| 3488 | 3213 | continue; |
| 3489 | 3214 | case ScopeIdDeferExpr: |
| 3490 | 3215 | case ScopeIdCImport: |
| 3491 | | case ScopeIdCoroPrelude: |
| 3492 | 3216 | zig_unreachable(); |
| 3493 | 3217 | } |
| 3494 | 3218 | } |
| ... | ... | @@ -3544,7 +3268,6 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o |
| 3544 | 3268 | continue; |
| 3545 | 3269 | case ScopeIdDeferExpr: |
| 3546 | 3270 | case ScopeIdCImport: |
| 3547 | | case ScopeIdCoroPrelude: |
| 3548 | 3271 | zig_unreachable(); |
| 3549 | 3272 | } |
| 3550 | 3273 | } |
| ... | ... | @@ -3563,18 +3286,6 @@ static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock * |
| 3563 | 3286 | ir_set_cursor_at_end(irb, basic_block); |
| 3564 | 3287 | } |
| 3565 | 3288 | |
| 3566 | | static ScopeSuspend *get_scope_suspend(Scope *scope) { |
| 3567 | | while (scope) { |
| 3568 | | if (scope->id == ScopeIdSuspend) |
| 3569 | | return (ScopeSuspend *)scope; |
| 3570 | | if (scope->id == ScopeIdFnDef) |
| 3571 | | return nullptr; |
| 3572 | | |
| 3573 | | scope = scope->parent; |
| 3574 | | } |
| 3575 | | return nullptr; |
| 3576 | | } |
| 3577 | | |
| 3578 | 3289 | static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { |
| 3579 | 3290 | while (scope) { |
| 3580 | 3291 | if (scope->id == ScopeIdDeferExpr) |
| ... | ... | @@ -3604,47 +3315,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode |
| 3604 | 3315 | return return_inst; |
| 3605 | 3316 | } |
| 3606 | 3317 | |
| 3607 | | IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "Suspended"); |
| 3608 | | IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "NotSuspended"); |
| 3609 | | IrBasicBlock *store_awaiter_block = ir_create_basic_block(irb, scope, "StoreAwaiter"); |
| 3610 | | IrBasicBlock *check_canceled_block = ir_create_basic_block(irb, scope, "CheckCanceled"); |
| 3611 | | |
| 3612 | | IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 |
| 3613 | | IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 |
| 3614 | | IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 |
| 3615 | | IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 |
| 3616 | | IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); |
| 3617 | | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); |
| 3618 | | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 3619 | | |
| 3620 | | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_field_ptr, return_value); |
| 3621 | | IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); |
| 3622 | | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| 3623 | | usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, ptr_mask, nullptr, |
| 3624 | | AtomicRmwOp_or, AtomicOrderSeqCst); |
| 3625 | | |
| 3626 | | IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); |
| 3627 | | IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); |
| 3628 | | ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); |
| 3629 | | |
| 3630 | | ir_set_cursor_at_end_and_append_block(irb, suspended_block); |
| 3631 | | ir_build_unreachable(irb, scope, node); |
| 3632 | | |
| 3633 | | ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); |
| 3634 | | IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); |
| 3635 | | // if we ever add null checking safety to the ptrtoint instruction, it needs to be disabled here |
| 3636 | | IrInstruction *have_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); |
| 3637 | | ir_build_cond_br(irb, scope, node, have_await_handle, store_awaiter_block, check_canceled_block, is_comptime); |
| 3638 | | |
| 3639 | | ir_set_cursor_at_end_and_append_block(irb, store_awaiter_block); |
| 3640 | | IrInstruction *await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, await_handle_addr); |
| 3641 | | ir_build_store_ptr(irb, scope, node, irb->exec->await_handle_var_ptr, await_handle); |
| 3642 | | ir_build_br(irb, scope, node, irb->exec->coro_normal_final, is_comptime); |
| 3643 | | |
| 3644 | | ir_set_cursor_at_end_and_append_block(irb, check_canceled_block); |
| 3645 | | IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); |
| 3646 | | IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); |
| 3647 | | return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime); |
| 3318 | zig_panic("TODO async return"); |
| 3648 | 3319 | } |
| 3649 | 3320 | |
| 3650 | 3321 | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| ... | ... | @@ -5386,7 +5057,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5386 | 5057 | FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; |
| 5387 | 5058 | |
| 5388 | 5059 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 5389 | | fn_inline, false, nullptr, nullptr, result_loc); |
| 5060 | fn_inline, false, nullptr, result_loc); |
| 5390 | 5061 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 5391 | 5062 | } |
| 5392 | 5063 | case BuiltinFnIdNewStackCall: |
| ... | ... | @@ -5417,7 +5088,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5417 | 5088 | } |
| 5418 | 5089 | |
| 5419 | 5090 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 5420 | | FnInlineAuto, false, nullptr, new_stack, result_loc); |
| 5091 | FnInlineAuto, false, new_stack, result_loc); |
| 5421 | 5092 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 5422 | 5093 | } |
| 5423 | 5094 | case BuiltinFnIdTypeId: |
| ... | ... | @@ -5722,17 +5393,12 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 5722 | 5393 | } |
| 5723 | 5394 | |
| 5724 | 5395 | bool is_async = node->data.fn_call_expr.is_async; |
| 5725 | | IrInstruction *async_allocator = nullptr; |
| 5726 | 5396 | if (is_async) { |
| 5727 | | if (node->data.fn_call_expr.async_allocator) { |
| 5728 | | async_allocator = ir_gen_node(irb, node->data.fn_call_expr.async_allocator, scope); |
| 5729 | | if (async_allocator == irb->codegen->invalid_instruction) |
| 5730 | | return async_allocator; |
| 5731 | | } |
| 5397 | zig_panic("TODO async fn call"); |
| 5732 | 5398 | } |
| 5733 | 5399 | |
| 5734 | 5400 | IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, |
| 5735 | | is_async, async_allocator, nullptr, result_loc); |
| 5401 | is_async, nullptr, result_loc); |
| 5736 | 5402 | return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); |
| 5737 | 5403 | } |
| 5738 | 5404 | |
| ... | ... | @@ -6751,22 +6417,6 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 6751 | 6417 | } |
| 6752 | 6418 | } |
| 6753 | 6419 | |
| 6754 | | static IrInstruction *ir_gen_promise_type(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 6755 | | assert(node->type == NodeTypePromiseType); |
| 6756 | | |
| 6757 | | AstNode *payload_type_node = node->data.promise_type.payload_type; |
| 6758 | | IrInstruction *payload_type_value = nullptr; |
| 6759 | | |
| 6760 | | if (payload_type_node != nullptr) { |
| 6761 | | payload_type_value = ir_gen_node(irb, payload_type_node, scope); |
| 6762 | | if (payload_type_value == irb->codegen->invalid_instruction) |
| 6763 | | return payload_type_value; |
| 6764 | | |
| 6765 | | } |
| 6766 | | |
| 6767 | | return ir_build_promise_type(irb, scope, node, payload_type_value); |
| 6768 | | } |
| 6769 | | |
| 6770 | 6420 | static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 6771 | 6421 | assert(node->type == NodeTypeUndefinedLiteral); |
| 6772 | 6422 | return ir_build_const_undefined(irb, scope, node); |
| ... | ... | @@ -7969,87 +7619,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo |
| 7969 | 7619 | //return_type = nullptr; |
| 7970 | 7620 | } |
| 7971 | 7621 | |
| 7972 | | IrInstruction *async_allocator_type_value = nullptr; |
| 7973 | | if (node->data.fn_proto.async_allocator_type != nullptr) { |
| 7974 | | async_allocator_type_value = ir_gen_node(irb, node->data.fn_proto.async_allocator_type, parent_scope); |
| 7975 | | if (async_allocator_type_value == irb->codegen->invalid_instruction) |
| 7976 | | return irb->codegen->invalid_instruction; |
| 7977 | | } |
| 7978 | | |
| 7979 | | return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, |
| 7980 | | async_allocator_type_value, is_var_args); |
| 7981 | | } |
| 7982 | | |
| 7983 | | static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode *node, |
| 7984 | | IrInstruction *target_inst, bool cancel_non_suspended, bool cancel_awaited) |
| 7985 | | { |
| 7986 | | IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "CancelDone"); |
| 7987 | | IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); |
| 7988 | | IrBasicBlock *pre_return_block = ir_create_basic_block(irb, scope, "PreReturn"); |
| 7989 | | IrBasicBlock *post_return_block = ir_create_basic_block(irb, scope, "PostReturn"); |
| 7990 | | IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); |
| 7991 | | |
| 7992 | | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7993 | | IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); |
| 7994 | | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); |
| 7995 | | IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 |
| 7996 | | IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, |
| 7997 | | get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); |
| 7998 | | IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 |
| 7999 | | IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 |
| 8000 | | IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 |
| 8001 | | IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 |
| 8002 | | |
| 8003 | | // TODO relies on Zig not re-ordering fields |
| 8004 | | IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst, |
| 8005 | | false); |
| 8006 | | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); |
| 8007 | | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 8008 | | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 8009 | | atomic_state_field_name, false); |
| 8010 | | |
| 8011 | | // set the is_canceled bit |
| 8012 | | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| 8013 | | usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr, |
| 8014 | | AtomicRmwOp_or, AtomicOrderSeqCst); |
| 8015 | | |
| 8016 | | IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); |
| 8017 | | IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); |
| 8018 | | ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); |
| 8019 | | |
| 8020 | | ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); |
| 8021 | | IrInstruction *awaiter_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); |
| 8022 | | IrInstruction *is_returned_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, awaiter_addr, ptr_mask, false); |
| 8023 | | ir_build_cond_br(irb, scope, node, is_returned_bool, post_return_block, pre_return_block, is_comptime); |
| 8024 | | |
| 8025 | | ir_set_cursor_at_end_and_append_block(irb, post_return_block); |
| 8026 | | if (cancel_awaited) { |
| 8027 | | ir_build_br(irb, scope, node, do_cancel_block, is_comptime); |
| 8028 | | } else { |
| 8029 | | IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); |
| 8030 | | IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); |
| 8031 | | ir_build_cond_br(irb, scope, node, is_awaited_bool, done_block, do_cancel_block, is_comptime); |
| 8032 | | } |
| 8033 | | |
| 8034 | | ir_set_cursor_at_end_and_append_block(irb, pre_return_block); |
| 8035 | | if (cancel_awaited) { |
| 8036 | | if (cancel_non_suspended) { |
| 8037 | | ir_build_br(irb, scope, node, do_cancel_block, is_comptime); |
| 8038 | | } else { |
| 8039 | | IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); |
| 8040 | | IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); |
| 8041 | | ir_build_cond_br(irb, scope, node, is_suspended_bool, do_cancel_block, done_block, is_comptime); |
| 8042 | | } |
| 8043 | | } else { |
| 8044 | | ir_build_br(irb, scope, node, done_block, is_comptime); |
| 8045 | | } |
| 8046 | | |
| 8047 | | ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); |
| 8048 | | ir_build_cancel(irb, scope, node, target_inst); |
| 8049 | | ir_build_br(irb, scope, node, done_block, is_comptime); |
| 8050 | | |
| 8051 | | ir_set_cursor_at_end_and_append_block(irb, done_block); |
| 8052 | | return ir_build_const_void(irb, scope, node); |
| 7622 | return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args); |
| 8053 | 7623 | } |
| 8054 | 7624 | |
| 8055 | 7625 | static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -8059,57 +7629,7 @@ static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) |
| 8059 | 7629 | if (target_inst == irb->codegen->invalid_instruction) |
| 8060 | 7630 | return irb->codegen->invalid_instruction; |
| 8061 | 7631 | |
| 8062 | | return ir_gen_cancel_target(irb, scope, node, target_inst, false, true); |
| 8063 | | } |
| 8064 | | |
| 8065 | | static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode *node, |
| 8066 | | IrInstruction *target_inst) |
| 8067 | | { |
| 8068 | | IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "ResumeDone"); |
| 8069 | | IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); |
| 8070 | | IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "IsSuspended"); |
| 8071 | | IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "IsNotSuspended"); |
| 8072 | | |
| 8073 | | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 8074 | | IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 |
| 8075 | | IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 |
| 8076 | | IrInstruction *and_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, is_suspended_mask); |
| 8077 | | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); |
| 8078 | | IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); |
| 8079 | | IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, |
| 8080 | | get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); |
| 8081 | | |
| 8082 | | // TODO relies on Zig not re-ordering fields |
| 8083 | | IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst, |
| 8084 | | false); |
| 8085 | | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); |
| 8086 | | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 8087 | | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 8088 | | atomic_state_field_name, false); |
| 8089 | | |
| 8090 | | // clear the is_suspended bit |
| 8091 | | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| 8092 | | usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr, |
| 8093 | | AtomicRmwOp_and, AtomicOrderSeqCst); |
| 8094 | | |
| 8095 | | IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); |
| 8096 | | IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); |
| 8097 | | ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); |
| 8098 | | |
| 8099 | | ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); |
| 8100 | | IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); |
| 8101 | | IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); |
| 8102 | | ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); |
| 8103 | | |
| 8104 | | ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); |
| 8105 | | ir_build_unreachable(irb, scope, node); |
| 8106 | | |
| 8107 | | ir_set_cursor_at_end_and_append_block(irb, suspended_block); |
| 8108 | | ir_build_coro_resume(irb, scope, node, target_inst); |
| 8109 | | ir_build_br(irb, scope, node, done_block, is_comptime); |
| 8110 | | |
| 8111 | | ir_set_cursor_at_end_and_append_block(irb, done_block); |
| 8112 | | return ir_build_const_void(irb, scope, node); |
| 7632 | zig_panic("TODO ir_gen_cancel"); |
| 8113 | 7633 | } |
| 8114 | 7634 | |
| 8115 | 7635 | static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -8119,7 +7639,7 @@ static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) |
| 8119 | 7639 | if (target_inst == irb->codegen->invalid_instruction) |
| 8120 | 7640 | return irb->codegen->invalid_instruction; |
| 8121 | 7641 | |
| 8122 | | return ir_gen_resume_target(irb, scope, node, target_inst); |
| 7642 | zig_panic("TODO ir_gen_resume"); |
| 8123 | 7643 | } |
| 8124 | 7644 | |
| 8125 | 7645 | static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -8129,298 +7649,13 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 8129 | 7649 | if (target_inst == irb->codegen->invalid_instruction) |
| 8130 | 7650 | return irb->codegen->invalid_instruction; |
| 8131 | 7651 | |
| 8132 | | ZigFn *fn_entry = exec_fn_entry(irb->exec); |
| 8133 | | if (!fn_entry) { |
| 8134 | | add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); |
| 8135 | | return irb->codegen->invalid_instruction; |
| 8136 | | } |
| 8137 | | if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { |
| 8138 | | add_node_error(irb->codegen, node, buf_sprintf("await in non-async function")); |
| 8139 | | return irb->codegen->invalid_instruction; |
| 8140 | | } |
| 8141 | | |
| 8142 | | ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); |
| 8143 | | if (scope_defer_expr) { |
| 8144 | | if (!scope_defer_expr->reported_err) { |
| 8145 | | add_node_error(irb->codegen, node, buf_sprintf("cannot await inside defer expression")); |
| 8146 | | scope_defer_expr->reported_err = true; |
| 8147 | | } |
| 8148 | | return irb->codegen->invalid_instruction; |
| 8149 | | } |
| 8150 | | |
| 8151 | | Scope *outer_scope = irb->exec->begin_scope; |
| 8152 | | |
| 8153 | | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst); |
| 8154 | | Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 8155 | | IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); |
| 8156 | | |
| 8157 | | if (irb->codegen->have_err_ret_tracing) { |
| 8158 | | IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); |
| 8159 | | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); |
| 8160 | | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); |
| 8161 | | ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); |
| 8162 | | } |
| 8163 | | |
| 8164 | | IrBasicBlock *already_awaited_block = ir_create_basic_block(irb, scope, "AlreadyAwaited"); |
| 8165 | | IrBasicBlock *not_awaited_block = ir_create_basic_block(irb, scope, "NotAwaited"); |
| 8166 | | IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); |
| 8167 | | IrBasicBlock *yes_suspend_block = ir_create_basic_block(irb, scope, "YesSuspend"); |
| 8168 | | IrBasicBlock *no_suspend_block = ir_create_basic_block(irb, scope, "NoSuspend"); |
| 8169 | | IrBasicBlock *merge_block = ir_create_basic_block(irb, scope, "MergeSuspend"); |
| 8170 | | IrBasicBlock *cleanup_block = ir_create_basic_block(irb, scope, "SuspendCleanup"); |
| 8171 | | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "SuspendResume"); |
| 8172 | | IrBasicBlock *cancel_target_block = ir_create_basic_block(irb, scope, "CancelTarget"); |
| 8173 | | IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); |
| 8174 | | IrBasicBlock *do_defers_block = ir_create_basic_block(irb, scope, "DoDefers"); |
| 8175 | | IrBasicBlock *destroy_block = ir_create_basic_block(irb, scope, "DestroyBlock"); |
| 8176 | | IrBasicBlock *my_suspended_block = ir_create_basic_block(irb, scope, "AlreadySuspended"); |
| 8177 | | IrBasicBlock *my_not_suspended_block = ir_create_basic_block(irb, scope, "NotAlreadySuspended"); |
| 8178 | | IrBasicBlock *do_suspend_block = ir_create_basic_block(irb, scope, "DoSuspend"); |
| 8179 | | |
| 8180 | | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 8181 | | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 8182 | | atomic_state_field_name, false); |
| 8183 | | |
| 8184 | | IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); |
| 8185 | | IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false); |
| 8186 | | IrInstruction *undef = ir_build_const_undefined(irb, scope, node); |
| 8187 | | IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); |
| 8188 | | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 8189 | | IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 |
| 8190 | | IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 |
| 8191 | | IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 |
| 8192 | | IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 |
| 8193 | | IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 |
| 8194 | | |
| 8195 | | ZigVar *result_var = ir_create_var(irb, node, scope, nullptr, |
| 8196 | | false, false, true, const_bool_false); |
| 8197 | | IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst); |
| 8198 | | IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type); |
| 8199 | | ir_build_await_bookkeeping(irb, scope, node, promise_result_type); |
| 8200 | | IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef, nullptr); |
| 8201 | | build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false); |
| 8202 | | IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var); |
| 8203 | | ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr); |
| 8204 | | IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle); |
| 8205 | | |
| 8206 | | IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle); |
| 8207 | | IrInstruction *mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, coro_handle_addr, await_mask, false); |
| 8208 | | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| 8209 | | usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr, |
| 8210 | | AtomicRmwOp_or, AtomicOrderSeqCst); |
| 8211 | | |
| 8212 | | IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); |
| 8213 | | IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); |
| 8214 | | ir_build_cond_br(irb, scope, node, is_awaited_bool, already_awaited_block, not_awaited_block, const_bool_false); |
| 8215 | | |
| 8216 | | ir_set_cursor_at_end_and_append_block(irb, already_awaited_block); |
| 8217 | | ir_build_unreachable(irb, scope, node); |
| 8218 | | |
| 8219 | | ir_set_cursor_at_end_and_append_block(irb, not_awaited_block); |
| 8220 | | IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); |
| 8221 | | IrInstruction *is_non_null = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); |
| 8222 | | IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); |
| 8223 | | IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); |
| 8224 | | ir_build_cond_br(irb, scope, node, is_canceled_bool, cancel_target_block, not_canceled_block, const_bool_false); |
| 8225 | | |
| 8226 | | ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); |
| 8227 | | ir_build_cond_br(irb, scope, node, is_non_null, no_suspend_block, yes_suspend_block, const_bool_false); |
| 8228 | | |
| 8229 | | ir_set_cursor_at_end_and_append_block(irb, cancel_target_block); |
| 8230 | | ir_build_cancel(irb, scope, node, target_inst); |
| 8231 | | ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); |
| 8232 | | |
| 8233 | | ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); |
| 8234 | | if (irb->codegen->have_err_ret_tracing) { |
| 8235 | | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 8236 | | IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); |
| 8237 | | IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); |
| 8238 | | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); |
| 8239 | | } |
| 8240 | | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 8241 | | IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); |
| 8242 | | // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to, |
| 8243 | | // because we're about to destroy the memory. So we store it into our result variable. |
| 8244 | | IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr); |
| 8245 | | ir_build_store_ptr(irb, scope, node, my_result_var_ptr, no_suspend_result); |
| 8246 | | ir_build_cancel(irb, scope, node, target_inst); |
| 8247 | | ir_build_br(irb, scope, node, merge_block, const_bool_false); |
| 8248 | | |
| 8249 | | |
| 8250 | | ir_set_cursor_at_end_and_append_block(irb, yes_suspend_block); |
| 8251 | | IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| 8252 | | usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, |
| 8253 | | AtomicRmwOp_or, AtomicOrderSeqCst); |
| 8254 | | IrInstruction *my_is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_suspended_mask, false); |
| 8255 | | IrInstruction *my_is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_suspended_value, zero, false); |
| 8256 | | ir_build_cond_br(irb, scope, node, my_is_suspended_bool, my_suspended_block, my_not_suspended_block, const_bool_false); |
| 8257 | | |
| 8258 | | ir_set_cursor_at_end_and_append_block(irb, my_suspended_block); |
| 8259 | | ir_build_unreachable(irb, scope, node); |
| 8260 | | |
| 8261 | | ir_set_cursor_at_end_and_append_block(irb, my_not_suspended_block); |
| 8262 | | IrInstruction *my_is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_canceled_mask, false); |
| 8263 | | IrInstruction *my_is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_canceled_value, zero, false); |
| 8264 | | ir_build_cond_br(irb, scope, node, my_is_canceled_bool, cleanup_block, do_suspend_block, const_bool_false); |
| 8265 | | |
| 8266 | | ir_set_cursor_at_end_and_append_block(irb, do_suspend_block); |
| 8267 | | IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, save_token, const_bool_false); |
| 8268 | | |
| 8269 | | IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); |
| 8270 | | cases[0].value = ir_build_const_u8(irb, scope, node, 0); |
| 8271 | | cases[0].block = resume_block; |
| 8272 | | cases[1].value = ir_build_const_u8(irb, scope, node, 1); |
| 8273 | | cases[1].block = destroy_block; |
| 8274 | | ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, |
| 8275 | | 2, cases, const_bool_false, nullptr); |
| 8276 | | |
| 8277 | | ir_set_cursor_at_end_and_append_block(irb, destroy_block); |
| 8278 | | ir_gen_cancel_target(irb, scope, node, target_inst, false, true); |
| 8279 | | ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); |
| 8280 | | |
| 8281 | | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); |
| 8282 | | IrInstruction *my_mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, ptr_mask, is_canceled_mask, false); |
| 8283 | | IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| 8284 | | usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr, |
| 8285 | | AtomicRmwOp_or, AtomicOrderSeqCst); |
| 8286 | | IrInstruction *my_await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, b_my_prev_atomic_value, ptr_mask, false); |
| 8287 | | IrInstruction *dont_have_my_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, my_await_handle_addr, zero, false); |
| 8288 | | IrInstruction *dont_destroy_ourselves = ir_build_bin_op(irb, scope, node, IrBinOpBoolAnd, dont_have_my_await_handle, is_canceled_bool, false); |
| 8289 | | ir_build_cond_br(irb, scope, node, dont_have_my_await_handle, do_defers_block, do_cancel_block, const_bool_false); |
| 8290 | | |
| 8291 | | ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); |
| 8292 | | IrInstruction *my_await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, my_await_handle_addr); |
| 8293 | | ir_gen_cancel_target(irb, scope, node, my_await_handle, true, false); |
| 8294 | | ir_mark_gen(ir_build_br(irb, scope, node, do_defers_block, const_bool_false)); |
| 8295 | | |
| 8296 | | ir_set_cursor_at_end_and_append_block(irb, do_defers_block); |
| 8297 | | ir_gen_defers_for_block(irb, scope, outer_scope, true); |
| 8298 | | ir_mark_gen(ir_build_cond_br(irb, scope, node, dont_destroy_ourselves, irb->exec->coro_early_final, irb->exec->coro_final_cleanup_block, const_bool_false)); |
| 8299 | | |
| 8300 | | ir_set_cursor_at_end_and_append_block(irb, resume_block); |
| 8301 | | ir_build_br(irb, scope, node, merge_block, const_bool_false); |
| 8302 | | |
| 8303 | | ir_set_cursor_at_end_and_append_block(irb, merge_block); |
| 8304 | | return ir_build_load_ptr(irb, scope, node, my_result_var_ptr); |
| 7652 | zig_panic("TODO ir_gen_await_expr"); |
| 8305 | 7653 | } |
| 8306 | 7654 | |
| 8307 | 7655 | static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 8308 | 7656 | assert(node->type == NodeTypeSuspend); |
| 8309 | 7657 | |
| 8310 | | ZigFn *fn_entry = exec_fn_entry(irb->exec); |
| 8311 | | if (!fn_entry) { |
| 8312 | | add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); |
| 8313 | | return irb->codegen->invalid_instruction; |
| 8314 | | } |
| 8315 | | if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { |
| 8316 | | add_node_error(irb->codegen, node, buf_sprintf("suspend in non-async function")); |
| 8317 | | return irb->codegen->invalid_instruction; |
| 8318 | | } |
| 8319 | | |
| 8320 | | ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(parent_scope); |
| 8321 | | if (scope_defer_expr) { |
| 8322 | | if (!scope_defer_expr->reported_err) { |
| 8323 | | ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside defer expression")); |
| 8324 | | add_error_note(irb->codegen, msg, scope_defer_expr->base.source_node, buf_sprintf("defer here")); |
| 8325 | | scope_defer_expr->reported_err = true; |
| 8326 | | } |
| 8327 | | return irb->codegen->invalid_instruction; |
| 8328 | | } |
| 8329 | | ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); |
| 8330 | | if (existing_suspend_scope) { |
| 8331 | | if (!existing_suspend_scope->reported_err) { |
| 8332 | | ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); |
| 8333 | | add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); |
| 8334 | | existing_suspend_scope->reported_err = true; |
| 8335 | | } |
| 8336 | | return irb->codegen->invalid_instruction; |
| 8337 | | } |
| 8338 | | |
| 8339 | | Scope *outer_scope = irb->exec->begin_scope; |
| 8340 | | |
| 8341 | | IrBasicBlock *cleanup_block = ir_create_basic_block(irb, parent_scope, "SuspendCleanup"); |
| 8342 | | IrBasicBlock *resume_block = ir_create_basic_block(irb, parent_scope, "SuspendResume"); |
| 8343 | | IrBasicBlock *suspended_block = ir_create_basic_block(irb, parent_scope, "AlreadySuspended"); |
| 8344 | | IrBasicBlock *canceled_block = ir_create_basic_block(irb, parent_scope, "IsCanceled"); |
| 8345 | | IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, parent_scope, "NotCanceled"); |
| 8346 | | IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, parent_scope, "NotAlreadySuspended"); |
| 8347 | | IrBasicBlock *cancel_awaiter_block = ir_create_basic_block(irb, parent_scope, "CancelAwaiter"); |
| 8348 | | |
| 8349 | | IrInstruction *promise_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_promise); |
| 8350 | | IrInstruction *const_bool_true = ir_build_const_bool(irb, parent_scope, node, true); |
| 8351 | | IrInstruction *const_bool_false = ir_build_const_bool(irb, parent_scope, node, false); |
| 8352 | | IrInstruction *usize_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_usize); |
| 8353 | | IrInstruction *is_canceled_mask = ir_build_const_usize(irb, parent_scope, node, 0x1); // 0b001 |
| 8354 | | IrInstruction *is_suspended_mask = ir_build_const_usize(irb, parent_scope, node, 0x2); // 0b010 |
| 8355 | | IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); |
| 8356 | | IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, parent_scope, node, 0x7); // 0b111 |
| 8357 | | IrInstruction *ptr_mask = ir_build_un_op(irb, parent_scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 |
| 8358 | | |
| 8359 | | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, parent_scope, node, |
| 8360 | | usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, |
| 8361 | | AtomicRmwOp_or, AtomicOrderSeqCst); |
| 8362 | | |
| 8363 | | IrInstruction *is_canceled_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); |
| 8364 | | IrInstruction *is_canceled_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); |
| 8365 | | ir_build_cond_br(irb, parent_scope, node, is_canceled_bool, canceled_block, not_canceled_block, const_bool_false); |
| 8366 | | |
| 8367 | | ir_set_cursor_at_end_and_append_block(irb, canceled_block); |
| 8368 | | IrInstruction *await_handle_addr = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); |
| 8369 | | IrInstruction *have_await_handle = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); |
| 8370 | | IrBasicBlock *post_canceled_block = irb->current_basic_block; |
| 8371 | | ir_build_cond_br(irb, parent_scope, node, have_await_handle, cancel_awaiter_block, cleanup_block, const_bool_false); |
| 8372 | | |
| 8373 | | ir_set_cursor_at_end_and_append_block(irb, cancel_awaiter_block); |
| 8374 | | IrInstruction *await_handle = ir_build_int_to_ptr(irb, parent_scope, node, promise_type_val, await_handle_addr); |
| 8375 | | ir_gen_cancel_target(irb, parent_scope, node, await_handle, true, false); |
| 8376 | | IrBasicBlock *post_cancel_awaiter_block = irb->current_basic_block; |
| 8377 | | ir_build_br(irb, parent_scope, node, cleanup_block, const_bool_false); |
| 8378 | | |
| 8379 | | ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); |
| 8380 | | IrInstruction *is_suspended_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); |
| 8381 | | IrInstruction *is_suspended_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); |
| 8382 | | ir_build_cond_br(irb, parent_scope, node, is_suspended_bool, suspended_block, not_suspended_block, const_bool_false); |
| 8383 | | |
| 8384 | | ir_set_cursor_at_end_and_append_block(irb, suspended_block); |
| 8385 | | ir_build_unreachable(irb, parent_scope, node); |
| 8386 | | |
| 8387 | | ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); |
| 8388 | | IrInstruction *suspend_code; |
| 8389 | | if (node->data.suspend.block == nullptr) { |
| 8390 | | suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false); |
| 8391 | | } else { |
| 8392 | | Scope *child_scope; |
| 8393 | | ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); |
| 8394 | | suspend_scope->resume_block = resume_block; |
| 8395 | | child_scope = &suspend_scope->base; |
| 8396 | | IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle); |
| 8397 | | ir_gen_node(irb, node->data.suspend.block, child_scope); |
| 8398 | | suspend_code = ir_mark_gen(ir_build_coro_suspend(irb, parent_scope, node, save_token, const_bool_false)); |
| 8399 | | } |
| 8400 | | |
| 8401 | | IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); |
| 8402 | | cases[0].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 0)); |
| 8403 | | cases[0].block = resume_block; |
| 8404 | | cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); |
| 8405 | | cases[1].block = canceled_block; |
| 8406 | | IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, parent_scope, node, suspend_code, |
| 8407 | | irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr); |
| 8408 | | ir_mark_gen(&switch_br->base); |
| 8409 | | |
| 8410 | | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); |
| 8411 | | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 8412 | | IrInstruction **incoming_values = allocate<IrInstruction *>(2); |
| 8413 | | incoming_blocks[0] = post_canceled_block; |
| 8414 | | incoming_values[0] = const_bool_true; |
| 8415 | | incoming_blocks[1] = post_cancel_awaiter_block; |
| 8416 | | incoming_values[1] = const_bool_false; |
| 8417 | | IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, |
| 8418 | | nullptr); |
| 8419 | | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); |
| 8420 | | ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false)); |
| 8421 | | |
| 8422 | | ir_set_cursor_at_end_and_append_block(irb, resume_block); |
| 8423 | | return ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); |
| 7658 | zig_panic("TODO ir_gen_suspend"); |
| 8424 | 7659 | } |
| 8425 | 7660 | |
| 8426 | 7661 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, |
| ... | ... | @@ -8512,8 +7747,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 8512 | 7747 | return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); |
| 8513 | 7748 | case NodeTypePointerType: |
| 8514 | 7749 | return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); |
| 8515 | | case NodeTypePromiseType: |
| 8516 | | return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval, result_loc); |
| 8517 | 7750 | case NodeTypeStringLiteral: |
| 8518 | 7751 | return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); |
| 8519 | 7752 | case NodeTypeUndefinedLiteral: |
| ... | ... | @@ -8624,105 +7857,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8624 | 7857 | ZigFn *fn_entry = exec_fn_entry(irb->exec); |
| 8625 | 7858 | |
| 8626 | 7859 | bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; |
| 8627 | | IrInstruction *coro_id; |
| 8628 | | IrInstruction *u8_ptr_type; |
| 8629 | | IrInstruction *const_bool_false; |
| 8630 | | IrInstruction *coro_promise_ptr; |
| 8631 | | IrInstruction *err_ret_trace_ptr; |
| 8632 | | ZigType *return_type; |
| 8633 | | Buf *result_ptr_field_name; |
| 8634 | | ZigVar *coro_size_var; |
| 8635 | 7860 | if (is_async) { |
| 8636 | | // create the coro promise |
| 8637 | | Scope *coro_scope = create_coro_prelude_scope(irb->codegen, node, scope); |
| 8638 | | const_bool_false = ir_build_const_bool(irb, coro_scope, node, false); |
| 8639 | | ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 8640 | | |
| 8641 | | return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; |
| 8642 | | IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); |
| 8643 | | // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa |
| 8644 | | ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); |
| 8645 | | IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); |
| 8646 | | IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef, nullptr); |
| 8647 | | build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false); |
| 8648 | | coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); |
| 8649 | | |
| 8650 | | ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 8651 | | IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); |
| 8652 | | IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, |
| 8653 | | get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); |
| 8654 | | IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value, nullptr); |
| 8655 | | build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false); |
| 8656 | | irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); |
| 8657 | | |
| 8658 | | u8_ptr_type = ir_build_const_type(irb, coro_scope, node, |
| 8659 | | get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); |
| 8660 | | IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, |
| 8661 | | coro_promise_ptr, false); |
| 8662 | | coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr); |
| 8663 | | coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 8664 | | IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); |
| 8665 | | build_decl_var_and_init(irb, coro_scope, node, coro_size_var, coro_size, "coro_size", const_bool_false); |
| 8666 | | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node, |
| 8667 | | ImplicitAllocatorIdArg); |
| 8668 | | irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false); |
| 8669 | | build_decl_var_and_init(irb, coro_scope, node, irb->exec->coro_allocator_var, implicit_allocator_ptr, |
| 8670 | | "allocator", const_bool_false); |
| 8671 | | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); |
| 8672 | | IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name, false); |
| 8673 | | IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr); |
| 8674 | | IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size); |
| 8675 | | IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr); |
| 8676 | | IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, coro_scope, "AllocError"); |
| 8677 | | IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, coro_scope, "AllocOk"); |
| 8678 | | ir_build_cond_br(irb, coro_scope, node, alloc_result_is_ok, alloc_ok_block, alloc_err_block, const_bool_false); |
| 8679 | | |
| 8680 | | ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); |
| 8681 | | // we can return undefined here, because the caller passes a pointer to the error struct field |
| 8682 | | // in the error union result, and we populate it in case of allocation failure. |
| 8683 | | ir_build_return(irb, coro_scope, node, undef); |
| 8684 | | |
| 8685 | | ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); |
| 8686 | | IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, maybe_coro_mem_ptr, |
| 8687 | | false); |
| 8688 | | irb->exec->coro_handle = ir_build_coro_begin(irb, coro_scope, node, coro_id, coro_mem_ptr); |
| 8689 | | |
| 8690 | | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 8691 | | irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 8692 | | atomic_state_field_name, false); |
| 8693 | | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 8694 | | ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero); |
| 8695 | | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 8696 | | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); |
| 8697 | | result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 8698 | | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); |
| 8699 | | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); |
| 8700 | | if (irb->codegen->have_err_ret_tracing) { |
| 8701 | | // initialize the error return trace |
| 8702 | | Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); |
| 8703 | | IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name, false); |
| 8704 | | |
| 8705 | | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 8706 | | err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); |
| 8707 | | ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); |
| 8708 | | |
| 8709 | | // coordinate with builtin.zig |
| 8710 | | Buf *index_name = buf_create_from_str("index"); |
| 8711 | | IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name, false); |
| 8712 | | ir_build_store_ptr(irb, scope, node, index_ptr, zero); |
| 8713 | | |
| 8714 | | Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); |
| 8715 | | IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false); |
| 8716 | | |
| 8717 | | IrInstruction *slice_value = ir_build_slice_src(irb, scope, node, return_addresses_ptr, zero, nullptr, false, no_result_loc()); |
| 8718 | | ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); |
| 8719 | | } |
| 8720 | | |
| 8721 | | |
| 8722 | | irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal"); |
| 8723 | | irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal"); |
| 8724 | | irb->exec->coro_suspend_block = ir_create_basic_block(irb, scope, "Suspend"); |
| 8725 | | irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); |
| 7861 | zig_panic("ir_gen async fn"); |
| 8726 | 7862 | } |
| 8727 | 7863 | |
| 8728 | 7864 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| ... | ... | @@ -8735,117 +7871,6 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8735 | 7871 | ir_gen_async_return(irb, scope, result->source_node, result, true); |
| 8736 | 7872 | } |
| 8737 | 7873 | |
| 8738 | | if (is_async) { |
| 8739 | | IrBasicBlock *invalid_resume_block = ir_create_basic_block(irb, scope, "InvalidResume"); |
| 8740 | | IrBasicBlock *check_free_block = ir_create_basic_block(irb, scope, "CheckFree"); |
| 8741 | | |
| 8742 | | ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_early_final); |
| 8743 | | IrInstruction *const_bool_true = ir_build_const_bool(irb, scope, node, true); |
| 8744 | | IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, nullptr, const_bool_true); |
| 8745 | | IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); |
| 8746 | | cases[0].value = ir_build_const_u8(irb, scope, node, 0); |
| 8747 | | cases[0].block = invalid_resume_block; |
| 8748 | | cases[1].value = ir_build_const_u8(irb, scope, node, 1); |
| 8749 | | cases[1].block = irb->exec->coro_final_cleanup_block; |
| 8750 | | ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr); |
| 8751 | | |
| 8752 | | ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block); |
| 8753 | | ir_build_coro_end(irb, scope, node); |
| 8754 | | ir_build_return(irb, scope, node, irb->exec->coro_handle); |
| 8755 | | |
| 8756 | | ir_set_cursor_at_end_and_append_block(irb, invalid_resume_block); |
| 8757 | | ir_build_unreachable(irb, scope, node); |
| 8758 | | |
| 8759 | | ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_normal_final); |
| 8760 | | if (type_has_bits(return_type)) { |
| 8761 | | IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, |
| 8762 | | get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, |
| 8763 | | false, false, PtrLenUnknown, 0, 0, 0, false)); |
| 8764 | | IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr); |
| 8765 | | IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len, |
| 8766 | | result_ptr, false); |
| 8767 | | IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, |
| 8768 | | u8_ptr_type_unknown_len, irb->exec->coro_result_field_ptr, false); |
| 8769 | | IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node, |
| 8770 | | fn_entry->type_entry->data.fn.fn_type_id.return_type); |
| 8771 | | IrInstruction *size_of_ret_val = ir_build_size_of(irb, scope, node, return_type_inst); |
| 8772 | | ir_build_memcpy(irb, scope, node, result_ptr_as_u8_ptr, return_value_ptr_as_u8_ptr, size_of_ret_val); |
| 8773 | | } |
| 8774 | | if (irb->codegen->have_err_ret_tracing) { |
| 8775 | | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); |
| 8776 | | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); |
| 8777 | | IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr); |
| 8778 | | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr); |
| 8779 | | } |
| 8780 | | // Before we destroy the coroutine frame, we need to load the target promise into |
| 8781 | | // a register or local variable which does not get spilled into the frame, |
| 8782 | | // otherwise llvm tries to access memory inside the destroyed frame. |
| 8783 | | IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, |
| 8784 | | irb->exec->await_handle_var_ptr, false, false); |
| 8785 | | IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); |
| 8786 | | ir_build_br(irb, scope, node, check_free_block, const_bool_false); |
| 8787 | | |
| 8788 | | ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_final_cleanup_block); |
| 8789 | | ir_build_br(irb, scope, node, check_free_block, const_bool_false); |
| 8790 | | |
| 8791 | | ir_set_cursor_at_end_and_append_block(irb, check_free_block); |
| 8792 | | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 8793 | | IrInstruction **incoming_values = allocate<IrInstruction *>(2); |
| 8794 | | incoming_blocks[0] = irb->exec->coro_final_cleanup_block; |
| 8795 | | incoming_values[0] = const_bool_false; |
| 8796 | | incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8797 | | incoming_values[1] = const_bool_true; |
| 8798 | | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 8799 | | |
| 8800 | | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); |
| 8801 | | IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); |
| 8802 | | merge_incoming_blocks[0] = irb->exec->coro_final_cleanup_block; |
| 8803 | | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); |
| 8804 | | merge_incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8805 | | merge_incoming_values[1] = await_handle_in_block; |
| 8806 | | IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values, nullptr); |
| 8807 | | |
| 8808 | | Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); |
| 8809 | | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, |
| 8810 | | ImplicitAllocatorIdLocalVar); |
| 8811 | | IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name, false); |
| 8812 | | IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr); |
| 8813 | | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 8814 | | IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); |
| 8815 | | IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, |
| 8816 | | get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, |
| 8817 | | false, false, PtrLenUnknown, 0, 0, 0, false)); |
| 8818 | | IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len, |
| 8819 | | coro_mem_ptr_maybe, false); |
| 8820 | | IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); |
| 8821 | | IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); |
| 8822 | | IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); |
| 8823 | | IrInstruction *mem_slice = ir_build_slice_src(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false, |
| 8824 | | no_result_loc()); |
| 8825 | | size_t arg_count = 5; |
| 8826 | | IrInstruction **args = allocate<IrInstruction *>(arg_count); |
| 8827 | | args[0] = implicit_allocator_ptr; // self |
| 8828 | | args[1] = mem_slice; // old_mem |
| 8829 | | args[2] = ir_build_const_usize(irb, scope, node, 8); // old_align |
| 8830 | | // TODO: intentional memory leak here. If this is set to 0 then there is an issue where a coroutine |
| 8831 | | // calls the function and it frees its own stack frame, but then the return value is a slice, which |
| 8832 | | // is implemented as an sret struct. writing to the return pointer causes invalid memory write. |
| 8833 | | // We could work around it by having a global helper function which has a void return type |
| 8834 | | // and calling that instead. But instead this hack will suffice until I rework coroutines to be |
| 8835 | | // non-allocating. Basically coroutines are not supported right now until they are reworked. |
| 8836 | | args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size |
| 8837 | | args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align |
| 8838 | | ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, |
| 8839 | | nullptr, no_result_loc()); |
| 8840 | | |
| 8841 | | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); |
| 8842 | | ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); |
| 8843 | | |
| 8844 | | ir_set_cursor_at_end_and_append_block(irb, resume_block); |
| 8845 | | ir_gen_resume_target(irb, scope, node, awaiter_handle); |
| 8846 | | ir_build_br(irb, scope, node, irb->exec->coro_suspend_block, const_bool_false); |
| 8847 | | } |
| 8848 | | |
| 8849 | 7874 | return true; |
| 8850 | 7875 | } |
| 8851 | 7876 | |
| ... | ... | @@ -10189,12 +9214,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 10189 | 9214 | return result; |
| 10190 | 9215 | } |
| 10191 | 9216 | |
| 10192 | | if (wanted_type == ira->codegen->builtin_types.entry_promise && |
| 10193 | | actual_type->id == ZigTypeIdPromise) |
| 10194 | | { |
| 10195 | | return result; |
| 10196 | | } |
| 10197 | | |
| 10198 | 9217 | // fn |
| 10199 | 9218 | if (wanted_type->id == ZigTypeIdFn && |
| 10200 | 9219 | actual_type->id == ZigTypeIdFn) |
| ... | ... | @@ -10229,20 +9248,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 10229 | 9248 | return result; |
| 10230 | 9249 | } |
| 10231 | 9250 | } |
| 10232 | | if (!wanted_type->data.fn.is_generic && wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync) { |
| 10233 | | ConstCastOnly child = types_match_const_cast_only(ira, |
| 10234 | | actual_type->data.fn.fn_type_id.async_allocator_type, |
| 10235 | | wanted_type->data.fn.fn_type_id.async_allocator_type, |
| 10236 | | source_node, false); |
| 10237 | | if (child.id == ConstCastResultIdInvalid) |
| 10238 | | return child; |
| 10239 | | if (child.id != ConstCastResultIdOk) { |
| 10240 | | result.id = ConstCastResultIdAsyncAllocatorType; |
| 10241 | | result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1); |
| 10242 | | *result.data.async_allocator_type = child; |
| 10243 | | return result; |
| 10244 | | } |
| 10245 | | } |
| 10246 | 9251 | if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { |
| 10247 | 9252 | result.id = ConstCastResultIdFnArgCount; |
| 10248 | 9253 | return result; |
| ... | ... | @@ -12559,12 +11564,10 @@ static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *sou |
| 12559 | 11564 | static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { |
| 12560 | 11565 | if (ty->id == ZigTypeIdPointer) return ty->data.pointer.child_type->id != ZigTypeIdPointer; |
| 12561 | 11566 | if (ty->id == ZigTypeIdFn) return true; |
| 12562 | | if (ty->id == ZigTypeIdPromise) return true; |
| 12563 | 11567 | if (ty->id == ZigTypeIdOptional) { |
| 12564 | 11568 | ZigType *ptr_ty = ty->data.maybe.child_type; |
| 12565 | 11569 | if (ptr_ty->id == ZigTypeIdPointer) return ptr_ty->data.pointer.child_type->id != ZigTypeIdPointer; |
| 12566 | 11570 | if (ptr_ty->id == ZigTypeIdFn) return true; |
| 12567 | | if (ptr_ty->id == ZigTypeIdPromise) return true; |
| 12568 | 11571 | } |
| 12569 | 11572 | return false; |
| 12570 | 11573 | } |
| ... | ... | @@ -13640,7 +12643,6 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * |
| 13640 | 12643 | case ZigTypeIdOpaque: |
| 13641 | 12644 | case ZigTypeIdBoundFn: |
| 13642 | 12645 | case ZigTypeIdArgTuple: |
| 13643 | | case ZigTypeIdPromise: |
| 13644 | 12646 | case ZigTypeIdEnum: |
| 13645 | 12647 | case ZigTypeIdEnumLiteral: |
| 13646 | 12648 | operator_allowed = is_equality_cmp; |
| ... | ... | @@ -15021,7 +14023,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 15021 | 14023 | case ZigTypeIdBoundFn: |
| 15022 | 14024 | case ZigTypeIdArgTuple: |
| 15023 | 14025 | case ZigTypeIdOpaque: |
| 15024 | | case ZigTypeIdPromise: |
| 15025 | 14026 | ir_add_error(ira, target, |
| 15026 | 14027 | buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); |
| 15027 | 14028 | break; |
| ... | ... | @@ -15045,7 +14046,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 15045 | 14046 | case ZigTypeIdBoundFn: |
| 15046 | 14047 | case ZigTypeIdArgTuple: |
| 15047 | 14048 | case ZigTypeIdOpaque: |
| 15048 | | case ZigTypeIdPromise: |
| 15049 | 14049 | case ZigTypeIdEnumLiteral: |
| 15050 | 14050 | ir_add_error(ira, target, |
| 15051 | 14051 | buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name))); |
| ... | ... | @@ -15124,42 +14124,6 @@ static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira, |
| 15124 | 14124 | return ir_const_type(ira, &instruction->base, result_type); |
| 15125 | 14125 | } |
| 15126 | 14126 | |
| 15127 | | IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr, ImplicitAllocatorId id) { |
| 15128 | | ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 15129 | | if (parent_fn_entry == nullptr) { |
| 15130 | | ir_add_error(ira, source_instr, buf_sprintf("no implicit allocator available")); |
| 15131 | | return ira->codegen->invalid_instruction; |
| 15132 | | } |
| 15133 | | |
| 15134 | | FnTypeId *parent_fn_type = &parent_fn_entry->type_entry->data.fn.fn_type_id; |
| 15135 | | if (parent_fn_type->cc != CallingConventionAsync) { |
| 15136 | | ir_add_error(ira, source_instr, buf_sprintf("async function call from non-async caller requires allocator parameter")); |
| 15137 | | return ira->codegen->invalid_instruction; |
| 15138 | | } |
| 15139 | | |
| 15140 | | assert(parent_fn_type->async_allocator_type != nullptr); |
| 15141 | | |
| 15142 | | switch (id) { |
| 15143 | | case ImplicitAllocatorIdArg: |
| 15144 | | { |
| 15145 | | IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope, |
| 15146 | | source_instr->source_node, ImplicitAllocatorIdArg); |
| 15147 | | result->value.type = parent_fn_type->async_allocator_type; |
| 15148 | | return result; |
| 15149 | | } |
| 15150 | | case ImplicitAllocatorIdLocalVar: |
| 15151 | | { |
| 15152 | | ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; |
| 15153 | | assert(coro_allocator_var != nullptr); |
| 15154 | | IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); |
| 15155 | | IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr); |
| 15156 | | assert(result->value.type != nullptr); |
| 15157 | | return result; |
| 15158 | | } |
| 15159 | | } |
| 15160 | | zig_unreachable(); |
| 15161 | | } |
| 15162 | | |
| 15163 | 14127 | static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type, |
| 15164 | 14128 | uint32_t align, const char *name_hint, bool force_comptime) |
| 15165 | 14129 | { |
| ... | ... | @@ -15589,50 +14553,6 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst |
| 15589 | 14553 | return ir_const_void(ira, &instruction->base); |
| 15590 | 14554 | } |
| 15591 | 14555 | |
| 15592 | | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, |
| 15593 | | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, |
| 15594 | | IrInstruction *async_allocator_inst) |
| 15595 | | { |
| 15596 | | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); |
| 15597 | | ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); |
| 15598 | | ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; |
| 15599 | | IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, |
| 15600 | | async_allocator_inst, container_type, false); |
| 15601 | | if (type_is_invalid(field_ptr_inst->value.type)) { |
| 15602 | | return ira->codegen->invalid_instruction; |
| 15603 | | } |
| 15604 | | ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type; |
| 15605 | | ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base); |
| 15606 | | |
| 15607 | | ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type; |
| 15608 | | if (realloc_fn_type->id != ZigTypeIdFn) { |
| 15609 | | ir_add_error(ira, &call_instruction->base, |
| 15610 | | buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name))); |
| 15611 | | return ira->codegen->invalid_instruction; |
| 15612 | | } |
| 15613 | | |
| 15614 | | ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type; |
| 15615 | | if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) { |
| 15616 | | ir_add_error(ira, fn_ref, |
| 15617 | | buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name))); |
| 15618 | | return ira->codegen->invalid_instruction; |
| 15619 | | } |
| 15620 | | ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type; |
| 15621 | | ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; |
| 15622 | | ZigType *promise_type = get_promise_type(ira->codegen, return_type); |
| 15623 | | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| 15624 | | |
| 15625 | | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(), |
| 15626 | | async_return_type, nullptr, true, true); |
| 15627 | | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 15628 | | return result_loc; |
| 15629 | | } |
| 15630 | | |
| 15631 | | return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, |
| 15632 | | casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, result_loc, |
| 15633 | | async_return_type); |
| 15634 | | } |
| 15635 | | |
| 15636 | 14556 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| 15637 | 14557 | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) |
| 15638 | 14558 | { |
| ... | ... | @@ -16330,32 +15250,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 16330 | 15250 | break; |
| 16331 | 15251 | } |
| 16332 | 15252 | } |
| 16333 | | IrInstruction *async_allocator_inst = nullptr; |
| 16334 | 15253 | if (call_instruction->is_async) { |
| 16335 | | AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type; |
| 16336 | | if (async_allocator_type_node != nullptr) { |
| 16337 | | ZigType *async_allocator_type = ir_analyze_type_expr(ira, impl_fn->child_scope, async_allocator_type_node); |
| 16338 | | if (type_is_invalid(async_allocator_type)) |
| 16339 | | return ira->codegen->invalid_instruction; |
| 16340 | | inst_fn_type_id.async_allocator_type = async_allocator_type; |
| 16341 | | } |
| 16342 | | IrInstruction *uncasted_async_allocator_inst; |
| 16343 | | if (call_instruction->async_allocator == nullptr) { |
| 16344 | | uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, |
| 16345 | | ImplicitAllocatorIdLocalVar); |
| 16346 | | if (type_is_invalid(uncasted_async_allocator_inst->value.type)) |
| 16347 | | return ira->codegen->invalid_instruction; |
| 16348 | | } else { |
| 16349 | | uncasted_async_allocator_inst = call_instruction->async_allocator->child; |
| 16350 | | if (type_is_invalid(uncasted_async_allocator_inst->value.type)) |
| 16351 | | return ira->codegen->invalid_instruction; |
| 16352 | | } |
| 16353 | | if (inst_fn_type_id.async_allocator_type == nullptr) { |
| 16354 | | inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type; |
| 16355 | | } |
| 16356 | | async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type); |
| 16357 | | if (type_is_invalid(async_allocator_inst->value.type)) |
| 16358 | | return ira->codegen->invalid_instruction; |
| 15254 | zig_panic("TODO async call"); |
| 16359 | 15255 | } |
| 16360 | 15256 | |
| 16361 | 15257 | auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); |
| ... | ... | @@ -16398,15 +15294,12 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 16398 | 15294 | |
| 16399 | 15295 | size_t impl_param_count = impl_fn_type_id->param_count; |
| 16400 | 15296 | if (call_instruction->is_async) { |
| 16401 | | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, |
| 16402 | | fn_ref, casted_args, impl_param_count, async_allocator_inst); |
| 16403 | | return ir_finish_anal(ira, result); |
| 15297 | zig_panic("TODO async call"); |
| 16404 | 15298 | } |
| 16405 | 15299 | |
| 16406 | | assert(async_allocator_inst == nullptr); |
| 16407 | 15300 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, |
| 16408 | 15301 | impl_fn, nullptr, impl_param_count, casted_args, fn_inline, |
| 16409 | | call_instruction->is_async, nullptr, casted_new_stack, result_loc, |
| 15302 | call_instruction->is_async, casted_new_stack, result_loc, |
| 16410 | 15303 | impl_fn_type_id->return_type); |
| 16411 | 15304 | |
| 16412 | 15305 | return ir_finish_anal(ira, new_call_instruction); |
| ... | ... | @@ -16474,25 +15367,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 16474 | 15367 | return ira->codegen->invalid_instruction; |
| 16475 | 15368 | |
| 16476 | 15369 | if (call_instruction->is_async) { |
| 16477 | | IrInstruction *uncasted_async_allocator_inst; |
| 16478 | | if (call_instruction->async_allocator == nullptr) { |
| 16479 | | uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, |
| 16480 | | ImplicitAllocatorIdLocalVar); |
| 16481 | | if (type_is_invalid(uncasted_async_allocator_inst->value.type)) |
| 16482 | | return ira->codegen->invalid_instruction; |
| 16483 | | } else { |
| 16484 | | uncasted_async_allocator_inst = call_instruction->async_allocator->child; |
| 16485 | | if (type_is_invalid(uncasted_async_allocator_inst->value.type)) |
| 16486 | | return ira->codegen->invalid_instruction; |
| 16487 | | |
| 16488 | | } |
| 16489 | | IrInstruction *async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, fn_type_id->async_allocator_type); |
| 16490 | | if (type_is_invalid(async_allocator_inst->value.type)) |
| 16491 | | return ira->codegen->invalid_instruction; |
| 16492 | | |
| 16493 | | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, |
| 16494 | | casted_args, call_param_count, async_allocator_inst); |
| 16495 | | return ir_finish_anal(ira, result); |
| 15370 | zig_panic("TODO async call"); |
| 16496 | 15371 | } |
| 16497 | 15372 | |
| 16498 | 15373 | if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) { |
| ... | ... | @@ -16513,7 +15388,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 16513 | 15388 | } |
| 16514 | 15389 | |
| 16515 | 15390 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, |
| 16516 | | call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, |
| 15391 | call_param_count, casted_args, fn_inline, false, casted_new_stack, |
| 16517 | 15392 | result_loc, return_type); |
| 16518 | 15393 | return ir_finish_anal(ira, new_call_instruction); |
| 16519 | 15394 | } |
| ... | ... | @@ -16694,7 +15569,6 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_ |
| 16694 | 15569 | case ZigTypeIdFn: |
| 16695 | 15570 | case ZigTypeIdBoundFn: |
| 16696 | 15571 | case ZigTypeIdArgTuple: |
| 16697 | | case ZigTypeIdPromise: |
| 16698 | 15572 | return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry)); |
| 16699 | 15573 | case ZigTypeIdUnreachable: |
| 16700 | 15574 | case ZigTypeIdOpaque: |
| ... | ... | @@ -18465,7 +17339,6 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 18465 | 17339 | case ZigTypeIdUnion: |
| 18466 | 17340 | case ZigTypeIdFn: |
| 18467 | 17341 | case ZigTypeIdBoundFn: |
| 18468 | | case ZigTypeIdPromise: |
| 18469 | 17342 | case ZigTypeIdVector: |
| 18470 | 17343 | { |
| 18471 | 17344 | ResolveStatus needed_status = (align_bytes == 0) ? |
| ... | ... | @@ -18580,7 +17453,6 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 18580 | 17453 | case ZigTypeIdUnion: |
| 18581 | 17454 | case ZigTypeIdFn: |
| 18582 | 17455 | case ZigTypeIdBoundFn: |
| 18583 | | case ZigTypeIdPromise: |
| 18584 | 17456 | case ZigTypeIdVector: |
| 18585 | 17457 | { |
| 18586 | 17458 | if ((err = ensure_complete_type(ira->codegen, child_type))) |
| ... | ... | @@ -18592,22 +17464,6 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 18592 | 17464 | zig_unreachable(); |
| 18593 | 17465 | } |
| 18594 | 17466 | |
| 18595 | | static IrInstruction *ir_analyze_instruction_promise_type(IrAnalyze *ira, IrInstructionPromiseType *instruction) { |
| 18596 | | ZigType *promise_type; |
| 18597 | | |
| 18598 | | if (instruction->payload_type == nullptr) { |
| 18599 | | promise_type = ira->codegen->builtin_types.entry_promise; |
| 18600 | | } else { |
| 18601 | | ZigType *payload_type = ir_resolve_type(ira, instruction->payload_type->child); |
| 18602 | | if (type_is_invalid(payload_type)) |
| 18603 | | return ira->codegen->invalid_instruction; |
| 18604 | | |
| 18605 | | promise_type = get_promise_type(ira->codegen, payload_type); |
| 18606 | | } |
| 18607 | | |
| 18608 | | return ir_const_type(ira, &instruction->base, promise_type); |
| 18609 | | } |
| 18610 | | |
| 18611 | 17467 | static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, |
| 18612 | 17468 | IrInstructionSizeOf *size_of_instruction) |
| 18613 | 17469 | { |
| ... | ... | @@ -18647,7 +17503,6 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, |
| 18647 | 17503 | case ZigTypeIdEnum: |
| 18648 | 17504 | case ZigTypeIdUnion: |
| 18649 | 17505 | case ZigTypeIdFn: |
| 18650 | | case ZigTypeIdPromise: |
| 18651 | 17506 | case ZigTypeIdVector: |
| 18652 | 17507 | { |
| 18653 | 17508 | uint64_t size_in_bytes = type_size(ira->codegen, type_entry); |
| ... | ... | @@ -19134,7 +17989,6 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 19134 | 17989 | case ZigTypeIdComptimeInt: |
| 19135 | 17990 | case ZigTypeIdEnumLiteral: |
| 19136 | 17991 | case ZigTypeIdPointer: |
| 19137 | | case ZigTypeIdPromise: |
| 19138 | 17992 | case ZigTypeIdFn: |
| 19139 | 17993 | case ZigTypeIdErrorSet: { |
| 19140 | 17994 | if (pointee_val) { |
| ... | ... | @@ -20645,32 +19499,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 20645 | 19499 | fields[0].type = ira->codegen->builtin_types.entry_type; |
| 20646 | 19500 | fields[0].data.x_type = type_entry->data.maybe.child_type; |
| 20647 | 19501 | |
| 20648 | | break; |
| 20649 | | } |
| 20650 | | case ZigTypeIdPromise: |
| 20651 | | { |
| 20652 | | result = create_const_vals(1); |
| 20653 | | result->special = ConstValSpecialStatic; |
| 20654 | | result->type = ir_type_info_get_type(ira, "Promise", nullptr); |
| 20655 | | |
| 20656 | | ConstExprValue *fields = create_const_vals(1); |
| 20657 | | result->data.x_struct.fields = fields; |
| 20658 | | |
| 20659 | | // child: ?type |
| 20660 | | ensure_field_index(result->type, "child", 0); |
| 20661 | | fields[0].special = ConstValSpecialStatic; |
| 20662 | | fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); |
| 20663 | | |
| 20664 | | if (type_entry->data.promise.result_type == nullptr) |
| 20665 | | fields[0].data.x_optional = nullptr; |
| 20666 | | else { |
| 20667 | | ConstExprValue *child_type = create_const_vals(1); |
| 20668 | | child_type->special = ConstValSpecialStatic; |
| 20669 | | child_type->type = ira->codegen->builtin_types.entry_type; |
| 20670 | | child_type->data.x_type = type_entry->data.promise.result_type; |
| 20671 | | fields[0].data.x_optional = child_type; |
| 20672 | | } |
| 20673 | | |
| 20674 | 19502 | break; |
| 20675 | 19503 | } |
| 20676 | 19504 | case ZigTypeIdEnum: |
| ... | ... | @@ -20982,7 +19810,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 20982 | 19810 | result->special = ConstValSpecialStatic; |
| 20983 | 19811 | result->type = ir_type_info_get_type(ira, "Fn", nullptr); |
| 20984 | 19812 | |
| 20985 | | ConstExprValue *fields = create_const_vals(6); |
| 19813 | ConstExprValue *fields = create_const_vals(5); |
| 20986 | 19814 | result->data.x_struct.fields = fields; |
| 20987 | 19815 | |
| 20988 | 19816 | // calling_convention: TypeInfo.CallingConvention |
| ... | ... | @@ -21015,19 +19843,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21015 | 19843 | return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; |
| 21016 | 19844 | fields[3].data.x_optional = return_type; |
| 21017 | 19845 | } |
| 21018 | | // async_allocator_type: type |
| 21019 | | ensure_field_index(result->type, "async_allocator_type", 4); |
| 21020 | | fields[4].special = ConstValSpecialStatic; |
| 21021 | | fields[4].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); |
| 21022 | | if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr) |
| 21023 | | fields[4].data.x_optional = nullptr; |
| 21024 | | else { |
| 21025 | | ConstExprValue *async_alloc_type = create_const_vals(1); |
| 21026 | | async_alloc_type->special = ConstValSpecialStatic; |
| 21027 | | async_alloc_type->type = ira->codegen->builtin_types.entry_type; |
| 21028 | | async_alloc_type->data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type; |
| 21029 | | fields[4].data.x_optional = async_alloc_type; |
| 21030 | | } |
| 21031 | 19846 | // args: []TypeInfo.FnArg |
| 21032 | 19847 | ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); |
| 21033 | 19848 | if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { |
| ... | ... | @@ -21042,10 +19857,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21042 | 19857 | fn_arg_array->data.x_array.special = ConstArraySpecialNone; |
| 21043 | 19858 | fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); |
| 21044 | 19859 | |
| 21045 | | init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false); |
| 19860 | init_const_slice(ira->codegen, &fields[4], fn_arg_array, 0, fn_arg_count, false); |
| 21046 | 19861 | |
| 21047 | | for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) |
| 21048 | | { |
| 19862 | for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { |
| 21049 | 19863 | FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; |
| 21050 | 19864 | ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; |
| 21051 | 19865 | |
| ... | ... | @@ -22803,11 +21617,7 @@ static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrIns |
| 22803 | 21617 | } |
| 22804 | 21618 | |
| 22805 | 21619 | static IrInstruction *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructionHandle *instruction) { |
| 22806 | | IrInstruction *result = ir_build_handle(&ira->new_irb, instruction->base.scope, instruction->base.source_node); |
| 22807 | | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 22808 | | assert(fn_entry != nullptr); |
| 22809 | | result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); |
| 22810 | | return result; |
| 21620 | zig_panic("TODO anlayze @handle()"); |
| 22811 | 21621 | } |
| 22812 | 21622 | |
| 22813 | 21623 | static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { |
| ... | ... | @@ -22841,7 +21651,6 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct |
| 22841 | 21651 | case ZigTypeIdInt: |
| 22842 | 21652 | case ZigTypeIdFloat: |
| 22843 | 21653 | case ZigTypeIdPointer: |
| 22844 | | case ZigTypeIdPromise: |
| 22845 | 21654 | case ZigTypeIdArray: |
| 22846 | 21655 | case ZigTypeIdStruct: |
| 22847 | 21656 | case ZigTypeIdOptional: |
| ... | ... | @@ -23401,15 +22210,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct |
| 23401 | 22210 | } |
| 23402 | 22211 | |
| 23403 | 22212 | if (fn_type_id.cc == CallingConventionAsync) { |
| 23404 | | if (instruction->async_allocator_type_value == nullptr) { |
| 23405 | | ir_add_error(ira, &instruction->base, |
| 23406 | | buf_sprintf("async fn proto missing allocator type")); |
| 23407 | | return ira->codegen->invalid_instruction; |
| 23408 | | } |
| 23409 | | IrInstruction *async_allocator_type_value = instruction->async_allocator_type_value->child; |
| 23410 | | fn_type_id.async_allocator_type = ir_resolve_type(ira, async_allocator_type_value); |
| 23411 | | if (type_is_invalid(fn_type_id.async_allocator_type)) |
| 23412 | | return ira->codegen->invalid_instruction; |
| 22213 | zig_panic("TODO"); |
| 23413 | 22214 | } |
| 23414 | 22215 | |
| 23415 | 22216 | return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); |
| ... | ... | @@ -23905,7 +22706,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 23905 | 22706 | case ZigTypeIdEnumLiteral: |
| 23906 | 22707 | case ZigTypeIdUndefined: |
| 23907 | 22708 | case ZigTypeIdNull: |
| 23908 | | case ZigTypeIdPromise: |
| 23909 | 22709 | case ZigTypeIdErrorUnion: |
| 23910 | 22710 | case ZigTypeIdErrorSet: |
| 23911 | 22711 | zig_unreachable(); |
| ... | ... | @@ -24059,7 +22859,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 24059 | 22859 | case ZigTypeIdEnumLiteral: |
| 24060 | 22860 | case ZigTypeIdUndefined: |
| 24061 | 22861 | case ZigTypeIdNull: |
| 24062 | | case ZigTypeIdPromise: |
| 24063 | 22862 | zig_unreachable(); |
| 24064 | 22863 | case ZigTypeIdVoid: |
| 24065 | 22864 | return ErrorNone; |
| ... | ... | @@ -24546,181 +23345,7 @@ static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstruct |
| 24546 | 23345 | } |
| 24547 | 23346 | |
| 24548 | 23347 | static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) { |
| 24549 | | IrInstruction *target_inst = instruction->target->child; |
| 24550 | | if (type_is_invalid(target_inst->value.type)) |
| 24551 | | return ira->codegen->invalid_instruction; |
| 24552 | | IrInstruction *casted_target = ir_implicit_cast(ira, target_inst, ira->codegen->builtin_types.entry_promise); |
| 24553 | | if (type_is_invalid(casted_target->value.type)) |
| 24554 | | return ira->codegen->invalid_instruction; |
| 24555 | | |
| 24556 | | IrInstruction *result = ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_target); |
| 24557 | | result->value.type = ira->codegen->builtin_types.entry_void; |
| 24558 | | result->value.special = ConstValSpecialStatic; |
| 24559 | | return result; |
| 24560 | | } |
| 24561 | | |
| 24562 | | static IrInstruction *ir_analyze_instruction_coro_id(IrAnalyze *ira, IrInstructionCoroId *instruction) { |
| 24563 | | IrInstruction *promise_ptr = instruction->promise_ptr->child; |
| 24564 | | if (type_is_invalid(promise_ptr->value.type)) |
| 24565 | | return ira->codegen->invalid_instruction; |
| 24566 | | |
| 24567 | | IrInstruction *result = ir_build_coro_id(&ira->new_irb, instruction->base.scope, instruction->base.source_node, |
| 24568 | | promise_ptr); |
| 24569 | | result->value.type = ira->codegen->builtin_types.entry_usize; |
| 24570 | | return result; |
| 24571 | | } |
| 24572 | | |
| 24573 | | static IrInstruction *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstructionCoroAlloc *instruction) { |
| 24574 | | IrInstruction *coro_id = instruction->coro_id->child; |
| 24575 | | if (type_is_invalid(coro_id->value.type)) |
| 24576 | | return ira->codegen->invalid_instruction; |
| 24577 | | |
| 24578 | | IrInstruction *result = ir_build_coro_alloc(&ira->new_irb, instruction->base.scope, instruction->base.source_node, |
| 24579 | | coro_id); |
| 24580 | | result->value.type = ira->codegen->builtin_types.entry_bool; |
| 24581 | | return result; |
| 24582 | | } |
| 24583 | | |
| 24584 | | static IrInstruction *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) { |
| 24585 | | IrInstruction *result = ir_build_coro_size(&ira->new_irb, instruction->base.scope, instruction->base.source_node); |
| 24586 | | result->value.type = ira->codegen->builtin_types.entry_usize; |
| 24587 | | return result; |
| 24588 | | } |
| 24589 | | |
| 24590 | | static IrInstruction *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) { |
| 24591 | | IrInstruction *coro_id = instruction->coro_id->child; |
| 24592 | | if (type_is_invalid(coro_id->value.type)) |
| 24593 | | return ira->codegen->invalid_instruction; |
| 24594 | | |
| 24595 | | IrInstruction *coro_mem_ptr = instruction->coro_mem_ptr->child; |
| 24596 | | if (type_is_invalid(coro_mem_ptr->value.type)) |
| 24597 | | return ira->codegen->invalid_instruction; |
| 24598 | | |
| 24599 | | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 24600 | | ir_assert(fn_entry != nullptr, &instruction->base); |
| 24601 | | IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node, |
| 24602 | | coro_id, coro_mem_ptr); |
| 24603 | | result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); |
| 24604 | | return result; |
| 24605 | | } |
| 24606 | | |
| 24607 | | static IrInstruction *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) { |
| 24608 | | return ir_get_implicit_allocator(ira, &instruction->base, instruction->id); |
| 24609 | | } |
| 24610 | | |
| 24611 | | static IrInstruction *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, IrInstructionCoroAllocFail *instruction) { |
| 24612 | | IrInstruction *err_val = instruction->err_val->child; |
| 24613 | | if (type_is_invalid(err_val->value.type)) |
| 24614 | | return ir_unreach_error(ira); |
| 24615 | | |
| 24616 | | IrInstruction *result = ir_build_coro_alloc_fail(&ira->new_irb, instruction->base.scope, instruction->base.source_node, err_val); |
| 24617 | | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| 24618 | | return ir_finish_anal(ira, result); |
| 24619 | | } |
| 24620 | | |
| 24621 | | static IrInstruction *ir_analyze_instruction_coro_suspend(IrAnalyze *ira, IrInstructionCoroSuspend *instruction) { |
| 24622 | | IrInstruction *save_point = nullptr; |
| 24623 | | if (instruction->save_point != nullptr) { |
| 24624 | | save_point = instruction->save_point->child; |
| 24625 | | if (type_is_invalid(save_point->value.type)) |
| 24626 | | return ira->codegen->invalid_instruction; |
| 24627 | | } |
| 24628 | | |
| 24629 | | IrInstruction *is_final = instruction->is_final->child; |
| 24630 | | if (type_is_invalid(is_final->value.type)) |
| 24631 | | return ira->codegen->invalid_instruction; |
| 24632 | | |
| 24633 | | IrInstruction *result = ir_build_coro_suspend(&ira->new_irb, instruction->base.scope, |
| 24634 | | instruction->base.source_node, save_point, is_final); |
| 24635 | | result->value.type = ira->codegen->builtin_types.entry_u8; |
| 24636 | | return result; |
| 24637 | | } |
| 24638 | | |
| 24639 | | static IrInstruction *ir_analyze_instruction_coro_end(IrAnalyze *ira, IrInstructionCoroEnd *instruction) { |
| 24640 | | IrInstruction *result = ir_build_coro_end(&ira->new_irb, instruction->base.scope, |
| 24641 | | instruction->base.source_node); |
| 24642 | | result->value.type = ira->codegen->builtin_types.entry_void; |
| 24643 | | return result; |
| 24644 | | } |
| 24645 | | |
| 24646 | | static IrInstruction *ir_analyze_instruction_coro_free(IrAnalyze *ira, IrInstructionCoroFree *instruction) { |
| 24647 | | IrInstruction *coro_id = instruction->coro_id->child; |
| 24648 | | if (type_is_invalid(coro_id->value.type)) |
| 24649 | | return ira->codegen->invalid_instruction; |
| 24650 | | |
| 24651 | | IrInstruction *coro_handle = instruction->coro_handle->child; |
| 24652 | | if (type_is_invalid(coro_handle->value.type)) |
| 24653 | | return ira->codegen->invalid_instruction; |
| 24654 | | |
| 24655 | | IrInstruction *result = ir_build_coro_free(&ira->new_irb, instruction->base.scope, |
| 24656 | | instruction->base.source_node, coro_id, coro_handle); |
| 24657 | | ZigType *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); |
| 24658 | | result->value.type = get_optional_type(ira->codegen, ptr_type); |
| 24659 | | return result; |
| 24660 | | } |
| 24661 | | |
| 24662 | | static IrInstruction *ir_analyze_instruction_coro_resume(IrAnalyze *ira, IrInstructionCoroResume *instruction) { |
| 24663 | | IrInstruction *awaiter_handle = instruction->awaiter_handle->child; |
| 24664 | | if (type_is_invalid(awaiter_handle->value.type)) |
| 24665 | | return ira->codegen->invalid_instruction; |
| 24666 | | |
| 24667 | | IrInstruction *casted_target = ir_implicit_cast(ira, awaiter_handle, ira->codegen->builtin_types.entry_promise); |
| 24668 | | if (type_is_invalid(casted_target->value.type)) |
| 24669 | | return ira->codegen->invalid_instruction; |
| 24670 | | |
| 24671 | | IrInstruction *result = ir_build_coro_resume(&ira->new_irb, instruction->base.scope, |
| 24672 | | instruction->base.source_node, casted_target); |
| 24673 | | result->value.type = ira->codegen->builtin_types.entry_void; |
| 24674 | | return result; |
| 24675 | | } |
| 24676 | | |
| 24677 | | static IrInstruction *ir_analyze_instruction_coro_save(IrAnalyze *ira, IrInstructionCoroSave *instruction) { |
| 24678 | | IrInstruction *coro_handle = instruction->coro_handle->child; |
| 24679 | | if (type_is_invalid(coro_handle->value.type)) |
| 24680 | | return ira->codegen->invalid_instruction; |
| 24681 | | |
| 24682 | | IrInstruction *result = ir_build_coro_save(&ira->new_irb, instruction->base.scope, |
| 24683 | | instruction->base.source_node, coro_handle); |
| 24684 | | result->value.type = ira->codegen->builtin_types.entry_usize; |
| 24685 | | return result; |
| 24686 | | } |
| 24687 | | |
| 24688 | | static IrInstruction *ir_analyze_instruction_coro_promise(IrAnalyze *ira, IrInstructionCoroPromise *instruction) { |
| 24689 | | IrInstruction *coro_handle = instruction->coro_handle->child; |
| 24690 | | if (type_is_invalid(coro_handle->value.type)) |
| 24691 | | return ira->codegen->invalid_instruction; |
| 24692 | | |
| 24693 | | if (coro_handle->value.type->id != ZigTypeIdPromise || |
| 24694 | | coro_handle->value.type->data.promise.result_type == nullptr) |
| 24695 | | { |
| 24696 | | ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", |
| 24697 | | buf_ptr(&coro_handle->value.type->name))); |
| 24698 | | return ira->codegen->invalid_instruction; |
| 24699 | | } |
| 24700 | | |
| 24701 | | ZigType *coro_frame_type = get_promise_frame_type(ira->codegen, |
| 24702 | | coro_handle->value.type->data.promise.result_type); |
| 24703 | | |
| 24704 | | IrInstruction *result = ir_build_coro_promise(&ira->new_irb, instruction->base.scope, |
| 24705 | | instruction->base.source_node, coro_handle); |
| 24706 | | result->value.type = get_pointer_to_type(ira->codegen, coro_frame_type, false); |
| 24707 | | return result; |
| 24708 | | } |
| 24709 | | |
| 24710 | | static IrInstruction *ir_analyze_instruction_coro_alloc_helper(IrAnalyze *ira, IrInstructionCoroAllocHelper *instruction) { |
| 24711 | | IrInstruction *realloc_fn = instruction->realloc_fn->child; |
| 24712 | | if (type_is_invalid(realloc_fn->value.type)) |
| 24713 | | return ira->codegen->invalid_instruction; |
| 24714 | | |
| 24715 | | IrInstruction *coro_size = instruction->coro_size->child; |
| 24716 | | if (type_is_invalid(coro_size->value.type)) |
| 24717 | | return ira->codegen->invalid_instruction; |
| 24718 | | |
| 24719 | | IrInstruction *result = ir_build_coro_alloc_helper(&ira->new_irb, instruction->base.scope, |
| 24720 | | instruction->base.source_node, realloc_fn, coro_size); |
| 24721 | | ZigType *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); |
| 24722 | | result->value.type = get_optional_type(ira->codegen, u8_ptr_type); |
| 24723 | | return result; |
| 23348 | zig_panic("TODO analyze cancel"); |
| 24724 | 23349 | } |
| 24725 | 23350 | |
| 24726 | 23351 | static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op) { |
| ... | ... | @@ -24853,65 +23478,6 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr |
| 24853 | 23478 | return result; |
| 24854 | 23479 | } |
| 24855 | 23480 | |
| 24856 | | static IrInstruction *ir_analyze_instruction_promise_result_type(IrAnalyze *ira, IrInstructionPromiseResultType *instruction) { |
| 24857 | | ZigType *promise_type = ir_resolve_type(ira, instruction->promise_type->child); |
| 24858 | | if (type_is_invalid(promise_type)) |
| 24859 | | return ira->codegen->invalid_instruction; |
| 24860 | | |
| 24861 | | if (promise_type->id != ZigTypeIdPromise || promise_type->data.promise.result_type == nullptr) { |
| 24862 | | ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", |
| 24863 | | buf_ptr(&promise_type->name))); |
| 24864 | | return ira->codegen->invalid_instruction; |
| 24865 | | } |
| 24866 | | |
| 24867 | | return ir_const_type(ira, &instruction->base, promise_type->data.promise.result_type); |
| 24868 | | } |
| 24869 | | |
| 24870 | | static IrInstruction *ir_analyze_instruction_await_bookkeeping(IrAnalyze *ira, IrInstructionAwaitBookkeeping *instruction) { |
| 24871 | | ZigType *promise_result_type = ir_resolve_type(ira, instruction->promise_result_type->child); |
| 24872 | | if (type_is_invalid(promise_result_type)) |
| 24873 | | return ira->codegen->invalid_instruction; |
| 24874 | | |
| 24875 | | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 24876 | | ir_assert(fn_entry != nullptr, &instruction->base); |
| 24877 | | |
| 24878 | | if (type_can_fail(promise_result_type)) { |
| 24879 | | fn_entry->calls_or_awaits_errorable_fn = true; |
| 24880 | | } |
| 24881 | | |
| 24882 | | return ir_const_void(ira, &instruction->base); |
| 24883 | | } |
| 24884 | | |
| 24885 | | static IrInstruction *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ira, |
| 24886 | | IrInstructionMergeErrRetTraces *instruction) |
| 24887 | | { |
| 24888 | | IrInstruction *coro_promise_ptr = instruction->coro_promise_ptr->child; |
| 24889 | | if (type_is_invalid(coro_promise_ptr->value.type)) |
| 24890 | | return ira->codegen->invalid_instruction; |
| 24891 | | |
| 24892 | | ir_assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer, &instruction->base); |
| 24893 | | ZigType *promise_frame_type = coro_promise_ptr->value.type->data.pointer.child_type; |
| 24894 | | ir_assert(promise_frame_type->id == ZigTypeIdStruct, &instruction->base); |
| 24895 | | ZigType *promise_result_type = promise_frame_type->data.structure.fields[1].type_entry; |
| 24896 | | |
| 24897 | | if (!type_can_fail(promise_result_type)) { |
| 24898 | | return ir_const_void(ira, &instruction->base); |
| 24899 | | } |
| 24900 | | |
| 24901 | | IrInstruction *src_err_ret_trace_ptr = instruction->src_err_ret_trace_ptr->child; |
| 24902 | | if (type_is_invalid(src_err_ret_trace_ptr->value.type)) |
| 24903 | | return ira->codegen->invalid_instruction; |
| 24904 | | |
| 24905 | | IrInstruction *dest_err_ret_trace_ptr = instruction->dest_err_ret_trace_ptr->child; |
| 24906 | | if (type_is_invalid(dest_err_ret_trace_ptr->value.type)) |
| 24907 | | return ira->codegen->invalid_instruction; |
| 24908 | | |
| 24909 | | IrInstruction *result = ir_build_merge_err_ret_traces(&ira->new_irb, instruction->base.scope, |
| 24910 | | instruction->base.source_node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); |
| 24911 | | result->value.type = ira->codegen->builtin_types.entry_void; |
| 24912 | | return result; |
| 24913 | | } |
| 24914 | | |
| 24915 | 23481 | static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) { |
| 24916 | 23482 | IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope, |
| 24917 | 23483 | instruction->base.source_node); |
| ... | ... | @@ -25530,8 +24096,6 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 25530 | 24096 | return ir_analyze_instruction_asm(ira, (IrInstructionAsm *)instruction); |
| 25531 | 24097 | case IrInstructionIdArrayType: |
| 25532 | 24098 | return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); |
| 25533 | | case IrInstructionIdPromiseType: |
| 25534 | | return ir_analyze_instruction_promise_type(ira, (IrInstructionPromiseType *)instruction); |
| 25535 | 24099 | case IrInstructionIdSizeOf: |
| 25536 | 24100 | return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction); |
| 25537 | 24101 | case IrInstructionIdTestNonNull: |
| ... | ... | @@ -25704,46 +24268,14 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 25704 | 24268 | return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction); |
| 25705 | 24269 | case IrInstructionIdCancel: |
| 25706 | 24270 | return ir_analyze_instruction_cancel(ira, (IrInstructionCancel *)instruction); |
| 25707 | | case IrInstructionIdCoroId: |
| 25708 | | return ir_analyze_instruction_coro_id(ira, (IrInstructionCoroId *)instruction); |
| 25709 | | case IrInstructionIdCoroAlloc: |
| 25710 | | return ir_analyze_instruction_coro_alloc(ira, (IrInstructionCoroAlloc *)instruction); |
| 25711 | | case IrInstructionIdCoroSize: |
| 25712 | | return ir_analyze_instruction_coro_size(ira, (IrInstructionCoroSize *)instruction); |
| 25713 | | case IrInstructionIdCoroBegin: |
| 25714 | | return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction); |
| 25715 | | case IrInstructionIdGetImplicitAllocator: |
| 25716 | | return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction); |
| 25717 | | case IrInstructionIdCoroAllocFail: |
| 25718 | | return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction); |
| 25719 | | case IrInstructionIdCoroSuspend: |
| 25720 | | return ir_analyze_instruction_coro_suspend(ira, (IrInstructionCoroSuspend *)instruction); |
| 25721 | | case IrInstructionIdCoroEnd: |
| 25722 | | return ir_analyze_instruction_coro_end(ira, (IrInstructionCoroEnd *)instruction); |
| 25723 | | case IrInstructionIdCoroFree: |
| 25724 | | return ir_analyze_instruction_coro_free(ira, (IrInstructionCoroFree *)instruction); |
| 25725 | | case IrInstructionIdCoroResume: |
| 25726 | | return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction); |
| 25727 | | case IrInstructionIdCoroSave: |
| 25728 | | return ir_analyze_instruction_coro_save(ira, (IrInstructionCoroSave *)instruction); |
| 25729 | | case IrInstructionIdCoroPromise: |
| 25730 | | return ir_analyze_instruction_coro_promise(ira, (IrInstructionCoroPromise *)instruction); |
| 25731 | | case IrInstructionIdCoroAllocHelper: |
| 25732 | | return ir_analyze_instruction_coro_alloc_helper(ira, (IrInstructionCoroAllocHelper *)instruction); |
| 25733 | 24271 | case IrInstructionIdAtomicRmw: |
| 25734 | 24272 | return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction); |
| 25735 | 24273 | case IrInstructionIdAtomicLoad: |
| 25736 | 24274 | return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction); |
| 25737 | | case IrInstructionIdPromiseResultType: |
| 25738 | | return ir_analyze_instruction_promise_result_type(ira, (IrInstructionPromiseResultType *)instruction); |
| 25739 | | case IrInstructionIdAwaitBookkeeping: |
| 25740 | | return ir_analyze_instruction_await_bookkeeping(ira, (IrInstructionAwaitBookkeeping *)instruction); |
| 25741 | 24275 | case IrInstructionIdSaveErrRetAddr: |
| 25742 | 24276 | return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction); |
| 25743 | 24277 | case IrInstructionIdAddImplicitReturnType: |
| 25744 | 24278 | return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); |
| 25745 | | case IrInstructionIdMergeErrRetTraces: |
| 25746 | | return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); |
| 25747 | 24279 | case IrInstructionIdMarkErrRetTracePtr: |
| 25748 | 24280 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 25749 | 24281 | case IrInstructionIdFloatOp: |
| ... | ... | @@ -25788,9 +24320,7 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 25788 | 24320 | old_exec->analysis = ira; |
| 25789 | 24321 | ira->codegen = codegen; |
| 25790 | 24322 | |
| 25791 | | ZigFn *fn_entry = exec_fn_entry(old_exec); |
| 25792 | | bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; |
| 25793 | | ira->explicit_return_type = is_async ? get_promise_type(codegen, expected_type) : expected_type; |
| 24323 | ira->explicit_return_type = expected_type; |
| 25794 | 24324 | ira->explicit_return_type_source_node = expected_type_source_node; |
| 25795 | 24325 | |
| 25796 | 24326 | ira->old_irb.codegen = codegen; |
| ... | ... | @@ -25889,17 +24419,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 25889 | 24419 | case IrInstructionIdSetAlignStack: |
| 25890 | 24420 | case IrInstructionIdExport: |
| 25891 | 24421 | case IrInstructionIdCancel: |
| 25892 | | case IrInstructionIdCoroId: |
| 25893 | | case IrInstructionIdCoroBegin: |
| 25894 | | case IrInstructionIdCoroAllocFail: |
| 25895 | | case IrInstructionIdCoroEnd: |
| 25896 | | case IrInstructionIdCoroResume: |
| 25897 | | case IrInstructionIdCoroSave: |
| 25898 | | case IrInstructionIdCoroAllocHelper: |
| 25899 | | case IrInstructionIdAwaitBookkeeping: |
| 25900 | 24422 | case IrInstructionIdSaveErrRetAddr: |
| 25901 | 24423 | case IrInstructionIdAddImplicitReturnType: |
| 25902 | | case IrInstructionIdMergeErrRetTraces: |
| 25903 | 24424 | case IrInstructionIdMarkErrRetTracePtr: |
| 25904 | 24425 | case IrInstructionIdAtomicRmw: |
| 25905 | 24426 | case IrInstructionIdCmpxchgGen: |
| ... | ... | @@ -25933,7 +24454,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 25933 | 24454 | case IrInstructionIdTypeOf: |
| 25934 | 24455 | case IrInstructionIdStructFieldPtr: |
| 25935 | 24456 | case IrInstructionIdArrayType: |
| 25936 | | case IrInstructionIdPromiseType: |
| 25937 | 24457 | case IrInstructionIdSliceType: |
| 25938 | 24458 | case IrInstructionIdSizeOf: |
| 25939 | 24459 | case IrInstructionIdTestNonNull: |
| ... | ... | @@ -25993,13 +24513,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 25993 | 24513 | case IrInstructionIdTagType: |
| 25994 | 24514 | case IrInstructionIdErrorReturnTrace: |
| 25995 | 24515 | case IrInstructionIdErrorUnion: |
| 25996 | | case IrInstructionIdGetImplicitAllocator: |
| 25997 | | case IrInstructionIdCoroAlloc: |
| 25998 | | case IrInstructionIdCoroSize: |
| 25999 | | case IrInstructionIdCoroSuspend: |
| 26000 | | case IrInstructionIdCoroFree: |
| 26001 | | case IrInstructionIdCoroPromise: |
| 26002 | | case IrInstructionIdPromiseResultType: |
| 26003 | 24516 | case IrInstructionIdFloatOp: |
| 26004 | 24517 | case IrInstructionIdMulAdd: |
| 26005 | 24518 | case IrInstructionIdAtomicLoad: |