authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-21 16:21:16-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-21 16:21:16-04:00
log72e983670e65eac0b89da5564432988862828b30
tree0fe5e7c91bbeee208e5b2036207c41f9eae20b99
parent54e716afdcb0609cfc42229ad925e6dc9b07a66f
signaturelock-open Commit is signed but in an unrecognized format.

simple async function call working


7 files changed, 448 insertions(+), 66 deletions(-)

CMakeLists.txt+1-1
......@@ -426,7 +426,6 @@ set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp")
426426set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp")
427427
428428set(ZIG_SOURCES
429 "${CMAKE_SOURCE_DIR}/src/glibc.cpp"
430429 "${CMAKE_SOURCE_DIR}/src/analyze.cpp"
431430 "${CMAKE_SOURCE_DIR}/src/ast_render.cpp"
432431 "${CMAKE_SOURCE_DIR}/src/bigfloat.cpp"
......@@ -438,6 +437,7 @@ set(ZIG_SOURCES
438437 "${CMAKE_SOURCE_DIR}/src/compiler.cpp"
439438 "${CMAKE_SOURCE_DIR}/src/errmsg.cpp"
440439 "${CMAKE_SOURCE_DIR}/src/error.cpp"
440 "${CMAKE_SOURCE_DIR}/src/glibc.cpp"
441441 "${CMAKE_SOURCE_DIR}/src/ir.cpp"
442442 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"
443443 "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"
src/all_types.hpp+30
......@@ -1251,6 +1251,7 @@ enum ZigTypeId {
12511251 ZigTypeIdBoundFn,
12521252 ZigTypeIdArgTuple,
12531253 ZigTypeIdOpaque,
1254 ZigTypeIdCoroFrame,
12541255 ZigTypeIdVector,
12551256 ZigTypeIdEnumLiteral,
12561257};
......@@ -1265,6 +1266,11 @@ struct ZigTypeOpaque {
12651266 Buf *bare_name;
12661267};
12671268
1269struct ZigTypeCoroFrame {
1270 ZigFn *fn;
1271 ZigType *locals_struct;
1272};
1273
12681274struct ZigType {
12691275 ZigTypeId id;
12701276 Buf name;
......@@ -1290,6 +1296,7 @@ struct ZigType {
12901296 ZigTypeBoundFn bound_fn;
12911297 ZigTypeVector vector;
12921298 ZigTypeOpaque opaque;
1299 ZigTypeCoroFrame frame;
12931300 } data;
12941301
12951302 // use these fields to make sure we don't duplicate type table entries for the same type
......@@ -1340,6 +1347,7 @@ struct ZigFn {
13401347 ScopeBlock *def_scope; // parent is child_scope
13411348 Buf symbol_name;
13421349 ZigType *type_entry; // function type
1350 ZigType *frame_type; // coro frame type
13431351 // in the case of normal functions this is the implicit return type
13441352 // in the case of async functions this is the implicit return type according to the
13451353 // zig source code, not according to zig ir
......@@ -1356,6 +1364,7 @@ struct ZigFn {
13561364
13571365 ZigList<IrInstructionAllocaGen *> alloca_gen_list;
13581366 ZigList<ZigVar *> variable_list;
1367 ZigList<IrBasicBlock *> resume_blocks;
13591368
13601369 Buf *section_name;
13611370 AstNode *set_alignstack_node;
......@@ -1365,6 +1374,7 @@ struct ZigFn {
13651374 ZigList<GlobalExport> export_list;
13661375
13671376 LLVMValueRef valgrind_client_request_array;
1377 LLVMBasicBlockRef preamble_llvm_block;
13681378
13691379 FnInline fn_inline;
13701380 FnAnalState anal_state;
......@@ -1512,6 +1522,7 @@ enum PanicMsgId {
15121522 PanicMsgIdBadEnumValue,
15131523 PanicMsgIdFloatToInt,
15141524 PanicMsgIdPtrCastNull,
1525 PanicMsgIdBadResume,
15151526
15161527 PanicMsgIdCount,
15171528};
......@@ -1755,6 +1766,7 @@ struct CodeGen {
17551766 ZigType *entry_global_error_set;
17561767 ZigType *entry_arg_tuple;
17571768 ZigType *entry_enum_literal;
1769 ZigType *entry_frame_header;
17581770 } builtin_types;
17591771 ZigType *align_amt_type;
17601772 ZigType *stack_trace_type;
......@@ -2119,6 +2131,8 @@ struct IrBasicBlock {
21192131 size_t ref_count;
21202132 // index into the basic block list
21212133 size_t index;
2134 // for coroutines, the resume_index which corresponds to this block
2135 size_t resume_index;
21222136 LLVMBasicBlockRef llvm_block;
21232137 LLVMBasicBlockRef llvm_exit_block;
21242138 // The instruction that referenced this basic block and caused us to
......@@ -2297,6 +2311,8 @@ enum IrInstructionId {
22972311 IrInstructionIdEndExpr,
22982312 IrInstructionIdPtrOfArrayToSlice,
22992313 IrInstructionIdUnionInitNamedField,
2314 IrInstructionIdSuspendBegin,
2315 IrInstructionIdSuspendBr,
23002316};
23012317
23022318struct IrInstruction {
......@@ -3511,6 +3527,18 @@ struct IrInstructionPtrOfArrayToSlice {
35113527 IrInstruction *result_loc;
35123528};
35133529
3530struct IrInstructionSuspendBegin {
3531 IrInstruction base;
3532
3533 IrBasicBlock *resume_block;
3534};
3535
3536struct IrInstructionSuspendBr {
3537 IrInstruction base;
3538
3539 IrBasicBlock *resume_block;
3540};
3541
35143542enum ResultLocId {
35153543 ResultLocIdInvalid,
35163544 ResultLocIdNone,
......@@ -3593,6 +3621,8 @@ static const size_t maybe_null_index = 1;
35933621static const size_t err_union_err_index = 0;
35943622static const size_t err_union_payload_index = 1;
35953623
3624static const size_t coro_resume_index_index = 0;
3625
35963626// TODO call graph analysis to find out what this number needs to be for every function
35973627// MUST BE A POWER OF TWO.
35983628static const size_t stack_trace_ptr_count = 32;
src/analyze.cpp+123-14
......@@ -228,6 +228,8 @@ AstNode *type_decl_node(ZigType *type_entry) {
228228 return type_entry->data.enumeration.decl_node;
229229 case ZigTypeIdUnion:
230230 return type_entry->data.unionation.decl_node;
231 case ZigTypeIdCoroFrame:
232 return type_entry->data.frame.fn->proto_node;
231233 case ZigTypeIdOpaque:
232234 case ZigTypeIdMetaType:
233235 case ZigTypeIdVoid:
......@@ -262,6 +264,20 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
262264 return type_entry->data.structure.resolve_status >= status;
263265 case ZigTypeIdUnion:
264266 return type_entry->data.unionation.resolve_status >= status;
267 case ZigTypeIdCoroFrame:
268 switch (status) {
269 case ResolveStatusInvalid:
270 zig_unreachable();
271 case ResolveStatusUnstarted:
272 case ResolveStatusZeroBitsKnown:
273 return true;
274 case ResolveStatusAlignmentKnown:
275 case ResolveStatusSizeKnown:
276 return type_entry->data.frame.locals_struct != nullptr;
277 case ResolveStatusLLVMFwdDecl:
278 case ResolveStatusLLVMFull:
279 return type_entry->llvm_type != nullptr;
280 }
265281 case ZigTypeIdEnum:
266282 switch (status) {
267283 case ResolveStatusUnstarted:
......@@ -345,6 +361,25 @@ static const char *ptr_len_to_star_str(PtrLen ptr_len) {
345361 zig_unreachable();
346362}
347363
364ZigType *get_coro_frame_type(CodeGen *g, ZigFn *fn) {
365 if (fn->frame_type != nullptr) {
366 return fn->frame_type;
367 }
368
369 ZigType *entry = new_type_table_entry(ZigTypeIdCoroFrame);
370 buf_resize(&entry->name, 0);
371 buf_appendf(&entry->name, "@Frame(%s)", buf_ptr(&fn->symbol_name));
372
373 entry->data.frame.fn = fn;
374
375 // Coroutine frames are always non-zero bits because they always have a resume index.
376 entry->abi_size = SIZE_MAX;
377 entry->size_in_bits = SIZE_MAX;
378
379 fn->frame_type = entry;
380 return entry;
381}
382
348383ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
349384 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
350385 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)
......@@ -1039,6 +1074,7 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
10391074 case ZigTypeIdBoundFn:
10401075 case ZigTypeIdArgTuple:
10411076 case ZigTypeIdOpaque:
1077 case ZigTypeIdCoroFrame:
10421078 add_node_error(g, source_node,
10431079 buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
10441080 buf_ptr(&type_entry->name)));
......@@ -1127,6 +1163,7 @@ bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
11271163 case ZigTypeIdBoundFn:
11281164 case ZigTypeIdArgTuple:
11291165 case ZigTypeIdVoid:
1166 case ZigTypeIdCoroFrame:
11301167 return false;
11311168 case ZigTypeIdOpaque:
11321169 case ZigTypeIdUnreachable:
......@@ -1297,6 +1334,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
12971334 case ZigTypeIdUnion:
12981335 case ZigTypeIdFn:
12991336 case ZigTypeIdVector:
1337 case ZigTypeIdCoroFrame:
13001338 switch (type_requires_comptime(g, type_entry)) {
13011339 case ReqCompTimeNo:
13021340 break;
......@@ -1392,6 +1430,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
13921430 case ZigTypeIdUnion:
13931431 case ZigTypeIdFn:
13941432 case ZigTypeIdVector:
1433 case ZigTypeIdCoroFrame:
13951434 switch (type_requires_comptime(g, fn_type_id.return_type)) {
13961435 case ReqCompTimeInvalid:
13971436 return g->builtin_types.entry_invalid;
......@@ -1825,6 +1864,39 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
18251864 return ErrorNone;
18261865}
18271866
1867static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
1868 assert(frame_type->data.frame.locals_struct == nullptr);
1869
1870 ZigFn *fn = frame_type->data.frame.fn;
1871 switch (fn->anal_state) {
1872 case FnAnalStateInvalid:
1873 return ErrorSemanticAnalyzeFail;
1874 case FnAnalStateComplete:
1875 break;
1876 case FnAnalStateReady:
1877 analyze_fn_body(g, fn);
1878 if (fn->anal_state == FnAnalStateInvalid)
1879 return ErrorSemanticAnalyzeFail;
1880 break;
1881 case FnAnalStateProbing:
1882 add_node_error(g, fn->proto_node,
1883 buf_sprintf("cannot resolve '%s': function not fully analyzed yet",
1884 buf_ptr(&frame_type->name)));
1885 return ErrorSemanticAnalyzeFail;
1886 }
1887 // TODO iterate over fn->alloca_gen_list
1888 ZigList<ZigType *> field_types = {};
1889 ZigList<const char *> field_names = {};
1890
1891 field_names.append("resume_index");
1892 field_types.append(g->builtin_types.entry_usize);
1893
1894 assert(field_names.length == field_types.length);
1895 frame_type->data.frame.locals_struct = get_struct_type(g, buf_ptr(&frame_type->name),
1896 field_names.items, field_types.items, field_names.length);
1897 return ErrorNone;
1898}
1899
18281900static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) {
18291901 // Only integer types are allowed by the C ABI
18301902 if(ty->id != ZigTypeIdInt)
......@@ -2997,6 +3069,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
29973069 case ZigTypeIdFn:
29983070 case ZigTypeIdBoundFn:
29993071 case ZigTypeIdVector:
3072 case ZigTypeIdCoroFrame:
30003073 return type_entry;
30013074 }
30023075 zig_unreachable();
......@@ -3496,6 +3569,7 @@ bool is_container(ZigType *type_entry) {
34963569 case ZigTypeIdArgTuple:
34973570 case ZigTypeIdOpaque:
34983571 case ZigTypeIdVector:
3572 case ZigTypeIdCoroFrame:
34993573 return false;
35003574 }
35013575 zig_unreachable();
......@@ -3552,6 +3626,7 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
35523626 case ZigTypeIdArgTuple:
35533627 case ZigTypeIdOpaque:
35543628 case ZigTypeIdVector:
3629 case ZigTypeIdCoroFrame:
35553630 zig_unreachable();
35563631 }
35573632 zig_unreachable();
......@@ -4002,6 +4077,7 @@ bool handle_is_ptr(ZigType *type_entry) {
40024077 return false;
40034078 case ZigTypeIdArray:
40044079 case ZigTypeIdStruct:
4080 case ZigTypeIdCoroFrame:
40054081 return type_has_bits(type_entry);
40064082 case ZigTypeIdErrorUnion:
40074083 return type_has_bits(type_entry->data.error_union.payload_type);
......@@ -4246,6 +4322,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
42464322 case ZigTypeIdVector:
42474323 // TODO better hashing algorithm
42484324 return 3647867726;
4325 case ZigTypeIdCoroFrame:
4326 // TODO better hashing algorithm
4327 return 675741936;
42494328 case ZigTypeIdBoundFn:
42504329 case ZigTypeIdInvalid:
42514330 case ZigTypeIdUnreachable:
......@@ -4310,6 +4389,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
43104389 case ZigTypeIdOpaque:
43114390 case ZigTypeIdErrorSet:
43124391 case ZigTypeIdEnum:
4392 case ZigTypeIdCoroFrame:
43134393 return false;
43144394
43154395 case ZigTypeIdPointer:
......@@ -4381,6 +4461,7 @@ static bool return_type_is_cacheable(ZigType *return_type) {
43814461 case ZigTypeIdEnum:
43824462 case ZigTypeIdPointer:
43834463 case ZigTypeIdVector:
4464 case ZigTypeIdCoroFrame:
43844465 return true;
43854466
43864467 case ZigTypeIdArray:
......@@ -4512,6 +4593,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
45124593 case ZigTypeIdBool:
45134594 case ZigTypeIdFloat:
45144595 case ZigTypeIdErrorUnion:
4596 case ZigTypeIdCoroFrame:
45154597 return OnePossibleValueNo;
45164598 case ZigTypeIdUndefined:
45174599 case ZigTypeIdNull:
......@@ -4599,6 +4681,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
45994681 case ZigTypeIdFloat:
46004682 case ZigTypeIdVoid:
46014683 case ZigTypeIdUnreachable:
4684 case ZigTypeIdCoroFrame:
46024685 return ReqCompTimeNo;
46034686 }
46044687 zig_unreachable();
......@@ -4941,6 +5024,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {
49415024 return resolve_enum_zero_bits(g, ty);
49425025 } else if (ty->id == ZigTypeIdUnion) {
49435026 return resolve_union_alignment(g, ty);
5027 } else if (ty->id == ZigTypeIdCoroFrame) {
5028 return resolve_coro_frame(g, ty);
49445029 }
49455030 return ErrorNone;
49465031 case ResolveStatusSizeKnown:
......@@ -4950,6 +5035,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {
49505035 return resolve_enum_zero_bits(g, ty);
49515036 } else if (ty->id == ZigTypeIdUnion) {
49525037 return resolve_union_type(g, ty);
5038 } else if (ty->id == ZigTypeIdCoroFrame) {
5039 return resolve_coro_frame(g, ty);
49535040 }
49545041 return ErrorNone;
49555042 case ResolveStatusLLVMFwdDecl:
......@@ -5144,6 +5231,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
51445231 return false;
51455232 }
51465233 return true;
5234 case ZigTypeIdCoroFrame:
5235 zig_panic("TODO");
51475236 case ZigTypeIdUndefined:
51485237 zig_panic("TODO");
51495238 case ZigTypeIdNull:
......@@ -5496,6 +5585,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
54965585 buf_appendf(buf, "(args value)");
54975586 return;
54985587 }
5588 case ZigTypeIdCoroFrame:
5589 buf_appendf(buf, "(TODO: coroutine frame value)");
5590 return;
5591
54995592 }
55005593 zig_unreachable();
55015594}
......@@ -5542,6 +5635,7 @@ uint32_t type_id_hash(TypeId x) {
55425635 case ZigTypeIdFn:
55435636 case ZigTypeIdBoundFn:
55445637 case ZigTypeIdArgTuple:
5638 case ZigTypeIdCoroFrame:
55455639 zig_unreachable();
55465640 case ZigTypeIdErrorUnion:
55475641 return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
......@@ -5590,6 +5684,7 @@ bool type_id_eql(TypeId a, TypeId b) {
55905684 case ZigTypeIdBoundFn:
55915685 case ZigTypeIdArgTuple:
55925686 case ZigTypeIdOpaque:
5687 case ZigTypeIdCoroFrame:
55935688 zig_unreachable();
55945689 case ZigTypeIdErrorUnion:
55955690 return a.data.error_union.err_set_type == b.data.error_union.err_set_type &&
......@@ -5818,10 +5913,12 @@ size_t type_id_index(ZigType *entry) {
58185913 return 20;
58195914 case ZigTypeIdOpaque:
58205915 return 21;
5821 case ZigTypeIdVector:
5916 case ZigTypeIdCoroFrame:
58225917 return 22;
5823 case ZigTypeIdEnumLiteral:
5918 case ZigTypeIdVector:
58245919 return 23;
5920 case ZigTypeIdEnumLiteral:
5921 return 24;
58255922 }
58265923 zig_unreachable();
58275924}
......@@ -5878,6 +5975,8 @@ const char *type_id_name(ZigTypeId id) {
58785975 return "Opaque";
58795976 case ZigTypeIdVector:
58805977 return "Vector";
5978 case ZigTypeIdCoroFrame:
5979 return "Frame";
58815980 }
58825981 zig_unreachable();
58835982}
......@@ -5947,7 +6046,7 @@ bool type_can_fail(ZigType *type_entry) {
59476046}
59486047
59496048bool fn_type_can_fail(FnTypeId *fn_type_id) {
5950 return type_can_fail(fn_type_id->return_type) || fn_type_id->cc == CallingConventionAsync;
6049 return type_can_fail(fn_type_id->return_type);
59516050}
59526051
59536052// ErrorNone - result pointer has the type
......@@ -6935,12 +7034,12 @@ static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {
69357034 debug_align_in_bits, get_llvm_di_type(g, elem_type), (int)type->data.array.len);
69367035}
69377036
6938static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {
7037void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type, ZigFn *fn) {
69397038 if (fn_type->llvm_di_type != nullptr) return;
69407039
69417040 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
69427041 bool first_arg_return = want_first_arg_sret(g, fn_type_id);
6943 bool is_async = fn_type_id->cc == CallingConventionAsync;
7042 bool is_async = fn_type_id->cc == CallingConventionAsync || (fn != nullptr && fn->resume_blocks.length != 0);
69447043 bool is_c_abi = fn_type_id->cc == CallingConventionC;
69457044 bool prefix_arg_error_return_trace = g->have_err_ret_tracing && fn_type_can_fail(fn_type_id);
69467045 // +1 for maybe making the first argument the return value
......@@ -6955,7 +7054,7 @@ static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {
69557054 param_di_types.append(get_llvm_di_type(g, fn_type_id->return_type));
69567055 ZigType *gen_return_type;
69577056 if (is_async) {
6958 gen_return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);
7057 gen_return_type = g->builtin_types.entry_usize;
69597058 } else if (!type_has_bits(fn_type_id->return_type)) {
69607059 gen_return_type = g->builtin_types.entry_void;
69617060 } else if (first_arg_return) {
......@@ -6974,13 +7073,10 @@ static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {
69747073 param_di_types.append(get_llvm_di_type(g, gen_type));
69757074 }
69767075 if (is_async) {
6977 // coroutine frame pointer
6978 // TODO if we can make this typed a little more it will be better for
6979 // debug symbols.
6980 // TODO do we need to make this aligned more?
6981 ZigType *void_star = get_pointer_to_type(g, g->builtin_types.entry_c_void, false);
6982 gen_param_types.append(get_llvm_type(g, void_star));
6983 param_di_types.append(get_llvm_di_type(g, void_star));
7076 ZigType *frame_type = (fn == nullptr) ? g->builtin_types.entry_frame_header : get_coro_frame_type(g, fn);
7077 ZigType *ptr_type = get_pointer_to_type(g, frame_type, false);
7078 gen_param_types.append(get_llvm_type(g, ptr_type));
7079 param_di_types.append(get_llvm_di_type(g, ptr_type));
69847080 }
69857081
69867082 fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);
......@@ -7055,6 +7151,17 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {
70557151 get_llvm_di_type(g, g->err_tag_type), "");
70567152}
70577153
7154static void resolve_llvm_types_coro_frame(CodeGen *g, ZigType *frame_type, ResolveStatus wanted_resolve_status) {
7155 if (frame_type->llvm_di_type != nullptr) return;
7156
7157 resolve_llvm_types_struct(g, frame_type->data.frame.locals_struct, wanted_resolve_status);
7158 frame_type->llvm_type = frame_type->data.frame.locals_struct->llvm_type;
7159 frame_type->llvm_di_type = frame_type->data.frame.locals_struct->llvm_di_type;
7160 frame_type->abi_size = frame_type->data.frame.locals_struct->abi_size;
7161 frame_type->abi_align = frame_type->data.frame.locals_struct->abi_align;
7162 frame_type->size_in_bits = frame_type->data.frame.locals_struct->size_in_bits;
7163}
7164
70587165static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
70597166 assert(type->id == ZigTypeIdOpaque || type_is_resolved(type, ResolveStatusSizeKnown));
70607167 assert(wanted_resolve_status > ResolveStatusSizeKnown);
......@@ -7096,7 +7203,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
70967203 case ZigTypeIdArray:
70977204 return resolve_llvm_types_array(g, type);
70987205 case ZigTypeIdFn:
7099 return resolve_llvm_types_fn(g, type);
7206 return resolve_llvm_types_fn(g, type, nullptr);
71007207 case ZigTypeIdErrorSet: {
71017208 if (type->llvm_di_type != nullptr) return;
71027209
......@@ -7115,6 +7222,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
71157222 type->abi_align, get_llvm_di_type(g, type->data.vector.elem_type), type->data.vector.len);
71167223 return;
71177224 }
7225 case ZigTypeIdCoroFrame:
7226 return resolve_llvm_types_coro_frame(g, type, wanted_resolve_status);
71187227 }
71197228 zig_unreachable();
71207229}
src/analyze.hpp+3
......@@ -16,6 +16,7 @@ ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg);
1616ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg);
1717void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg);
1818ZigType *new_type_table_entry(ZigTypeId id);
19ZigType *get_coro_frame_type(CodeGen *g, ZigFn *fn);
1920ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const);
2021ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
2122 bool is_volatile, PtrLen ptr_len,
......@@ -247,4 +248,6 @@ void src_assert(bool ok, AstNode *source_node);
247248bool is_container(ZigType *type_entry);
248249ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name);
249250
251void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type, ZigFn *fn);
252
250253#endif
src/codegen.cpp+116-23
......@@ -498,7 +498,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
498498
499499 ZigType *fn_type = fn_table_entry->type_entry;
500500 // Make the raw_type_ref populated
501 (void)get_llvm_type(g, fn_type);
501 resolve_llvm_types_fn(g, fn_type, fn_table_entry);
502502 LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref;
503503 if (fn_table_entry->body_node == nullptr) {
504504 LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name));
......@@ -921,9 +921,8 @@ static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) {
921921 return false;
922922}
923923
924static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
924static bool ir_want_runtime_safety_scope(CodeGen *g, Scope *scope) {
925925 // TODO memoize
926 Scope *scope = instruction->scope;
927926 while (scope) {
928927 if (scope->id == ScopeIdBlock) {
929928 ScopeBlock *block_scope = (ScopeBlock *)scope;
......@@ -941,6 +940,10 @@ static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
941940 g->build_mode != BuildModeSmallRelease);
942941}
943942
943static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
944 return ir_want_runtime_safety_scope(g, instruction->scope);
945}
946
944947static Buf *panic_msg_buf(PanicMsgId msg_id) {
945948 switch (msg_id) {
946949 case PanicMsgIdCount:
......@@ -981,6 +984,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
981984 return buf_create_from_str("integer part of floating point value out of bounds");
982985 case PanicMsgIdPtrCastNull:
983986 return buf_create_from_str("cast causes pointer to be null");
987 case PanicMsgIdBadResume:
988 return buf_create_from_str("invalid resume of async function");
984989 }
985990 zig_unreachable();
986991}
......@@ -1027,14 +1032,18 @@ static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) {
10271032 gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);
10281033}
10291034
1030static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) {
1031 if (ir_want_runtime_safety(g, source_instruction)) {
1035static void gen_assertion_scope(CodeGen *g, PanicMsgId msg_id, Scope *source_scope) {
1036 if (ir_want_runtime_safety_scope(g, source_scope)) {
10321037 gen_safety_crash(g, msg_id);
10331038 } else {
10341039 LLVMBuildUnreachable(g->builder);
10351040 }
10361041}
10371042
1043static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) {
1044 return gen_assertion_scope(g, msg_id, source_instruction->scope);
1045}
1046
10381047static LLVMValueRef get_stacksave_fn_val(CodeGen *g) {
10391048 if (g->stacksave_fn_val)
10401049 return g->stacksave_fn_val;
......@@ -2092,6 +2101,10 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut
20922101}
20932102
20942103static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {
2104 if (g->cur_fn->resume_blocks.length != 0) {
2105 LLVMBuildRet(g->builder, LLVMGetUndef(g->builtin_types.entry_usize->llvm_type));
2106 return nullptr;
2107 }
20952108 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
20962109 if (return_instruction->value == nullptr) {
20972110 LLVMBuildRetVoid(g->builder);
......@@ -3375,8 +3388,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
33753388static bool get_prefix_arg_err_ret_stack(CodeGen *g, FnTypeId *fn_type_id) {
33763389 return g->have_err_ret_tracing &&
33773390 (fn_type_id->return_type->id == ZigTypeIdErrorUnion ||
3378 fn_type_id->return_type->id == ZigTypeIdErrorSet ||
3379 fn_type_id->cc == CallingConventionAsync);
3391 fn_type_id->return_type->id == ZigTypeIdErrorSet);
33803392}
33813393
33823394static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) {
......@@ -3440,15 +3452,23 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
34403452 bool is_var_args = fn_type_id->is_var_args;
34413453 ZigList<LLVMValueRef> gen_param_values = {};
34423454 LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr;
3443 if (first_arg_ret) {
3455 if (instruction->is_async) {
3456 assert(result_loc != nullptr);
3457 assert(instruction->fn_entry != nullptr);
3458 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, result_loc, coro_resume_index_index, "");
3459 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type);
3460 LLVMBuildStore(g->builder, zero, resume_index_ptr);
3461
3462 if (prefix_arg_err_ret_stack) {
3463 zig_panic("TODO");
3464 }
3465
34443466 gen_param_values.append(result_loc);
3445 }
3446 if (prefix_arg_err_ret_stack) {
3467 } else if (first_arg_ret) {
3468 gen_param_values.append(result_loc);
3469 } else if (prefix_arg_err_ret_stack) {
34473470 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));
34483471 }
3449 if (instruction->is_async) {
3450 zig_panic("TODO codegen async call");
3451 }
34523472 FnWalk fn_walk = {};
34533473 fn_walk.id = FnWalkIdCall;
34543474 fn_walk.data.call.inst = instruction;
......@@ -3489,9 +3509,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
34893509
34903510
34913511 if (instruction->is_async) {
3492 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
3493 LLVMBuildStore(g->builder, result, payload_ptr);
3494 return result_loc;
3512 return nullptr;
34953513 }
34963514
34973515 if (src_return_type->id == ZigTypeIdUnreachable) {
......@@ -4921,6 +4939,24 @@ static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutable *executab
49214939 return nullptr;
49224940}
49234941
4942static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutable *executable,
4943 IrInstructionSuspendBegin *instruction)
4944{
4945 LLVMValueRef locals_ptr = g->cur_ret_ptr;
4946 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, locals_ptr, coro_resume_index_index, "");
4947 LLVMValueRef new_resume_index = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
4948 instruction->resume_block->resume_index, false);
4949 LLVMBuildStore(g->builder, new_resume_index, resume_index_ptr);
4950 return nullptr;
4951}
4952
4953static LLVMValueRef ir_render_suspend_br(CodeGen *g, IrExecutable *executable,
4954 IrInstructionSuspendBr *instruction)
4955{
4956 LLVMBuildRet(g->builder, LLVMGetUndef(g->builtin_types.entry_usize->llvm_type));
4957 return nullptr;
4958}
4959
49244960static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
49254961 AstNode *source_node = instruction->source_node;
49264962 Scope *scope = instruction->scope;
......@@ -5161,6 +5197,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
51615197 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
51625198 case IrInstructionIdPtrOfArrayToSlice:
51635199 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction);
5200 case IrInstructionIdSuspendBegin:
5201 return ir_render_suspend_begin(g, executable, (IrInstructionSuspendBegin *)instruction);
5202 case IrInstructionIdSuspendBr:
5203 return ir_render_suspend_br(g, executable, (IrInstructionSuspendBr *)instruction);
51645204 }
51655205 zig_unreachable();
51665206}
......@@ -5422,7 +5462,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
54225462 }
54235463 return val;
54245464 }
5425
5465 case ZigTypeIdCoroFrame:
5466 zig_panic("TODO bit pack a coroutine frame");
54265467 }
54275468 zig_unreachable();
54285469}
......@@ -5943,7 +5984,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
59435984 case ZigTypeIdArgTuple:
59445985 case ZigTypeIdOpaque:
59455986 zig_unreachable();
5946
5987 case ZigTypeIdCoroFrame:
5988 zig_panic("TODO");
59475989 }
59485990 zig_unreachable();
59495991}
......@@ -6027,12 +6069,20 @@ static void generate_error_name_table(CodeGen *g) {
60276069static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {
60286070 IrExecutable *executable = &fn->analyzed_executable;
60296071 assert(executable->basic_block_list.length > 0);
6072 LLVMValueRef fn_val = fn_llvm_value(g, fn);
6073 LLVMBasicBlockRef first_bb = nullptr;
6074 if (fn->resume_blocks.length != 0) {
6075 first_bb = LLVMAppendBasicBlock(fn_val, "AsyncSwitch");
6076 fn->preamble_llvm_block = first_bb;
6077 }
60306078 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
60316079 IrBasicBlock *bb = executable->basic_block_list.at(block_i);
6032 bb->llvm_block = LLVMAppendBasicBlock(fn_llvm_value(g, fn), bb->name_hint);
6080 bb->llvm_block = LLVMAppendBasicBlock(fn_val, bb->name_hint);
6081 }
6082 if (first_bb == nullptr) {
6083 first_bb = executable->basic_block_list.at(0)->llvm_block;
60336084 }
6034 IrBasicBlock *entry_bb = executable->basic_block_list.at(0);
6035 LLVMPositionBuilderAtEnd(g->builder, entry_bb->llvm_block);
6085 LLVMPositionBuilderAtEnd(g->builder, first_bb);
60366086}
60376087
60386088static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val,
......@@ -6209,7 +6259,7 @@ static void do_code_gen(CodeGen *g) {
62096259 build_all_basic_blocks(g, fn_table_entry);
62106260 clear_debug_source_node(g);
62116261
6212 if (want_sret) {
6262 if (want_sret || fn_table_entry->resume_blocks.length != 0) {
62136263 g->cur_ret_ptr = LLVMGetParam(fn, 0);
62146264 } else if (handle_is_ptr(fn_type_id->return_type)) {
62156265 g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0);
......@@ -6357,6 +6407,41 @@ static void do_code_gen(CodeGen *g) {
63576407 fn_walk_init.data.inits.gen_i = gen_i_init;
63586408 walk_function_params(g, fn_table_entry->type_entry, &fn_walk_init);
63596409
6410 if (fn_table_entry->resume_blocks.length != 0) {
6411 if (!g->strip_debug_symbols) {
6412 AstNode *source_node = fn_table_entry->proto_node;
6413 ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1,
6414 (int)source_node->column + 1, get_di_scope(g, fn_table_entry->child_scope));
6415 }
6416 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
6417 LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume");
6418 LLVMPositionBuilderAtEnd(g->builder, bad_resume_block);
6419 gen_assertion_scope(g, PanicMsgIdBadResume, fn_table_entry->child_scope);
6420
6421 LLVMBasicBlockRef get_size_block = LLVMAppendBasicBlock(g->cur_fn_val, "GetSize");
6422 LLVMPositionBuilderAtEnd(g->builder, get_size_block);
6423 assert(fn_table_entry->frame_type->abi_size != 0);
6424 assert(fn_table_entry->frame_type->abi_size != SIZE_MAX);
6425 LLVMValueRef size_val = LLVMConstInt(usize_type_ref, fn_table_entry->frame_type->abi_size, false);
6426 LLVMBuildRet(g->builder, size_val);
6427
6428 LLVMPositionBuilderAtEnd(g->builder, fn_table_entry->preamble_llvm_block);
6429 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr,
6430 coro_resume_index_index, "");
6431 LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, "");
6432 // The +1 is because index 0 is reserved for getting the size.
6433 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, resume_index, bad_resume_block,
6434 fn_table_entry->resume_blocks.length + 1);
6435
6436 LLVMValueRef zero = LLVMConstNull(usize_type_ref);
6437 LLVMAddCase(switch_instr, zero, get_size_block);
6438
6439 for (size_t resume_i = 0; resume_i < fn_table_entry->resume_blocks.length; resume_i += 1) {
6440 LLVMValueRef case_value = LLVMConstInt(usize_type_ref, resume_i + 1, false);
6441 LLVMAddCase(switch_instr, case_value, fn_table_entry->resume_blocks.at(resume_i)->llvm_block);
6442 }
6443 }
6444
63606445 ir_render(g, fn_table_entry);
63616446
63626447 }
......@@ -6644,9 +6729,13 @@ static void define_builtin_types(CodeGen *g) {
66446729
66456730 g->primitive_type_table.put(&entry->name, entry);
66466731 }
6732 {
6733 const char *field_names[] = {"resume_index"};
6734 ZigType *field_types[] = {g->builtin_types.entry_usize};
6735 g->builtin_types.entry_frame_header = get_struct_type(g, "(frame header)", field_names, field_types, 1);
6736 }
66476737}
66486738
6649
66506739static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) {
66516740 BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1);
66526741 buf_init_from_str(&builtin_fn->name, name);
......@@ -7072,6 +7161,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
70727161 " BoundFn: Fn,\n"
70737162 " ArgTuple: void,\n"
70747163 " Opaque: void,\n"
7164 " Frame: void,\n"
70757165 " Vector: Vector,\n"
70767166 " EnumLiteral: void,\n"
70777167 "\n\n"
......@@ -8335,6 +8425,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
83358425 case ZigTypeIdArgTuple:
83368426 case ZigTypeIdErrorUnion:
83378427 case ZigTypeIdErrorSet:
8428 case ZigTypeIdCoroFrame:
83388429 zig_unreachable();
83398430 case ZigTypeIdVoid:
83408431 case ZigTypeIdUnreachable:
......@@ -8518,6 +8609,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
85188609 case ZigTypeIdUndefined:
85198610 case ZigTypeIdNull:
85208611 case ZigTypeIdArgTuple:
8612 case ZigTypeIdCoroFrame:
85218613 zig_unreachable();
85228614 }
85238615}
......@@ -8685,6 +8777,7 @@ static void gen_h_file(CodeGen *g) {
86858777 case ZigTypeIdOptional:
86868778 case ZigTypeIdFn:
86878779 case ZigTypeIdVector:
8780 case ZigTypeIdCoroFrame:
86888781 zig_unreachable();
86898782 case ZigTypeIdEnum:
86908783 if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {
src/ir.cpp+159-28
......@@ -318,6 +318,7 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
318318 case ZigTypeIdFn:
319319 case ZigTypeIdArgTuple:
320320 case ZigTypeIdVector:
321 case ZigTypeIdCoroFrame:
321322 return false;
322323 }
323324 zig_unreachable();
......@@ -1026,6 +1027,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInitNamedFi
10261027 return IrInstructionIdUnionInitNamedField;
10271028}
10281029
1030static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBegin *) {
1031 return IrInstructionIdSuspendBegin;
1032}
1033
1034static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBr *) {
1035 return IrInstructionIdSuspendBr;
1036}
1037
10291038template<typename T>
10301039static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
10311040 T *special_instruction = allocate<T>(1);
......@@ -3183,6 +3192,30 @@ static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *s
31833192 return &instruction->base;
31843193}
31853194
3195static IrInstruction *ir_build_suspend_begin(IrBuilder *irb, Scope *scope, AstNode *source_node,
3196 IrBasicBlock *resume_block)
3197{
3198 IrInstructionSuspendBegin *instruction = ir_build_instruction<IrInstructionSuspendBegin>(irb, scope, source_node);
3199 instruction->base.value.type = irb->codegen->builtin_types.entry_void;
3200 instruction->resume_block = resume_block;
3201
3202 ir_ref_bb(resume_block);
3203
3204 return &instruction->base;
3205}
3206
3207static IrInstruction *ir_build_suspend_br(IrBuilder *irb, Scope *scope, AstNode *source_node,
3208 IrBasicBlock *resume_block)
3209{
3210 IrInstructionSuspendBr *instruction = ir_build_instruction<IrInstructionSuspendBr>(irb, scope, source_node);
3211 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable;
3212 instruction->resume_block = resume_block;
3213
3214 ir_ref_bb(resume_block);
3215
3216 return &instruction->base;
3217}
3218
31863219static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
31873220 results[ReturnKindUnconditional] = 0;
31883221 results[ReturnKindError] = 0;
......@@ -3286,6 +3319,18 @@ static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *
32863319 ir_set_cursor_at_end(irb, basic_block);
32873320}
32883321
3322static ScopeSuspend *get_scope_suspend(Scope *scope) {
3323 while (scope) {
3324 if (scope->id == ScopeIdSuspend)
3325 return (ScopeSuspend *)scope;
3326 if (scope->id == ScopeIdFnDef)
3327 return nullptr;
3328
3329 scope = scope->parent;
3330 }
3331 return nullptr;
3332}
3333
32893334static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) {
32903335 while (scope) {
32913336 if (scope->id == ScopeIdDeferExpr)
......@@ -3308,14 +3353,9 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
33083353{
33093354 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value));
33103355
3311 bool is_async = exec_is_async(irb->exec);
3312 if (!is_async) {
3313 IrInstruction *return_inst = ir_build_return(irb, scope, node, return_value);
3314 return_inst->is_gen = is_generated_code;
3315 return return_inst;
3316 }
3317
3318 zig_panic("TODO async return");
3356 IrInstruction *return_inst = ir_build_return(irb, scope, node, return_value);
3357 return_inst->is_gen = is_generated_code;
3358 return return_inst;
33193359}
33203360
33213361static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
......@@ -5393,12 +5433,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
53935433 }
53945434
53955435 bool is_async = node->data.fn_call_expr.is_async;
5396 if (is_async) {
5397 zig_panic("TODO async fn call");
5398 }
5399
5400 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,
5401 is_async, nullptr, result_loc);
5436 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
5437 FnInlineAuto, is_async, nullptr, result_loc);
54025438 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc);
54035439}
54045440
......@@ -7655,7 +7691,45 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
76557691static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
76567692 assert(node->type == NodeTypeSuspend);
76577693
7658 zig_panic("TODO ir_gen_suspend");
7694 ZigFn *fn_entry = exec_fn_entry(irb->exec);
7695 if (!fn_entry) {
7696 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition"));
7697 return irb->codegen->invalid_instruction;
7698 }
7699 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(parent_scope);
7700 if (scope_defer_expr) {
7701 if (!scope_defer_expr->reported_err) {
7702 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside defer expression"));
7703 add_error_note(irb->codegen, msg, scope_defer_expr->base.source_node, buf_sprintf("defer here"));
7704 scope_defer_expr->reported_err = true;
7705 }
7706 return irb->codegen->invalid_instruction;
7707 }
7708 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope);
7709 if (existing_suspend_scope) {
7710 if (!existing_suspend_scope->reported_err) {
7711 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block"));
7712 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here"));
7713 existing_suspend_scope->reported_err = true;
7714 }
7715 return irb->codegen->invalid_instruction;
7716 }
7717
7718 IrBasicBlock *resume_block = ir_create_basic_block(irb, parent_scope, "Resume");
7719
7720 ir_build_suspend_begin(irb, parent_scope, node, resume_block);
7721 if (node->data.suspend.block != nullptr) {
7722 Scope *child_scope;
7723 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope);
7724 suspend_scope->resume_block = resume_block;
7725 child_scope = &suspend_scope->base;
7726 IrInstruction *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope);
7727 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res));
7728 }
7729
7730 IrInstruction *result = ir_build_suspend_br(irb, parent_scope, node, resume_block);
7731 ir_set_cursor_at_end_and_append_block(irb, resume_block);
7732 return result;
76597733}
76607734
76617735static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
......@@ -7854,13 +7928,6 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
78547928 // Entry block gets a reference because we enter it to begin.
78557929 ir_ref_bb(irb->current_basic_block);
78567930
7857 ZigFn *fn_entry = exec_fn_entry(irb->exec);
7858
7859 bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync;
7860 if (is_async) {
7861 zig_panic("ir_gen async fn");
7862 }
7863
78647931 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
78657932 assert(result);
78667933 if (irb->exec->invalid)
......@@ -12659,6 +12726,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
1265912726 case ZigTypeIdNull:
1266012727 case ZigTypeIdErrorUnion:
1266112728 case ZigTypeIdUnion:
12729 case ZigTypeIdCoroFrame:
1266212730 operator_allowed = false;
1266312731 break;
1266412732 case ZigTypeIdOptional:
......@@ -14023,6 +14091,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
1402314091 case ZigTypeIdBoundFn:
1402414092 case ZigTypeIdArgTuple:
1402514093 case ZigTypeIdOpaque:
14094 case ZigTypeIdCoroFrame:
1402614095 ir_add_error(ira, target,
1402714096 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
1402814097 break;
......@@ -14047,6 +14116,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
1404714116 case ZigTypeIdArgTuple:
1404814117 case ZigTypeIdOpaque:
1404914118 case ZigTypeIdEnumLiteral:
14119 case ZigTypeIdCoroFrame:
1405014120 ir_add_error(ira, target,
1405114121 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
1405214122 break;
......@@ -14553,6 +14623,20 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst
1455314623 return ir_const_void(ira, &instruction->base);
1455414624}
1455514625
14626static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
14627 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count)
14628{
14629 ir_assert(fn_entry != nullptr, &call_instruction->base);
14630
14631 ZigType *frame_type = get_coro_frame_type(ira->codegen, fn_entry);
14632 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
14633 frame_type, nullptr, true, true);
14634 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {
14635 return result_loc;
14636 }
14637 return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count,
14638 casted_args, FnInlineAuto, true, nullptr, result_loc, frame_type);
14639}
1455614640static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
1455714641 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)
1455814642{
......@@ -15366,16 +15450,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1536615450 if (type_is_invalid(return_type))
1536715451 return ira->codegen->invalid_instruction;
1536815452
15369 if (call_instruction->is_async) {
15370 zig_panic("TODO async call");
15371 }
15372
1537315453 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) {
1537415454 ir_add_error(ira, &call_instruction->base,
1537515455 buf_sprintf("no-inline call of inline function"));
1537615456 return ira->codegen->invalid_instruction;
1537715457 }
1537815458
15459 if (call_instruction->is_async) {
15460 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,
15461 casted_args, call_param_count);
15462 return ir_finish_anal(ira, result);
15463 }
15464
1537915465 IrInstruction *result_loc;
1538015466 if (handle_is_ptr(return_type)) {
1538115467 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
......@@ -15535,7 +15621,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
1553515621 zig_unreachable();
1553615622}
1553715623
15538static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
15624static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
1553915625 Error err;
1554015626 IrInstruction *value = un_op_instruction->value->child;
1554115627 ZigType *type_entry = ir_resolve_type(ira, value);
......@@ -15569,6 +15655,7 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_
1556915655 case ZigTypeIdFn:
1557015656 case ZigTypeIdBoundFn:
1557115657 case ZigTypeIdArgTuple:
15658 case ZigTypeIdCoroFrame:
1557215659 return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry));
1557315660 case ZigTypeIdUnreachable:
1557415661 case ZigTypeIdOpaque:
......@@ -15733,7 +15820,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction
1573315820 return result;
1573415821 }
1573515822 case IrUnOpOptional:
15736 return ir_analyze_maybe(ira, instruction);
15823 return ir_analyze_optional_type(ira, instruction);
1573715824 }
1573815825 zig_unreachable();
1573915826}
......@@ -17340,6 +17427,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
1734017427 case ZigTypeIdFn:
1734117428 case ZigTypeIdBoundFn:
1734217429 case ZigTypeIdVector:
17430 case ZigTypeIdCoroFrame:
1734317431 {
1734417432 ResolveStatus needed_status = (align_bytes == 0) ?
1734517433 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
......@@ -17454,6 +17542,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
1745417542 case ZigTypeIdFn:
1745517543 case ZigTypeIdBoundFn:
1745617544 case ZigTypeIdVector:
17545 case ZigTypeIdCoroFrame:
1745717546 {
1745817547 if ((err = ensure_complete_type(ira->codegen, child_type)))
1745917548 return ira->codegen->invalid_instruction;
......@@ -17504,6 +17593,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
1750417593 case ZigTypeIdUnion:
1750517594 case ZigTypeIdFn:
1750617595 case ZigTypeIdVector:
17596 case ZigTypeIdCoroFrame:
1750717597 {
1750817598 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
1750917599 return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes);
......@@ -18067,6 +18157,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1806718157 case ZigTypeIdArgTuple:
1806818158 case ZigTypeIdOpaque:
1806918159 case ZigTypeIdVector:
18160 case ZigTypeIdCoroFrame:
1807018161 ir_add_error(ira, &switch_target_instruction->base,
1807118162 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
1807218163 return ira->codegen->invalid_instruction;
......@@ -19906,6 +19997,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
1990619997
1990719998 break;
1990819999 }
20000 case ZigTypeIdCoroFrame:
20001 zig_panic("TODO @typeInfo for coro frames");
1990920002 }
1991020003
1991120004 assert(result != nullptr);
......@@ -21660,6 +21753,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct
2166021753 case ZigTypeIdUnion:
2166121754 case ZigTypeIdFn:
2166221755 case ZigTypeIdVector:
21756 case ZigTypeIdCoroFrame:
2166321757 {
2166421758 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
2166521759 return ir_const_unsigned(ira, &instruction->base, align_in_bytes);
......@@ -22815,6 +22909,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
2281522909 zig_panic("TODO buf_write_value_bytes fn type");
2281622910 case ZigTypeIdUnion:
2281722911 zig_panic("TODO buf_write_value_bytes union type");
22912 case ZigTypeIdCoroFrame:
22913 zig_panic("TODO buf_write_value_bytes coro frame type");
2281822914 }
2281922915 zig_unreachable();
2282022916}
......@@ -22994,6 +23090,8 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
2299423090 zig_panic("TODO buf_read_value_bytes fn type");
2299523091 case ZigTypeIdUnion:
2299623092 zig_panic("TODO buf_read_value_bytes union type");
23093 case ZigTypeIdCoroFrame:
23094 zig_panic("TODO buf_read_value_bytes coro frame type");
2299723095 }
2299823096 zig_unreachable();
2299923097}
......@@ -24021,6 +24119,33 @@ static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *i
2402124119 union_type, field_name, field_result_loc, result_loc);
2402224120}
2402324121
24122static IrInstruction *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstructionSuspendBegin *instruction) {
24123 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, instruction->resume_block, &instruction->base);
24124 if (new_bb == nullptr)
24125 return ir_unreach_error(ira);
24126 return ir_build_suspend_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node, new_bb);
24127}
24128
24129static IrInstruction *ir_analyze_instruction_suspend_br(IrAnalyze *ira, IrInstructionSuspendBr *instruction) {
24130 IrBasicBlock *old_dest_block = instruction->resume_block;
24131
24132 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &instruction->base);
24133 if (new_bb == nullptr)
24134 return ir_unreach_error(ira);
24135
24136 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
24137 ir_assert(fn_entry != nullptr, &instruction->base);
24138 fn_entry->resume_blocks.append(new_bb);
24139 // This is done after appending the block because resume_index 0 is reserved for querying the size.
24140 new_bb->resume_index = fn_entry->resume_blocks.length;
24141
24142 ir_push_resume_block(ira, old_dest_block);
24143
24144 IrInstruction *result = ir_build_suspend_br(&ira->new_irb,
24145 instruction->base.scope, instruction->base.source_node, new_bb);
24146 return ir_finish_anal(ira, result);
24147}
24148
2402424149static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) {
2402524150 switch (instruction->id) {
2402624151 case IrInstructionIdInvalid:
......@@ -24304,6 +24429,10 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
2430424429 return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction);
2430524430 case IrInstructionIdUnionInitNamedField:
2430624431 return ir_analyze_instruction_union_init_named_field(ira, (IrInstructionUnionInitNamedField *)instruction);
24432 case IrInstructionIdSuspendBegin:
24433 return ir_analyze_instruction_suspend_begin(ira, (IrInstructionSuspendBegin *)instruction);
24434 case IrInstructionIdSuspendBr:
24435 return ir_analyze_instruction_suspend_br(ira, (IrInstructionSuspendBr *)instruction);
2430724436 }
2430824437 zig_unreachable();
2430924438}
......@@ -24436,6 +24565,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2443624565 case IrInstructionIdOptionalWrap:
2443724566 case IrInstructionIdVectorToArray:
2443824567 case IrInstructionIdResetResult:
24568 case IrInstructionIdSuspendBegin:
24569 case IrInstructionIdSuspendBr:
2443924570 return true;
2444024571
2444124572 case IrInstructionIdPhi:
src/ir_print.cpp+16
......@@ -1503,6 +1503,16 @@ static void ir_print_union_init_named_field(IrPrint *irp, IrInstructionUnionInit
15031503 fprintf(irp->f, ")");
15041504}
15051505
1506static void ir_print_suspend_begin(IrPrint *irp, IrInstructionSuspendBegin *instruction) {
1507 fprintf(irp->f, "@suspendBegin()");
1508}
1509
1510static void ir_print_suspend_br(IrPrint *irp, IrInstructionSuspendBr *instruction) {
1511 fprintf(irp->f, "@suspendBr(");
1512 ir_print_other_block(irp, instruction->resume_block);
1513 fprintf(irp->f, ")");
1514}
1515
15061516static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
15071517 ir_print_prefix(irp, instruction);
15081518 switch (instruction->id) {
......@@ -1961,6 +1971,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
19611971 case IrInstructionIdUnionInitNamedField:
19621972 ir_print_union_init_named_field(irp, (IrInstructionUnionInitNamedField *)instruction);
19631973 break;
1974 case IrInstructionIdSuspendBegin:
1975 ir_print_suspend_begin(irp, (IrInstructionSuspendBegin *)instruction);
1976 break;
1977 case IrInstructionIdSuspendBr:
1978 ir_print_suspend_br(irp, (IrInstructionSuspendBr *)instruction);
1979 break;
19641980 }
19651981 fprintf(irp->f, "\n");
19661982}