diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-04-29 22:50:53 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-29 22:50:53 -0400 |
| commit | cc39d453c45645296cd771c94d97b8a77469be91 (patch) | |
| tree | 8d9c857255ac15fe2f8125789f8a42a7a03573eb /src | |
| parent | a0a2ce92ca129d28e22c63f7bace1672c43776b5 (diff) | |
| parent | 596f7df02e78adf334eed4a1f14eafa31ca611b9 (diff) | |
| download | zig-cc39d453c45645296cd771c94d97b8a77469be91.tar.gz zig-cc39d453c45645296cd771c94d97b8a77469be91.zip | |
Merge pull request #11549 from Vexu/stage2-fixes
Stage2: fix comptime unreachable, adjust Zir.Extended
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 114 | ||||
| -rw-r--r-- | src/Module.zig | 8 | ||||
| -rw-r--r-- | src/Sema.zig | 180 | ||||
| -rw-r--r-- | src/Zir.zig | 154 | ||||
| -rw-r--r-- | src/print_zir.zig | 61 |
5 files changed, 274 insertions, 243 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index c9fd82bd5f..f74a2b2d39 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -72,6 +72,7 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void { i32 => @bitCast(u32, @field(extra, field.name)), Zir.Inst.Call.Flags => @bitCast(u32, @field(extra, field.name)), Zir.Inst.SwitchBlock.Bits => @bitCast(u32, @field(extra, field.name)), + Zir.Inst.ExtendedFunc.Bits => @bitCast(u32, @field(extra, field.name)), else => @compileError("bad field type"), }; i += 1; @@ -740,7 +741,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr _ = try gz.addAsIndex(.{ .tag = .@"unreachable", .data = .{ .@"unreachable" = .{ - .safety = true, + .force_comptime = gz.force_comptime, .src_node = gz.nodeIndexToRelative(node), } }, }); @@ -1078,8 +1079,14 @@ fn awaitExpr( }); } const operand = try expr(gz, scope, .none, rhs_node); - const tag: Zir.Inst.Tag = if (gz.nosuspend_node != 0) .await_nosuspend else .@"await"; - const result = try gz.addUnNode(tag, operand, node); + const result = if (gz.nosuspend_node != 0) + try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = operand, + }) + else + try gz.addUnNode(.@"await", operand, node); + return rvalue(gz, rl, result, node); } @@ -2239,6 +2246,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .field_val_named, .func, .func_inferred, + .func_extended, .int, .int_big, .float, @@ -2349,7 +2357,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .int_to_ptr, .float_cast, .int_cast, - .err_set_cast, .ptr_cast, .truncate, .align_cast, @@ -2386,15 +2393,24 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .c_import, .@"resume", .@"await", - .await_nosuspend, .ret_err_value_code, - .extended, .closure_get, .array_base_ptr, .field_base_ptr, .param_type, + .ret_ptr, + .ret_type, => break :b false, + .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) { + .breakpoint, + .fence, + .set_align_stack, + .set_float_mode, + => break :b true, + else => break :b false, + }, + // ZIR instructions that are always `noreturn`. .@"break", .break_inline, @@ -2415,11 +2431,11 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner }, // ZIR instructions that are always `void`. - .breakpoint, - .fence, .dbg_stmt, .dbg_var_ptr, .dbg_var_val, + .dbg_block_begin, + .dbg_block_end, .ensure_result_used, .ensure_result_non_error, .@"export", @@ -2436,9 +2452,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .validate_struct_init_comptime, .validate_array_init, .validate_array_init_comptime, - .set_align_stack, .set_cold, - .set_float_mode, .set_runtime_safety, .closure_capture, .memcpy, @@ -6310,9 +6324,9 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref } const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node, true)) .{ - .ptr = try gz.addNodeExtended(.ret_ptr, node), + .ptr = try gz.addNode(.ret_ptr, node), } else .{ - .ty = try gz.addNodeExtended(.ret_type, node), + .ty = try gz.addNode(.ret_type, node), }; const prev_anon_name_strategy = gz.anon_name_strategy; gz.anon_name_strategy = .func; @@ -7183,7 +7197,26 @@ fn builtinCall( }, .fence => { const order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[0]); - const result = try gz.addUnNode(.fence, order, node); + const result = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = order, + }); + return rvalue(gz, rl, result, node); + }, + .set_float_mode => { + const order = try expr(gz, scope, .{ .coerced_ty = .float_mode_type }, params[0]); + const result = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = order, + }); + return rvalue(gz, rl, result, node); + }, + .set_align_stack => { + const order = try expr(gz, scope, align_rl, params[0]); + const result = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = order, + }); return rvalue(gz, rl, result, node); }, @@ -7198,14 +7231,13 @@ fn builtinCall( return rvalue(gz, rl, result, node); }, - .breakpoint => return simpleNoOpVoid(gz, rl, node, .breakpoint), - // zig fmt: off .This => return rvalue(gz, rl, try gz.addNodeExtended(.this, node), node), .return_address => return rvalue(gz, rl, try gz.addNodeExtended(.ret_addr, node), node), .error_return_trace => return rvalue(gz, rl, try gz.addNodeExtended(.error_return_trace, node), node), .frame => return rvalue(gz, rl, try gz.addNodeExtended(.frame, node), node), .frame_address => return rvalue(gz, rl, try gz.addNodeExtended(.frame_address, node), node), + .breakpoint => return rvalue(gz, rl, try gz.addNodeExtended(.breakpoint, node), node), .type_info => return simpleUnOpType(gz, scope, rl, node, params[0], .type_info), .size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .size_of), @@ -7222,9 +7254,7 @@ fn builtinCall( .embed_file => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .embed_file), .error_name => return simpleUnOp(gz, scope, rl, node, .{ .ty = .anyerror_type }, params[0], .error_name), .panic => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .panic), - .set_align_stack => return simpleUnOp(gz, scope, rl, node, align_rl, params[0], .set_align_stack), .set_cold => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_cold), - .set_float_mode => return simpleUnOp(gz, scope, rl, node, .{ .coerced_ty = .float_mode_type }, params[0], .set_float_mode), .set_runtime_safety => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_runtime_safety), .sqrt => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sqrt), .sin => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sin), @@ -7252,7 +7282,6 @@ fn builtinCall( .int_to_enum => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_enum), .float_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .float_cast), .int_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .int_cast), - .err_set_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .err_set_cast), .ptr_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .ptr_cast), .truncate => return typeCast(gz, scope, rl, node, params[0], params[1], .truncate), // zig fmt: on @@ -7266,6 +7295,14 @@ fn builtinCall( }); return rvalue(gz, rl, result, node); }, + .err_set_cast => { + const result = try gz.addExtendedPayload(.err_set_cast, Zir.Inst.BinNode{ + .lhs = try typeExpr(gz, scope, params[0]), + .rhs = try expr(gz, scope, .none, params[1]), + .node = gz.nodeIndexToRelative(node), + }); + return rvalue(gz, rl, result, node); + }, // zig fmt: off .has_decl => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_decl), @@ -8940,7 +8977,8 @@ fn rvalue( const result = r: { if (refToIndex(raw_result)) |result_index| { const zir_tags = gz.astgen.instructions.items(.tag); - if (zir_tags[result_index].isAlwaysVoid()) { + const data = gz.astgen.instructions.items(.data)[result_index]; + if (zir_tags[result_index].isAlwaysVoid(data)) { break :r Zir.Inst.Ref.void_value; } } @@ -9987,10 +10025,18 @@ const GenZir = struct { @boolToInt(args.cc != .none), ); const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedFunc{ - .src_node = gz.nodeIndexToRelative(args.src_node), .param_block = args.param_block, .ret_body_len = @intCast(u32, ret_ty.len), .body_len = @intCast(u32, body.len), + .bits = .{ + .is_var_args = args.is_var_args, + .is_inferred_error = args.is_inferred_error, + .has_lib_name = args.lib_name != 0, + .has_cc = args.cc != .none, + .has_align = args.align_inst != .none, + .is_test = args.is_test, + .is_extern = args.is_extern, + }, }); if (args.lib_name != 0) { astgen.extra.appendAssumeCapacity(args.lib_name); @@ -10014,19 +10060,10 @@ const GenZir = struct { astgen.instructions.items(.data)[args.ret_br].@"break".block_inst = new_index; } astgen.instructions.appendAssumeCapacity(.{ - .tag = .extended, - .data = .{ .extended = .{ - .opcode = .func, - .small = @bitCast(u16, Zir.Inst.ExtendedFunc.Small{ - .is_var_args = args.is_var_args, - .is_inferred_error = args.is_inferred_error, - .has_lib_name = args.lib_name != 0, - .has_cc = args.cc != .none, - .has_align = args.align_inst != .none, - .is_test = args.is_test, - .is_extern = args.is_extern, - }), - .operand = payload_index, + .tag = .func_extended, + .data = .{ .pl_node = .{ + .src_node = gz.nodeIndexToRelative(args.src_node), + .payload_index = payload_index, } }, }); gz.instructions.appendAssumeCapacity(new_index); @@ -10893,9 +10930,7 @@ const GenZir = struct { fn addDbgBlockBegin(gz: *GenZir) !void { if (gz.force_comptime) return; - _ = try gz.add(.{ .tag = .extended, .data = .{ - .extended = .{ .opcode = .dbg_block_begin, .small = undefined, .operand = undefined }, - } }); + _ = try gz.add(.{ .tag = .dbg_block_begin, .data = undefined }); } fn addDbgBlockEnd(gz: *GenZir) !void { @@ -10903,18 +10938,15 @@ const GenZir = struct { const gpa = gz.astgen.gpa; const tags = gz.astgen.instructions.items(.tag); - const data = gz.astgen.instructions.items(.data); const last_inst = gz.instructions.items[gz.instructions.items.len - 1]; // remove dbg_block_begin immediately followed by dbg_block_end - if (tags[last_inst] == .extended and data[last_inst].extended.opcode == .dbg_block_begin) { + if (tags[last_inst] == .dbg_block_begin) { _ = gz.instructions.pop(); return; } const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); - try gz.astgen.instructions.append(gpa, .{ .tag = .extended, .data = .{ - .extended = .{ .opcode = .dbg_block_end, .small = undefined, .operand = undefined }, - } }); + try gz.astgen.instructions.append(gpa, .{ .tag = .dbg_block_end, .data = undefined }); try gz.instructions.insert(gpa, gz.instructions.items.len - 1, new_index); } diff --git a/src/Module.zig b/src/Module.zig index 1119d73ab0..55ec1fdd2c 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1532,10 +1532,10 @@ pub const Fn = struct { switch (zir_tags[func.zir_body_inst]) { .func => return false, .func_inferred => return true, - .extended => { - const extended = zir.instructions.items(.data)[func.zir_body_inst].extended; - const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small); - return small.is_inferred_error; + .func_extended => { + const inst_data = zir.instructions.items(.data)[func.zir_body_inst].pl_node; + const extra = zir.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index); + return extra.data.bits.is_inferred_error; }, else => unreachable, } diff --git a/src/Sema.zig b/src/Sema.zig index c9d8f090ae..ccfb11e639 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -745,6 +745,7 @@ fn analyzeBodyInner( .field_call_bind => try sema.zirFieldCallBind(block, inst), .func => try sema.zirFunc(block, inst, false), .func_inferred => try sema.zirFunc(block, inst, true), + .func_extended => try sema.zirFuncExtended(block, inst), .import => try sema.zirImport(block, inst), .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst), .int => try sema.zirInt(block, inst), @@ -819,7 +820,6 @@ fn analyzeBodyInner( .int_to_ptr => try sema.zirIntToPtr(block, inst), .float_cast => try sema.zirFloatCast(block, inst), .int_cast => try sema.zirIntCast(block, inst), - .err_set_cast => try sema.zirErrSetCast(block, inst), .ptr_cast => try sema.zirPtrCast(block, inst), .truncate => try sema.zirTruncate(block, inst), .align_cast => try sema.zirAlignCast(block, inst), @@ -842,8 +842,7 @@ fn analyzeBodyInner( .field_parent_ptr => try sema.zirFieldParentPtr(block, inst), .builtin_async_call => try sema.zirBuiltinAsyncCall(block, inst), .@"resume" => try sema.zirResume(block, inst), - .@"await" => try sema.zirAwait(block, inst, false), - .await_nosuspend => try sema.zirAwait(block, inst, true), + .@"await" => try sema.zirAwait(block, inst), .array_base_ptr => try sema.zirArrayBasePtr(block, inst), .field_base_ptr => try sema.zirFieldBasePtr(block, inst), @@ -894,6 +893,9 @@ fn analyzeBodyInner( .shl_exact => try sema.zirShl(block, inst, .shl_exact), .shl_sat => try sema.zirShl(block, inst, .shl_sat), + .ret_ptr => try sema.zirRetPtr(block, inst), + .ret_type => try sema.zirRetType(block, inst), + // Instructions that we know to *always* be noreturn based solely on their tag. // These functions match the return type of analyzeBody so that we can // tail call them here. @@ -910,14 +912,11 @@ fn analyzeBodyInner( const extended = datas[inst].extended; break :ext switch (extended.opcode) { // zig fmt: off - .func => try sema.zirFuncExtended( block, extended, inst), .variable => try sema.zirVarExtended( block, extended), .struct_decl => try sema.zirStructDecl( block, extended, inst), .enum_decl => try sema.zirEnumDecl( block, extended), .union_decl => try sema.zirUnionDecl( block, extended, inst), .opaque_decl => try sema.zirOpaqueDecl( block, extended), - .ret_ptr => try sema.zirRetPtr( block, extended), - .ret_type => try sema.zirRetType( block, extended), .this => try sema.zirThis( block, extended), .ret_addr => try sema.zirRetAddr( block, extended), .builtin_src => try sema.zirBuiltinSrc( block, extended), @@ -940,16 +939,28 @@ fn analyzeBodyInner( .wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended), .prefetch => try sema.zirPrefetch( block, extended), .field_call_bind_named => try sema.zirFieldCallBindNamed(block, extended), + .err_set_cast => try sema.zirErrSetCast( block, extended), + .await_nosuspend => try sema.zirAwaitNosuspend( block, extended), // zig fmt: on - .dbg_block_begin => { - dbg_block_begins += 1; - try sema.zirDbgBlockBegin(block); + .fence => { + try sema.zirFence(block, extended); + i += 1; + continue; + }, + .set_float_mode => { + try sema.zirSetFloatMode(block, extended); i += 1; continue; }, - .dbg_block_end => { - dbg_block_begins -= 1; - try sema.zirDbgBlockEnd(block); + .set_align_stack => { + try sema.zirSetAlignStack(block, extended); + i += 1; + continue; + }, + .breakpoint => { + if (!block.is_comptime) { + _ = try block.addNoOp(.breakpoint); + } i += 1; continue; }, @@ -961,18 +972,6 @@ fn analyzeBodyInner( // continue the loop. // We also know that they cannot be referenced later, so we avoid // putting them into the map. - .breakpoint => { - if (!block.is_comptime) { - _ = try block.addNoOp(.breakpoint); - } - i += 1; - continue; - }, - .fence => { - try sema.zirFence(block, inst); - i += 1; - continue; - }, .dbg_stmt => { try sema.zirDbgStmt(block, inst); i += 1; @@ -988,6 +987,18 @@ fn analyzeBodyInner( i += 1; continue; }, + .dbg_block_begin => { + dbg_block_begins += 1; + try sema.zirDbgBlockBegin(block); + i += 1; + continue; + }, + .dbg_block_end => { + dbg_block_begins -= 1; + try sema.zirDbgBlockEnd(block); + i += 1; + continue; + }, .ensure_err_payload_void => { try sema.zirEnsureErrPayloadVoid(block, inst); i += 1; @@ -1078,21 +1089,11 @@ fn analyzeBodyInner( i += 1; continue; }, - .set_align_stack => { - try sema.zirSetAlignStack(block, inst); - i += 1; - continue; - }, .set_cold => { try sema.zirSetCold(block, inst); i += 1; continue; }, - .set_float_mode => { - try sema.zirSetFloatMode(block, inst); - i += 1; - continue; - }, .set_runtime_safety => { try sema.zirSetRuntimeSafety(block, inst); i += 1; @@ -2452,15 +2453,12 @@ fn zirErrorSetDecl( return sema.analyzeDeclVal(block, src, new_decl_index); } -fn zirRetPtr( - sema: *Sema, - block: *Block, - extended: Zir.Inst.Extended.InstData, -) CompileError!Air.Inst.Ref { +fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); - const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; + const inst_data = sema.code.instructions.items(.data)[inst].node; + const src: LazySrcLoc = .{ .node_offset = inst_data }; try sema.requireFunctionBlock(block, src); if (block.is_comptime) { @@ -2493,15 +2491,12 @@ fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins return sema.analyzeRef(block, inst_data.src(), operand); } -fn zirRetType( - sema: *Sema, - block: *Block, - extended: Zir.Inst.Extended.InstData, -) CompileError!Air.Inst.Ref { +fn zirRetType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); - const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; + const inst_data = sema.code.instructions.items(.data)[inst].node; + const src: LazySrcLoc = .{ .node_offset = inst_data }; try sema.requireFunctionBlock(block, src); return sema.addType(sema.fn_ret_ty); } @@ -3746,9 +3741,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v sema.fn_ret_ty.zigTypeTag() == .ErrorUnion) { if (Zir.refToIndex(extra.lhs)) |ptr_index| { - if (zir_tags[ptr_index] == .extended and - zir_datas[ptr_index].extended.opcode == .ret_ptr) - { + if (zir_tags[ptr_index] == .ret_ptr) { try sema.addToInferredErrorSet(operand); } } @@ -4392,11 +4385,11 @@ pub fn analyzeExport( errdefer de_gop.value_ptr.* = gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1); } -fn zirSetAlignStack(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { - const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; - const src: LazySrcLoc = inst_data.src(); - const alignment = try sema.resolveAlign(block, operand_src, inst_data.operand); +fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { + const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; + const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; + const src: LazySrcLoc = .{ .node_offset = extra.node }; + const alignment = try sema.resolveAlign(block, operand_src, extra.operand); if (alignment > 256) { return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{ alignment, @@ -4433,10 +4426,10 @@ fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi func.is_cold = is_cold; } -fn zirSetFloatMode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { - const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const src: LazySrcLoc = inst_data.src(); - const float_mode = try sema.resolveBuiltinEnum(block, src, inst_data.operand, "FloatMode"); +fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { + const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; + const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; + const float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode"); switch (float_mode) { .Strict => return, .Optimized => { @@ -4451,12 +4444,12 @@ fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand); } -fn zirFence(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { +fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { if (block.is_comptime) return; - const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; - const order = try sema.resolveAtomicOrder(block, order_src, inst_data.operand); + const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; + const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; + const order = try sema.resolveAtomicOrder(block, order_src, extra.operand); if (@enumToInt(order) < @enumToInt(std.builtin.AtomicOrder.Acquire)) { return sema.fail(block, order_src, "atomic ordering must be Acquire or stricter", .{}); @@ -12337,14 +12330,15 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi } fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { - const tracy = trace(@src()); - defer tracy.end(); - const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable"; const src = inst_data.src(); + + if (block.is_comptime or inst_data.force_comptime) { + return sema.fail(block, src, "reached unreachable code", .{}); + } try sema.requireRuntimeBlock(block, src); // TODO Add compile error for @optimizeFor occurring too late in a scope. - try block.addUnreachable(src, inst_data.safety); + try block.addUnreachable(src, true); return always_noreturn; } @@ -14143,12 +14137,11 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai return block.addBitCast(type_res, operand_coerced); } -fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { - const inst_data = sema.code.instructions.items(.data)[inst].pl_node; - const src = inst_data.src(); - const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; - const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; +fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { + const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; + const src: LazySrcLoc = .{ .node_offset = extra.node }; + const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; + const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node }; const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs); const operand = sema.resolveInst(extra.rhs); const operand_ty = sema.typeOf(operand); @@ -16006,15 +15999,24 @@ fn zirAwait( sema: *Sema, block: *Block, inst: Zir.Inst.Index, - is_nosuspend: bool, ) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - _ = is_nosuspend; return sema.fail(block, src, "TODO: Sema.zirAwait", .{}); } +fn zirAwaitNosuspend( + sema: *Sema, + block: *Block, + extended: Zir.Inst.Extended.InstData, +) CompileError!Air.Inst.Ref { + const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; + const src: LazySrcLoc = .{ .node_offset = extra.node }; + + return sema.fail(block, src, "TODO: Sema.zirAwaitNosuspend", .{}); +} + fn zirVarExtended( sema: *Sema, block: *Block, @@ -16097,37 +16099,33 @@ fn zirVarExtended( return result; } -fn zirFuncExtended( - sema: *Sema, - block: *Block, - extended: Zir.Inst.Extended.InstData, - inst: Zir.Inst.Index, -) CompileError!Air.Inst.Ref { +fn zirFuncExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); - const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, extended.operand); - const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; - const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node }; + const inst_data = sema.code.instructions.items(.data)[inst].pl_node; + const src = inst_data.src(); + const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index); + + const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = inst_data.src_node }; const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align - const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small); var extra_index: usize = extra.end; - const lib_name: ?[]const u8 = if (small.has_lib_name) blk: { + const lib_name: ?[]const u8 = if (extra.data.bits.has_lib_name) blk: { const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]); extra_index += 1; break :blk lib_name; } else null; - const cc: std.builtin.CallingConvention = if (small.has_cc) blk: { + const cc: std.builtin.CallingConvention = if (extra.data.bits.has_cc) blk: { const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); extra_index += 1; const cc_tv = try sema.resolveInstConst(block, cc_src, cc_ref); break :blk cc_tv.val.toEnum(std.builtin.CallingConvention); } else .Unspecified; - const align_val: Value = if (small.has_align) blk: { + const align_val: Value = if (extra.data.bits.has_align) blk: { const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); extra_index += 1; const align_tv = try sema.resolveInstConst(block, align_src, align_ref); @@ -16144,13 +16142,13 @@ fn zirFuncExtended( src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data; } - const is_var_args = small.is_var_args; - const is_inferred_error = small.is_inferred_error; - const is_extern = small.is_extern; + const is_var_args = extra.data.bits.is_var_args; + const is_inferred_error = extra.data.bits.is_inferred_error; + const is_extern = extra.data.bits.is_extern; return sema.funcCommon( block, - extra.data.src_node, + inst_data.src_node, inst, ret_ty_body, cc, diff --git a/src/Zir.zig b/src/Zir.zig index f4c62a6f24..9ef6d33b86 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -73,6 +73,7 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) struct { data: T, en i32 => @bitCast(i32, code.extra[i]), Inst.Call.Flags => @bitCast(Inst.Call.Flags, code.extra[i]), Inst.SwitchBlock.Bits => @bitCast(Inst.SwitchBlock.Bits, code.extra[i]), + Inst.ExtendedFunc.Bits => @bitCast(Inst.ExtendedFunc.Bits, code.extra[i]), else => @compileError("bad field type"), }; i += 1; @@ -278,8 +279,6 @@ pub const Inst = struct { /// break instruction in a block, and the target block is the parent. /// Uses the `break` union field. break_inline, - /// Uses the `node` union field. - breakpoint, /// Function call. /// Uses `pl_node`. AST node is the function call. Payload is `Call`. call, @@ -331,6 +330,10 @@ pub const Inst = struct { /// Same as `dbg_var_ptr` but the local is always a const and the operand /// is the local's value. dbg_var_val, + /// Marks the beginning of a semantic scope for debug info variables. + dbg_block_begin, + /// Marks the end of a semantic scope for debug info variables. + dbg_block_end, /// Uses a name to identify a Decl and takes a pointer to it. /// Uses the `str_tok` union field. decl_ref, @@ -413,6 +416,10 @@ pub const Inst = struct { func, /// Same as `func` but has an inferred error set. func_inferred, + /// Represents a function declaration or function prototype, depending on + /// whether body_len is 0. + /// Uses the `pl_node` union field. `payload_index` points to a `ExtendedFunc`. + func_extended, /// Implements the `@import` builtin. /// Uses the `str_tok` field. import, @@ -499,6 +506,12 @@ pub const Inst = struct { /// this instruction; a following 'ret' instruction will do the diversion. /// Uses the `str_tok` union field. ret_err_value_code, + /// Obtains a pointer to the return value. + /// Uses the `node` union field. + ret_ptr, + /// Obtains the return type of the in-scope function. + /// Uses the `node` union field. + ret_type, /// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified. /// Uses the `ptr_type_simple` union field. ptr_type_simple, @@ -744,8 +757,6 @@ pub const Inst = struct { size_of, /// Implements the `@bitSizeOf` builtin. Uses `un_node`. bit_size_of, - /// Implements the `@fence` builtin. Uses `un_node`. - fence, /// Implement builtin `@ptrToInt`. Uses `un_node`. /// Convert a pointer to a `usize` integer. @@ -774,12 +785,8 @@ pub const Inst = struct { error_name, /// Implement builtin `@panic`. Uses `un_node`. panic, - /// Implement builtin `@setAlignStack`. Uses `un_node`. - set_align_stack, /// Implement builtin `@setCold`. Uses `un_node`. set_cold, - /// Implement builtin `@setFloatMode`. Uses `un_node`. - set_float_mode, /// Implement builtin `@setRuntimeSafety`. Uses `un_node`. set_runtime_safety, /// Implement builtin `@sqrt`. Uses `un_node`. @@ -843,9 +850,6 @@ pub const Inst = struct { /// Convert an integer value to another integer type, asserting that the destination type /// can hold the same mathematical value. int_cast, - /// Implements the `@errSetCast` builtin. - /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand. - err_set_cast, /// Implements the `@ptrCast` builtin. /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand. ptr_cast, @@ -972,7 +976,6 @@ pub const Inst = struct { /// Implements `resume` syntax. Uses `un_node` field. @"resume", @"await", - await_nosuspend, /// When a type or function refers to a comptime value from an outer /// scope, that forms a closure over comptime value. The outer scope @@ -1028,8 +1031,6 @@ pub const Inst = struct { .bool_br_and, .bool_br_or, .bool_not, - .breakpoint, - .fence, .call, .cmp_lt, .cmp_lte, @@ -1044,6 +1045,8 @@ pub const Inst = struct { .dbg_stmt, .dbg_var_ptr, .dbg_var_val, + .dbg_block_begin, + .dbg_block_end, .decl_ref, .decl_val, .load, @@ -1064,6 +1067,7 @@ pub const Inst = struct { .field_val_named, .func, .func_inferred, + .func_extended, .has_decl, .int, .int_big, @@ -1164,9 +1168,7 @@ pub const Inst = struct { .bool_to_int, .embed_file, .error_name, - .set_align_stack, .set_cold, - .set_float_mode, .set_runtime_safety, .sqrt, .sin, @@ -1192,7 +1194,6 @@ pub const Inst = struct { .int_to_ptr, .float_cast, .int_cast, - .err_set_cast, .ptr_cast, .truncate, .align_cast, @@ -1231,11 +1232,12 @@ pub const Inst = struct { .c_import, .@"resume", .@"await", - .await_nosuspend, .ret_err_value_code, .extended, .closure_get, .closure_capture, + .ret_ptr, + .ret_type, => false, .@"break", @@ -1258,13 +1260,13 @@ pub const Inst = struct { /// AstGen uses this to find out if `Ref.void_value` should be used in place /// of the result of a given instruction. This allows Sema to forego adding /// the instruction to the map after analysis. - pub fn isAlwaysVoid(tag: Tag) bool { + pub fn isAlwaysVoid(tag: Tag, data: Data) bool { return switch (tag) { - .breakpoint, - .fence, .dbg_stmt, .dbg_var_ptr, .dbg_var_val, + .dbg_block_begin, + .dbg_block_end, .ensure_result_used, .ensure_result_non_error, .ensure_err_payload_void, @@ -1283,9 +1285,7 @@ pub const Inst = struct { .validate_array_init_comptime, .@"export", .export_value, - .set_align_stack, .set_cold, - .set_float_mode, .set_runtime_safety, .memcpy, .memset, @@ -1353,6 +1353,7 @@ pub const Inst = struct { .field_val_named, .func, .func_inferred, + .func_extended, .has_decl, .int, .int_big, @@ -1464,7 +1465,6 @@ pub const Inst = struct { .int_to_ptr, .float_cast, .int_cast, - .err_set_cast, .ptr_cast, .truncate, .align_cast, @@ -1500,9 +1500,7 @@ pub const Inst = struct { .c_import, .@"resume", .@"await", - .await_nosuspend, .ret_err_value_code, - .extended, .closure_get, .closure_capture, .@"break", @@ -1514,11 +1512,18 @@ pub const Inst = struct { .ret_load, .ret_tok, .ret_err_value, + .ret_ptr, + .ret_type, .@"unreachable", .repeat, .repeat_inline, .panic, => false, + + .extended => switch (data.extended.opcode) { + .breakpoint, .fence => true, + else => false, + }, }; } @@ -1563,7 +1568,6 @@ pub const Inst = struct { .bool_br_or = .bool_br, .@"break" = .@"break", .break_inline = .@"break", - .breakpoint = .node, .call = .pl_node, .cmp_lt = .pl_node, .cmp_lte = .pl_node, @@ -1580,6 +1584,8 @@ pub const Inst = struct { .dbg_stmt = .dbg_stmt, .dbg_var_ptr = .str_op, .dbg_var_val = .str_op, + .dbg_block_begin = .tok, + .dbg_block_end = .tok, .decl_ref = .str_tok, .decl_val = .str_tok, .load = .un_node, @@ -1602,6 +1608,7 @@ pub const Inst = struct { .field_call_bind = .pl_node, .func = .pl_node, .func_inferred = .pl_node, + .func_extended = .pl_node, .import = .str_tok, .int = .int, .int_big = .str, @@ -1623,6 +1630,8 @@ pub const Inst = struct { .ret_tok = .un_tok, .ret_err_value = .str_tok, .ret_err_value_code = .str_tok, + .ret_ptr = .node, + .ret_type = .node, .ptr_type_simple = .ptr_type_simple, .ptr_type = .ptr_type, .slice_start = .pl_node, @@ -1685,7 +1694,6 @@ pub const Inst = struct { .type_info = .un_node, .size_of = .un_node, .bit_size_of = .un_node, - .fence = .un_node, .ptr_to_int = .un_node, .error_to_int = .un_node, @@ -1698,9 +1706,7 @@ pub const Inst = struct { .embed_file = .un_node, .error_name = .un_node, .panic = .un_node, - .set_align_stack = .un_node, .set_cold = .un_node, - .set_float_mode = .un_node, .set_runtime_safety = .un_node, .sqrt = .un_node, .sin = .un_node, @@ -1728,7 +1734,6 @@ pub const Inst = struct { .int_to_enum = .pl_node, .float_cast = .pl_node, .int_cast = .pl_node, - .err_set_cast = .pl_node, .ptr_cast = .pl_node, .truncate = .pl_node, .align_cast = .pl_node, @@ -1788,7 +1793,6 @@ pub const Inst = struct { .@"resume" = .un_node, .@"await" = .un_node, - .await_nosuspend = .un_node, .closure_capture = .un_tok, .closure_get = .inst_node, @@ -1806,11 +1810,6 @@ pub const Inst = struct { /// Rarer instructions are here; ones that do not fit in the 8-bit `Tag` enum. /// `noreturn` instructions may not go here; they must be part of the main `Tag` enum. pub const Extended = enum(u16) { - /// Represents a function declaration or function prototype, depending on - /// whether body_len is 0. - /// `operand` is payload index to `ExtendedFunc`. - /// `small` is `ExtendedFunc.Small`. - func, /// Declares a global variable. /// `operand` is payload index to `ExtendedVar`. /// `small` is `ExtendedVar.Small`. @@ -1834,12 +1833,6 @@ pub const Inst = struct { /// `operand` is payload index to `OpaqueDecl`. /// `small` is `OpaqueDecl.Small`. opaque_decl, - /// Obtains a pointer to the return value. - /// `operand` is `src_node: i32`. - ret_ptr, - /// Obtains the return type of the in-scope function. - /// `operand` is `src_node: i32`. - ret_type, /// Implements the `@This` builtin. /// `operand` is `src_node: i32`. this, @@ -1917,10 +1910,6 @@ pub const Inst = struct { /// The `@prefetch` builtin. /// `operand` is payload index to `BinNode`. prefetch, - /// Marks the beginning of a semantic scope for debug info variables. - dbg_block_begin, - /// Marks the end of a semantic scope for debug info variables. - dbg_block_end, /// Given a pointer to a struct or object that contains virtual fields, returns the /// named field. If there is no named field, searches in the type for a decl that /// matches the field name. The decl is resolved and we ensure that it's a function @@ -1931,6 +1920,22 @@ pub const Inst = struct { /// `builtin_call` instruction. Any other use is invalid zir and may crash the compiler. /// Uses `pl_node` field. The AST node is the `@field` builtin. Payload is FieldNamedNode. field_call_bind_named, + /// Implements the `@fence` builtin. + /// `operand` is payload index to `UnNode`. + fence, + /// Implement builtin `@setFloatMode`. + /// `operand` is payload index to `UnNode`. + set_float_mode, + /// Implement builtin `@setAlignStack`. + /// `operand` is payload index to `UnNode`. + set_align_stack, + /// Implements the `@errSetCast` builtin. + /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand. + err_set_cast, + /// `operand` is payload index to `UnNode`. + await_nosuspend, + /// `operand` is `src_node: i32`. + breakpoint, pub const InstData = struct { opcode: Extended, @@ -2502,11 +2507,7 @@ pub const Inst = struct { /// Offset from Decl AST node index. /// `Tag` determines which kind of AST node this points to. src_node: i32, - /// `false`: Not safety checked - the compiler will assume the - /// correctness of this instruction. - /// `true`: In safety-checked modes, this will generate a call - /// to the panic function unless it can be proven unreachable by the compiler. - safety: bool, + force_comptime: bool, pub fn src(self: @This()) LazySrcLoc { return .{ .node_offset = self.src_node }; @@ -2623,14 +2624,14 @@ pub const Inst = struct { /// 4. body: Index // for each body_len /// 5. src_locs: Func.SrcLocs // if body_len != 0 pub const ExtendedFunc = struct { - src_node: i32, /// If this is 0 it means a void return type. ret_body_len: u32, /// Points to the block that contains the param instructions for this function. param_block: Index, body_len: u32, + bits: Bits, - pub const Small = packed struct { + pub const Bits = packed struct { is_var_args: bool, is_inferred_error: bool, has_lib_name: bool, @@ -2638,7 +2639,7 @@ pub const Inst = struct { has_align: bool, is_test: bool, is_extern: bool, - _: u9 = undefined, + _: u25 = undefined, }; }; @@ -3462,14 +3463,11 @@ pub fn declIterator(zir: Zir, decl_inst: u32) DeclIterator { switch (tags[decl_inst]) { // Functions are allowed and yield no iterations. // There is one case matching this in the extended instruction set below. - .func, - .func_inferred, - => return declIteratorInner(zir, 0, 0), + .func, .func_inferred, .func_extended => return declIteratorInner(zir, 0, 0), .extended => { const extended = datas[decl_inst].extended; switch (extended.opcode) { - .func => return declIteratorInner(zir, 0, 0), .struct_decl => { const small = @bitCast(Inst.StructDecl.Small, extended.small); var extra_index: usize = extended.operand; @@ -3574,21 +3572,21 @@ fn findDeclsInner( const body = zir.extra[extra.end..][0..extra.data.body_len]; return zir.findDeclsBody(list, body); }, + .func_extended => { + try list.append(inst); + + const inst_data = datas[inst].pl_node; + const extra = zir.extraData(Inst.ExtendedFunc, inst_data.payload_index); + var extra_index: usize = extra.end; + extra_index += @boolToInt(extra.data.bits.has_lib_name); + extra_index += @boolToInt(extra.data.bits.has_cc); + extra_index += @boolToInt(extra.data.bits.has_align); + const body = zir.extra[extra_index..][0..extra.data.body_len]; + return zir.findDeclsBody(list, body); + }, .extended => { const extended = datas[inst].extended; switch (extended.opcode) { - .func => { - try list.append(inst); - - const extra = zir.extraData(Inst.ExtendedFunc, extended.operand); - const small = @bitCast(Inst.ExtendedFunc.Small, extended.small); - var extra_index: usize = extra.end; - extra_index += @boolToInt(small.has_lib_name); - extra_index += @boolToInt(small.has_cc); - extra_index += @boolToInt(small.has_align); - const body = zir.extra[extra_index..][0..extra.data.body_len]; - return zir.findDeclsBody(list, body); - }, // Decl instructions are interesting but have no body. // TODO yes they do have a body actually. recurse over them just like block instructions. @@ -3735,15 +3733,13 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo { .body = body, }; }, - .extended => blk: { - const extended = datas[fn_inst].extended; - assert(extended.opcode == .func); - const extra = zir.extraData(Inst.ExtendedFunc, extended.operand); - const small = @bitCast(Inst.ExtendedFunc.Small, extended.small); + .func_extended => blk: { + const inst_data = datas[fn_inst].pl_node; + const extra = zir.extraData(Inst.ExtendedFunc, inst_data.payload_index); var extra_index: usize = extra.end; - extra_index += @boolToInt(small.has_lib_name); - extra_index += @boolToInt(small.has_cc); - extra_index += @boolToInt(small.has_align); + extra_index += @boolToInt(extra.data.bits.has_lib_name); + extra_index += @boolToInt(extra.data.bits.has_cc); + extra_index += @boolToInt(extra.data.bits.has_align); const ret_ty_body = zir.extra[extra_index..][0..extra.data.ret_body_len]; extra_index += ret_ty_body.len; const body = zir.extra[extra_index..][0..extra.data.body_len]; diff --git a/src/print_zir.zig b/src/print_zir.zig index 776aeffbdc..ac90c26cf6 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -200,9 +200,7 @@ const Writer = struct { .embed_file, .error_name, .panic, - .set_align_stack, .set_cold, - .set_float_mode, .set_runtime_safety, .sqrt, .sin, @@ -231,8 +229,6 @@ const Writer = struct { .elem_type, .@"resume", .@"await", - .await_nosuspend, - .fence, .switch_cond, .switch_cond_ref, .array_base_ptr, @@ -343,7 +339,6 @@ const Writer = struct { .int_to_enum, .float_cast, .int_cast, - .err_set_cast, .ptr_cast, .truncate, .align_cast, @@ -405,13 +400,14 @@ const Writer = struct { .as_node => try self.writeAs(stream, inst), - .breakpoint, .repeat, .repeat_inline, .alloc_inferred, .alloc_inferred_mut, .alloc_inferred_comptime, .alloc_inferred_comptime_mut, + .ret_ptr, + .ret_type, => try self.writeNode(stream, inst), .error_value, @@ -433,6 +429,7 @@ const Writer = struct { .func => try self.writeFunc(stream, inst, false), .func_inferred => try self.writeFunc(stream, inst, true), + .func_extended => try self.writeFuncExtended(stream, inst), .@"unreachable" => try self.writeUnreachable(stream, inst), @@ -444,6 +441,10 @@ const Writer = struct { .dbg_stmt => try self.writeDbgStmt(stream, inst), + .dbg_block_begin, + .dbg_block_end, + => try stream.writeAll("))"), + .closure_get => try self.writeInstNode(stream, inst), .extended => try self.writeExtended(stream, inst), @@ -454,13 +455,12 @@ const Writer = struct { const extended = self.code.instructions.items(.data)[inst].extended; try stream.print("{s}(", .{@tagName(extended.opcode)}); switch (extended.opcode) { - .ret_ptr, - .ret_type, .this, .ret_addr, .error_return_trace, .frame, .frame_address, + .breakpoint, => try self.writeExtNode(stream, extended), .builtin_src => { @@ -469,12 +469,7 @@ const Writer = struct { try stream.print(":{d}:{d}", .{ inst_data.line + 1, inst_data.column + 1 }); }, - .dbg_block_begin, - .dbg_block_end, - => try stream.writeAll("))"), - .@"asm" => try self.writeAsm(stream, extended), - .func => try self.writeFuncExtended(stream, extended), .variable => try self.writeVarExtended(stream, extended), .alloc => try self.writeAllocExtended(stream, extended), @@ -492,7 +487,14 @@ const Writer = struct { .enum_decl => try self.writeEnumDecl(stream, extended), .opaque_decl => try self.writeOpaqueDecl(stream, extended), - .c_undef, .c_include, .wasm_memory_size => { + .await_nosuspend, + .c_undef, + .c_include, + .fence, + .set_float_mode, + .set_align_stack, + .wasm_memory_size, + => { const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data; const src: LazySrcLoc = .{ .node_offset = inst_data.node }; try self.writeInstRef(stream, inst_data.operand); @@ -500,7 +502,12 @@ const Writer = struct { try self.writeSrc(stream, src); }, - .builtin_extern, .c_define, .wasm_memory_grow, .prefetch => { + .builtin_extern, + .c_define, + .err_set_cast, + .wasm_memory_grow, + .prefetch, + => { const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data; const src: LazySrcLoc = .{ .node_offset = inst_data.node }; try self.writeInstRef(stream, inst_data.lhs); @@ -1913,24 +1920,24 @@ const Writer = struct { ); } - fn writeFuncExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { - const extra = self.code.extraData(Zir.Inst.ExtendedFunc, extended.operand); - const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; - const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small); + fn writeFuncExtended(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { + const inst_data = self.code.instructions.items(.data)[inst].pl_node; + const extra = self.code.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index); + const src = inst_data.src(); var extra_index: usize = extra.end; - if (small.has_lib_name) { + if (extra.data.bits.has_lib_name) { const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]); extra_index += 1; try stream.print("lib_name=\"{}\", ", .{std.zig.fmtEscapes(lib_name)}); } - try self.writeFlag(stream, "test, ", small.is_test); - const cc: Zir.Inst.Ref = if (!small.has_cc) .none else blk: { + try self.writeFlag(stream, "test, ", extra.data.bits.is_test); + const cc: Zir.Inst.Ref = if (!extra.data.bits.has_cc) .none else blk: { const cc = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); extra_index += 1; break :blk cc; }; - const align_inst: Zir.Inst.Ref = if (!small.has_align) .none else blk: { + const align_inst: Zir.Inst.Ref = if (!extra.data.bits.has_align) .none else blk: { const align_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); extra_index += 1; break :blk align_inst; @@ -1949,9 +1956,9 @@ const Writer = struct { return self.writeFuncCommon( stream, ret_ty_body, - small.is_inferred_error, - small.is_var_args, - small.is_extern, + extra.data.bits.is_inferred_error, + extra.data.bits.is_var_args, + extra.data.bits.is_extern, cc, align_inst, body, @@ -2091,8 +2098,6 @@ const Writer = struct { fn writeUnreachable(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { const inst_data = self.code.instructions.items(.data)[inst].@"unreachable"; - const safety_str = if (inst_data.safety) "safe" else "unsafe"; - try stream.print("{s}) ", .{safety_str}); try self.writeSrc(stream, inst_data.src()); } |
