| author | |
| committer | |
| log | 72e983670e65eac0b89da5564432988862828b30 |
| tree | 0fe5e7c91bbeee208e5b2036207c41f9eae20b99 |
| parent | 54e716afdcb0609cfc42229ad925e6dc9b07a66f |
| signature | Commit is signed but in an unrecognized format. |
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") |
| 426 | set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp") | 426 | set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp") |
| 427 | 427 | ||
| 428 | set(ZIG_SOURCES | 428 | set(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 | }; |
| 1267 | 1268 | ||
| 1269 | struct ZigTypeCoroFrame { | ||
| 1270 | ZigFn *fn; | ||
| 1271 | ZigType *locals_struct; | ||
| 1272 | }; | ||
| 1273 | |||
| 1268 | struct ZigType { | 1274 | struct 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; |
| 1294 | 1301 | ||
| 1295 | // use these fields to make sure we don't duplicate type table entries for the same type | 1302 | // 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_scope | 1347 | ScopeBlock *def_scope; // parent is child_scope |
| 1341 | Buf symbol_name; | 1348 | Buf symbol_name; |
| 1342 | ZigType *type_entry; // function type | 1349 | ZigType *type_entry; // function type |
| 1350 | ZigType *frame_type; // coro frame type | ||
| 1343 | // in the case of normal functions this is the implicit return type | 1351 | // 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 the | 1352 | // in the case of async functions this is the implicit return type according to the |
| 1345 | // zig source code, not according to zig ir | 1353 | // zig source code, not according to zig ir |
| ... | @@ -1356,6 +1364,7 @@ struct ZigFn { | ... | @@ -1356,6 +1364,7 @@ struct ZigFn { |
| 1356 | 1364 | ||
| 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; | ||
| 1359 | 1368 | ||
| 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; |
| 1366 | 1375 | ||
| 1367 | LLVMValueRef valgrind_client_request_array; | 1376 | LLVMValueRef valgrind_client_request_array; |
| 1377 | LLVMBasicBlockRef preamble_llvm_block; | ||
| 1368 | 1378 | ||
| 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, | ||
| 1515 | 1526 | ||
| 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 list | 2132 | // 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 to | 2138 | // 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 | }; |
| 2301 | 2317 | ||
| 2302 | struct IrInstruction { | 2318 | struct IrInstruction { |
| ... | @@ -3511,6 +3527,18 @@ struct IrInstructionPtrOfArrayToSlice { | ... | @@ -3511,6 +3527,18 @@ struct IrInstructionPtrOfArrayToSlice { |
| 3511 | IrInstruction *result_loc; | 3527 | IrInstruction *result_loc; |
| 3512 | }; | 3528 | }; |
| 3513 | 3529 | ||
| 3530 | struct IrInstructionSuspendBegin { | ||
| 3531 | IrInstruction base; | ||
| 3532 | |||
| 3533 | IrBasicBlock *resume_block; | ||
| 3534 | }; | ||
| 3535 | |||
| 3536 | struct IrInstructionSuspendBr { | ||
| 3537 | IrInstruction base; | ||
| 3538 | |||
| 3539 | IrBasicBlock *resume_block; | ||
| 3540 | }; | ||
| 3541 | |||
| 3514 | enum ResultLocId { | 3542 | enum 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; |
| 3593 | static const size_t err_union_err_index = 0; | 3621 | static const size_t err_union_err_index = 0; |
| 3594 | static const size_t err_union_payload_index = 1; | 3622 | static const size_t err_union_payload_index = 1; |
| 3595 | 3623 | ||
| 3624 | static 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 function | 3626 | // 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. |
| 3598 | static const size_t stack_trace_ptr_count = 32; | 3628 | static 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 | } |
| 347 | 363 | ||
| 364 | ZigType *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 | |||
| 348 | ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const, | 383 | ZigType *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 | } |
| 1827 | 1866 | ||
| 1867 | static 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 | |||
| 1828 | static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) { | 1900 | static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) { |
| 1829 | // Only integer types are allowed by the C ABI | 1901 | // 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 algorithm | 4323 | // 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; |
| 4314 | 4394 | ||
| 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; |
| 4385 | 4466 | ||
| 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 | } |
| 5948 | 6047 | ||
| 5949 | bool fn_type_can_fail(FnTypeId *fn_type_id) { | 6048 | bool 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 | } |
| 5952 | 6051 | ||
| 5953 | // ErrorNone - result pointer has the type | 6052 | // 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 | } |
| 6937 | 7036 | ||
| 6938 | static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) { | 7037 | void 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; |
| 6940 | 7039 | ||
| 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 value | 7045 | // +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 pointer | 7076 | 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 for | 7077 | 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 | } |
| 6985 | 7081 | ||
| 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 | } |
| 7057 | 7153 | ||
| 7154 | static 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 | |||
| 7058 | static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) { | 7165 | static 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; |
| 7102 | 7209 | ||
| ... | @@ -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); |
| 16 | ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg); | 16 | ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg); |
| 17 | void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg); | 17 | void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg); |
| 18 | ZigType *new_type_table_entry(ZigTypeId id); | 18 | ZigType *new_type_table_entry(ZigTypeId id); |
| 19 | ZigType *get_coro_frame_type(CodeGen *g, ZigFn *fn); | ||
| 19 | ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const); | 20 | ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const); |
| 20 | ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const, | 21 | ZigType *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); |
| 247 | bool is_container(ZigType *type_entry); | 248 | bool is_container(ZigType *type_entry); |
| 248 | ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name); | 249 | ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name); |
| 249 | 250 | ||
| 251 | void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type, ZigFn *fn); | ||
| 252 | |||
| 250 | #endif | 253 | #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) { |
| 498 | 498 | ||
| 499 | ZigType *fn_type = fn_table_entry->type_entry; | 499 | ZigType *fn_type = fn_table_entry->type_entry; |
| 500 | // Make the raw_type_ref populated | 500 | // 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 | } |
| 923 | 923 | ||
| 924 | static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) { | 924 | static bool ir_want_runtime_safety_scope(CodeGen *g, Scope *scope) { |
| 925 | // TODO memoize | 925 | // 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 | } |
| 943 | 942 | ||
| 943 | static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) { | ||
| 944 | return ir_want_runtime_safety_scope(g, instruction->scope); | ||
| 945 | } | ||
| 946 | |||
| 944 | static Buf *panic_msg_buf(PanicMsgId msg_id) { | 947 | static 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 | } |
| 1029 | 1034 | ||
| 1030 | static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) { | 1035 | static 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 | } |
| 1037 | 1042 | ||
| 1043 | static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) { | ||
| 1044 | return gen_assertion_scope(g, msg_id, source_instruction->scope); | ||
| 1045 | } | ||
| 1046 | |||
| 1038 | static LLVMValueRef get_stacksave_fn_val(CodeGen *g) { | 1047 | static 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 | } |
| 2093 | 2102 | ||
| 2094 | static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) { | 2103 | static 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 |
| 3375 | static bool get_prefix_arg_err_ret_stack(CodeGen *g, FnTypeId *fn_type_id) { | 3388 | static 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 | } |
| 3381 | 3393 | ||
| 3382 | static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) { | 3394 | static 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 |
| 3489 | 3509 | ||
| 3490 | 3510 | ||
| 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 | } |
| 3496 | 3514 | ||
| 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 | } |
| 4923 | 4941 | ||
| 4942 | static 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 | |||
| 4953 | static 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 | |||
| 4924 | static void set_debug_location(CodeGen *g, IrInstruction *instruction) { | 4960 | static 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 | } |
| 5425 | 5465 | 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(); |
| 5946 | 5987 | 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) { |
| 6027 | static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) { | 6069 | static 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 | } |
| 6037 | 6087 | ||
| 6038 | static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val, | 6088 | static 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); |
| 6211 | 6261 | ||
| 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); |
| 6359 | 6409 | ||
| 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); |
| 6361 | 6446 | ||
| 6362 | } | 6447 | } |
| ... | @@ -6644,9 +6729,13 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -6644,9 +6729,13 @@ static void define_builtin_types(CodeGen *g) { |
| 6644 | 6729 | ||
| 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 | } |
| 6648 | 6738 | ||
| 6649 | |||
| 6650 | static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) { | 6739 | static 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 | } |
| 1028 | 1029 | ||
| 1030 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBegin *) { | ||
| 1031 | return IrInstructionIdSuspendBegin; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBr *) { | ||
| 1035 | return IrInstructionIdSuspendBr; | ||
| 1036 | } | ||
| 1037 | |||
| 1029 | template<typename T> | 1038 | template<typename T> |
| 1030 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 1039 | static 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 | } |
| 3185 | 3194 | ||
| 3195 | static 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 | |||
| 3207 | static 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 | |||
| 3186 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { | 3219 | static 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 | } |
| 3288 | 3321 | ||
| 3322 | static 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 | |||
| 3289 | static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { | 3334 | static 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)); |
| 3310 | 3355 | ||
| 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 | } |
| 3320 | 3360 | ||
| 3321 | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { | 3361 | static 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 | } |
| 5394 | 5434 | ||
| 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 | } |
| 5404 | 5440 | ||
| ... | @@ -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 |
| 7655 | static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { | 7691 | static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 7656 | assert(node->type == NodeTypeSuspend); | 7692 | assert(node->type == NodeTypeSuspend); |
| 7657 | 7693 | ||
| 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 | } |
| 7660 | 7734 | ||
| 7661 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, | 7735 | static 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); |
| 7856 | 7930 | ||
| 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 | } |
| 14555 | 14625 | ||
| 14626 | static 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 | } | ||
| 14556 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, | 14640 | static 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; |
| 15368 | 15452 | ||
| 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 | } |
| 15378 | 15458 | ||
| 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 | } |
| 15537 | 15623 | ||
| 15538 | static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { | 15624 | static 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 |
| 19906 | 19997 | ||
| 19907 | break; | 19998 | break; |
| 19908 | } | 19999 | } |
| 20000 | case ZigTypeIdCoroFrame: | ||
| 20001 | zig_panic("TODO @typeInfo for coro frames"); | ||
| 19909 | } | 20002 | } |
| 19910 | 20003 | ||
| 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 | } |
| 24023 | 24121 | ||
| 24122 | static 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 | |||
| 24129 | static 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 | |||
| 24024 | static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { | 24149 | static 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; |
| 24440 | 24571 | ||
| 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 | } |
| 1505 | 1505 | ||
| 1506 | static void ir_print_suspend_begin(IrPrint *irp, IrInstructionSuspendBegin *instruction) { | ||
| 1507 | fprintf(irp->f, "@suspendBegin()"); | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | static 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 | |||
| 1506 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 1516 | static 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 | } |