| ... | @@ -698,17 +698,27 @@ pub const Object = struct { | ... | @@ -698,17 +698,27 @@ pub const Object = struct { |
| 698 | indent_counter: usize, | 698 | indent_counter: usize, |
| 699 | | 699 | |
| 700 | const indent_width = 1; | 700 | const indent_width = 1; |
| | 701 | const indent_char = ' '; |
| 701 | | 702 | |
| 702 | fn newline(o: *Object) !void { | 703 | fn newline(o: *Object) !void { |
| 703 | const bw = &o.code.buffered_writer; | 704 | const bw = &o.code.buffered_writer; |
| 704 | try bw.writeByte('\n'); | 705 | try bw.writeByte('\n'); |
| 705 | try bw.splatByteAll(' ', o.indent_counter); | 706 | try bw.splatByteAll(indent_char, o.indent_counter); |
| 706 | } | 707 | } |
| 707 | fn indent(o: *Object) void { | 708 | fn indent(o: *Object) void { |
| 708 | o.indent_counter += indent_width; | 709 | o.indent_counter += indent_width; |
| 709 | } | 710 | } |
| 710 | fn outdent(o: *Object) void { | 711 | fn outdent(o: *Object) !void { |
| 711 | o.indent_counter -= indent_width; | 712 | o.indent_counter -= indent_width; |
| | 713 | const written = o.code.getWritten(); |
| | 714 | switch (written[written.len - 1]) { |
| | 715 | indent_char => o.code.shrinkRetainingCapacity(written.len - indent_width), |
| | 716 | '\n' => try o.code.buffered_writer.splatByteAll(indent_char, o.indent_counter), |
| | 717 | else => { |
| | 718 | std.debug.print("\"{f}\"\n", .{std.zig.fmtEscapes(written[written.len -| 100..])}); |
| | 719 | unreachable; |
| | 720 | }, |
| | 721 | } |
| 712 | } | 722 | } |
| 713 | }; | 723 | }; |
| 714 | | 724 | |
| ... | @@ -1041,7 +1051,7 @@ pub const DeclGen = struct { | ... | @@ -1041,7 +1051,7 @@ pub const DeclGen = struct { |
| 1041 | .error_union => |error_union| switch (ctype.info(ctype_pool)) { | 1051 | .error_union => |error_union| switch (ctype.info(ctype_pool)) { |
| 1042 | .basic => switch (error_union.val) { | 1052 | .basic => switch (error_union.val) { |
| 1043 | .err_name => |err_name| try dg.renderErrorName(writer, err_name), | 1053 | .err_name => |err_name| try dg.renderErrorName(writer, err_name), |
| 1044 | .payload => try writer.writeAll("0"), | 1054 | .payload => try writer.writeByte('0'), |
| 1045 | }, | 1055 | }, |
| 1046 | .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable, | 1056 | .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable, |
| 1047 | .aggregate => |aggregate| { | 1057 | .aggregate => |aggregate| { |
| ... | @@ -1197,7 +1207,7 @@ pub const DeclGen = struct { | ... | @@ -1197,7 +1207,7 @@ pub const DeclGen = struct { |
| 1197 | .none => "true", | 1207 | .none => "true", |
| 1198 | else => "false", | 1208 | else => "false", |
| 1199 | }) else switch (opt.val) { | 1209 | }) else switch (opt.val) { |
| 1200 | .none => try writer.writeAll("0"), | 1210 | .none => try writer.writeByte('0'), |
| 1201 | else => |payload| switch (ip.indexToKey(payload)) { | 1211 | else => |payload| switch (ip.indexToKey(payload)) { |
| 1202 | .undef => |err_ty| try dg.renderUndefValue( | 1212 | .undef => |err_ty| try dg.renderUndefValue( |
| 1203 | writer, | 1213 | writer, |
| ... | @@ -1528,7 +1538,7 @@ pub const DeclGen = struct { | ... | @@ -1528,7 +1538,7 @@ pub const DeclGen = struct { |
| 1528 | try writer.writeByte(')'); | 1538 | try writer.writeByte(')'); |
| 1529 | } | 1539 | } |
| 1530 | try dg.renderValue(writer, Value.fromInterned(un.val), location); | 1540 | try dg.renderValue(writer, Value.fromInterned(un.val), location); |
| 1531 | } else try writer.writeAll("0"); | 1541 | } else try writer.writeByte('0'); |
| 1532 | return; | 1542 | return; |
| 1533 | } | 1543 | } |
| 1534 | | 1544 | |
| ... | @@ -2786,7 +2796,7 @@ pub fn genErrDecls(o: *Object) Error!void { | ... | @@ -2786,7 +2796,7 @@ pub fn genErrDecls(o: *Object) Error!void { |
| 2786 | try bw.print(" = {d}u,", .{value}); | 2796 | try bw.print(" = {d}u,", .{value}); |
| 2787 | try o.newline(); | 2797 | try o.newline(); |
| 2788 | } | 2798 | } |
| 2789 | o.outdent(); | 2799 | try o.outdent(); |
| 2790 | try bw.writeAll("};"); | 2800 | try bw.writeAll("};"); |
| 2791 | try o.newline(); | 2801 | try o.newline(); |
| 2792 | } | 2802 | } |
| ... | @@ -2895,6 +2905,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn | ... | @@ -2895,6 +2905,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn |
| 2895 | try bw.print("case {f}: {{", .{ | 2905 | try bw.print("case {f}: {{", .{ |
| 2896 | try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, pt), .Other), | 2906 | try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, pt), .Other), |
| 2897 | }); | 2907 | }); |
| | 2908 | o.indent(); |
| 2898 | try o.newline(); | 2909 | try o.newline(); |
| 2899 | try bw.writeAll("static "); | 2910 | try bw.writeAll("static "); |
| 2900 | try o.dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, Const, .none, .complete); | 2911 | try o.dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, Const, .none, .complete); |
| ... | @@ -2909,16 +2920,15 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn | ... | @@ -2909,16 +2920,15 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn |
| 2909 | try o.dg.fmtIntLiteral(try pt.intValue(.usize, tag_name_len), .Other), | 2920 | try o.dg.fmtIntLiteral(try pt.intValue(.usize, tag_name_len), .Other), |
| 2910 | }); | 2921 | }); |
| 2911 | try o.newline(); | 2922 | try o.newline(); |
| 2912 | | 2923 | try o.outdent(); |
| 2913 | try bw.writeByte('}'); | 2924 | try bw.writeByte('}'); |
| 2914 | try o.newline(); | 2925 | try o.newline(); |
| 2915 | } | 2926 | } |
| | 2927 | try o.outdent(); |
| 2916 | try bw.writeByte('}'); | 2928 | try bw.writeByte('}'); |
| 2917 | try o.newline(); | 2929 | try o.newline(); |
| 2918 | try bw.writeAll("while ("); | 2930 | try airUnreach(o); |
| 2919 | try o.dg.renderValue(bw, Value.true, .Other); | 2931 | try o.outdent(); |
| 2920 | try bw.writeAll(") "); | | |
| 2921 | _ = try airBreakpoint(o, bw); | | |
| 2922 | try bw.writeByte('}'); | 2932 | try bw.writeByte('}'); |
| 2923 | try o.newline(); | 2933 | try o.newline(); |
| 2924 | }, | 2934 | }, |
| ... | @@ -2940,6 +2950,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn | ... | @@ -2940,6 +2950,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn |
| 2940 | .fmt_ctype_pool_string = fn_name, | 2950 | .fmt_ctype_pool_string = fn_name, |
| 2941 | }); | 2951 | }); |
| 2942 | try bw.writeAll(" {"); | 2952 | try bw.writeAll(" {"); |
| | 2953 | o.indent(); |
| 2943 | try o.newline(); | 2954 | try o.newline(); |
| 2944 | try bw.writeAll("return "); | 2955 | try bw.writeAll("return "); |
| 2945 | try o.dg.renderNavName(bw, fn_nav_index); | 2956 | try o.dg.renderNavName(bw, fn_nav_index); |
| ... | @@ -2950,6 +2961,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn | ... | @@ -2950,6 +2961,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn |
| 2950 | } | 2961 | } |
| 2951 | try bw.writeAll(");"); | 2962 | try bw.writeAll(");"); |
| 2952 | try o.newline(); | 2963 | try o.newline(); |
| | 2964 | try o.outdent(); |
| 2953 | try bw.writeByte('}'); | 2965 | try bw.writeByte('}'); |
| 2954 | try o.newline(); | 2966 | try o.newline(); |
| 2955 | }, | 2967 | }, |
| ... | @@ -3066,7 +3078,10 @@ fn genFunc(f: *Function) !void { | ... | @@ -3066,7 +3078,10 @@ fn genFunc(f: *Function) !void { |
| 3066 | f.free_locals_map.clearRetainingCapacity(); | 3078 | f.free_locals_map.clearRetainingCapacity(); |
| 3067 | | 3079 | |
| 3068 | const main_body = f.air.getMainBody(); | 3080 | const main_body = f.air.getMainBody(); |
| 3069 | try genBodyResolveState(f, undefined, &.{}, main_body, false); | 3081 | o.indent(); |
| | 3082 | try genBodyResolveState(f, undefined, &.{}, main_body, true); |
| | 3083 | try o.outdent(); |
| | 3084 | try o.code.buffered_writer.writeByte('}'); |
| 3070 | try o.newline(); | 3085 | try o.newline(); |
| 3071 | if (o.dg.expected_block) |_| | 3086 | if (o.dg.expected_block) |_| |
| 3072 | return f.fail("runtime code not allowed in naked function", .{}); | 3087 | return f.fail("runtime code not allowed in naked function", .{}); |
| ... | @@ -3285,11 +3300,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void { | ... | @@ -3285,11 +3300,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void { |
| 3285 | if (body.len == 0) { | 3300 | if (body.len == 0) { |
| 3286 | try bw.writeAll("{}"); | 3301 | try bw.writeAll("{}"); |
| 3287 | } else { | 3302 | } else { |
| 3288 | try bw.writeAll("{"); | 3303 | try bw.writeByte('{'); |
| 3289 | f.object.indent(); | 3304 | f.object.indent(); |
| 3290 | try f.object.newline(); | 3305 | try f.object.newline(); |
| 3291 | try genBodyInner(f, body); | 3306 | try genBodyInner(f, body); |
| 3292 | f.object.outdent(); | 3307 | try f.object.outdent(); |
| 3293 | try bw.writeByte('}'); | 3308 | try bw.writeByte('}'); |
| 3294 | } | 3309 | } |
| 3295 | } | 3310 | } |
| ... | @@ -3367,7 +3382,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { | ... | @@ -3367,7 +3382,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { |
| 3367 | | 3382 | |
| 3368 | .arg => try airArg(f, inst), | 3383 | .arg => try airArg(f, inst), |
| 3369 | | 3384 | |
| 3370 | .breakpoint => try airBreakpoint(&f.object, &f.object.code.buffered_writer), | 3385 | .breakpoint => try airBreakpoint(f), |
| 3371 | .ret_addr => try airRetAddr(f, inst), | 3386 | .ret_addr => try airRetAddr(f, inst), |
| 3372 | .frame_addr => try airFrameAddress(f, inst), | 3387 | .frame_addr => try airFrameAddress(f, inst), |
| 3373 | | 3388 | |
| ... | @@ -3621,7 +3636,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { | ... | @@ -3621,7 +3636,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { |
| 3621 | .ret_safe => return airRet(f, inst, false), // TODO | 3636 | .ret_safe => return airRet(f, inst, false), // TODO |
| 3622 | .ret_load => return airRet(f, inst, true), | 3637 | .ret_load => return airRet(f, inst, true), |
| 3623 | .trap => return airTrap(f, &f.object.code.buffered_writer), | 3638 | .trap => return airTrap(f, &f.object.code.buffered_writer), |
| 3624 | .unreach => return airUnreach(f), | 3639 | .unreach => return airUnreach(&f.object), |
| 3625 | | 3640 | |
| 3626 | // Instructions which may be `noreturn`. | 3641 | // Instructions which may be `noreturn`. |
| 3627 | .block => res: { | 3642 | .block => res: { |
| ... | @@ -4017,18 +4032,14 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void { | ... | @@ -4017,18 +4032,14 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void { |
| 4017 | try f.writeCValueDeref(bw, ret_val) | 4032 | try f.writeCValueDeref(bw, ret_val) |
| 4018 | else | 4033 | else |
| 4019 | try f.writeCValue(bw, ret_val, .Other); | 4034 | try f.writeCValue(bw, ret_val, .Other); |
| 4020 | try bw.writeByte(';'); | 4035 | try bw.writeAll(";\n"); |
| 4021 | try f.object.newline(); | | |
| 4022 | if (is_array) { | 4036 | if (is_array) { |
| 4023 | try freeLocal(f, inst, ret_val.new_local, null); | 4037 | try freeLocal(f, inst, ret_val.new_local, null); |
| 4024 | } | 4038 | } |
| 4025 | } else { | 4039 | } else { |
| 4026 | try reap(f, inst, &.{un_op}); | 4040 | try reap(f, inst, &.{un_op}); |
| 4027 | // Not even allowed to return void in a naked function. | 4041 | // Not even allowed to return void in a naked function. |
| 4028 | if (!f.object.dg.is_naked_fn) { | 4042 | if (!f.object.dg.is_naked_fn) try bw.writeAll("return;\n"); |
| 4029 | try bw.writeAll("return;"); | | |
| 4030 | try f.object.newline(); | | |
| 4031 | } | | |
| 4032 | } | 4043 | } |
| 4033 | } | 4044 | } |
| 4034 | | 4045 | |
| ... | @@ -4817,7 +4828,10 @@ fn airCall( | ... | @@ -4817,7 +4828,10 @@ fn airCall( |
| 4817 | try f.freeCValue(inst, resolved_arg); | 4828 | try f.freeCValue(inst, resolved_arg); |
| 4818 | } | 4829 | } |
| 4819 | try bw.writeAll(");"); | 4830 | try bw.writeAll(");"); |
| 4820 | try f.object.newline(); | 4831 | switch (modifier) { |
| | 4832 | .always_tail => try bw.writeByte('\n'), |
| | 4833 | else => try f.object.newline(), |
| | 4834 | } |
| 4821 | | 4835 | |
| 4822 | const result = result: { | 4836 | const result = result: { |
| 4823 | if (result_local == .none or !lowersToArray(ret_ty, pt)) | 4837 | if (result_local == .none or !lowersToArray(ret_ty, pt)) |
| ... | @@ -4925,8 +4939,6 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) | ... | @@ -4925,8 +4939,6 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) |
| 4925 | try die(f, inst, death.toRef()); | 4939 | try die(f, inst, death.toRef()); |
| 4926 | } | 4940 | } |
| 4927 | | 4941 | |
| 4928 | try f.object.newline(); | | |
| 4929 | | | |
| 4930 | // noreturn blocks have no `br` instructions reaching them, so we don't want a label | 4942 | // noreturn blocks have no `br` instructions reaching them, so we don't want a label |
| 4931 | if (f.object.dg.is_naked_fn) { | 4943 | if (f.object.dg.is_naked_fn) { |
| 4932 | if (f.object.dg.expected_block) |expected_block| { | 4944 | if (f.object.dg.expected_block) |expected_block| { |
| ... | @@ -4936,7 +4948,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) | ... | @@ -4936,7 +4948,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) |
| 4936 | } | 4948 | } |
| 4937 | } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) { | 4949 | } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) { |
| 4938 | // label must be followed by an expression, include an empty one. | 4950 | // label must be followed by an expression, include an empty one. |
| 4939 | try bw.print("zig_block_{d}:;", .{block_id}); | 4951 | try bw.print("\nzig_block_{d}:;", .{block_id}); |
| 4940 | try f.object.newline(); | 4952 | try f.object.newline(); |
| 4941 | } | 4953 | } |
| 4942 | | 4954 | |
| ... | @@ -5057,14 +5069,12 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void { | ... | @@ -5057,14 +5069,12 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void { |
| 5057 | try a.end(f, bw); | 5069 | try a.end(f, bw); |
| 5058 | } | 5070 | } |
| 5059 | | 5071 | |
| 5060 | try bw.print("goto zig_block_{d};", .{block.block_id}); | 5072 | try bw.print("goto zig_block_{d};\n", .{block.block_id}); |
| 5061 | try f.object.newline(); | | |
| 5062 | } | 5073 | } |
| 5063 | | 5074 | |
| 5064 | fn airRepeat(f: *Function, inst: Air.Inst.Index) !void { | 5075 | fn airRepeat(f: *Function, inst: Air.Inst.Index) !void { |
| 5065 | const repeat = f.air.instructions.items(.data)[@intFromEnum(inst)].repeat; | 5076 | const repeat = f.air.instructions.items(.data)[@intFromEnum(inst)].repeat; |
| 5066 | try f.object.code.buffered_writer.print("goto zig_loop_{d};", .{@intFromEnum(repeat.loop_inst)}); | 5077 | try f.object.code.buffered_writer.print("goto zig_loop_{d};\n", .{@intFromEnum(repeat.loop_inst)}); |
| 5067 | try f.object.newline(); | | |
| 5068 | } | 5078 | } |
| 5069 | | 5079 | |
| 5070 | fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void { | 5080 | fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void { |
| ... | @@ -5093,8 +5103,7 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void { | ... | @@ -5093,8 +5103,7 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void { |
| 5093 | } | 5103 | } |
| 5094 | } | 5104 | } |
| 5095 | } else switch_br.cases_len; | 5105 | } else switch_br.cases_len; |
| 5096 | try bw.print("goto zig_switch_{d}_dispatch_{d};", .{ @intFromEnum(br.block_inst), target_case_idx }); | 5106 | try bw.print("goto zig_switch_{d}_dispatch_{d};\n", .{ @intFromEnum(br.block_inst), target_case_idx }); |
| 5097 | try f.object.newline(); | | |
| 5098 | return; | 5107 | return; |
| 5099 | } | 5108 | } |
| 5100 | | 5109 | |
| ... | @@ -5106,7 +5115,7 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void { | ... | @@ -5106,7 +5115,7 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void { |
| 5106 | try f.writeCValue(bw, cond, .Other); | 5115 | try f.writeCValue(bw, cond, .Other); |
| 5107 | try bw.writeByte(';'); | 5116 | try bw.writeByte(';'); |
| 5108 | try f.object.newline(); | 5117 | try f.object.newline(); |
| 5109 | try bw.print("goto zig_switch_{d}_loop;", .{@intFromEnum(br.block_inst)}); | 5118 | try bw.print("goto zig_switch_{d}_loop;\n", .{@intFromEnum(br.block_inst)}); |
| 5110 | } | 5119 | } |
| 5111 | | 5120 | |
| 5112 | fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | 5121 | fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | @@ -5241,13 +5250,13 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal | ... | @@ -5241,13 +5250,13 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal |
| 5241 | fn airTrap(f: *Function, bw: *std.io.BufferedWriter) !void { | 5250 | fn airTrap(f: *Function, bw: *std.io.BufferedWriter) !void { |
| 5242 | // Not even allowed to call trap in a naked function. | 5251 | // Not even allowed to call trap in a naked function. |
| 5243 | if (f.object.dg.is_naked_fn) return; | 5252 | if (f.object.dg.is_naked_fn) return; |
| 5244 | try bw.writeAll("zig_trap();"); | 5253 | try bw.writeAll("zig_trap();\n"); |
| 5245 | try f.object.newline(); | | |
| 5246 | } | 5254 | } |
| 5247 | | 5255 | |
| 5248 | fn airBreakpoint(o: *Object, bw: *std.io.BufferedWriter) !CValue { | 5256 | fn airBreakpoint(f: *Function) !CValue { |
| | 5257 | const bw = &f.object.code.buffered_writer; |
| 5249 | try bw.writeAll("zig_breakpoint();"); | 5258 | try bw.writeAll("zig_breakpoint();"); |
| 5250 | try o.newline(); | 5259 | try f.object.newline(); |
| 5251 | return .none; | 5260 | return .none; |
| 5252 | } | 5261 | } |
| 5253 | | 5262 | |
| ... | @@ -5273,11 +5282,10 @@ fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5273,11 +5282,10 @@ fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5273 | return local; | 5282 | return local; |
| 5274 | } | 5283 | } |
| 5275 | | 5284 | |
| 5276 | fn airUnreach(f: *Function) !void { | 5285 | fn airUnreach(o: *Object) !void { |
| 5277 | // Not even allowed to call unreachable in a naked function. | 5286 | // Not even allowed to call unreachable in a naked function. |
| 5278 | if (f.object.dg.is_naked_fn) return; | 5287 | if (o.dg.is_naked_fn) return; |
| 5279 | try f.object.code.buffered_writer.writeAll("zig_unreachable();"); | 5288 | try o.code.buffered_writer.writeAll("zig_unreachable();\n"); |
| 5280 | try f.object.newline(); | | |
| 5281 | } | 5289 | } |
| 5282 | | 5290 | |
| 5283 | fn airLoop(f: *Function, inst: Air.Inst.Index) !void { | 5291 | fn airLoop(f: *Function, inst: Air.Inst.Index) !void { |
| ... | @@ -5407,10 +5415,11 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void | ... | @@ -5407,10 +5415,11 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void |
| 5407 | f.object.indent(); | 5415 | f.object.indent(); |
| 5408 | try f.object.newline(); | 5416 | try f.object.newline(); |
| 5409 | if (is_dispatch_loop) { | 5417 | if (is_dispatch_loop) { |
| 5410 | try bw.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx }); | 5418 | try bw.print("zig_switch_{d}_dispatch_{d}:;", .{ @intFromEnum(inst), case.idx }); |
| | 5419 | try f.object.newline(); |
| 5411 | } | 5420 | } |
| 5412 | try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true); | 5421 | try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true); |
| 5413 | f.object.outdent(); | 5422 | try f.object.outdent(); |
| 5414 | try bw.writeByte('}'); | 5423 | try bw.writeByte('}'); |
| 5415 | if (f.object.dg.expected_block) |_| | 5424 | if (f.object.dg.expected_block) |_| |
| 5416 | return f.fail("runtime code not allowed in naked function", .{}); | 5425 | return f.fail("runtime code not allowed in naked function", .{}); |
| ... | @@ -5456,7 +5465,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void | ... | @@ -5456,7 +5465,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void |
| 5456 | try bw.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx }); | 5465 | try bw.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx }); |
| 5457 | } | 5466 | } |
| 5458 | try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true); | 5467 | try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true); |
| 5459 | f.object.outdent(); | 5468 | try f.object.outdent(); |
| 5460 | try bw.writeByte('}'); | 5469 | try bw.writeByte('}'); |
| 5461 | if (f.object.dg.expected_block) |_| | 5470 | if (f.object.dg.expected_block) |_| |
| 5462 | return f.fail("runtime code not allowed in naked function", .{}); | 5471 | return f.fail("runtime code not allowed in naked function", .{}); |
| ... | @@ -5474,14 +5483,10 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void | ... | @@ -5474,14 +5483,10 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void |
| 5474 | try genBody(f, else_body); | 5483 | try genBody(f, else_body); |
| 5475 | if (f.object.dg.expected_block) |_| | 5484 | if (f.object.dg.expected_block) |_| |
| 5476 | return f.fail("runtime code not allowed in naked function", .{}); | 5485 | return f.fail("runtime code not allowed in naked function", .{}); |
| 5477 | } else { | 5486 | } else try airUnreach(&f.object); |
| 5478 | try bw.writeAll("zig_unreachable();"); | | |
| 5479 | } | | |
| 5480 | try f.object.newline(); | | |
| 5481 | | | |
| 5482 | f.object.outdent(); | | |
| 5483 | try bw.writeByte('}'); | | |
| 5484 | try f.object.newline(); | 5487 | try f.object.newline(); |
| | 5488 | try f.object.outdent(); |
| | 5489 | try bw.writeAll("}\n"); |
| 5485 | } | 5490 | } |
| 5486 | | 5491 | |
| 5487 | fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool { | 5492 | fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool { |
| ... | @@ -6868,7 +6873,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue | ... | @@ -6868,7 +6873,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 6868 | try bw.writeAll("NULL"); | 6873 | try bw.writeAll("NULL"); |
| 6869 | try a.end(f, bw); | 6874 | try a.end(f, bw); |
| 6870 | } | 6875 | } |
| 6871 | f.object.outdent(); | 6876 | try f.object.outdent(); |
| 6872 | try bw.writeByte('}'); | 6877 | try bw.writeByte('}'); |
| 6873 | try f.object.newline(); | 6878 | try f.object.newline(); |
| 6874 | } else { | 6879 | } else { |
| ... | @@ -8119,6 +8124,7 @@ fn compareOperatorC(operator: std.math.CompareOperator) []const u8 { | ... | @@ -8119,6 +8124,7 @@ fn compareOperatorC(operator: std.math.CompareOperator) []const u8 { |
| 8119 | const StringLiteral = struct { | 8124 | const StringLiteral = struct { |
| 8120 | len: usize, | 8125 | len: usize, |
| 8121 | cur_len: usize, | 8126 | cur_len: usize, |
| | 8127 | start_count: usize, |
| 8122 | bw: *std.io.BufferedWriter, | 8128 | bw: *std.io.BufferedWriter, |
| 8123 | | 8129 | |
| 8124 | // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal, | 8130 | // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal, |
| ... | @@ -8136,6 +8142,7 @@ const StringLiteral = struct { | ... | @@ -8136,6 +8142,7 @@ const StringLiteral = struct { |
| 8136 | return .{ | 8142 | return .{ |
| 8137 | .cur_len = 0, | 8143 | .cur_len = 0, |
| 8138 | .len = len, | 8144 | .len = len, |
| | 8145 | .start_count = bw.count, |
| 8139 | .bw = bw, | 8146 | .bw = bw, |
| 8140 | }; | 8147 | }; |
| 8141 | } | 8148 | } |
| ... | @@ -8175,7 +8182,7 @@ const StringLiteral = struct { | ... | @@ -8175,7 +8182,7 @@ const StringLiteral = struct { |
| 8175 | | 8182 | |
| 8176 | pub fn writeChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void { | 8183 | pub fn writeChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void { |
| 8177 | if (sl.len <= max_string_initializer_len) { | 8184 | if (sl.len <= max_string_initializer_len) { |
| 8178 | if (sl.cur_len == 0 and sl.bw.count > 1) | 8185 | if (sl.cur_len == 0 and sl.bw.count - sl.start_count > 1) |
| 8179 | try sl.bw.writeAll("\"\""); | 8186 | try sl.bw.writeAll("\"\""); |
| 8180 | | 8187 | |
| 8181 | const count = sl.bw.count; | 8188 | const count = sl.bw.count; |
| ... | @@ -8186,7 +8193,7 @@ const StringLiteral = struct { | ... | @@ -8186,7 +8193,7 @@ const StringLiteral = struct { |
| 8186 | | 8193 | |
| 8187 | if (sl.cur_len >= max_literal_len) sl.cur_len = 0; | 8194 | if (sl.cur_len >= max_literal_len) sl.cur_len = 0; |
| 8188 | } else { | 8195 | } else { |
| 8189 | if (sl.bw.count > 1) try sl.bw.writeByte(','); | 8196 | if (sl.bw.count - sl.start_count > 1) try sl.bw.writeByte(','); |
| 8190 | try sl.bw.print("'\\x{x}'", .{c}); | 8197 | try sl.bw.print("'\\x{x}'", .{c}); |
| 8191 | } | 8198 | } |
| 8192 | } | 8199 | } |
| ... | @@ -8502,7 +8509,7 @@ const Vectorize = struct { | ... | @@ -8502,7 +8509,7 @@ const Vectorize = struct { |
| 8502 | | 8509 | |
| 8503 | pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, bw: *std.io.BufferedWriter) !void { | 8510 | pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, bw: *std.io.BufferedWriter) !void { |
| 8504 | if (self.index != .none) { | 8511 | if (self.index != .none) { |
| 8505 | f.object.outdent(); | 8512 | try f.object.outdent(); |
| 8506 | try bw.writeByte('}'); | 8513 | try bw.writeByte('}'); |
| 8507 | try f.object.newline(); | 8514 | try f.object.newline(); |
| 8508 | try freeLocal(f, inst, self.index.new_local, null); | 8515 | try freeLocal(f, inst, self.index.new_local, null); |