| author | |
| committer | |
| log | fbfae832eaf520f7fcc632580b4b4a7fb171f90f |
| tree | 1a8b34df8132e7bffc336235cfdae17f261f41c9 |
| parent | 49be88859d3cef22c5cc27c908264a235c78a4d0 |
Inside a nosuspend block, emit function calls as nosuspend calls.
Also inside a comptime block, emit function calls as comptime calls.
Also emit `async foo()` calls as async calls.
Remove compile error for `nosuspend` block inside `suspend` block.
Instead of implicitly treating every `suspend` block also as a
`nosuspend` block (which would make sense), we leave suspension points
as compile errors, to hint to the programmer about accidents. Of course
they may then assert `nosuspend` by introducing a block within their
suspend block.
To make room in `Zir.Inst.Tag` I moved `typeof_peer` and `compile_log`
to `Extended`.5 files changed, 118 insertions(+), 69 deletions(-)
BRANCH_TODO-1| ... | @@ -37,7 +37,6 @@ | ... | @@ -37,7 +37,6 @@ |
| 37 | * when handling decls, catch the error and continue, so that | 37 | * when handling decls, catch the error and continue, so that |
| 38 | AstGen can report more than one compile error. | 38 | AstGen can report more than one compile error. |
| 39 | 39 | ||
| 40 | * AstGen: inside a nosuspend block, emit function calls as nosuspend calls | ||
| 41 | * AstGen: add result location pointers to function calls | 40 | * AstGen: add result location pointers to function calls |
| 42 | 41 | ||
| 43 | const container_name_hash: Scope.NameHash = if (found_pkg) |pkg| | 42 | const container_name_hash: Scope.NameHash = if (found_pkg) |pkg| |
src/AstGen.zig+17-24| ... | @@ -900,11 +900,6 @@ pub fn nosuspendExpr( | ... | @@ -900,11 +900,6 @@ pub fn nosuspendExpr( |
| 900 | try astgen.errNoteNode(gz.nosuspend_node, "other nosuspend block here", .{}), | 900 | try astgen.errNoteNode(gz.nosuspend_node, "other nosuspend block here", .{}), |
| 901 | }); | 901 | }); |
| 902 | } | 902 | } |
| 903 | if (gz.suspend_node != 0) { | ||
| 904 | return astgen.failNodeNotes(node, "inside a suspend block, nosuspend is implied", .{}, &[_]u32{ | ||
| 905 | try astgen.errNoteNode(gz.suspend_node, "suspend block here", .{}), | ||
| 906 | }); | ||
| 907 | } | ||
| 908 | gz.nosuspend_node = node; | 903 | gz.nosuspend_node = node; |
| 909 | const result = try expr(gz, scope, rl, body_node); | 904 | const result = try expr(gz, scope, rl, body_node); |
| 910 | gz.nosuspend_node = 0; | 905 | gz.nosuspend_node = 0; |
| ... | @@ -1803,6 +1798,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner | ... | @@ -1803,6 +1798,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner |
| 1803 | .bool_and, | 1798 | .bool_and, |
| 1804 | .bool_or, | 1799 | .bool_or, |
| 1805 | .call_compile_time, | 1800 | .call_compile_time, |
| 1801 | .call_nosuspend, | ||
| 1802 | .call_async, | ||
| 1806 | .cmp_lt, | 1803 | .cmp_lt, |
| 1807 | .cmp_lte, | 1804 | .cmp_lte, |
| 1808 | .cmp_eq, | 1805 | .cmp_eq, |
| ... | @@ -1876,7 +1873,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner | ... | @@ -1876,7 +1873,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner |
| 1876 | .slice_end, | 1873 | .slice_end, |
| 1877 | .slice_sentinel, | 1874 | .slice_sentinel, |
| 1878 | .import, | 1875 | .import, |
| 1879 | .typeof_peer, | ||
| 1880 | .switch_block, | 1876 | .switch_block, |
| 1881 | .switch_block_multi, | 1877 | .switch_block_multi, |
| 1882 | .switch_block_else, | 1878 | .switch_block_else, |
| ... | @@ -2001,7 +1997,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner | ... | @@ -2001,7 +1997,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner |
| 2001 | .ensure_result_non_error, | 1997 | .ensure_result_non_error, |
| 2002 | .@"export", | 1998 | .@"export", |
| 2003 | .set_eval_branch_quota, | 1999 | .set_eval_branch_quota, |
| 2004 | .compile_log, | ||
| 2005 | .ensure_err_payload_void, | 2000 | .ensure_err_payload_void, |
| 2006 | .@"break", | 2001 | .@"break", |
| 2007 | .break_inline, | 2002 | .break_inline, |
| ... | @@ -6074,11 +6069,7 @@ fn typeOf( | ... | @@ -6074,11 +6069,7 @@ fn typeOf( |
| 6074 | items[param_i] = try expr(gz, scope, .none, param); | 6069 | items[param_i] = try expr(gz, scope, .none, param); |
| 6075 | } | 6070 | } |
| 6076 | 6071 | ||
| 6077 | const result = try gz.addPlNode(.typeof_peer, node, Zir.Inst.MultiOp{ | 6072 | const result = try gz.addExtendedMultiOp(.typeof_peer, node, items); |
| 6078 | .operands_len = @intCast(u32, params.len), | ||
| 6079 | }); | ||
| 6080 | try gz.astgen.appendRefs(items); | ||
| 6081 | |||
| 6082 | return rvalue(gz, scope, rl, result, node); | 6073 | return rvalue(gz, scope, rl, result, node); |
| 6083 | } | 6074 | } |
| 6084 | 6075 | ||
| ... | @@ -6138,10 +6129,7 @@ fn builtinCall( | ... | @@ -6138,10 +6129,7 @@ fn builtinCall( |
| 6138 | 6129 | ||
| 6139 | for (params) |param, i| arg_refs[i] = try expr(gz, scope, .none, param); | 6130 | for (params) |param, i| arg_refs[i] = try expr(gz, scope, .none, param); |
| 6140 | 6131 | ||
| 6141 | const result = try gz.addPlNode(.compile_log, node, Zir.Inst.MultiOp{ | 6132 | const result = try gz.addExtendedMultiOp(.compile_log, node, arg_refs); |
| 6142 | .operands_len = @intCast(u32, params.len), | ||
| 6143 | }); | ||
| 6144 | try gz.astgen.appendRefs(arg_refs); | ||
| 6145 | return rvalue(gz, scope, rl, result, node); | 6133 | return rvalue(gz, scope, rl, result, node); |
| 6146 | }, | 6134 | }, |
| 6147 | .field => { | 6135 | .field => { |
| ... | @@ -6745,9 +6733,6 @@ fn callExpr( | ... | @@ -6745,9 +6733,6 @@ fn callExpr( |
| 6745 | call: ast.full.Call, | 6733 | call: ast.full.Call, |
| 6746 | ) InnerError!Zir.Inst.Ref { | 6734 | ) InnerError!Zir.Inst.Ref { |
| 6747 | const astgen = gz.astgen; | 6735 | const astgen = gz.astgen; |
| 6748 | if (call.async_token) |async_token| { | ||
| 6749 | return astgen.failTok(async_token, "async and related features are not yet supported", .{}); | ||
| 6750 | } | ||
| 6751 | const lhs = try expr(gz, scope, .none, call.ast.fn_expr); | 6736 | const lhs = try expr(gz, scope, .none, call.ast.fn_expr); |
| 6752 | 6737 | ||
| 6753 | const args = try astgen.gpa.alloc(Zir.Inst.Ref, call.ast.params.len); | 6738 | const args = try astgen.gpa.alloc(Zir.Inst.Ref, call.ast.params.len); |
| ... | @@ -6764,9 +6749,17 @@ fn callExpr( | ... | @@ -6764,9 +6749,17 @@ fn callExpr( |
| 6764 | args[i] = try expr(gz, scope, .{ .ty = param_type }, param_node); | 6749 | args[i] = try expr(gz, scope, .{ .ty = param_type }, param_node); |
| 6765 | } | 6750 | } |
| 6766 | 6751 | ||
| 6767 | const modifier: std.builtin.CallOptions.Modifier = switch (call.async_token != null) { | 6752 | const modifier: std.builtin.CallOptions.Modifier = blk: { |
| 6768 | true => .async_kw, | 6753 | if (gz.force_comptime) { |
| 6769 | false => .auto, | 6754 | break :blk .compile_time; |
| 6755 | } | ||
| 6756 | if (call.async_token != null) { | ||
| 6757 | break :blk .async_kw; | ||
| 6758 | } | ||
| 6759 | if (gz.nosuspend_node != 0) { | ||
| 6760 | break :blk .no_async; | ||
| 6761 | } | ||
| 6762 | break :blk .auto; | ||
| 6770 | }; | 6763 | }; |
| 6771 | const result: Zir.Inst.Ref = res: { | 6764 | const result: Zir.Inst.Ref = res: { |
| 6772 | const tag: Zir.Inst.Tag = switch (modifier) { | 6765 | const tag: Zir.Inst.Tag = switch (modifier) { |
| ... | @@ -6774,10 +6767,10 @@ fn callExpr( | ... | @@ -6774,10 +6767,10 @@ fn callExpr( |
| 6774 | true => break :res try gz.addUnNode(.call_none, lhs, node), | 6767 | true => break :res try gz.addUnNode(.call_none, lhs, node), |
| 6775 | false => .call, | 6768 | false => .call, |
| 6776 | }, | 6769 | }, |
| 6777 | .async_kw => return astgen.failNode(node, "async and related features are not yet supported", .{}), | 6770 | .async_kw => .call_async, |
| 6778 | .never_tail => unreachable, | 6771 | .never_tail => unreachable, |
| 6779 | .never_inline => unreachable, | 6772 | .never_inline => unreachable, |
| 6780 | .no_async => return astgen.failNode(node, "async and related features are not yet supported", .{}), | 6773 | .no_async => .call_nosuspend, |
| 6781 | .always_tail => unreachable, | 6774 | .always_tail => unreachable, |
| 6782 | .always_inline => unreachable, | 6775 | .always_inline => unreachable, |
| 6783 | .compile_time => .call_compile_time, | 6776 | .compile_time => .call_compile_time, |
src/Module.zig+33| ... | @@ -1533,6 +1533,39 @@ pub const Scope = struct { | ... | @@ -1533,6 +1533,39 @@ pub const Scope = struct { |
| 1533 | return gz.indexToRef(new_index); | 1533 | return gz.indexToRef(new_index); |
| 1534 | } | 1534 | } |
| 1535 | 1535 | ||
| 1536 | pub fn addExtendedMultiOp( | ||
| 1537 | gz: *GenZir, | ||
| 1538 | opcode: Zir.Inst.Extended, | ||
| 1539 | node: ast.Node.Index, | ||
| 1540 | operands: []const Zir.Inst.Ref, | ||
| 1541 | ) !Zir.Inst.Ref { | ||
| 1542 | const astgen = gz.astgen; | ||
| 1543 | const gpa = astgen.gpa; | ||
| 1544 | |||
| 1545 | try gz.instructions.ensureUnusedCapacity(gpa, 1); | ||
| 1546 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); | ||
| 1547 | try astgen.extra.ensureUnusedCapacity( | ||
| 1548 | gpa, | ||
| 1549 | @typeInfo(Zir.Inst.NodeMultiOp).Struct.fields.len + operands.len, | ||
| 1550 | ); | ||
| 1551 | |||
| 1552 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.NodeMultiOp{ | ||
| 1553 | .src_node = gz.nodeIndexToRelative(node), | ||
| 1554 | }); | ||
| 1555 | const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len); | ||
| 1556 | astgen.instructions.appendAssumeCapacity(.{ | ||
| 1557 | .tag = .extended, | ||
| 1558 | .data = .{ .extended = .{ | ||
| 1559 | .opcode = opcode, | ||
| 1560 | .small = @intCast(u16, operands.len), | ||
| 1561 | .operand = payload_index, | ||
| 1562 | } }, | ||
| 1563 | }); | ||
| 1564 | gz.instructions.appendAssumeCapacity(new_index); | ||
| 1565 | astgen.appendRefsAssumeCapacity(operands); | ||
| 1566 | return gz.indexToRef(new_index); | ||
| 1567 | } | ||
| 1568 | |||
| 1536 | pub fn addArrayTypeSentinel( | 1569 | pub fn addArrayTypeSentinel( |
| 1537 | gz: *GenZir, | 1570 | gz: *GenZir, |
| 1538 | len: Zir.Inst.Ref, | 1571 | len: Zir.Inst.Ref, |
src/Sema.zig+26-16| ... | @@ -161,6 +161,8 @@ pub fn analyzeBody( | ... | @@ -161,6 +161,8 @@ pub fn analyzeBody( |
| 161 | .call => try sema.zirCall(block, inst, .auto, false), | 161 | .call => try sema.zirCall(block, inst, .auto, false), |
| 162 | .call_chkused => try sema.zirCall(block, inst, .auto, true), | 162 | .call_chkused => try sema.zirCall(block, inst, .auto, true), |
| 163 | .call_compile_time => try sema.zirCall(block, inst, .compile_time, false), | 163 | .call_compile_time => try sema.zirCall(block, inst, .compile_time, false), |
| 164 | .call_nosuspend => try sema.zirCall(block, inst, .no_async, false), | ||
| 165 | .call_async => try sema.zirCall(block, inst, .async_kw, false), | ||
| 164 | .call_none => try sema.zirCallNone(block, inst, false), | 166 | .call_none => try sema.zirCallNone(block, inst, false), |
| 165 | .call_none_chkused => try sema.zirCallNone(block, inst, true), | 167 | .call_none_chkused => try sema.zirCallNone(block, inst, true), |
| 166 | .cmp_eq => try sema.zirCmp(block, inst, .eq), | 168 | .cmp_eq => try sema.zirCmp(block, inst, .eq), |
| ... | @@ -254,7 +256,6 @@ pub fn analyzeBody( | ... | @@ -254,7 +256,6 @@ pub fn analyzeBody( |
| 254 | .bit_size_of => try sema.zirBitSizeOf(block, inst), | 256 | .bit_size_of => try sema.zirBitSizeOf(block, inst), |
| 255 | .typeof => try sema.zirTypeof(block, inst), | 257 | .typeof => try sema.zirTypeof(block, inst), |
| 256 | .typeof_elem => try sema.zirTypeofElem(block, inst), | 258 | .typeof_elem => try sema.zirTypeofElem(block, inst), |
| 257 | .typeof_peer => try sema.zirTypeofPeer(block, inst), | ||
| 258 | .log2_int_type => try sema.zirLog2IntType(block, inst), | 259 | .log2_int_type => try sema.zirLog2IntType(block, inst), |
| 259 | .typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst), | 260 | .typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst), |
| 260 | .xor => try sema.zirBitwise(block, inst, .xor), | 261 | .xor => try sema.zirBitwise(block, inst, .xor), |
| ... | @@ -403,10 +404,6 @@ pub fn analyzeBody( | ... | @@ -403,10 +404,6 @@ pub fn analyzeBody( |
| 403 | try sema.zirEnsureResultUsed(block, inst); | 404 | try sema.zirEnsureResultUsed(block, inst); |
| 404 | continue; | 405 | continue; |
| 405 | }, | 406 | }, |
| 406 | .compile_log => { | ||
| 407 | try sema.zirCompileLog(block, inst); | ||
| 408 | continue; | ||
| 409 | }, | ||
| 410 | .set_eval_branch_quota => { | 407 | .set_eval_branch_quota => { |
| 411 | try sema.zirSetEvalBranchQuota(block, inst); | 408 | try sema.zirSetEvalBranchQuota(block, inst); |
| 412 | continue; | 409 | continue; |
| ... | @@ -519,6 +516,8 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro | ... | @@ -519,6 +516,8 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro |
| 519 | .alloc => return sema.zirAllocExtended( block, extended), | 516 | .alloc => return sema.zirAllocExtended( block, extended), |
| 520 | .builtin_extern => return sema.zirBuiltinExtern( block, extended), | 517 | .builtin_extern => return sema.zirBuiltinExtern( block, extended), |
| 521 | .@"asm" => return sema.zirAsm( block, extended), | 518 | .@"asm" => return sema.zirAsm( block, extended), |
| 519 | .typeof_peer => return sema.zirTypeofPeer( block, extended), | ||
| 520 | .compile_log => return sema.zirCompileLog( block, extended), | ||
| 522 | .c_undef => return sema.zirCUndef( block, extended), | 521 | .c_undef => return sema.zirCUndef( block, extended), |
| 523 | .c_include => return sema.zirCInclude( block, extended), | 522 | .c_include => return sema.zirCInclude( block, extended), |
| 524 | .c_define => return sema.zirCDefine( block, extended), | 523 | .c_define => return sema.zirCDefine( block, extended), |
| ... | @@ -1533,14 +1532,18 @@ fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner | ... | @@ -1533,14 +1532,18 @@ fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner |
| 1533 | return sema.mod.fail(&block.base, src, "{s}", .{msg}); | 1532 | return sema.mod.fail(&block.base, src, "{s}", .{msg}); |
| 1534 | } | 1533 | } |
| 1535 | 1534 | ||
| 1536 | fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void { | 1535 | fn zirCompileLog( |
| 1536 | sema: *Sema, | ||
| 1537 | block: *Scope.Block, | ||
| 1538 | extended: Zir.Inst.Extended.InstData, | ||
| 1539 | ) InnerError!*Inst { | ||
| 1537 | var managed = sema.mod.compile_log_text.toManaged(sema.gpa); | 1540 | var managed = sema.mod.compile_log_text.toManaged(sema.gpa); |
| 1538 | defer sema.mod.compile_log_text = managed.moveToUnmanaged(); | 1541 | defer sema.mod.compile_log_text = managed.moveToUnmanaged(); |
| 1539 | const writer = managed.writer(); | 1542 | const writer = managed.writer(); |
| 1540 | 1543 | ||
| 1541 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 1544 | const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand); |
| 1542 | const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); | 1545 | const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; |
| 1543 | const args = sema.code.refSlice(extra.end, extra.data.operands_len); | 1546 | const args = sema.code.refSlice(extra.end, extended.small); |
| 1544 | 1547 | ||
| 1545 | for (args) |arg_ref, i| { | 1548 | for (args) |arg_ref, i| { |
| 1546 | if (i != 0) try writer.print(", ", .{}); | 1549 | if (i != 0) try writer.print(", ", .{}); |
| ... | @@ -1556,8 +1559,12 @@ fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr | ... | @@ -1556,8 +1559,12 @@ fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr |
| 1556 | 1559 | ||
| 1557 | const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, sema.owner_decl); | 1560 | const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, sema.owner_decl); |
| 1558 | if (!gop.found_existing) { | 1561 | if (!gop.found_existing) { |
| 1559 | gop.entry.value = inst_data.src().toSrcLoc(&block.base); | 1562 | gop.entry.value = src.toSrcLoc(&block.base); |
| 1560 | } | 1563 | } |
| 1564 | return sema.mod.constInst(sema.arena, src, .{ | ||
| 1565 | .ty = Type.initTag(.void), | ||
| 1566 | .val = Value.initTag(.void_value), | ||
| 1567 | }); | ||
| 1561 | } | 1568 | } |
| 1562 | 1569 | ||
| 1563 | fn zirRepeat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Zir.Inst.Index { | 1570 | fn zirRepeat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Zir.Inst.Index { |
| ... | @@ -4680,16 +4687,19 @@ fn zirLog2IntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerE | ... | @@ -4680,16 +4687,19 @@ fn zirLog2IntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerE |
| 4680 | return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirLog2IntType", .{}); | 4687 | return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirLog2IntType", .{}); |
| 4681 | } | 4688 | } |
| 4682 | 4689 | ||
| 4683 | fn zirTypeofPeer(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | 4690 | fn zirTypeofPeer( |
| 4691 | sema: *Sema, | ||
| 4692 | block: *Scope.Block, | ||
| 4693 | extended: Zir.Inst.Extended.InstData, | ||
| 4694 | ) InnerError!*Inst { | ||
| 4684 | const tracy = trace(@src()); | 4695 | const tracy = trace(@src()); |
| 4685 | defer tracy.end(); | 4696 | defer tracy.end(); |
| 4686 | 4697 | ||
| 4687 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 4698 | const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand); |
| 4688 | const src = inst_data.src(); | 4699 | const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; |
| 4689 | const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); | 4700 | const args = sema.code.refSlice(extra.end, extended.small); |
| 4690 | const args = sema.code.refSlice(extra.end, extra.data.operands_len); | ||
| 4691 | 4701 | ||
| 4692 | const inst_list = try sema.gpa.alloc(*ir.Inst, extra.data.operands_len); | 4702 | const inst_list = try sema.gpa.alloc(*ir.Inst, args.len); |
| 4693 | defer sema.gpa.free(inst_list); | 4703 | defer sema.gpa.free(inst_list); |
| 4694 | 4704 | ||
| 4695 | for (args) |arg_ref, i| { | 4705 | for (args) |arg_ref, i| { |
src/Zir.zig+42-28| ... | @@ -238,6 +238,10 @@ pub const Inst = struct { | ... | @@ -238,6 +238,10 @@ pub const Inst = struct { |
| 238 | call_chkused, | 238 | call_chkused, |
| 239 | /// Same as `call` but with modifier `.compile_time`. | 239 | /// Same as `call` but with modifier `.compile_time`. |
| 240 | call_compile_time, | 240 | call_compile_time, |
| 241 | /// Same as `call` but with modifier `.no_suspend`. | ||
| 242 | call_nosuspend, | ||
| 243 | /// Same as `call` but with modifier `.async_kw`. | ||
| 244 | call_async, | ||
| 241 | /// Function call with modifier `.auto`, empty parameter list. | 245 | /// Function call with modifier `.auto`, empty parameter list. |
| 242 | /// Uses the `un_node` field. Operand is callee. AST node is the function call. | 246 | /// Uses the `un_node` field. Operand is callee. AST node is the function call. |
| 243 | call_none, | 247 | call_none, |
| ... | @@ -266,10 +270,6 @@ pub const Inst = struct { | ... | @@ -266,10 +270,6 @@ pub const Inst = struct { |
| 266 | /// Uses the `bin` union field. | 270 | /// Uses the `bin` union field. |
| 267 | /// LHS is destination element type, RHS is result pointer. | 271 | /// LHS is destination element type, RHS is result pointer. |
| 268 | coerce_result_ptr, | 272 | coerce_result_ptr, |
| 269 | /// Log compile time variables and emit an error message. | ||
| 270 | /// Uses the `pl_node` union field. The AST node is the compile log builtin call. | ||
| 271 | /// The payload is `MultiOp`. | ||
| 272 | compile_log, | ||
| 273 | /// Conditional branch. Splits control flow based on a boolean condition value. | 273 | /// Conditional branch. Splits control flow based on a boolean condition value. |
| 274 | /// Uses the `pl_node` union field. AST node is an if, while, for, etc. | 274 | /// Uses the `pl_node` union field. AST node is an if, while, for, etc. |
| 275 | /// Payload is `CondBr`. | 275 | /// Payload is `CondBr`. |
| ... | @@ -523,10 +523,6 @@ pub const Inst = struct { | ... | @@ -523,10 +523,6 @@ pub const Inst = struct { |
| 523 | /// Given a value which is a pointer, returns the element type. | 523 | /// Given a value which is a pointer, returns the element type. |
| 524 | /// Uses the `un_node` field. | 524 | /// Uses the `un_node` field. |
| 525 | typeof_elem, | 525 | typeof_elem, |
| 526 | /// The builtin `@TypeOf` which returns the type after Peer Type Resolution | ||
| 527 | /// of one or more params. | ||
| 528 | /// Uses the `pl_node` field. AST node is the `@TypeOf` call. Payload is `MultiOp`. | ||
| 529 | typeof_peer, | ||
| 530 | /// Given a value, look at the type of it, which must be an integer type. | 526 | /// Given a value, look at the type of it, which must be an integer type. |
| 531 | /// Returns the integer type for the RHS of a shift operation. | 527 | /// Returns the integer type for the RHS of a shift operation. |
| 532 | /// Uses the `un_node` field. | 528 | /// Uses the `un_node` field. |
| ... | @@ -990,6 +986,8 @@ pub const Inst = struct { | ... | @@ -990,6 +986,8 @@ pub const Inst = struct { |
| 990 | .call, | 986 | .call, |
| 991 | .call_chkused, | 987 | .call_chkused, |
| 992 | .call_compile_time, | 988 | .call_compile_time, |
| 989 | .call_nosuspend, | ||
| 990 | .call_async, | ||
| 993 | .call_none, | 991 | .call_none, |
| 994 | .call_none_chkused, | 992 | .call_none_chkused, |
| 995 | .cmp_lt, | 993 | .cmp_lt, |
| ... | @@ -1085,12 +1083,10 @@ pub const Inst = struct { | ... | @@ -1085,12 +1083,10 @@ pub const Inst = struct { |
| 1085 | .slice_end, | 1083 | .slice_end, |
| 1086 | .slice_sentinel, | 1084 | .slice_sentinel, |
| 1087 | .import, | 1085 | .import, |
| 1088 | .typeof_peer, | ||
| 1089 | .typeof_log2_int_type, | 1086 | .typeof_log2_int_type, |
| 1090 | .log2_int_type, | 1087 | .log2_int_type, |
| 1091 | .resolve_inferred_alloc, | 1088 | .resolve_inferred_alloc, |
| 1092 | .set_eval_branch_quota, | 1089 | .set_eval_branch_quota, |
| 1093 | .compile_log, | ||
| 1094 | .switch_capture, | 1090 | .switch_capture, |
| 1095 | .switch_capture_ref, | 1091 | .switch_capture_ref, |
| 1096 | .switch_capture_multi, | 1092 | .switch_capture_multi, |
| ... | @@ -1268,6 +1264,17 @@ pub const Inst = struct { | ... | @@ -1268,6 +1264,17 @@ pub const Inst = struct { |
| 1268 | /// * 0bX0000000_00000000 - is volatile | 1264 | /// * 0bX0000000_00000000 - is volatile |
| 1269 | /// `operand` is payload index to `Asm`. | 1265 | /// `operand` is payload index to `Asm`. |
| 1270 | @"asm", | 1266 | @"asm", |
| 1267 | /// Log compile time variables and emit an error message. | ||
| 1268 | /// `operand` is payload index to `NodeMultiOp`. | ||
| 1269 | /// `small` is `operands_len`. | ||
| 1270 | /// The AST node is the compile log builtin call. | ||
| 1271 | compile_log, | ||
| 1272 | /// The builtin `@TypeOf` which returns the type after Peer Type Resolution | ||
| 1273 | /// of one or more params. | ||
| 1274 | /// `operand` is payload index to `NodeMultiOp`. | ||
| 1275 | /// `small` is `operands_len`. | ||
| 1276 | /// The AST node is the builtin call. | ||
| 1277 | typeof_peer, | ||
| 1271 | /// `operand` is payload index to `UnNode`. | 1278 | /// `operand` is payload index to `UnNode`. |
| 1272 | c_undef, | 1279 | c_undef, |
| 1273 | /// `operand` is payload index to `UnNode`. | 1280 | /// `operand` is payload index to `UnNode`. |
| ... | @@ -1897,6 +1904,11 @@ pub const Inst = struct { | ... | @@ -1897,6 +1904,11 @@ pub const Inst = struct { |
| 1897 | operands_len: u32, | 1904 | operands_len: u32, |
| 1898 | }; | 1905 | }; |
| 1899 | 1906 | ||
| 1907 | /// Trailing: operand: Ref, // for each `operands_len` (stored in `small`). | ||
| 1908 | pub const NodeMultiOp = struct { | ||
| 1909 | src_node: i32, | ||
| 1910 | }; | ||
| 1911 | |||
| 1900 | /// This data is stored inside extra, with trailing operands according to `body_len`. | 1912 | /// This data is stored inside extra, with trailing operands according to `body_len`. |
| 1901 | /// Each operand is an `Index`. | 1913 | /// Each operand is an `Index`. |
| 1902 | pub const Block = struct { | 1914 | pub const Block = struct { |
| ... | @@ -2540,6 +2552,8 @@ const Writer = struct { | ... | @@ -2540,6 +2552,8 @@ const Writer = struct { |
| 2540 | .call, | 2552 | .call, |
| 2541 | .call_chkused, | 2553 | .call_chkused, |
| 2542 | .call_compile_time, | 2554 | .call_compile_time, |
| 2555 | .call_nosuspend, | ||
| 2556 | .call_async, | ||
| 2543 | => try self.writePlNodeCall(stream, inst), | 2557 | => try self.writePlNodeCall(stream, inst), |
| 2544 | 2558 | ||
| 2545 | .block, | 2559 | .block, |
| ... | @@ -2584,10 +2598,6 @@ const Writer = struct { | ... | @@ -2584,10 +2598,6 @@ const Writer = struct { |
| 2584 | .switch_block_ref_else_multi => try self.writePlNodeSwitchBlockMulti(stream, inst, .@"else"), | 2598 | .switch_block_ref_else_multi => try self.writePlNodeSwitchBlockMulti(stream, inst, .@"else"), |
| 2585 | .switch_block_ref_under_multi => try self.writePlNodeSwitchBlockMulti(stream, inst, .under), | 2599 | .switch_block_ref_under_multi => try self.writePlNodeSwitchBlockMulti(stream, inst, .under), |
| 2586 | 2600 | ||
| 2587 | .compile_log, | ||
| 2588 | .typeof_peer, | ||
| 2589 | => try self.writePlNodeMultiOp(stream, inst), | ||
| 2590 | |||
| 2591 | .field_ptr, | 2601 | .field_ptr, |
| 2592 | .field_val, | 2602 | .field_val, |
| 2593 | => try self.writePlNodeField(stream, inst), | 2603 | => try self.writePlNodeField(stream, inst), |
| ... | @@ -2646,6 +2656,10 @@ const Writer = struct { | ... | @@ -2646,6 +2656,10 @@ const Writer = struct { |
| 2646 | .@"asm" => try self.writeAsm(stream, extended), | 2656 | .@"asm" => try self.writeAsm(stream, extended), |
| 2647 | .func => try self.writeFuncExtended(stream, extended), | 2657 | .func => try self.writeFuncExtended(stream, extended), |
| 2648 | 2658 | ||
| 2659 | .compile_log, | ||
| 2660 | .typeof_peer, | ||
| 2661 | => try self.writeNodeMultiOp(stream, extended), | ||
| 2662 | |||
| 2649 | .alloc, | 2663 | .alloc, |
| 2650 | .builtin_extern, | 2664 | .builtin_extern, |
| 2651 | .c_undef, | 2665 | .c_undef, |
| ... | @@ -2836,6 +2850,19 @@ const Writer = struct { | ... | @@ -2836,6 +2850,19 @@ const Writer = struct { |
| 2836 | try self.writeSrc(stream, inst_data.src()); | 2850 | try self.writeSrc(stream, inst_data.src()); |
| 2837 | } | 2851 | } |
| 2838 | 2852 | ||
| 2853 | fn writeNodeMultiOp(self: *Writer, stream: anytype, extended: Inst.Extended.InstData) !void { | ||
| 2854 | const extra = self.code.extraData(Inst.NodeMultiOp, extended.operand); | ||
| 2855 | const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; | ||
| 2856 | const operands = self.code.refSlice(extra.end, extended.small); | ||
| 2857 | |||
| 2858 | for (operands) |operand, i| { | ||
| 2859 | if (i != 0) try stream.writeAll(", "); | ||
| 2860 | try self.writeInstRef(stream, operand); | ||
| 2861 | } | ||
| 2862 | try stream.writeAll(")) "); | ||
| 2863 | try self.writeSrc(stream, src); | ||
| 2864 | } | ||
| 2865 | |||
| 2839 | fn writeAsm(self: *Writer, stream: anytype, extended: Inst.Extended.InstData) !void { | 2866 | fn writeAsm(self: *Writer, stream: anytype, extended: Inst.Extended.InstData) !void { |
| 2840 | const extra = self.code.extraData(Inst.Asm, extended.operand); | 2867 | const extra = self.code.extraData(Inst.Asm, extended.operand); |
| 2841 | const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; | 2868 | const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; |
| ... | @@ -2902,7 +2929,7 @@ const Writer = struct { | ... | @@ -2902,7 +2929,7 @@ const Writer = struct { |
| 2902 | } | 2929 | } |
| 2903 | } | 2930 | } |
| 2904 | } | 2931 | } |
| 2905 | try stream.writeAll(") "); | 2932 | try stream.writeAll(")) "); |
| 2906 | try self.writeSrc(stream, src); | 2933 | try self.writeSrc(stream, src); |
| 2907 | } | 2934 | } |
| 2908 | 2935 | ||
| ... | @@ -3457,19 +3484,6 @@ const Writer = struct { | ... | @@ -3457,19 +3484,6 @@ const Writer = struct { |
| 3457 | try self.writeSrc(stream, inst_data.src()); | 3484 | try self.writeSrc(stream, inst_data.src()); |
| 3458 | } | 3485 | } |
| 3459 | 3486 | ||
| 3460 | fn writePlNodeMultiOp(self: *Writer, stream: anytype, inst: Inst.Index) !void { | ||
| 3461 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | ||
| 3462 | const extra = self.code.extraData(Inst.MultiOp, inst_data.payload_index); | ||
| 3463 | const operands = self.code.refSlice(extra.end, extra.data.operands_len); | ||
| 3464 | |||
| 3465 | for (operands) |operand, i| { | ||
| 3466 | if (i != 0) try stream.writeAll(", "); | ||
| 3467 | try self.writeInstRef(stream, operand); | ||
| 3468 | } | ||
| 3469 | try stream.writeAll(") "); | ||
| 3470 | try self.writeSrc(stream, inst_data.src()); | ||
| 3471 | } | ||
| 3472 | |||
| 3473 | fn writePlNodeField(self: *Writer, stream: anytype, inst: Inst.Index) !void { | 3487 | fn writePlNodeField(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 3474 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | 3488 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 3475 | const extra = self.code.extraData(Inst.Field, inst_data.payload_index).data; | 3489 | const extra = self.code.extraData(Inst.Field, inst_data.payload_index).data; |