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")...@@ -426,7 +426,6 @@ set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp")
426set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp")426set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp")
427427
428set(ZIG_SOURCES428set(ZIG_SOURCES
429 "${CMAKE_SOURCE_DIR}/src/glibc.cpp"
430 "${CMAKE_SOURCE_DIR}/src/analyze.cpp"429 "${CMAKE_SOURCE_DIR}/src/analyze.cpp"
431 "${CMAKE_SOURCE_DIR}/src/ast_render.cpp"430 "${CMAKE_SOURCE_DIR}/src/ast_render.cpp"
432 "${CMAKE_SOURCE_DIR}/src/bigfloat.cpp"431 "${CMAKE_SOURCE_DIR}/src/bigfloat.cpp"
...@@ -438,6 +437,7 @@ set(ZIG_SOURCES...@@ -438,6 +437,7 @@ set(ZIG_SOURCES
438 "${CMAKE_SOURCE_DIR}/src/compiler.cpp"437 "${CMAKE_SOURCE_DIR}/src/compiler.cpp"
439 "${CMAKE_SOURCE_DIR}/src/errmsg.cpp"438 "${CMAKE_SOURCE_DIR}/src/errmsg.cpp"
440 "${CMAKE_SOURCE_DIR}/src/error.cpp"439 "${CMAKE_SOURCE_DIR}/src/error.cpp"
440 "${CMAKE_SOURCE_DIR}/src/glibc.cpp"
441 "${CMAKE_SOURCE_DIR}/src/ir.cpp"441 "${CMAKE_SOURCE_DIR}/src/ir.cpp"
442 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"442 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"
443 "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"443 "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"
src/all_types.hpp+30
...@@ -1251,6 +1251,7 @@ enum ZigTypeId {...@@ -1251,6 +1251,7 @@ enum ZigTypeId {
1251 ZigTypeIdBoundFn,1251 ZigTypeIdBoundFn,
1252 ZigTypeIdArgTuple,1252 ZigTypeIdArgTuple,
1253 ZigTypeIdOpaque,1253 ZigTypeIdOpaque,
1254 ZigTypeIdCoroFrame,
1254 ZigTypeIdVector,1255 ZigTypeIdVector,
1255 ZigTypeIdEnumLiteral,1256 ZigTypeIdEnumLiteral,
1256};1257};
...@@ -1265,6 +1266,11 @@ struct ZigTypeOpaque {...@@ -1265,6 +1266,11 @@ struct ZigTypeOpaque {
1265 Buf *bare_name;1266 Buf *bare_name;
1266};1267};
12671268
1269struct ZigTypeCoroFrame {
1270 ZigFn *fn;
1271 ZigType *locals_struct;
1272};
1273
1268struct ZigType {1274struct ZigType {
1269 ZigTypeId id;1275 ZigTypeId id;
1270 Buf name;1276 Buf name;
...@@ -1290,6 +1296,7 @@ struct ZigType {...@@ -1290,6 +1296,7 @@ struct ZigType {
1290 ZigTypeBoundFn bound_fn;1296 ZigTypeBoundFn bound_fn;
1291 ZigTypeVector vector;1297 ZigTypeVector vector;
1292 ZigTypeOpaque opaque;1298 ZigTypeOpaque opaque;
1299 ZigTypeCoroFrame frame;
1293 } data;1300 } data;
12941301
1295 // use these fields to make sure we don't duplicate type table entries for the same type1302 // use these fields to make sure we don't duplicate type table entries for the same type
...@@ -1340,6 +1347,7 @@ struct ZigFn {...@@ -1340,6 +1347,7 @@ struct ZigFn {
1340 ScopeBlock *def_scope; // parent is child_scope1347 ScopeBlock *def_scope; // parent is child_scope
1341 Buf symbol_name;1348 Buf symbol_name;
1342 ZigType *type_entry; // function type1349 ZigType *type_entry; // function type
1350 ZigType *frame_type; // coro frame type
1343 // in the case of normal functions this is the implicit return type1351 // in the case of normal functions this is the implicit return type
1344 // in the case of async functions this is the implicit return type according to the1352 // in the case of async functions this is the implicit return type according to the
1345 // zig source code, not according to zig ir1353 // zig source code, not according to zig ir
...@@ -1356,6 +1364,7 @@ struct ZigFn {...@@ -1356,6 +1364,7 @@ struct ZigFn {
13561364
1357 ZigList<IrInstructionAllocaGen *> alloca_gen_list;1365 ZigList<IrInstructionAllocaGen *> alloca_gen_list;
1358 ZigList<ZigVar *> variable_list;1366 ZigList<ZigVar *> variable_list;
1367 ZigList<IrBasicBlock *> resume_blocks;
13591368
1360 Buf *section_name;1369 Buf *section_name;
1361 AstNode *set_alignstack_node;1370 AstNode *set_alignstack_node;
...@@ -1365,6 +1374,7 @@ struct ZigFn {...@@ -1365,6 +1374,7 @@ struct ZigFn {
1365 ZigList<GlobalExport> export_list;1374 ZigList<GlobalExport> export_list;
13661375
1367 LLVMValueRef valgrind_client_request_array;1376 LLVMValueRef valgrind_client_request_array;
1377 LLVMBasicBlockRef preamble_llvm_block;
13681378
1369 FnInline fn_inline;1379 FnInline fn_inline;
1370 FnAnalState anal_state;1380 FnAnalState anal_state;
...@@ -1512,6 +1522,7 @@ enum PanicMsgId {...@@ -1512,6 +1522,7 @@ enum PanicMsgId {
1512 PanicMsgIdBadEnumValue,1522 PanicMsgIdBadEnumValue,
1513 PanicMsgIdFloatToInt,1523 PanicMsgIdFloatToInt,
1514 PanicMsgIdPtrCastNull,1524 PanicMsgIdPtrCastNull,
1525 PanicMsgIdBadResume,
15151526
1516 PanicMsgIdCount,1527 PanicMsgIdCount,
1517};1528};
...@@ -1755,6 +1766,7 @@ struct CodeGen {...@@ -1755,6 +1766,7 @@ struct CodeGen {
1755 ZigType *entry_global_error_set;1766 ZigType *entry_global_error_set;
1756 ZigType *entry_arg_tuple;1767 ZigType *entry_arg_tuple;
1757 ZigType *entry_enum_literal;1768 ZigType *entry_enum_literal;
1769 ZigType *entry_frame_header;
1758 } builtin_types;1770 } builtin_types;
1759 ZigType *align_amt_type;1771 ZigType *align_amt_type;
1760 ZigType *stack_trace_type;1772 ZigType *stack_trace_type;
...@@ -2119,6 +2131,8 @@ struct IrBasicBlock {...@@ -2119,6 +2131,8 @@ struct IrBasicBlock {
2119 size_t ref_count;2131 size_t ref_count;
2120 // index into the basic block list2132 // index into the basic block list
2121 size_t index;2133 size_t index;
2134 // for coroutines, the resume_index which corresponds to this block
2135 size_t resume_index;
2122 LLVMBasicBlockRef llvm_block;2136 LLVMBasicBlockRef llvm_block;
2123 LLVMBasicBlockRef llvm_exit_block;2137 LLVMBasicBlockRef llvm_exit_block;
2124 // The instruction that referenced this basic block and caused us to2138 // The instruction that referenced this basic block and caused us to
...@@ -2297,6 +2311,8 @@ enum IrInstructionId {...@@ -2297,6 +2311,8 @@ enum IrInstructionId {
2297 IrInstructionIdEndExpr,2311 IrInstructionIdEndExpr,
2298 IrInstructionIdPtrOfArrayToSlice,2312 IrInstructionIdPtrOfArrayToSlice,
2299 IrInstructionIdUnionInitNamedField,2313 IrInstructionIdUnionInitNamedField,
2314 IrInstructionIdSuspendBegin,
2315 IrInstructionIdSuspendBr,
2300};2316};
23012317
2302struct IrInstruction {2318struct IrInstruction {
...@@ -3511,6 +3527,18 @@ struct IrInstructionPtrOfArrayToSlice {...@@ -3511,6 +3527,18 @@ struct IrInstructionPtrOfArrayToSlice {
3511 IrInstruction *result_loc;3527 IrInstruction *result_loc;
3512};3528};
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
3514enum ResultLocId {3542enum ResultLocId {
3515 ResultLocIdInvalid,3543 ResultLocIdInvalid,
3516 ResultLocIdNone,3544 ResultLocIdNone,
...@@ -3593,6 +3621,8 @@ static const size_t maybe_null_index = 1;...@@ -3593,6 +3621,8 @@ static const size_t maybe_null_index = 1;
3593static const size_t err_union_err_index = 0;3621static const size_t err_union_err_index = 0;
3594static const size_t err_union_payload_index = 1;3622static const size_t err_union_payload_index = 1;
35953623
3624static const size_t coro_resume_index_index = 0;
3625
3596// TODO call graph analysis to find out what this number needs to be for every function3626// TODO call graph analysis to find out what this number needs to be for every function
3597// MUST BE A POWER OF TWO.3627// MUST BE A POWER OF TWO.
3598static const size_t stack_trace_ptr_count = 32;3628static const size_t stack_trace_ptr_count = 32;
src/analyze.cpp+123-14
...@@ -228,6 +228,8 @@ AstNode *type_decl_node(ZigType *type_entry) {...@@ -228,6 +228,8 @@ AstNode *type_decl_node(ZigType *type_entry) {
228 return type_entry->data.enumeration.decl_node;228 return type_entry->data.enumeration.decl_node;
229 case ZigTypeIdUnion:229 case ZigTypeIdUnion:
230 return type_entry->data.unionation.decl_node;230 return type_entry->data.unionation.decl_node;
231 case ZigTypeIdCoroFrame:
232 return type_entry->data.frame.fn->proto_node;
231 case ZigTypeIdOpaque:233 case ZigTypeIdOpaque:
232 case ZigTypeIdMetaType:234 case ZigTypeIdMetaType:
233 case ZigTypeIdVoid:235 case ZigTypeIdVoid:
...@@ -262,6 +264,20 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {...@@ -262,6 +264,20 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
262 return type_entry->data.structure.resolve_status >= status;264 return type_entry->data.structure.resolve_status >= status;
263 case ZigTypeIdUnion:265 case ZigTypeIdUnion:
264 return type_entry->data.unionation.resolve_status >= status;266 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 }
265 case ZigTypeIdEnum:281 case ZigTypeIdEnum:
266 switch (status) {282 switch (status) {
267 case ResolveStatusUnstarted:283 case ResolveStatusUnstarted:
...@@ -345,6 +361,25 @@ static const char *ptr_len_to_star_str(PtrLen ptr_len) {...@@ -345,6 +361,25 @@ static const char *ptr_len_to_star_str(PtrLen ptr_len) {
345 zig_unreachable();361 zig_unreachable();
346}362}
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
348ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,383ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
349 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,384 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
350 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)385 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...@@ -1039,6 +1074,7 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
1039 case ZigTypeIdBoundFn:1074 case ZigTypeIdBoundFn:
1040 case ZigTypeIdArgTuple:1075 case ZigTypeIdArgTuple:
1041 case ZigTypeIdOpaque:1076 case ZigTypeIdOpaque:
1077 case ZigTypeIdCoroFrame:
1042 add_node_error(g, source_node,1078 add_node_error(g, source_node,
1043 buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",1079 buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
1044 buf_ptr(&type_entry->name)));1080 buf_ptr(&type_entry->name)));
...@@ -1127,6 +1163,7 @@ bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {...@@ -1127,6 +1163,7 @@ bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
1127 case ZigTypeIdBoundFn:1163 case ZigTypeIdBoundFn:
1128 case ZigTypeIdArgTuple:1164 case ZigTypeIdArgTuple:
1129 case ZigTypeIdVoid:1165 case ZigTypeIdVoid:
1166 case ZigTypeIdCoroFrame:
1130 return false;1167 return false;
1131 case ZigTypeIdOpaque:1168 case ZigTypeIdOpaque:
1132 case ZigTypeIdUnreachable:1169 case ZigTypeIdUnreachable:
...@@ -1297,6 +1334,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -1297,6 +1334,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
1297 case ZigTypeIdUnion:1334 case ZigTypeIdUnion:
1298 case ZigTypeIdFn:1335 case ZigTypeIdFn:
1299 case ZigTypeIdVector:1336 case ZigTypeIdVector:
1337 case ZigTypeIdCoroFrame:
1300 switch (type_requires_comptime(g, type_entry)) {1338 switch (type_requires_comptime(g, type_entry)) {
1301 case ReqCompTimeNo:1339 case ReqCompTimeNo:
1302 break;1340 break;
...@@ -1392,6 +1430,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -1392,6 +1430,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
1392 case ZigTypeIdUnion:1430 case ZigTypeIdUnion:
1393 case ZigTypeIdFn:1431 case ZigTypeIdFn:
1394 case ZigTypeIdVector:1432 case ZigTypeIdVector:
1433 case ZigTypeIdCoroFrame:
1395 switch (type_requires_comptime(g, fn_type_id.return_type)) {1434 switch (type_requires_comptime(g, fn_type_id.return_type)) {
1396 case ReqCompTimeInvalid:1435 case ReqCompTimeInvalid:
1397 return g->builtin_types.entry_invalid;1436 return g->builtin_types.entry_invalid;
...@@ -1825,6 +1864,39 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {...@@ -1825,6 +1864,39 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
1825 return ErrorNone;1864 return ErrorNone;
1826}1865}
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
1828static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) {1900static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) {
1829 // Only integer types are allowed by the C ABI1901 // Only integer types are allowed by the C ABI
1830 if(ty->id != ZigTypeIdInt)1902 if(ty->id != ZigTypeIdInt)
...@@ -2997,6 +3069,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry...@@ -2997,6 +3069,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
2997 case ZigTypeIdFn:3069 case ZigTypeIdFn:
2998 case ZigTypeIdBoundFn:3070 case ZigTypeIdBoundFn:
2999 case ZigTypeIdVector:3071 case ZigTypeIdVector:
3072 case ZigTypeIdCoroFrame:
3000 return type_entry;3073 return type_entry;
3001 }3074 }
3002 zig_unreachable();3075 zig_unreachable();
...@@ -3496,6 +3569,7 @@ bool is_container(ZigType *type_entry) {...@@ -3496,6 +3569,7 @@ bool is_container(ZigType *type_entry) {
3496 case ZigTypeIdArgTuple:3569 case ZigTypeIdArgTuple:
3497 case ZigTypeIdOpaque:3570 case ZigTypeIdOpaque:
3498 case ZigTypeIdVector:3571 case ZigTypeIdVector:
3572 case ZigTypeIdCoroFrame:
3499 return false;3573 return false;
3500 }3574 }
3501 zig_unreachable();3575 zig_unreachable();
...@@ -3552,6 +3626,7 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {...@@ -3552,6 +3626,7 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
3552 case ZigTypeIdArgTuple:3626 case ZigTypeIdArgTuple:
3553 case ZigTypeIdOpaque:3627 case ZigTypeIdOpaque:
3554 case ZigTypeIdVector:3628 case ZigTypeIdVector:
3629 case ZigTypeIdCoroFrame:
3555 zig_unreachable();3630 zig_unreachable();
3556 }3631 }
3557 zig_unreachable();3632 zig_unreachable();
...@@ -4002,6 +4077,7 @@ bool handle_is_ptr(ZigType *type_entry) {...@@ -4002,6 +4077,7 @@ bool handle_is_ptr(ZigType *type_entry) {
4002 return false;4077 return false;
4003 case ZigTypeIdArray:4078 case ZigTypeIdArray:
4004 case ZigTypeIdStruct:4079 case ZigTypeIdStruct:
4080 case ZigTypeIdCoroFrame:
4005 return type_has_bits(type_entry);4081 return type_has_bits(type_entry);
4006 case ZigTypeIdErrorUnion:4082 case ZigTypeIdErrorUnion:
4007 return type_has_bits(type_entry->data.error_union.payload_type);4083 return type_has_bits(type_entry->data.error_union.payload_type);
...@@ -4246,6 +4322,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {...@@ -4246,6 +4322,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
4246 case ZigTypeIdVector:4322 case ZigTypeIdVector:
4247 // TODO better hashing algorithm4323 // TODO better hashing algorithm
4248 return 3647867726;4324 return 3647867726;
4325 case ZigTypeIdCoroFrame:
4326 // TODO better hashing algorithm
4327 return 675741936;
4249 case ZigTypeIdBoundFn:4328 case ZigTypeIdBoundFn:
4250 case ZigTypeIdInvalid:4329 case ZigTypeIdInvalid:
4251 case ZigTypeIdUnreachable:4330 case ZigTypeIdUnreachable:
...@@ -4310,6 +4389,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {...@@ -4310,6 +4389,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
4310 case ZigTypeIdOpaque:4389 case ZigTypeIdOpaque:
4311 case ZigTypeIdErrorSet:4390 case ZigTypeIdErrorSet:
4312 case ZigTypeIdEnum:4391 case ZigTypeIdEnum:
4392 case ZigTypeIdCoroFrame:
4313 return false;4393 return false;
43144394
4315 case ZigTypeIdPointer:4395 case ZigTypeIdPointer:
...@@ -4381,6 +4461,7 @@ static bool return_type_is_cacheable(ZigType *return_type) {...@@ -4381,6 +4461,7 @@ static bool return_type_is_cacheable(ZigType *return_type) {
4381 case ZigTypeIdEnum:4461 case ZigTypeIdEnum:
4382 case ZigTypeIdPointer:4462 case ZigTypeIdPointer:
4383 case ZigTypeIdVector:4463 case ZigTypeIdVector:
4464 case ZigTypeIdCoroFrame:
4384 return true;4465 return true;
43854466
4386 case ZigTypeIdArray:4467 case ZigTypeIdArray:
...@@ -4512,6 +4593,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {...@@ -4512,6 +4593,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
4512 case ZigTypeIdBool:4593 case ZigTypeIdBool:
4513 case ZigTypeIdFloat:4594 case ZigTypeIdFloat:
4514 case ZigTypeIdErrorUnion:4595 case ZigTypeIdErrorUnion:
4596 case ZigTypeIdCoroFrame:
4515 return OnePossibleValueNo;4597 return OnePossibleValueNo;
4516 case ZigTypeIdUndefined:4598 case ZigTypeIdUndefined:
4517 case ZigTypeIdNull:4599 case ZigTypeIdNull:
...@@ -4599,6 +4681,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {...@@ -4599,6 +4681,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
4599 case ZigTypeIdFloat:4681 case ZigTypeIdFloat:
4600 case ZigTypeIdVoid:4682 case ZigTypeIdVoid:
4601 case ZigTypeIdUnreachable:4683 case ZigTypeIdUnreachable:
4684 case ZigTypeIdCoroFrame:
4602 return ReqCompTimeNo;4685 return ReqCompTimeNo;
4603 }4686 }
4604 zig_unreachable();4687 zig_unreachable();
...@@ -4941,6 +5024,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {...@@ -4941,6 +5024,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {
4941 return resolve_enum_zero_bits(g, ty);5024 return resolve_enum_zero_bits(g, ty);
4942 } else if (ty->id == ZigTypeIdUnion) {5025 } else if (ty->id == ZigTypeIdUnion) {
4943 return resolve_union_alignment(g, ty);5026 return resolve_union_alignment(g, ty);
5027 } else if (ty->id == ZigTypeIdCoroFrame) {
5028 return resolve_coro_frame(g, ty);
4944 }5029 }
4945 return ErrorNone;5030 return ErrorNone;
4946 case ResolveStatusSizeKnown:5031 case ResolveStatusSizeKnown:
...@@ -4950,6 +5035,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {...@@ -4950,6 +5035,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {
4950 return resolve_enum_zero_bits(g, ty);5035 return resolve_enum_zero_bits(g, ty);
4951 } else if (ty->id == ZigTypeIdUnion) {5036 } else if (ty->id == ZigTypeIdUnion) {
4952 return resolve_union_type(g, ty);5037 return resolve_union_type(g, ty);
5038 } else if (ty->id == ZigTypeIdCoroFrame) {
5039 return resolve_coro_frame(g, ty);
4953 }5040 }
4954 return ErrorNone;5041 return ErrorNone;
4955 case ResolveStatusLLVMFwdDecl:5042 case ResolveStatusLLVMFwdDecl:
...@@ -5144,6 +5231,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {...@@ -5144,6 +5231,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
5144 return false;5231 return false;
5145 }5232 }
5146 return true;5233 return true;
5234 case ZigTypeIdCoroFrame:
5235 zig_panic("TODO");
5147 case ZigTypeIdUndefined:5236 case ZigTypeIdUndefined:
5148 zig_panic("TODO");5237 zig_panic("TODO");
5149 case ZigTypeIdNull:5238 case ZigTypeIdNull:
...@@ -5496,6 +5585,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -5496,6 +5585,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
5496 buf_appendf(buf, "(args value)");5585 buf_appendf(buf, "(args value)");
5497 return;5586 return;
5498 }5587 }
5588 case ZigTypeIdCoroFrame:
5589 buf_appendf(buf, "(TODO: coroutine frame value)");
5590 return;
5591
5499 }5592 }
5500 zig_unreachable();5593 zig_unreachable();
5501}5594}
...@@ -5542,6 +5635,7 @@ uint32_t type_id_hash(TypeId x) {...@@ -5542,6 +5635,7 @@ uint32_t type_id_hash(TypeId x) {
5542 case ZigTypeIdFn:5635 case ZigTypeIdFn:
5543 case ZigTypeIdBoundFn:5636 case ZigTypeIdBoundFn:
5544 case ZigTypeIdArgTuple:5637 case ZigTypeIdArgTuple:
5638 case ZigTypeIdCoroFrame:
5545 zig_unreachable();5639 zig_unreachable();
5546 case ZigTypeIdErrorUnion:5640 case ZigTypeIdErrorUnion:
5547 return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);5641 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) {...@@ -5590,6 +5684,7 @@ bool type_id_eql(TypeId a, TypeId b) {
5590 case ZigTypeIdBoundFn:5684 case ZigTypeIdBoundFn:
5591 case ZigTypeIdArgTuple:5685 case ZigTypeIdArgTuple:
5592 case ZigTypeIdOpaque:5686 case ZigTypeIdOpaque:
5687 case ZigTypeIdCoroFrame:
5593 zig_unreachable();5688 zig_unreachable();
5594 case ZigTypeIdErrorUnion:5689 case ZigTypeIdErrorUnion:
5595 return a.data.error_union.err_set_type == b.data.error_union.err_set_type &&5690 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) {...@@ -5818,10 +5913,12 @@ size_t type_id_index(ZigType *entry) {
5818 return 20;5913 return 20;
5819 case ZigTypeIdOpaque:5914 case ZigTypeIdOpaque:
5820 return 21;5915 return 21;
5821 case ZigTypeIdVector:5916 case ZigTypeIdCoroFrame:
5822 return 22;5917 return 22;
5823 case ZigTypeIdEnumLiteral:5918 case ZigTypeIdVector:
5824 return 23;5919 return 23;
5920 case ZigTypeIdEnumLiteral:
5921 return 24;
5825 }5922 }
5826 zig_unreachable();5923 zig_unreachable();
5827}5924}
...@@ -5878,6 +5975,8 @@ const char *type_id_name(ZigTypeId id) {...@@ -5878,6 +5975,8 @@ const char *type_id_name(ZigTypeId id) {
5878 return "Opaque";5975 return "Opaque";
5879 case ZigTypeIdVector:5976 case ZigTypeIdVector:
5880 return "Vector";5977 return "Vector";
5978 case ZigTypeIdCoroFrame:
5979 return "Frame";
5881 }5980 }
5882 zig_unreachable();5981 zig_unreachable();
5883}5982}
...@@ -5947,7 +6046,7 @@ bool type_can_fail(ZigType *type_entry) {...@@ -5947,7 +6046,7 @@ bool type_can_fail(ZigType *type_entry) {
5947}6046}
59486047
5949bool fn_type_can_fail(FnTypeId *fn_type_id) {6048bool 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);
5951}6050}
59526051
5953// ErrorNone - result pointer has the type6052// ErrorNone - result pointer has the type
...@@ -6935,12 +7034,12 @@ static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {...@@ -6935,12 +7034,12 @@ static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {
6935 debug_align_in_bits, get_llvm_di_type(g, elem_type), (int)type->data.array.len);7034 debug_align_in_bits, get_llvm_di_type(g, elem_type), (int)type->data.array.len);
6936}7035}
69377036
6938static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {7037void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type, ZigFn *fn) {
6939 if (fn_type->llvm_di_type != nullptr) return;7038 if (fn_type->llvm_di_type != nullptr) return;
69407039
6941 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;7040 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
6942 bool first_arg_return = want_first_arg_sret(g, fn_type_id);7041 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);
6944 bool is_c_abi = fn_type_id->cc == CallingConventionC;7043 bool is_c_abi = fn_type_id->cc == CallingConventionC;
6945 bool prefix_arg_error_return_trace = g->have_err_ret_tracing && fn_type_can_fail(fn_type_id);7044 bool prefix_arg_error_return_trace = g->have_err_ret_tracing && fn_type_can_fail(fn_type_id);
6946 // +1 for maybe making the first argument the return value7045 // +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) {...@@ -6955,7 +7054,7 @@ static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {
6955 param_di_types.append(get_llvm_di_type(g, fn_type_id->return_type));7054 param_di_types.append(get_llvm_di_type(g, fn_type_id->return_type));
6956 ZigType *gen_return_type;7055 ZigType *gen_return_type;
6957 if (is_async) {7056 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;
6959 } else if (!type_has_bits(fn_type_id->return_type)) {7058 } else if (!type_has_bits(fn_type_id->return_type)) {
6960 gen_return_type = g->builtin_types.entry_void;7059 gen_return_type = g->builtin_types.entry_void;
6961 } else if (first_arg_return) {7060 } else if (first_arg_return) {
...@@ -6974,13 +7073,10 @@ static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {...@@ -6974,13 +7073,10 @@ static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {
6974 param_di_types.append(get_llvm_di_type(g, gen_type));7073 param_di_types.append(get_llvm_di_type(g, gen_type));
6975 }7074 }
6976 if (is_async) {7075 if (is_async) {
6977 // coroutine frame pointer7076 ZigType *frame_type = (fn == nullptr) ? g->builtin_types.entry_frame_header : get_coro_frame_type(g, fn);
6978 // TODO if we can make this typed a little more it will be better for7077 ZigType *ptr_type = get_pointer_to_type(g, frame_type, false);
6979 // debug symbols.7078 gen_param_types.append(get_llvm_type(g, ptr_type));
6980 // TODO do we need to make this aligned more?7079 param_di_types.append(get_llvm_di_type(g, ptr_type));
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));
6984 }7080 }
69857081
6986 fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);7082 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) {...@@ -7055,6 +7151,17 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {
7055 get_llvm_di_type(g, g->err_tag_type), "");7151 get_llvm_di_type(g, g->err_tag_type), "");
7056}7152}
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
7058static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {7165static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
7059 assert(type->id == ZigTypeIdOpaque || type_is_resolved(type, ResolveStatusSizeKnown));7166 assert(type->id == ZigTypeIdOpaque || type_is_resolved(type, ResolveStatusSizeKnown));
7060 assert(wanted_resolve_status > ResolveStatusSizeKnown);7167 assert(wanted_resolve_status > ResolveStatusSizeKnown);
...@@ -7096,7 +7203,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r...@@ -7096,7 +7203,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
7096 case ZigTypeIdArray:7203 case ZigTypeIdArray:
7097 return resolve_llvm_types_array(g, type);7204 return resolve_llvm_types_array(g, type);
7098 case ZigTypeIdFn:7205 case ZigTypeIdFn:
7099 return resolve_llvm_types_fn(g, type);7206 return resolve_llvm_types_fn(g, type, nullptr);
7100 case ZigTypeIdErrorSet: {7207 case ZigTypeIdErrorSet: {
7101 if (type->llvm_di_type != nullptr) return;7208 if (type->llvm_di_type != nullptr) return;
71027209
...@@ -7115,6 +7222,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r...@@ -7115,6 +7222,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
7115 type->abi_align, get_llvm_di_type(g, type->data.vector.elem_type), type->data.vector.len);7222 type->abi_align, get_llvm_di_type(g, type->data.vector.elem_type), type->data.vector.len);
7116 return;7223 return;
7117 }7224 }
7225 case ZigTypeIdCoroFrame:
7226 return resolve_llvm_types_coro_frame(g, type, wanted_resolve_status);
7118 }7227 }
7119 zig_unreachable();7228 zig_unreachable();
7120}7229}
src/analyze.hpp+3
...@@ -16,6 +16,7 @@ ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg);...@@ -16,6 +16,7 @@ ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg);
16ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg);16ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg);
17void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg);17void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg);
18ZigType *new_type_table_entry(ZigTypeId id);18ZigType *new_type_table_entry(ZigTypeId id);
19ZigType *get_coro_frame_type(CodeGen *g, ZigFn *fn);
19ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const);20ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const);
20ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,21ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
21 bool is_volatile, PtrLen ptr_len,22 bool is_volatile, PtrLen ptr_len,
...@@ -247,4 +248,6 @@ void src_assert(bool ok, AstNode *source_node);...@@ -247,4 +248,6 @@ void src_assert(bool ok, AstNode *source_node);
247bool is_container(ZigType *type_entry);248bool is_container(ZigType *type_entry);
248ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name);249ConstExprValue *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
250#endif253#endif
src/codegen.cpp+116-23
...@@ -498,7 +498,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {...@@ -498,7 +498,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
498498
499 ZigType *fn_type = fn_table_entry->type_entry;499 ZigType *fn_type = fn_table_entry->type_entry;
500 // Make the raw_type_ref populated500 // 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);
502 LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref;502 LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref;
503 if (fn_table_entry->body_node == nullptr) {503 if (fn_table_entry->body_node == nullptr) {
504 LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name));504 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) {...@@ -921,9 +921,8 @@ static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) {
921 return false;921 return false;
922}922}
923923
924static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {924static bool ir_want_runtime_safety_scope(CodeGen *g, Scope *scope) {
925 // TODO memoize925 // TODO memoize
926 Scope *scope = instruction->scope;
927 while (scope) {926 while (scope) {
928 if (scope->id == ScopeIdBlock) {927 if (scope->id == ScopeIdBlock) {
929 ScopeBlock *block_scope = (ScopeBlock *)scope;928 ScopeBlock *block_scope = (ScopeBlock *)scope;
...@@ -941,6 +940,10 @@ static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {...@@ -941,6 +940,10 @@ static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
941 g->build_mode != BuildModeSmallRelease);940 g->build_mode != BuildModeSmallRelease);
942}941}
943942
943static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
944 return ir_want_runtime_safety_scope(g, instruction->scope);
945}
946
944static Buf *panic_msg_buf(PanicMsgId msg_id) {947static Buf *panic_msg_buf(PanicMsgId msg_id) {
945 switch (msg_id) {948 switch (msg_id) {
946 case PanicMsgIdCount:949 case PanicMsgIdCount:
...@@ -981,6 +984,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {...@@ -981,6 +984,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
981 return buf_create_from_str("integer part of floating point value out of bounds");984 return buf_create_from_str("integer part of floating point value out of bounds");
982 case PanicMsgIdPtrCastNull:985 case PanicMsgIdPtrCastNull:
983 return buf_create_from_str("cast causes pointer to be null");986 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");
984 }989 }
985 zig_unreachable();990 zig_unreachable();
986}991}
...@@ -1027,14 +1032,18 @@ static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) {...@@ -1027,14 +1032,18 @@ static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) {
1027 gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);1032 gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);
1028}1033}
10291034
1030static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) {1035static void gen_assertion_scope(CodeGen *g, PanicMsgId msg_id, Scope *source_scope) {
1031 if (ir_want_runtime_safety(g, source_instruction)) {1036 if (ir_want_runtime_safety_scope(g, source_scope)) {
1032 gen_safety_crash(g, msg_id);1037 gen_safety_crash(g, msg_id);
1033 } else {1038 } else {
1034 LLVMBuildUnreachable(g->builder);1039 LLVMBuildUnreachable(g->builder);
1035 }1040 }
1036}1041}
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
1038static LLVMValueRef get_stacksave_fn_val(CodeGen *g) {1047static LLVMValueRef get_stacksave_fn_val(CodeGen *g) {
1039 if (g->stacksave_fn_val)1048 if (g->stacksave_fn_val)
1040 return g->stacksave_fn_val;1049 return g->stacksave_fn_val;
...@@ -2092,6 +2101,10 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut...@@ -2092,6 +2101,10 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut
2092}2101}
20932102
2094static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {2103static 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 }
2095 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {2108 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
2096 if (return_instruction->value == nullptr) {2109 if (return_instruction->value == nullptr) {
2097 LLVMBuildRetVoid(g->builder);2110 LLVMBuildRetVoid(g->builder);
...@@ -3375,8 +3388,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -3375,8 +3388,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
3375static bool get_prefix_arg_err_ret_stack(CodeGen *g, FnTypeId *fn_type_id) {3388static bool get_prefix_arg_err_ret_stack(CodeGen *g, FnTypeId *fn_type_id) {
3376 return g->have_err_ret_tracing &&3389 return g->have_err_ret_tracing &&
3377 (fn_type_id->return_type->id == ZigTypeIdErrorUnion ||3390 (fn_type_id->return_type->id == ZigTypeIdErrorUnion ||
3378 fn_type_id->return_type->id == ZigTypeIdErrorSet ||3391 fn_type_id->return_type->id == ZigTypeIdErrorSet);
3379 fn_type_id->cc == CallingConventionAsync);
3380}3392}
33813393
3382static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) {3394static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) {
...@@ -3440,15 +3452,23 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3440,15 +3452,23 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3440 bool is_var_args = fn_type_id->is_var_args;3452 bool is_var_args = fn_type_id->is_var_args;
3441 ZigList<LLVMValueRef> gen_param_values = {};3453 ZigList<LLVMValueRef> gen_param_values = {};
3442 LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr;3454 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
3444 gen_param_values.append(result_loc);3466 gen_param_values.append(result_loc);
3445 }3467 } else if (first_arg_ret) {
3446 if (prefix_arg_err_ret_stack) {3468 gen_param_values.append(result_loc);
3469 } else if (prefix_arg_err_ret_stack) {
3447 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));3470 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));
3448 }3471 }
3449 if (instruction->is_async) {
3450 zig_panic("TODO codegen async call");
3451 }
3452 FnWalk fn_walk = {};3472 FnWalk fn_walk = {};
3453 fn_walk.id = FnWalkIdCall;3473 fn_walk.id = FnWalkIdCall;
3454 fn_walk.data.call.inst = instruction;3474 fn_walk.data.call.inst = instruction;
...@@ -3489,9 +3509,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3489,9 +3509,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
34893509
34903510
3491 if (instruction->is_async) {3511 if (instruction->is_async) {
3492 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");3512 return nullptr;
3493 LLVMBuildStore(g->builder, result, payload_ptr);
3494 return result_loc;
3495 }3513 }
34963514
3497 if (src_return_type->id == ZigTypeIdUnreachable) {3515 if (src_return_type->id == ZigTypeIdUnreachable) {
...@@ -4921,6 +4939,24 @@ static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutable *executab...@@ -4921,6 +4939,24 @@ static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutable *executab
4921 return nullptr;4939 return nullptr;
4922}4940}
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
4924static void set_debug_location(CodeGen *g, IrInstruction *instruction) {4960static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
4925 AstNode *source_node = instruction->source_node;4961 AstNode *source_node = instruction->source_node;
4926 Scope *scope = instruction->scope;4962 Scope *scope = instruction->scope;
...@@ -5161,6 +5197,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5161,6 +5197,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5161 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);5197 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
5162 case IrInstructionIdPtrOfArrayToSlice:5198 case IrInstructionIdPtrOfArrayToSlice:
5163 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction);5199 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);
5164 }5204 }
5165 zig_unreachable();5205 zig_unreachable();
5166}5206}
...@@ -5422,7 +5462,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con...@@ -5422,7 +5462,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
5422 }5462 }
5423 return val;5463 return val;
5424 }5464 }
54255465 case ZigTypeIdCoroFrame:
5466 zig_panic("TODO bit pack a coroutine frame");
5426 }5467 }
5427 zig_unreachable();5468 zig_unreachable();
5428}5469}
...@@ -5943,7 +5984,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -5943,7 +5984,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
5943 case ZigTypeIdArgTuple:5984 case ZigTypeIdArgTuple:
5944 case ZigTypeIdOpaque:5985 case ZigTypeIdOpaque:
5945 zig_unreachable();5986 zig_unreachable();
59465987 case ZigTypeIdCoroFrame:
5988 zig_panic("TODO");
5947 }5989 }
5948 zig_unreachable();5990 zig_unreachable();
5949}5991}
...@@ -6027,12 +6069,20 @@ static void generate_error_name_table(CodeGen *g) {...@@ -6027,12 +6069,20 @@ static void generate_error_name_table(CodeGen *g) {
6027static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {6069static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {
6028 IrExecutable *executable = &fn->analyzed_executable;6070 IrExecutable *executable = &fn->analyzed_executable;
6029 assert(executable->basic_block_list.length > 0);6071 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 }
6030 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {6078 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
6031 IrBasicBlock *bb = executable->basic_block_list.at(block_i);6079 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;
6033 }6084 }
6034 IrBasicBlock *entry_bb = executable->basic_block_list.at(0);6085 LLVMPositionBuilderAtEnd(g->builder, first_bb);
6035 LLVMPositionBuilderAtEnd(g->builder, entry_bb->llvm_block);
6036}6086}
60376087
6038static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val,6088static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val,
...@@ -6209,7 +6259,7 @@ static void do_code_gen(CodeGen *g) {...@@ -6209,7 +6259,7 @@ static void do_code_gen(CodeGen *g) {
6209 build_all_basic_blocks(g, fn_table_entry);6259 build_all_basic_blocks(g, fn_table_entry);
6210 clear_debug_source_node(g);6260 clear_debug_source_node(g);
62116261
6212 if (want_sret) {6262 if (want_sret || fn_table_entry->resume_blocks.length != 0) {
6213 g->cur_ret_ptr = LLVMGetParam(fn, 0);6263 g->cur_ret_ptr = LLVMGetParam(fn, 0);
6214 } else if (handle_is_ptr(fn_type_id->return_type)) {6264 } else if (handle_is_ptr(fn_type_id->return_type)) {
6215 g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0);6265 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) {...@@ -6357,6 +6407,41 @@ static void do_code_gen(CodeGen *g) {
6357 fn_walk_init.data.inits.gen_i = gen_i_init;6407 fn_walk_init.data.inits.gen_i = gen_i_init;
6358 walk_function_params(g, fn_table_entry->type_entry, &fn_walk_init);6408 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
6360 ir_render(g, fn_table_entry);6445 ir_render(g, fn_table_entry);
63616446
6362 }6447 }
...@@ -6644,9 +6729,13 @@ static void define_builtin_types(CodeGen *g) {...@@ -6644,9 +6729,13 @@ static void define_builtin_types(CodeGen *g) {
66446729
6645 g->primitive_type_table.put(&entry->name, entry);6730 g->primitive_type_table.put(&entry->name, entry);
6646 }6731 }
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 }
6647}6737}
66486738
6649
6650static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) {6739static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) {
6651 BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1);6740 BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1);
6652 buf_init_from_str(&builtin_fn->name, name);6741 buf_init_from_str(&builtin_fn->name, name);
...@@ -7072,6 +7161,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7072,6 +7161,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7072 " BoundFn: Fn,\n"7161 " BoundFn: Fn,\n"
7073 " ArgTuple: void,\n"7162 " ArgTuple: void,\n"
7074 " Opaque: void,\n"7163 " Opaque: void,\n"
7164 " Frame: void,\n"
7075 " Vector: Vector,\n"7165 " Vector: Vector,\n"
7076 " EnumLiteral: void,\n"7166 " EnumLiteral: void,\n"
7077 "\n\n"7167 "\n\n"
...@@ -8335,6 +8425,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e...@@ -8335,6 +8425,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
8335 case ZigTypeIdArgTuple:8425 case ZigTypeIdArgTuple:
8336 case ZigTypeIdErrorUnion:8426 case ZigTypeIdErrorUnion:
8337 case ZigTypeIdErrorSet:8427 case ZigTypeIdErrorSet:
8428 case ZigTypeIdCoroFrame:
8338 zig_unreachable();8429 zig_unreachable();
8339 case ZigTypeIdVoid:8430 case ZigTypeIdVoid:
8340 case ZigTypeIdUnreachable:8431 case ZigTypeIdUnreachable:
...@@ -8518,6 +8609,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu...@@ -8518,6 +8609,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
8518 case ZigTypeIdUndefined:8609 case ZigTypeIdUndefined:
8519 case ZigTypeIdNull:8610 case ZigTypeIdNull:
8520 case ZigTypeIdArgTuple:8611 case ZigTypeIdArgTuple:
8612 case ZigTypeIdCoroFrame:
8521 zig_unreachable();8613 zig_unreachable();
8522 }8614 }
8523}8615}
...@@ -8685,6 +8777,7 @@ static void gen_h_file(CodeGen *g) {...@@ -8685,6 +8777,7 @@ static void gen_h_file(CodeGen *g) {
8685 case ZigTypeIdOptional:8777 case ZigTypeIdOptional:
8686 case ZigTypeIdFn:8778 case ZigTypeIdFn:
8687 case ZigTypeIdVector:8779 case ZigTypeIdVector:
8780 case ZigTypeIdCoroFrame:
8688 zig_unreachable();8781 zig_unreachable();
8689 case ZigTypeIdEnum:8782 case ZigTypeIdEnum:
8690 if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {8783 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) {...@@ -318,6 +318,7 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
318 case ZigTypeIdFn:318 case ZigTypeIdFn:
319 case ZigTypeIdArgTuple:319 case ZigTypeIdArgTuple:
320 case ZigTypeIdVector:320 case ZigTypeIdVector:
321 case ZigTypeIdCoroFrame:
321 return false;322 return false;
322 }323 }
323 zig_unreachable();324 zig_unreachable();
...@@ -1026,6 +1027,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInitNamedFi...@@ -1026,6 +1027,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInitNamedFi
1026 return IrInstructionIdUnionInitNamedField;1027 return IrInstructionIdUnionInitNamedField;
1027}1028}
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
1029template<typename T>1038template<typename T>
1030static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {1039static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
1031 T *special_instruction = allocate<T>(1);1040 T *special_instruction = allocate<T>(1);
...@@ -3183,6 +3192,30 @@ static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *s...@@ -3183,6 +3192,30 @@ static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *s
3183 return &instruction->base;3192 return &instruction->base;
3184}3193}
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
3186static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {3219static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
3187 results[ReturnKindUnconditional] = 0;3220 results[ReturnKindUnconditional] = 0;
3188 results[ReturnKindError] = 0;3221 results[ReturnKindError] = 0;
...@@ -3286,6 +3319,18 @@ static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *...@@ -3286,6 +3319,18 @@ static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *
3286 ir_set_cursor_at_end(irb, basic_block);3319 ir_set_cursor_at_end(irb, basic_block);
3287}3320}
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
3289static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) {3334static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) {
3290 while (scope) {3335 while (scope) {
3291 if (scope->id == ScopeIdDeferExpr)3336 if (scope->id == ScopeIdDeferExpr)
...@@ -3308,14 +3353,9 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode...@@ -3308,14 +3353,9 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
3308{3353{
3309 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value));3354 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value));
33103355
3311 bool is_async = exec_is_async(irb->exec);3356 IrInstruction *return_inst = ir_build_return(irb, scope, node, return_value);
3312 if (!is_async) {3357 return_inst->is_gen = is_generated_code;
3313 IrInstruction *return_inst = ir_build_return(irb, scope, node, return_value);3358 return return_inst;
3314 return_inst->is_gen = is_generated_code;
3315 return return_inst;
3316 }
3317
3318 zig_panic("TODO async return");
3319}3359}
33203360
3321static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {3361static 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...@@ -5393,12 +5433,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
5393 }5433 }
53945434
5395 bool is_async = node->data.fn_call_expr.is_async;5435 bool is_async = node->data.fn_call_expr.is_async;
5396 if (is_async) {5436 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
5397 zig_panic("TODO async fn call");5437 FnInlineAuto, is_async, nullptr, result_loc);
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);
5402 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc);5438 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc);
5403}5439}
54045440
...@@ -7655,7 +7691,45 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -7655,7 +7691,45 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
7655static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) {7691static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
7656 assert(node->type == NodeTypeSuspend);7692 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;
7659}7733}
76607734
7661static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,7735static 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...@@ -7854,13 +7928,6 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
7854 // Entry block gets a reference because we enter it to begin.7928 // Entry block gets a reference because we enter it to begin.
7855 ir_ref_bb(irb->current_basic_block);7929 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
7864 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);7931 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
7865 assert(result);7932 assert(result);
7866 if (irb->exec->invalid)7933 if (irb->exec->invalid)
...@@ -12659,6 +12726,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *...@@ -12659,6 +12726,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
12659 case ZigTypeIdNull:12726 case ZigTypeIdNull:
12660 case ZigTypeIdErrorUnion:12727 case ZigTypeIdErrorUnion:
12661 case ZigTypeIdUnion:12728 case ZigTypeIdUnion:
12729 case ZigTypeIdCoroFrame:
12662 operator_allowed = false;12730 operator_allowed = false;
12663 break;12731 break;
12664 case ZigTypeIdOptional:12732 case ZigTypeIdOptional:
...@@ -14023,6 +14091,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio...@@ -14023,6 +14091,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
14023 case ZigTypeIdBoundFn:14091 case ZigTypeIdBoundFn:
14024 case ZigTypeIdArgTuple:14092 case ZigTypeIdArgTuple:
14025 case ZigTypeIdOpaque:14093 case ZigTypeIdOpaque:
14094 case ZigTypeIdCoroFrame:
14026 ir_add_error(ira, target,14095 ir_add_error(ira, target,
14027 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));14096 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
14028 break;14097 break;
...@@ -14047,6 +14116,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio...@@ -14047,6 +14116,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
14047 case ZigTypeIdArgTuple:14116 case ZigTypeIdArgTuple:
14048 case ZigTypeIdOpaque:14117 case ZigTypeIdOpaque:
14049 case ZigTypeIdEnumLiteral:14118 case ZigTypeIdEnumLiteral:
14119 case ZigTypeIdCoroFrame:
14050 ir_add_error(ira, target,14120 ir_add_error(ira, target,
14051 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));14121 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
14052 break;14122 break;
...@@ -14553,6 +14623,20 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst...@@ -14553,6 +14623,20 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst
14553 return ir_const_void(ira, &instruction->base);14623 return ir_const_void(ira, &instruction->base);
14554}14624}
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}
14556static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,14640static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
14557 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)14641 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)
14558{14642{
...@@ -15366,16 +15450,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15366,16 +15450,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15366 if (type_is_invalid(return_type))15450 if (type_is_invalid(return_type))
15367 return ira->codegen->invalid_instruction;15451 return ira->codegen->invalid_instruction;
1536815452
15369 if (call_instruction->is_async) {
15370 zig_panic("TODO async call");
15371 }
15372
15373 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) {15453 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) {
15374 ir_add_error(ira, &call_instruction->base,15454 ir_add_error(ira, &call_instruction->base,
15375 buf_sprintf("no-inline call of inline function"));15455 buf_sprintf("no-inline call of inline function"));
15376 return ira->codegen->invalid_instruction;15456 return ira->codegen->invalid_instruction;
15377 }15457 }
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
15379 IrInstruction *result_loc;15465 IrInstruction *result_loc;
15380 if (handle_is_ptr(return_type)) {15466 if (handle_is_ptr(return_type)) {
15381 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,15467 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...@@ -15535,7 +15621,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
15535 zig_unreachable();15621 zig_unreachable();
15536}15622}
1553715623
15538static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {15624static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
15539 Error err;15625 Error err;
15540 IrInstruction *value = un_op_instruction->value->child;15626 IrInstruction *value = un_op_instruction->value->child;
15541 ZigType *type_entry = ir_resolve_type(ira, value);15627 ZigType *type_entry = ir_resolve_type(ira, value);
...@@ -15569,6 +15655,7 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_...@@ -15569,6 +15655,7 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_
15569 case ZigTypeIdFn:15655 case ZigTypeIdFn:
15570 case ZigTypeIdBoundFn:15656 case ZigTypeIdBoundFn:
15571 case ZigTypeIdArgTuple:15657 case ZigTypeIdArgTuple:
15658 case ZigTypeIdCoroFrame:
15572 return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry));15659 return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry));
15573 case ZigTypeIdUnreachable:15660 case ZigTypeIdUnreachable:
15574 case ZigTypeIdOpaque:15661 case ZigTypeIdOpaque:
...@@ -15733,7 +15820,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction...@@ -15733,7 +15820,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction
15733 return result;15820 return result;
15734 }15821 }
15735 case IrUnOpOptional:15822 case IrUnOpOptional:
15736 return ir_analyze_maybe(ira, instruction);15823 return ir_analyze_optional_type(ira, instruction);
15737 }15824 }
15738 zig_unreachable();15825 zig_unreachable();
15739}15826}
...@@ -17340,6 +17427,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -17340,6 +17427,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
17340 case ZigTypeIdFn:17427 case ZigTypeIdFn:
17341 case ZigTypeIdBoundFn:17428 case ZigTypeIdBoundFn:
17342 case ZigTypeIdVector:17429 case ZigTypeIdVector:
17430 case ZigTypeIdCoroFrame:
17343 {17431 {
17344 ResolveStatus needed_status = (align_bytes == 0) ?17432 ResolveStatus needed_status = (align_bytes == 0) ?
17345 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;17433 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
...@@ -17454,6 +17542,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,...@@ -17454,6 +17542,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
17454 case ZigTypeIdFn:17542 case ZigTypeIdFn:
17455 case ZigTypeIdBoundFn:17543 case ZigTypeIdBoundFn:
17456 case ZigTypeIdVector:17544 case ZigTypeIdVector:
17545 case ZigTypeIdCoroFrame:
17457 {17546 {
17458 if ((err = ensure_complete_type(ira->codegen, child_type)))17547 if ((err = ensure_complete_type(ira->codegen, child_type)))
17459 return ira->codegen->invalid_instruction;17548 return ira->codegen->invalid_instruction;
...@@ -17504,6 +17593,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,...@@ -17504,6 +17593,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
17504 case ZigTypeIdUnion:17593 case ZigTypeIdUnion:
17505 case ZigTypeIdFn:17594 case ZigTypeIdFn:
17506 case ZigTypeIdVector:17595 case ZigTypeIdVector:
17596 case ZigTypeIdCoroFrame:
17507 {17597 {
17508 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);17598 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
17509 return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes);17599 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,...@@ -18067,6 +18157,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
18067 case ZigTypeIdArgTuple:18157 case ZigTypeIdArgTuple:
18068 case ZigTypeIdOpaque:18158 case ZigTypeIdOpaque:
18069 case ZigTypeIdVector:18159 case ZigTypeIdVector:
18160 case ZigTypeIdCoroFrame:
18070 ir_add_error(ira, &switch_target_instruction->base,18161 ir_add_error(ira, &switch_target_instruction->base,
18071 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));18162 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
18072 return ira->codegen->invalid_instruction;18163 return ira->codegen->invalid_instruction;
...@@ -19906,6 +19997,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -19906,6 +19997,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
1990619997
19907 break;19998 break;
19908 }19999 }
20000 case ZigTypeIdCoroFrame:
20001 zig_panic("TODO @typeInfo for coro frames");
19909 }20002 }
1991020003
19911 assert(result != nullptr);20004 assert(result != nullptr);
...@@ -21660,6 +21753,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct...@@ -21660,6 +21753,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct
21660 case ZigTypeIdUnion:21753 case ZigTypeIdUnion:
21661 case ZigTypeIdFn:21754 case ZigTypeIdFn:
21662 case ZigTypeIdVector:21755 case ZigTypeIdVector:
21756 case ZigTypeIdCoroFrame:
21663 {21757 {
21664 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);21758 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
21665 return ir_const_unsigned(ira, &instruction->base, align_in_bytes);21759 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...@@ -22815,6 +22909,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
22815 zig_panic("TODO buf_write_value_bytes fn type");22909 zig_panic("TODO buf_write_value_bytes fn type");
22816 case ZigTypeIdUnion:22910 case ZigTypeIdUnion:
22817 zig_panic("TODO buf_write_value_bytes union type");22911 zig_panic("TODO buf_write_value_bytes union type");
22912 case ZigTypeIdCoroFrame:
22913 zig_panic("TODO buf_write_value_bytes coro frame type");
22818 }22914 }
22819 zig_unreachable();22915 zig_unreachable();
22820}22916}
...@@ -22994,6 +23090,8 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou...@@ -22994,6 +23090,8 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
22994 zig_panic("TODO buf_read_value_bytes fn type");23090 zig_panic("TODO buf_read_value_bytes fn type");
22995 case ZigTypeIdUnion:23091 case ZigTypeIdUnion:
22996 zig_panic("TODO buf_read_value_bytes union type");23092 zig_panic("TODO buf_read_value_bytes union type");
23093 case ZigTypeIdCoroFrame:
23094 zig_panic("TODO buf_read_value_bytes coro frame type");
22997 }23095 }
22998 zig_unreachable();23096 zig_unreachable();
22999}23097}
...@@ -24021,6 +24119,33 @@ static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *i...@@ -24021,6 +24119,33 @@ static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *i
24021 union_type, field_name, field_result_loc, result_loc);24119 union_type, field_name, field_result_loc, result_loc);
24022}24120}
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
24024static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) {24149static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) {
24025 switch (instruction->id) {24150 switch (instruction->id) {
24026 case IrInstructionIdInvalid:24151 case IrInstructionIdInvalid:
...@@ -24304,6 +24429,10 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -24304,6 +24429,10 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
24304 return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction);24429 return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction);
24305 case IrInstructionIdUnionInitNamedField:24430 case IrInstructionIdUnionInitNamedField:
24306 return ir_analyze_instruction_union_init_named_field(ira, (IrInstructionUnionInitNamedField *)instruction);24431 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);
24307 }24436 }
24308 zig_unreachable();24437 zig_unreachable();
24309}24438}
...@@ -24436,6 +24565,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24436,6 +24565,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24436 case IrInstructionIdOptionalWrap:24565 case IrInstructionIdOptionalWrap:
24437 case IrInstructionIdVectorToArray:24566 case IrInstructionIdVectorToArray:
24438 case IrInstructionIdResetResult:24567 case IrInstructionIdResetResult:
24568 case IrInstructionIdSuspendBegin:
24569 case IrInstructionIdSuspendBr:
24439 return true;24570 return true;
2444024571
24441 case IrInstructionIdPhi:24572 case IrInstructionIdPhi:
src/ir_print.cpp+16
...@@ -1503,6 +1503,16 @@ static void ir_print_union_init_named_field(IrPrint *irp, IrInstructionUnionInit...@@ -1503,6 +1503,16 @@ static void ir_print_union_init_named_field(IrPrint *irp, IrInstructionUnionInit
1503 fprintf(irp->f, ")");1503 fprintf(irp->f, ")");
1504}1504}
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
1506static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1516static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1507 ir_print_prefix(irp, instruction);1517 ir_print_prefix(irp, instruction);
1508 switch (instruction->id) {1518 switch (instruction->id) {
...@@ -1961,6 +1971,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1961,6 +1971,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1961 case IrInstructionIdUnionInitNamedField:1971 case IrInstructionIdUnionInitNamedField:
1962 ir_print_union_init_named_field(irp, (IrInstructionUnionInitNamedField *)instruction);1972 ir_print_union_init_named_field(irp, (IrInstructionUnionInitNamedField *)instruction);
1963 break;1973 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;
1964 }1980 }
1965 fprintf(irp->f, "\n");1981 fprintf(irp->f, "\n");
1966}1982}